Torne seu idioma * principalmente * inutilizável! (Tópico dos policiais)

61

Inspirado por este comentário ...

Obrigado aos usuários Step Hen , Wheat-Wizard e Dennis por ajudarem a solidificar a especificação deste desafio antes de publicá-lo!

Este é o tópico dos policiais. Para o tópico dos ladrões, clique aqui


Nesse desafio , você tem a tarefa de executar um código que o torna para que sua linguagem não atenda mais aos nossos critérios de ser uma linguagem de programação. Nesse desafio, isso significa fazer com que o idioma não possa mais ...

  • Obter entrada e saída numéricas

  • Adicione dois números juntos

  • Teste se um determinado número é primo ou não.

Esse é um desafio de , onde há dois desafios diferentes com dois objetivos diferentes: os policiais tentarão escrever algum código que torne a linguagem praticamente inutilizável e os ladrões tentarão encontrar a solução alternativa oculta que permite que os policiais recuperar o idioma deles.

Como policial, você deve escrever dois trechos de código:

  1. Um que torna seu idioma praticamente inutilizável, por exemplo, removendo funções internas para realizar operações numéricas e de entrada / saída. Quanto mais recursos você remover, melhor. Este código não tem permissão para travar ou sair. Deve ser possível adicionar código ao final deste trecho, e esse código será avaliado . E...

  2. ... um trecho de código que recebe dois números inteiros não negativos como entrada, os adiciona e gera sua soma. Esse trecho ainda deve funcionar corretamente mesmo após a execução do primeiro trecho. Quando os dois trechos são combinados, eles devem formar um programa completo que adicione dois números ou definir uma função que adicione dois números. Idealmente, esse snippet deve se basear em comportamentos muito obscuros, para ser mais difícil de encontrar.

Você pode escolher qualquer método padrão de entrada e saída . No entanto, você deve revelar exatamente qual formato (entrada e saída) está usando. Um ladrão não pode decifrar sua resposta, a menos que use o mesmo formato que você.

Depois de escrever esses dois trechos, você deve postar o primeiro como resposta, sem revelar o segundo. Sua resposta deve conter todas as informações a seguir:

  • O primeiro trecho (obviamente não o segundo).

  • Idioma (incluindo versão secundária, já que a maioria dos envios provavelmente dependerá de casos extremos)

  • Formato IO, incluindo se é uma função ou um programa completo. Os ladrões devem usar o mesmo formato para que sua fenda seja válida.

  • Quaisquer casos extremos estranhos necessários para que sua resposta funcione. Por exemplo, é executado apenas no linux ou requer uma conexão com a Internet . Obviamente, isso é um pouco subjetivo, mas se um policial tem algum caso extremo que o impede de rachar e só revela isso depois de estar seguro, considero esse mau espírito esportivo. Um ladrão em potencial deve ter todas as informações necessárias para decifrar sua resposta antes que ela seja decifrada.

Você não precisa revelar sua contagem de bytes até que sua resposta esteja segura.

Aqui está um exemplo. Para o primeiro snippet, você pode enviar o seguinte programa Python 3:

Python 3

print=None

Leva a entrada de STDIN e a saída para STDOUT

E então, como seu segundo trecho, você pode escrever:

import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Isso é válido porque ele recebe dois números como entrada e gera a soma deles, mesmo que você junte os dois trechos, por exemplo

print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

No entanto, será extremamente fácil para um ladrão encontrar uma solução. Como isso seria muito fácil de decifrar, você pode tentar corrigir esta abordagem específica da seguinte maneira:

import sys
sys.stdout=None
print=None

No entanto, mesmo isso tem uma solução muito fácil:

del print
a,b=int(input()),int(input())
print(a+b)

Como policial, seu objetivo é tornar a solução oculta o mais obscura possível, para impedir que os ladrões a encontrem.

Os ladrões vão olhar para uma das suas respostas e tentar decifrá-la. Eles podem decifrá-lo escrevendo qualquer trecho válido que possa funcionar como o trecho 2 (adicionando dois números depois que o idioma ficar inutilizável). Isso não precisa ser o mesmo snippet que você pretendia originalmente. Se um ladrão quebrar sua resposta, ele deixará um comentário e, em seguida, você deverá editá-lo para indicar que foi quebrado. Se sua postagem estiver com problemas, edite sua resposta para mostrar a solução (snippet 2) que você pretendia originalmente. Esta não é uma regra em si , apenas uma sugestão amigável para manter o jogo divertido. Você não tem que.

Se uma resposta permanecer sem quebra por uma semana inteira, você poderá editar seu segundo snippet e indicar que sua resposta está segura . Se você não editá-lo depois que a semana terminar, outros usuários ainda poderão decifrá-lo até você. Se você não revelar seu segundo trecho, não poderá reivindicar pontos por sua resposta ou chamá-lo de seguro.

O vencedor do tópico da polícia é a resposta mais curta e segura, incluindo os dois trechos , contados em bytes, e essa resposta será aceita após um tempo suficiente. Você não precisa revelar sua contagem de bytes até que sua resposta seja segura, pois a contagem de bytes é irrelevante para sua pontuação até que sua resposta seja segura. No caso de ter passado tempo suficiente e nenhuma resposta permanecer sem quebra, o vencedor será a resposta que permanecerá sem quebra por mais tempo.

Diverta-se!

Esclarecimentos sobre regras

  • O primeiro trecho deve ser executado corretamente sem receber nenhuma entrada . Pode produzir o que você quiser e essa saída será ignorada - desde que o snippet seja concluído, o segundo snippet será executado corretamente.

  • O segundo trecho deve realmente ser executado para que sua resposta seja válida. Isso significa uma resposta como

    import sys
    sys.exit()
    

    não é válido porque não quebra o idioma. Simplesmente sai. Da mesma forma, a inserção de um loop infinito não é válida, pois o segundo trecho nunca será executado.

  • Depois de estar seguro, sua pontuação é a contagem de bytes de ambos os trechos .

  • Isso remonta a Por favor, revele quaisquer casos extremos estranhos necessários para que sua resposta funcione ... Seu envio deve conter informações suficientes antes de ser revelado para ser reproduzível após ser revelado. Isso significa que se sua resposta se tornar segura e você editar em: Aqui está a minha resposta. Ah, sim, BTW isso só funciona se você executá-lo no Solaris, a piada é sua! sua resposta é inválida e será excluída e não será considerada elegível para ganhar.

  • O segundo trecho pode travar após a saída da soma - desde que a saída ainda esteja correta (por exemplo, se você optar por enviar para STDERR e obter várias informações de falha, isso é inválido).

  • Você não pode editar seu código depois de enviar uma resposta.

  • Você não pode confiar em funções criptográficas como criptografia, funções de hash, CSPRNGs etc.

Snippet para encontrar envios sem rachaduras:

DJMcMayhem
fonte
3
O que deve ser feito para idiomas como C? A concatenação permite apenas um "snippet principal", e qualquer lógica terá que ir para lá. Por exemplo, se eu tiver int main(){ do_evil_stuff(); }onde o código de usuários deve ir? Em uma função? Depois de todas as declarações em main?
Conor O'Brien
11
O segundo trecho pode ser colocado em qualquer lugar do primeiro trecho?
precisa
11
Não sei nada sobre codificação, mas este desafio parece incrível,
Pritt Balagopal
2
Eu editei no incrível trecho de jimmy23013 . Sinta-se à vontade para reverter, mas eu mesmo o estava usando para encontrar envios e achei que poderia ajudar outras pessoas.
Dom Hastings
2
@DomHastings Isso é extremamente útil! Muito obrigado :)
DJMcMayhem

Respostas:

2

Gforth 0.7.3 (TIO) , 231 bytes [SAFE]

Esse código redefine como inúteis alguns métodos de saída necessários, além de adição e algo crucial para declarar funções. Boa sorte!

: . ;
: dec. ;
: u. ;
: .r ;
: u.r ;
: d. ;
: ud. ;
: d.r ;
: ud.r ;
: emit ;
: type ;
: + postpone 2drop ;
: ; + + + postpone exit reveal postpone [ ;

A entrada será dois números inteiros assinados, retirados da parte superior da pilha como parâmetros de função. Saída para STDOUT.

Portanto, você deve corrigir o dano causado e definir uma função que retire os dois principais valores da pilha e imprima o resultado como um número inteiro (não um float) em STDOUT sem saída adicional (sem espaço à direita).

Aqui está um modelo , se sua função de objetivo for nomeada f.

Solução:



Na verdade, removi a immediatepalavra-chave do final da redefinição de 79 bytes; ; portanto, era necessário que uma resposta a incluísse no início. A função que defini é basicamente equivalente à definição interna de ., mas não imprime o espaço no final e a adição é realizada primeiro, movendo os números para a pilha de ponto flutuante e vice-versa.

immediate : f s>f s>f f+ f>d swap over dabs <<# #s rot sign #> (type) #>> 0 0 ;

Experimente online

mbomb007
fonte
11
Esta é uma resposta muito boa. Nesse ritmo, parece que pode acabar sendo a única resposta sem quebra!
DJMcMayhem
:) Combinei alguns obstáculos diferentes. Neste momento, estou pensando se poderia ter feito apenas uma para melhorar minha pontuação. Mas é possível que ter mais de um seja o motivo pelo qual ele ainda não tenha sido quebrado.
mbomb007
21

Haskell, rachado por Christian Sievers

import Prelude(getLine,print)
a=a

Programa completo, lendo dois números inteiros (incluindo negativos) de stdin e escrevendo para stdout.

Acabei de desativar o Prelude, então quase nada está no escopo e adicionei uma definição; importações adicionais são sintaticamente inválidas. Eu te dei getLinee pensei print.


Editado para adicionar minha solução original. O crack de Christian era diferente, mas explora os mesmos recursos básicos (você pode obter uma quantidade surpreendente de computação acessando funções que possuem açúcar sintático, mesmo quando você não pode chamar nada embutido diretamente ou mesmo nomear os tipos envolvidos).

import Prelude(getLine,print)
a=a
(x:l)!0=x
(x:l)!n=l!d[0..n]
d[x,y]=x
d(x:l)=d l
x^y=[x..]!y
x+y=f[0..y](x^y)(-((-x)^(-y)))
f[]x y=y
f _ x y=x
f.g= \x->f(g x)
f&0= \x->x
f&n=f.(f&d[0..n])
x*y=((+x)&y)0
x%[]=x
x%('-':s)= -(x%s)
x%(c:s)=x*10+i c%s
i c=l['1'..c]
l[]=0
l(x:s)=1+l s
main=do
 x<-getLine
 y<-getLine
 print((0%x)+(0%y))

O que provavelmente não é super-golfe, mas aqui está mais legível:

import Prelude(getLine,print)
a=a

-- List indexing
(x : _) !! 0 = x
(_ : xs) !! n = xs !! (sndLast [0..n])

-- sndLast [0..n] lets us decrement a positive integer
sndLast [x, _] = x
sndLast (_ : xs) = sndLast xs

-- Pseudo-addition: right-operator must be non-negative
x +~ y = [x..] !! y

-- Generalised addition by sign-flipping if y is negative
x + y = switch [0..y] (x +~ y) (-((-x) +~ (-y)))
  where switch [] _ empty = empty   -- [0..y] is null if y is negative
        switch _ nonempty _ = nonempty

f . g = \x -> f (g x)

-- compose a function with itself N times
composeN f 0 = \x -> x
composeN f n = f . (composeN f (sndLast [0..n]))

-- multiplication is chained addition
x * y = composeN (+x) y 0

strToNat acc [] = acc
strToNat acc ('-' : cs) = -(strToNat acc cs)
strToNat acc (c : cs) = strToNat (acc * 10 + charToDigit c) cs

charToDigit c = length ['1'..c]

length [] = 0
length (_ : xs) = 1 + length xs

main = do
  x <- getLine
  y <- getLine
  print (strToNat 0 x + strToNat 0 y)
Ben
fonte
2
Cracked
Christian Sievers
17

Python 2 , Rachado

Implementa a adição como uma função nomeada

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
f=lambda\

Experimente online!

O que isso faz?

Com o objetivo de ajudá-lo um pouco, explicarei o que isso faz. Este código abre o arquivo de origem e verifica se o restante do código se encaixa nos seguintes critérios:

  • Não contém a sequência import
  • É feito apenas dos personagens &)(,.:[]a`cdfijmonrt~

Se falhar em qualquer um dos critérios, o limite de recursão será definido como 1significando que qualquer código que você escrever atingirá o limite de recursão.

Não há truques aqui, escrevi uma solução que usa apenas esses caracteres e não importa, não estou fazendo nada subversivo, mas direi que acho que isso será muito difícil de decifrar.

Para economizar algum tempo, aqui está uma pequena lista de coisas úteis que você não pode fazer com esta restrição

  • + bem duh,

  • eval/ execNão ia deixar você se safar com isso

  • Números, eles podem ser mais úteis do que você pensa

  • Literais de string

  • len

  • =, Sem atribuir variáveis

  • >, <, ==. . . Eu deixei você sem comparações

  • *, -, /, %, ^, |, >>, << Os únicos operadores disponíveis são ~e&

  • __foo__, Nenhum desses métodos sofisticados de sublinhado duplo é permitido.

Assistente de Trigo
fonte
11
Uau, isso é muito ruim. Agradável!
HyperNeutrino
Resposta fantástica para começar as coisas :) :)
DJMcMayhem
Hehe, isso só pode ter sido inspirada por que mudo king-of-the-hill desafio Tentei spec no chat que uma vez
Stephen
4
Eu acho que este é um crack válido: codegolf.stackexchange.com/a/133209/68942
HyperNeutrino 19/07/17
RE o primeiro trecho: This code is not allowed to crash or exit.(veja o bate-papo para discussão sobre isso)
Stephen
12

Python 2 , Rachado

Esta é a quarta iteração desta resposta. Cada uma das últimas respostas foi quebrada ao redefinir a profundidade da recursão.

Implementa a adição como uma função nomeada

import sys
if set("".join(open(__file__).read().split('\n')[4:]))-set(' &)(,.:[]a`cdfijmonrt~'):sys.setrecursionlimit(1)
for m in sys.modules:sys.modules[m]=None
del sys;f=lambda\

Experimente online!

O que isso faz?

Com o objetivo de ajudá-lo um pouco, explicarei o que isso faz. Esse código abre o arquivo de origem e verifica se o restante do código é composto apenas pelos caracteres &)(,.:[]a`cdfijmonrt~

Se falhar, o limite de recursão é definido como 1significando que qualquer código que você escreve atingirá o limite de recursão.

Também desabilitei todos os módulos, para que você não possa importar nada.

Não há truques aqui, escrevi uma solução que usa apenas esses caracteres e não importa, não estou fazendo nada subversivo, mas direi que acho que isso será muito difícil de decifrar.

Para economizar algum tempo, aqui está uma pequena lista de coisas úteis que você não pode fazer com esta restrição

  • + bem duh,

  • eval/ execNão ia deixar você se safar com isso

  • Números, eles podem ser mais úteis do que você pensa

  • Literais de string

  • len

  • =, Sem atribuir variáveis

  • >, <, ==. . . Eu deixei você sem comparações

  • *, -, /, %, ^, |, >>, << Os únicos operadores disponíveis são ~e&

  • __foo__, Nenhum desses métodos sofisticados de sublinhado duplo é permitido.

Minha solução

Então, agora que o xnor o quebrou de uma maneira que estou suficientemente satisfeito, vou revelar minha solução

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

Surpresa, surpresa, é uma pilha enorme de bobagens. Em vez de quebrar isso, vou passar pelo processo de como fiz isso.

Comecei com um algoritmo de adição bastante padrão

r,o:(o and f(r^o,r&o<<1))or r

Então eu usei um truque bit a bit para representar ^com |, &, ~.

r,o:(o and f((r|o)&~(r&o),r&o<<1))or r

Eu usei outro truque bit a bit para se livrar do |

r,o:(o and f(~(~r&~o)&~(r&o),r&o<<1))or r

Agora tudo o que resta é o <<, não deve ser muito difícil, certo? Bem, prepare-se para um passeio esburacado. Para substituir o deslocamento de bits, usei cadeias para acrescentar um zero ao final de sua representação binária

r,o:(o and f(~(~r&~o)&~(r&o),int(bin(r&o)[2:]+"0",2)))or r

Isso tem alguns problemas, mas o principal está usando adição , então eu trabalhei com isso usando um formato

r,o:(o and f(~(~r&~o)&~(r&o),int("{}0".format(bin(r&o)[2:]),2)))or r

Não temos permissão para usar bin, então usei a formatação de string para converter em binário.

r,o:(o and f(~(~r&~o)&~(r&o),int("{0:b}0".format(r&o),2)))or r

Como os literais de string são proibidos, eu tenho que construir o string {0:b}0com partes feitas com tiquetaques traseiros e joinelas juntas.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join(["{","0",":","b","}","0"]).format(r&o),2)))or r

A string vazia é bem fácil, você pode simplesmente fazer

`r`[:0]

Os zeros eram

`0`

e {:}todos foram retirados de dicionários.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],"b",`dict()`[-1],`0`]).format(r&o),2)))or r

bparece bastante difícil de obter, não é no nosso conjunto de caracteres, então como é que vamos obter um objeto que tem um bem sua repr? Bem, aqui está como: Quando você usa repruma função interna, obtém algo que se parece com

<built-in function name>

E é de onde conseguiremos o nosso b.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],`min`[1],`dict()`[-1],`0`]).format(r&o),2)))or r

Agora tudo o que resta são números, eu só preciso de -1, 0, 1 e 2, e aqui está como os representei:

-1 = ~(r&~r)
 0 = r&~r
 1 = []in[[]]
 2 = `~([]in[[]])`[[]in[[]]:]

2 poderia ser um byte mais curto, pois

```r&~r```.find(`r&~r`)

com base nas sugestões do @ Blender nos comentários, mas não pensei nisso até depois do fato.

Então, substituímos esses números em

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

E isso é o crack.

Assistente de Trigo
fonte
Esse snippet parece ter erro por si só.
ATaco 19/07
@ ATaco Eu acredito que isso foi discutido no chat e foi decidido que estava tudo bem.
Assistente de trigo
As regras declaram explicitamente o contrário. "Este código não tem permissão para travar ou sair."
ATaco 19/07
@ATaco Aqui está a mensagem que ele disse que a atualizaria quando tivesse a chance.
Assistente de trigo
5
Rachado?
xnor
10

C (gcc) Rachado!

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}

Experimente online!

Entrada de STDIN e saída para STDOUT.

Isso é executado sem erros. Hahaha, isso é muito ruim. Eu só testei no gcc do TIO. Normalmente, você deve anexar seu código após este trecho para que ele funcione :) O comentário é ruim, não o escute.

Testado em gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1). Deve funcionar em qualquer sistema Linux.

Solução original

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}
void __attribute__ ((destructor)) dtor() {
    int a,b,c,d;a=b=c=0;
    struct FILE* z = popen("cat", "r");
#define q(x)for(;(c=getc(z))^32&&c^-1;)x=10*x+c-48;
q(a);q(b);
    char*y=calloc(c=a+b,1);
    for(a=0;c;){y[a++]=(48+(c%10));c=c/10;}
    for(b=0;b<a/2;b++){d=y[b];y[b]=y[a-b-1];y[a-b-1]=d;}
    write(1,y,a);
}
Conor O'Brien
fonte
@ LegionMammal978 Ah sim
Conor O'Brien
2
Especifique sua plataforma!
1937 Joshua
@Joshua eu adicionei algumas informações
Conor O'Brien
4
rachado
Dennis
Bem, __asm__e você tem muitas funções para escolher :) não pense que C e C ++ são bons inimigos aqui.
Edmz 19/07
10

C (GCC no Linux) (quebrado)

Em vez de usar técnicas tolas de sandbox de leitura de arquivos, fazemos da maneira correta - com a lista de permissões da SECCOMP!

Sua tarefa: implementar adição com entrada de STDIN e saída para STDOUT.

#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <syscall.h>
#include <stdio.h>
void sandbox();
__attribute__ ((constructor(0))) int s() {
    close(0);
    close(1);
    close(2);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
}
int main() {
    sandbox();
    syscall(SYS_exit, EXIT_SUCCESS);
}
void sandbox() {
    // Your code here!
}

Experimente online!

WTF é isso !?

Para ajudá-lo em sua tarefa insuperável, explicarei o que esse código faz.

__attribute__ ((constructor(0)))garante que a sfunção seja executada primeiro. A função fecha todos os descritores de arquivos abertos para STDIN, STDOUT e STDERR. Em seguida, o programa se restringe a uma lista de permissões SECCOMP estrita, que limita as chamadas do sistema ao seguinte:

read(2)
write(2)
_exit(2)
sigreturn(2)

Portanto, você não pode abrir novos arquivos (ou basicamente fazer qualquer coisa). Em seguida, chegamos ao main e chamamos seu código, muito bem envolvido na sandboxfunção.

O syscall(SYS_exit, EXIT_SUCCESS);final é apenas para garantir que o programa saia corretamente - por padrão, o GCC sairá com o exit_group(2)que não é permitido pela lista de permissões da SECCOMP. Essa função de saída é chamada após a execução do seu código.

Portanto, você não possui descritores de arquivos abertos e não pode abrir nada de novo. Impossível, certo? ;)

Sísifo
fonte
3
rachado
2012rcampion
9

Haskell , rachado por Ben

main=main--

Experimente online! Este deve ser um programa completo que lê dois números de stdin e gera a soma para stdout.

Cada programa completo inicia executando a mainfunção, mas aqui se mainchama e causa um loop infinito. Para piorar a situação, um comentário de linha é iniciado --diretamente atrás da chamada recursiva para evitar alterá-la para, por exemplo, main2e depois definir isso para fazer a soma.


Solução pretendida:

main=main--$()
_ --$ _ = do
     x <- readLn
     y <- readLn
     print $ x+y

Experimente online!

--inicia um comentário de linha, a menos que ele também possa ser analisado como parte de um operador. (O realce da sintaxe parece desconhecer esse fato.) --$É um operador de infixo válido que assume maincomo primeiro argumento e algum segundo argumento fictício (). Em seguida, é definido para ignorar os dois argumentos e executar a tarefa necessária.

Laikoni
fonte
5
você pode simplesmente adicionar "where main = ..."
michi7x7 19/07/19
+1 para uma solução Haskell que só funciona por causa da avaliação lenta de Haskell.
Jules
8

Montagem em modo real de 16 bits x86 ( rachada )

_main:
    call l
    cli
    hlt
l:  pop si
    xor ax, ax
    mov bp, cs
    mov es, ax
    mov di, 12
    mov [di], si
    mov [di + 2], bp
    pushf
    mov bp, sp
    or word [bp], 256
    popf

Fácil se você souber o truque.

Joshua
fonte
11
Como você está aceitando a entrada? Na pilha, ou nos registros? (Além disso, parece que este é suposto ser a montagem de 16 bits, mas se assim for, or [bp], 256. É inválido Isso é suposto ser or WORD PTR [bp], 256?)
Cody Grey
11
Além disso, você deve especificar qual processador está usando; existem muitas versões e clones do x86 por aí, e muitas instruções indefinidas. Se eu escrevesse o código para um "clone 80186 obscuro" que, por acaso, tivesse uma instrução indefinida que exigisse alguns argumentos e blá blá blá ... Também poderemos precisar de ambiente. O Windows de 16 bits deu uma garantia SS == DS que outros sistemas talvez não, por exemplo.
Orion
11
Você só precisa especificar qual processador se estiver usando algum truque que funcione apenas em um modelo específico (ou uma geração específica). Esse código não é assim, então acho que "x86-16" é suficiente. Na minha opinião, quanto mais geral, melhor. Concordou que o modo real ou protegido deve ser especificado, embora a presença da hltinstrução (anel 0) implique fortemente que esse não é o modo protegido.
Cody cinzento
3
@ Josué, se não funcionar em todas as plataformas, você precisa especificar pelo menos uma plataforma em que funcionará, acredito. Your submission must contain enough information before being revealed to be reproducible after being revealed
21717 Stephen
11
@StepHen: A solução para desbloquear o idioma é independente da plataforma, uma vez especificado o modo real x86-16, mas a E / S não é independente da plataforma. Quem o interrompe pode especificar o sistema operacional para o qual ele rompeu. Eu adicionei o rótulo _main mais tarde, para que alguém pudesse, em teoria, fazer uma pausa quase agnóstica vinculando-se à libc.
1937 Joshua
4

Javascript, Rachado

Esse desafio se baseia no de Grant Davis , mas corrige a solução que ele tinha em mente (que cria um iframe e usa o iframe window). A solução é executada no console javascript no Chrome about:blank pagee leva dois input()segundos, os soma e console.logo resultado. Coloque seu código depois:

d=prompt=console=document;new MutationObserver(s=>s.forEach(e=>{t=e.target;t.parentNode.removeChild(t)})).observe(d,{"childList":d, "subtree":d})

Primeiro, espancar prompte consolee definir o atalho d. Em seguida, criamos um observador de mutações com um retorno de chamada que remove todos os destinos mutados. Definimos esse observador de mutação para observar o documento, notificar childListe subtreemodificar. Em vez do literal true, usamos nosso atalho para o valor verdadeiro document(a especificação não permite isso, mas o chrome sim).

Depois de postar isso, percebi um clobber muito mais elegante. Minha solução pretendida ainda funciona, mas o crack publicado não:

 h=document.querySelector("html");h.parentNode.removeChild(h);
Daniel Franklin
fonte
Bem vindo ao site! Estou interessado em ver o que a solução será :)
DJMcMayhem
4

Perl 5, quebrado por Ilmari Karonen

$_=<DATA>;
s/[+'{dPz|K.UD!_ iJ;o}e6tjWb7253k@%&Iq4l0AN:?\$8B`Yywn9^pfmZQTF"M#-]//g;
eval;
print@_,$!,pop,shift,<>,eval"@>",$\,@ARGV,eval"@$",$@,eval"@@",$,,eval"@,",$/
__DATA__

A entrada é recebida em linhas separadas STDINe a saída é impressa STDOUT.

Todo o código segue o __DATA__marcador. Isso usa um método semelhante à solução do @ WheatWizard, pois o código é analisado e os caracteres inutilizáveis ​​são removidos.

Isso foi testado nas versões 5.8, 5.10 e 5.16 e não requer sinalizadores de linha de comando.

Experimente online!

Dom Hastings
fonte
2
Você poderia especificar o método e o formato de entrada / saída?
Ilmari Karonen
@IlmariKaronen Desculpas, é STDINcom caracteres em linhas separadas e STDOUT. Vou adicionar isso ao corpo principal.
Dom Hastings
Rachado , eu acho.
Ilmari Karonen
4

Python 3, quebrado pelo zbw

import sys
for mod in sys.modules.values():mod.__dict__.clear()
1+1

Todos os módulos foram excluídos, o que significa que não há recursos internos disponíveis e muito mais pode ser feito. Saída para STDOUT, entrada de STDIN. Esta é a segunda iteração desta resposta depois que a anterior foi interrompida por uma falha trivial ao adicionar uma declaração de interrupção.

pppery
fonte
Estou muito curioso para ver o trecho que funciona depois disso
NickA 21/07/17
Bem, você tem que esperar sete dias ou por uma rachadura não-trivial, o que ocorrer primeiro ...
pppery
Bem, bem, desafios como estes são muito difíceis de serem bem
pppery
4

APL (ngn-apl) , quebrado por ngn

Feito em cooperação com meu colega Marshall .

Entrada através de argumentos esquerdo e direito para +. Ou seja, seu objetivo é inserir o código após o seguinte, para que sua última linha leia ⎕←3+2e 5saia para STDOUT.

+←-←−←⍴←≢←≡←⊥←⊤←⍟←○←⍳←⌹←~←∈←∊←⍷←<←≤←=←≥←>←≠←,←⍪←⌷←⌽←⍉←⊖←{}⋄⍣←∘

Experimente online!

Funciona definindo todas as funções úteis para as {}quais um ou dois argumentos e retorna uma lista numérica vazia. Também define apenas para compor funções.


Rachadura

+←{⌈/⍋⍺⍵1/0}

⍺⍵1/0 replicar 0 pelo argumento da esquerda e o argumento da direita e 1

 obter os índices que classificariam isso (já que todos os elementos são zero, fornece 0 1 2… (a + b)

⌈/ o valor máximo (a + b)

Adão
fonte
ngn / apl inclui a capacidade de executar JavaScript arbitrário. Não considero válida essa solução, pois seria sobre desativar o JavaScript em vez da APL. Existe de fato uma maneira válida (embora obscura) de redefinir +usando apenas APL puro e sem truques sujos.
Adám 19/07/19
3

Python 2 , Rachado

Esta é a segunda iteração de uma resposta que foi quebrada uma vez pelo @HyperNuetrino usando um método que eu não esperava. Eu já o corrigi, então espero que as únicas soluções restantes tenham que obedecer às restrições que pretendi.

Implementa a adição como uma função nomeada

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
sys.modules['sys'],sys.modules['os']=None,None;del sys;f=lambda\

Experimente online!

Assistente de Trigo
fonte
Eu acho que poderia fazer isso se tivesse um u, mas estou preso sem ele.
Isaacg
@isaacg Apenas por curiosidade, com o que você gostaria u?
Assistente de trigo
.count. Posso obter uma string contanto que a saída desejada, mas não tenho como medir seu comprimento.
Isaacg
__import__('sys').setrecursionlimit(100)... e nada foi corrigido. Eu realmente não tenho vontade de publicá-lo no tópico do ladrão, parece trapaça. Experimente online
Value Ink
3

Java 8, Rachado por @ OlivierGrégoire

Aqui está a minha tentativa. Basicamente, a idéia é sobrecarregar todos os namespaces que você pode usar para gerar (e refletir, espero). A saída é destinada ao sdout (System.out).

class java {
    public static void main(String[]s){
       //there is no executable code in snippet one.
       //your code here.
    }
    class Class{}
    class Method{}
    class System{}
    class FileDescriptor{}
    class Logger{}
    class Runtime{}
    class Scanner{}
}

A lista negra é normalmente uma abordagem pior do que a lista de permissões, por isso tenho certeza de que é apenas uma questão de tempo até que alguém tenha uma abordagem que eu não considerei.

Lord Farquaad
fonte
11
Esta não é uma classe executável ...
Olivier Grégoire
11
@ OlivierGrégoire Desculpe por isso, adicionei class String{}após o teste sem perceber que ele iria nocautear main(String[] ...). Ele deve funcionar agora
Lord Farquaad
11
Sim, isso é possível, obrigado! :) Porém, isso não muda a rachadura que estou prestes a fazer: p
Olivier Grégoire
11
Rachado! Eu realmente gostei desta :)
Olivier Grégoire
11
Eu estava olhando para algo assim (desculpe, é difícil formatar o código nos comentários), mas acho que sua solução é muito mais limpa:int sum = 0; new Exception("" + sum) { public void printStackTrace() { ClassLoader cl = ClassLoader.getSystemClassLoader(); try { printStackTrace(new PrintStream((PrintStream)cl.loadClass("java.lang.System").getDeclaredField("out").get(null))); } catch (Exception e){} } }.printStackTrace();
Lord Farquaad
3

cQuents, quebrado por Mayube

#|1,1:A

Isso deve ser bastante fácil, mas você nunca sabe.

O "problema" é que, sem Cno seu código, você tem um erro.

Solução da Mayube:

#|1,1:A+BC

Cada item na sequência é a primeira entrada mais a segunda vez a terceira (aka 1)

Minhas soluções:

#1,1:A+B,C

A sequência alterna entre a primeira entrada mais a segunda entrada e a terceira entrada (1). O primeiro item no segundo é A+B.

#1,1:A+B+C-C

Semelhante à solução do Mayube - em vez de multiplicar B*C, apenas adiciona Ce subtrai.

Experimente online!

Explicação

#|1,1      Append 1 and 1 to the end of the user's input
     :     Set mode to : (sequence 1: if given n, output nth term in sequence; if given no n, output whole sequence)
      A    Each item in the sequence equals the first input

Atualmente, este programa gera 1, uma vez que, sem entrada do usuário, a primeira entrada é a primeira 1na entrada padrão ( #).

Stephen
fonte
Os docs parecem realmente sem jeito formulado, não posso para a vida de me descobrir o que significa quando se dizDefault input is combined with user input to form the total input, which must align with the expected input (which is based on the highest input requested by the Sequence Definition)
Skidsdev
@ Mayube é estranho, eu preciso encontrar uma maneira de dizê-lo corretamente. Basicamente, sua entrada no programa pode ser igual à entrada mais alta consultada por variáveis A,B,C,D,Eno código. Por exemplo, se em algum momento você tiver a variável Dem seu programa, o analisador espera que haja 4 entradas, mas se houver também um E, o analisador espera que existam 5 entradas. Não pode haver menos do que o valor esperado. No entanto, sempre há uma última entrada opcional n, que é usada de maneiras diferentes por modos diferentes.
Stephen
@ Mayube, o trecho que publiquei acima contém um A, portanto ele procura uma entrada. Como existem dois, ambos provenientes dos #quais especifica a entrada padrão, ele usa o primeiro como Avalor e o segundo como n.
21717 Stephen
Então, se eu desse duas entradas e acrescentasse BC, A seria a primeira entrada, B seria a segunda, C seria 1 e n seria a segunda 1?
Skidsdev 19/07
@ Mayube exatamente, desculpe pelos meus documentos ruins. TMI: se o início parecesse #1,1(sem barra), seria: A como o primeiro 1, B como o segundo 1, C como a primeira entrada en como a segunda entrada. Também pode fazer #1|1, onde A é o primeiro 1, B é, é a primeira entrada, C representa a segunda entrada, e n é o segundo 1.
Stephen
3

Node.JS versão 7.3.0 (Rachado por Dom Hastings)

var p=process,f;(_=>{var w=p.stdout.write,n='f'+(Math.random()*1e7|0),l=1
f=p.stdout.write=a=>eval(`(function ${n}(a){while(l&&((typeof a)[0]!='s'||'f'+a!=n));a=l?l="":a;w.apply(p.stdout,arguments);})`)(a)})();

Coloque o segundo bloco de código após o primeiro.

Isenção de responsabilidade: o segundo bloco de código não funcionará por si só (sem ser colocado após o primeiro). Se isso não for permitido, no entanto, eu posso modificar o segundo trecho.

Este é um programa completo. Saída é process.stdout(STDOUT), entrada é process.argv(argumentos de linha de comando)

Este é o meu primeiro policial e ladrão, espero que este seja um bom desafio :)

Experimente online!


O desafio explicou

Gera uma variável aleatória nde 0 a 1e7. Se você chamar de gravação com o correto n, não imprime nada, mas define lcomo 0, que "desbloqueia" a função de gravação, permitindo imprimir qualquer coisa. Se você tentar chamar write com uma não-string, o enviará para um loop infinito. Se você tentar chamar a gravação com algo diferente do correto, nenquanto a gravação estiver "bloqueada", o enviará para um loop infinito para evitar adivinhações.

A solução pretendida

Ignora o tipo de que aparentemente verifica apenas as strings usando um Symbol, que também começa com s. Isso gera um erro na função resultante da chamada de avaliação, porque você não pode adicionar a string "f" a um símbolo. Nós capturamos o erro e usamos regex para recuperar no rastreamento de pilha, onde está o nome da função. Em seguida, tentamos escrever nque não imprime nada, mas define a variável "lock" lcomo 0 para "desbloquear" a função de gravação. Agora que a função de gravação está desbloqueada, apenas imprimimos a soma.

try{f(Symbol())}catch(e){f(e.stack.match(/f(\d+)/)[1])
f(+p.argv[2]+ +p.argv[3]+"")}
jrich
fonte
Rachado!
Dom Hastings
Isso é genial ... Eu estava no caminho certo originalmente então! Obrigado pelo treinamento do cérebro!
Dom Hastings
3

RProgN2 , rachado por Arnold Palmer

"+-/*÷^"{²[[\=};

Escreve sobre todos os operadores matemáticos, sem nenhuma maneira de restaurá-los. Em particular, ele os substitui por uma função que remove os dois principais itens da pilha.

Experimente online!

Solução original

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=
{     }`d=                                  #Define a function, "d", which returns n-1
 S                                          #Convert the input to a stack, which, as a number, makes a stack of 1 - n.
  ]‘                                        #Duplicate the stack, and pop the top value off it.
    [                                       #Discard the popped'd value.
     L                                      #Get the length of the stack, which now is n-1.
          {   }`i=                          #Define a function, "i", which returns n+1
           0R                               #Get the range of numbers between 0 and n.
             L                              #Get the length of that stack, which is n+1
                  «                    »`+= #Define a function, "+", which takes two numbers, and outputs their sum. We use «» here, because it localises references, instead of globalising them.
                   x=                       #Set the first input to the value of "x", which by default, is x.
                     y=                     #Ditto for y.
                       x{          x}:      #While x is truthy, which in this case, is non-zero.
                         xd                 #Get x - 1
                           `x=              #Set x to it.
                              yi`y=         #And set y to y + 1
                                      y     #Push y to the output. And we're done.

Experimente online!

ATaco
fonte
Estou examinando sua documentação e não consigo encontrar o que o ²símbolo faz. Quer me esclarecer?
21917 Arnold Palmer
Essa documentação não é incrivelmente relevante para RProgN2, e que o símbolo leva os próximos dois conceitos [[neste caso, e envolve-los em um @ArnoldPalmer função
Ataco
Cracked
Arnold Palmer
Dang, isso é muito melhor. Eu não sabia sobre os operadores de pilha, o que certamente teria sido útil. Além disso, o conhecimento «»cria variáveis ​​locais, em vez de estragar as globais, teria sido super útil.
9609 Arnold Palmer
3

Haskell, 161 144 bytes, Rachado por BlackCap

{-#OPTIONS_GHC -fth -w#-}
module M where

Entrada para STDIN, saída para STDERR. Adicione ao final do programa.

Edit: Pretende ser compilado sem argumentos extras do GHC, apenas o normal ghc --make prog.hs.

Editado novamente para diminuir a contagem de bytes.

Diverta-se!

zbw
fonte
Então, eu não posso fazer isso, porque a função principal não será chamada? main = do x <- readLn :: IO Integer; y <- readLn; print $ x + y
BlackCap
@BlackCap Não, porque o GHC espera que a mainfunção esteja no módulo Mainquando nenhum -main-issinalizador for fornecido.
ZBW
Isso não funciona, mas eu quero compartilhar a idéia de qualquer maneira
Cabeção
Vou chamar isso de rachado. Aqui estava minha solução pretendida. Não funciona no TIO, porque o wrapper não envia a entrada para o compilador.
ZBW
Se você postar sua solução, marcarei como quebrada.
ZBW
3

Mascarpone , rachado por Ilmari Karonen

[ Make 'i' and 'z' print 'q' ]$
v ['q.]v* 'i<^
v ['q.]v* 'z<^

[ Disable some standard commands ]$
v[]v*   '1<^
v[]v*   '$<^
v[]v*   '@<^
v[]v*   '{<^
v[]v*   '}<^
v[<:]v* '<<^
v[]v*   'v<^$

A entrada é um número de igreja no stdio, usando ipara incremento e zpara zero. Por exemplo, 2 + 3 seria:

iiziiiz

Com uma nova linha à direita, a

saída deve ser um número no stdout, no mesmo formato que no stdio. Por exemplo, se a resposta for cinco, você deve gerar:

iiiiiz

(mascarpone não tem conceito de números)


Solução pretendida:

: '[/''/'i/'./' /':/',/'>/'!/']/* 'i<^
: '[/':/',/'>/'!/']/* 'z<^
: ,>!
'z.

Não é imediatamente aparente na documentação, mas, como @IlmariKaronen afirmou em seu crack, os literais de string em Mascarpone são na verdade açúcar sintático para forçar uma sequência de caracteres.

Escrevi deliberadamente comentários [this]$para fazer parecer que estou pressionando uma corda e soltando-a imediatamente depois. Um cracker ingênuo pode ter tentado algo como [:,>!]/*empurrar uma corda, trocá-la com o intérprete e interpretá-la.

Também finjo colocar o intérprete que deixei na pilha $, mas $já foi redefinido para um NOP. Você fica com esse intérprete na pilha e precisa carregá-lo durante todo o programa; através de cada caractere de cada string.

BlackCap
fonte
Rachado. E não, eu nunca tinha ouvido falar de Mascarpone antes deste desafio.
Ilmari Karonen
@IlmariKaronen Novo idioma favorito? Bom trabalho!
BlackCap
2

C # (.NET Core) rachado por Ilmari Karonen

Também rachado por Joshua .

namespace System
{
    class Console
    {
        static void Main()
        {
            //Your code goes here
        }
    }
}

Lê os dois valores de stdin e grava o resultado em stdout. Testado no Windows com Framework Versão 3, 4.6 e no TIO .

Aqui está o programa completo que eu pretendia.

namespace System
{
    class Console
    {
        static void Main()
        {
            var t = Reflection.Assembly.Load("mscorlib").GetType("System.Console");
            var r = t.GetMethod("ReadLine");
            int a = int.Parse((string)r.Invoke(null, null));
            int b = int.Parse((string)r.Invoke(null, null));
            var w = t.GetMethod("WriteLine", new[] { typeof(int) });
            w.Invoke(null, new object[] { a + b });
        }
    }
}

Experimente online!

raznagul
fonte
Rachado.
Ilmari Karonen
codegolf.stackexchange.com/a/133412/14306 Presumo que essa não foi a solução pretendida.
Joshua
@IlmariKaronen: +1. Esta foi a solução pretendida.
raznagul
@ Josué: +1 por encontrar uma solução diferente da que eu pretendia.
raznagul
2

GolfScript , rachado por Dennis

{}' !$%&()*+,-./<=>?@[\]^`|~'':'*~;

Experimente online!

Afinal, este é um desafio do , por que não experimentar o GolfScript?

Uma solução válida deve ser um trecho que leia dois números inteiros da pilha, adicione-os e retorne o resultado na pilha. O problema é que ele ainda deve funcionar mesmo depois que o código acima redefiniu quase todos os operadores internos do GolfScript para não fazer absolutamente nada. Pelo menos eu deixei ;intocado, para que você ainda possa retirar valores da pilha. ;-) Seu código deve funcionar no interpretador GolfScript padrão, conforme implementado, por exemplo, no TIO (veja o link acima).


A solução de Dennis , como a minha , baseia-se no recurso raramente usado do GolfScript, que permite o código Ruby interpolado em strings com aspas duplas. Usamos esse recurso para definir um novo operador de adição que funcione exatamente como o +operador interno e depois chamá-lo.

(Uma razão pela qual o recurso de interpolação Ruby no GolfScript é tão raramente usado é que, desajeitadamente, o código Ruby interpolado é executado durante a análise e sua saída é armazenada em cache pelo intérprete GolfScript. Portanto, se você tem uma string com código Ruby interpolado em um loop, o código será executado apenas uma vez antes que o programa real seja iniciado e, em seguida, sempre retorne o mesmo valor em todas as iterações do loop.Você pode contornar isso usando a string eval para adiar a análise, mas isso torna a sintaxe já estranha ainda mais feio e detalhado, e de qualquer forma, para esse desafio, desativei também o operador eval.No~ entanto, acontece que a definição de novos operadores GolfScript internos é uma coisa que esse recurso realmente faz muito bem e de forma limpa.)

Ilmari Karonen
fonte
Dica
CalculatorFeline
Rachado. Finalmente descobri o que eu estava fazendo de errado.
Dennis19 /
@Dennis: Sim, você acertou em cheio desta vez. FWIW, minha solução pretendida foi "#{var'_','gpush a+b'.cc2}";_, que funciona exatamente como a sua, exceto por ser alguns bytes mais curta.
Ilmari Karonen
2

Node.js v8.2.0, rachado por Dom Hastings

let mess = ctx => f => new Proxy (f, {
  has: (t, p) => p in t || p in ctx
, get: (t, p) => {
    let k = p in t? t[p]: ctx[p];

    if (k instanceof Function) return (
      function fetch (_k) {
        return mess (ctx) ( x => ( q => q instanceof Function
                                      ? fetch (q)
                                      : t (q)
                                  ) ( _k(x) )
                          )
      })(k);

    return k;
  }
});

with (mess (global) (x => x)) {
  dot   = f => a => b => f(a(b))
  ap    = f => g => x => f (x) (g (x))
  flip  = f => x => y => f (y) (x)
  Const = a => b => a
  id    = x => x
  num   = n => n (x => x + 1) (0)
  log   = console.log

  let x = flip (Const . id . id)
    , y = flip (Const . id . id . id)
  for (let i = 0; i < process.argv[2]; i++) x = ap (dot) (x)
  for (let i = 0; i < process.argv[3]; i++) y = ap (dot) (y)
  process.argv = [];

  logic = x => y => /* Your code here */;

  log . id . num ( logic (ap (dot) (x))
                         (f => z => (( y(flip (id) . id . flip (dot (id)) (f)) ) (Const (z))) (id) )
                 );
}

Você deve implementar a logicfunção. Entrada são os argumentos fornecidos (a partir de stdin), saída é o que a sua função retorna (é impressa em stdout).


Minha igreja de código codifica os números da entrada. O restante do código existe apenas para intimidá-lo.
A função mess faz alguns truques para implementar a notação sem ponto ( a . b == dot (a) (b)), que eu principalmente uso para adicionar . id .a lugares aleatórios, o que não faz nada, mas confunde qualquer pessoa não familiarizada com a programação funcional.
A transformação aplicada aos números antes de eu passá-los para a logicfunção é x+1e y-1, que soma 0, então é outro NOP a ser adicionado à obscuridade.

A solução pretendida foi:

logic = x => y => f => z => x (f) (y (f) (z))
BlackCap
fonte
11
Rachado!
Dom Hastings
@DomHastings Isso não é a solução pretendida, mas eu vou dizer que você pode, contanto que o programa pára sem uma exceção, e não imprime caracteres adicionais para a saída
Cabeção
Acabei de publicar uma alternativa! (Você pode ver a minha solução anterior na história do que a resposta embora!)
Dom Hastings
Oh uau, eu estava longe ... Ainda assim, é melhor do que minha primeira tentativa muito barata! Obrigado pelo quebra-cabeça!
Dom Hastings
2

Inform 7 , rachado por ppperry

For reading a command: rule fails.

[Your code here.]

A entrada deve ser digitada pelo player como um comando interativo, por exemplo, add 17 to 25ou sum 17 25. Você pode escolher a forma exata do comando que deve ser digitado, desde que inclua dois números. A soma dos números (por exemplo 42) deve ser impressa em resposta ao comando.

O desafio, é claro, é fazer isso enquanto toda a atividade "ler um comando" é substituída por uma não-operação. Provavelmente existem várias maneiras de resolver esse problema, mas pelo menos deve exigir alguma familiaridade com o idioma. O que eu inventei é realmente bastante simples, se um pouco inesperado.

Testei minha solução no GNOME Inform 7 IDE, versão 6L38 , no Ubuntu Linux. A solução pretendida funciona nos back-ends Glulx e Z-machine e deve funcionar em outras versões recentes do Inform 7. Observe que (sem uma solução alternativa adequada) o código acima fará com que o intérprete fique ocupado quando tentar ler um comando; o intérprete da Z-machine parece ficar completamente sem resposta quando isso acontece e não pode ser parado no IDE, por isso recomendo usar o Glulx para teste.

Ilmari Karonen
fonte
rachado , e em caso você estava pensando, eu nunca tinha ouvido falar de informar antes de este desafio
pppery
2

CPython 3 (novamente), quebrado por Sisyphus

import sys,os,functools
def p(f,e,a,_=os._exit):
 if e == "c_call":_(1)
sys.setprofile(p)

Você pode fazer o que quiser - desde que não seja implementado em C. Isso significa que não print, não input- todos irão atingir a _(1)linha e terminar. Entrada de STDIN com os números em duas linhas separadas, saída para STDOUT. Gostaria de saber quanto tempo isso vai durar ... Demorei um pouco para encontrar o segundo trecho de trabalho depois de inventar esse truque incapacitante. A especificação explícita do Cpython para evitar falhas com base em alguma implementação alternativa do sys.setprofile.

pppery
fonte
Rachado. Eu tenho muito pouca idéia de por que isso funciona.
Sísifo
Acho que posso perguntar agora: por quê functools?
Dennis
@ Dennis Porque sispyphus descoberto uma brecha, não a solução pretendida
pppery
@Sisyphus Seu crack foi relatado como um bug em python #
pppery
2

Java 8 ( Rachado )

Segunda tentativa. Dessa vez, investi dois minutos de testes.

static {

    try {

        System.setIn(null);
        System.setOut(null);
        System.setErr(null);

        for (Method m : System.class.getMethods()) {

            m.setAccessible(false);

        }

        System.class.getMethod("getSecurityManager", new Class[0]).setAccessible(false);

        for (Method m : Class.class.getMethods()) {

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                if (p.getName().equals("createSecurityManager")) throw new SecurityException();
                if (p.getActions().startsWith("read")) throw new SecurityException();

            }

        };

        System.setSecurityManager(mngr);

        // Your code goes here.

    } catch (Throwable t) {

    }

}

A maioria das coisas deve ser coberta.

racer290
fonte
11
Você poderia incluir isso em uma classe com as importações apropriadas? É o tipo de desafio em que essas pequenas alterações podem fazer ou quebrar uma entrada. Eu tenho várias soluções para esta como está, mas isso reduz drasticamente se você simplesmente incluir isso em uma classe / interface. Além disso, o formato para remover todas essas linhas seria muito bom para nós, leitores.
Olivier Grégoire
Lá, uma resposta quebrada usando exatamente o seu código. E um +1 porque parece que eu esqueci. Desculpa.
Olivier Grégoire
As chamadas #setAccessible (false) não fazem nada.
Nevay 19/07/19
1

Python 2 rachado

import sys,hashlib
c=open(__file__).read().split()[-1]
if c!='#'and hashlib.sha256(c).hexdigest()!='e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843':sys.exit() #

Experimente online!

Eu prefácio isso dizendo que esta resposta é uma jogada idiota, pretendida como uma resposta de limite inferior.


Inspirado pelas respostas do Wheat Wizard e HyperNeutrino .

O trecho lê o arquivo de origem e se recusa a continuar se o último pedaço de código separado por espaço em branco não for compartilhado e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843.

EDIT : Editado ligeiramente em resposta a este comentário . O problema principal não muda, qualquer tentativa de crack não é invalidada.

TwiNight
fonte
11
RE o primeiro trecho:This code is not allowed to crash or exit.
Stephen
Isso é inválido porque sai, o que não é permitido para o primeiro snippet.
DJMcMayhem
11
rachado
Dennis
1

Java 8 rachado por @ OlivierGrégoire

Eu tentei dificultar o máximo possível! :) E, diferentemente da outra resposta Java até agora, você terá que seguir as regras exatas do desafio, colocando-o após todo esse trecho (para que não, você não coloque seu código no public static void main(String[] args)método, coloque-o depois de toda a aula. :) Boa sorte!

Adicionei comentários para mostrar o que está sendo restrito.
( Inspirado nesta postagem, que é menos restritiva e passível de beatificação com a mesma abordagem que eu poderia usar para minha resposta. )

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FilePermission;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

  // Put everything in a static block so it is run before the static main method 
  // and any trailing (static) initializer-blocks:
  static {
    try {
      initializing();
    } catch (final Exception e) {
    }
  }

  static void initializing() throws Exception {
    // Overwrite System.out, System.err and System.in:
    System.setOut(new PrintStream(new ByteArrayOutputStream()));
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
    System.setIn(new ByteArrayInputStream(new byte[0]));

    // Enable reflection for System.out, System.err and System.in:
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    final Class<?> fdClass = java.io.FileDescriptor.class;
    final Field outField = fdClass.getDeclaredField("out");
    outField.setAccessible(true);
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    final Field errField = fdClass.getDeclaredField("err");
    errField.setAccessible(true);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    final Field inField = fdClass.getDeclaredField("in");
    inField.setAccessible(true);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);

    // Replace existing System.out FileDescriptor with a new (useless) one:
    outField.set(null, new FileDescriptor());
    // Replace existing System.err FileDescriptor with a new (useless) one:
    errField.set(null, new FileDescriptor());
    // Replace existing System.in FileDescriptor with a new (useless) one:
    inField.set(null, new FileDescriptor());

    // Disable reflection for System.out, System.err, System.in again:
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
    inField.setAccessible(false);
    errField.setAccessible(false);
    outField.setAccessible(false);
    modifiersField.setAccessible(false);

    // Overwrite the SecurityManager:
    System.setSecurityManager(new SecurityManager() {

      private boolean exitAllowed = false;

      @Override
      public void checkExec(final String cmd) {
        throw new SecurityException();
      }

      @Override
      public void checkPermission(final java.security.Permission perm) {
        final String name = perm.getName();
        // You're not allowed to read/write files:
        if (name.equals("setIO") || name.equals("writeFileDescriptor")
            || name.equals("readFileDescriptor")
            || ((perm instanceof FilePermission) && name.startsWith("/proc/self/fd/"))) {
          throw new SecurityException();
        }
        // You're not allowed to overwrite the Security settings:
        if (name.equals("setSecurityManager") || name.equals("suppressAccessChecks")) {
          throw new SecurityException();
        }
        // You're not allowed to use reflection anymore:
        if (name.equals("getModifiers") || name.equals("get") || name.equals("set")
            || name.equals("setBoolean") || name.equals("setByte")
            || name.equals("setChar") || name.equals("setShort") || name.equals("setInt")
            || name.equals("setLong") || name.equals("setFloat") || name.equals("setDouble")
            || name.equals("setFieldAccessor") || name.equals("setFieldAccessor")) {
          throw new SecurityException();
        }
        // When you try to leave the current VM it will stop the program:
        if (name.startsWith("exitVM") && !this.exitAllowed) {
          this.exitAllowed = true;
          System.exit(0);
        }

        // You know what, nothing is allowed!
        throw new SecurityException("Mhuahahahaha!");
      }
    });
  }

  public static void main(String[] args) {
    // Overwritting all given arguments:
    args = new String[0];

    // Exit the program before you can do anything!
    System.exit(0);
  }
}

// Your code goes below:

Experimente aqui. (ideone.com em vez de TIO, pois parece não funcionar lá. Os testes foram feitos no Eclipse IDE, mas minha solução pretendida funcionará se você usar ideone.com)

Kevin Cruijssen
fonte
11
Rachado!
Olivier Grégoire
1

Geléia: CRACKED

Isso será incrivelmente fácil em comparação com a incrível resposta em Python do Wheat Wizard, mas aqui vamos nós: P

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø<insert code snippet here>

O sha256 hexadigesto da minha solução alternativa, incluindo o primeiro snippet, é cfeb1e193ad77f66f039c0d6a792a3e4c311490f6412698e019ca1fae10c0e0a.

Nota

Você pode não ter nenhuma linha nova no código, exceto nas seqüências de caracteres, caso contrário, esse código nem será executado, o que anula o objetivo desse desafio.

Rachado por DJMcMayhem

Para ser justo, isso usa uma nova linha, então eu gostaria de ver uma solução que não use uma nova linha.

Também uma solução de Jonathan Allan

Isso não usa uma nova linha, por isso foi quebrada. : P

Minha solução é esta:

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø“print(int(input())+int(input()))”ŒV

O primeiro trecho exclui apenas átomos de caractere único, o que significa que o Python eval ainda funciona :)))

HyperNeutrino
fonte
O segundo trecho é sempre anexado ao final do primeiro trecho.
19417 Stephen
@StepHen Apenas especificando: P Mas eu esqueci de adicionar a nota; isso é realmente importante.
HyperNeutrino
3
Eu não acho que você pode restringir os ladrões assim. Se você pode decifrá-lo com o Newlines, é um crack válido. Existe alguma maneira de impedir que Novas Linhas sejam adicionadas ou forçar a primeira linha a ser executada?
DJMcMayhem
11
Eu gosto do seu crack pretendido. Muito sorrateira.
Dennis19 /
1

JavaScript, Rachado

Entrada: prompt()duas vezes

Resultado: console.log()

Minha solução não funciona no jsfiddle. Funciona na página about: blank com o console JS do Google chrome.

prompt=console=0

Minha solução:

x=document.createElement("iframe")
x.src="data:text/html,<script>console.log(prompt()-0+(prompt()-0))</script>"
document.body.appendChild(x)

Explicação:

Eu removi o prompt e o console, definindo-os como 0.

Na minha solução, crio um iframe, que cria uma sandbox, e uma nova instância da janela em que o prompt e o console funcionam corretamente.

Grant Davis
fonte
11
Rachado?
Ilmari Karonen
@CRDrost Não acredito que exista teste de primalidade nas especificações e você não mostra os dois trechos.
21917 Stephen
Desculpe, você está certo, eu interpretei errado.
CR Drost
1

Java, Rachado

import java.lang.reflect.*;
public class Main{
  public static void main(String... args){
    System.setOut(null);
    System.setErr(null);
    /*Your code here*/
  }
}

Isso deve ser muito fácil de quebrar.

Solução pretendida

import java.lang.reflect.*;
public class Main{
public static void main(String... args){
  System.setOut(null);
  System.setErr(null);
  try{
    Class<?> cistream = Class.forName("java.io.InputStream");
    Class<?> cfostream = Class.forName("java.io.FileOutputStream");
    Class<?> costream = Class.forName("java.io.OutputStream");
    Class<?> cfdescriptor = Class.forName("java.io.FileDescriptor");
    Object sout = cfostream.getConstructor(cfdescriptor).newInstance(cfdescriptor.getField("out").get(null));
    Class<?> csys = Class.forName("java.lang.System");
    Field mod = Field.class.getDeclaredField("modifiers");
    mod.setAccessible(true);
    Field stdout = csys.getField("out");
    mod.set(stdout,Integer.class.cast(mod.get(stdout) )&~ Modifier.FINAL);
    stdout.set(null,Class.forName("java.io.PrintStream").getConstructor(costream).newInstance(sout));
    Class<?> cscanner = Class.forName("java.util.Scanner");
    Object scanner = cscanner.getConstructor(cistream).newInstance(System.in);
    Method nextInt = cscanner.getMethod("nextInt");
    int f = Integer.class.cast(nextInt.invoke(scanner));
    int s = Integer.class.cast(nextInt.invoke(scanner));
    int sum = s + f;
    System.out.println(sum);
  }catch(Throwable t){t.printStackTrace();}
  }
}

Experimente online

Roman Gräf
fonte
Eu esqueci totalmente sobre java.io.. Mas você tem a solução destina-se de qualquer maneira ..
Roman Gräf
Não vejo nenhum problema aqui. Na verdade, eu escrevi o segundo snipet apenas esqueci de editá-lo. Segundo o TIO, o primeiro trecho de código é compilado sem nenhum aviso.
Roman Gräf
@ OlivierGrégoire Feito. Eu acho que qualquer IDE vai gritar comigo por isso, mas eu pelo menos o compilador aceita ...
Roman Gräf