Torne seu idioma * principalmente * inutilizável (tópico do ladrão)


31

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 do ladrão! Para o tópico dos policiais, 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 tentam escrever um código que torne a linguagem praticamente inutilizável, e os ladrões tentam encontrar a solução oculta que permite que os policiais recuperar o idioma deles.

Os policiais escreverão dois trechos de código:

  1. Um que torna seu idioma praticamente inutilizável, por exemplo, removendo funções incorporadas para realizar operações numéricas e de entrada / saída. 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 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. Esse snippet provavelmente dependerá de um comportamento obscuro e será difícil de encontrar.

Os policiais também escolherão qualquer método padrão de entrada e saída . No entanto, eles devem revelar exatamente qual formato (entrada e saída) eles estão usando. Para que você decida a resposta deles, siga o mesmo formato de entrada / saída, ou o seu crack não conta.

A resposta da polícia sempre revelará

  • 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 ser um crack válido.

  • Quaisquer casos extremos estranhos necessários para que a resposta funcione. Por exemplo, é executado apenas no linux ou requer uma conexão com a Internet .

Como um assaltante, você deve examinar um dos envios da polícia e tentar decifrá-lo. Você pode 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). Esse não precisa ser o mesmo trecho que o policial escreveu originalmente. Depois de ter uma resposta quebrada, poste seu código como resposta neste tópico e poste um link para sua resposta como um comentário na resposta do policial. Em seguida, essa postagem será editada para indicar que foi quebrada.

Aqui está um exemplo. Para o primeiro trecho, você pode ver o seguinte programa python 3 como uma resposta da polícia:

Python 3

print=None

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

Um segundo snippet válido pode ser

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)

Este é um crack válido para a resposta deles.

Se a resposta de um policial permanecer sem quebra por uma semana inteira, ele poderá editar seu segundo trecho e indicar que sua resposta agora está segura . Uma vez editado para ser seguro, você não poderá mais tentar decifrá-lo. Se eles não o editarem como seguro, você pode continuar tentando quebrá-lo até que eles o façam.

O vencedor do tópico do ladrão é o usuário que obteve mais respostas, com o desempate sendo o momento em que alcançaram N rachaduras. (portanto, se dois usuários diferentes tiverem cinco rachaduras, por exemplo, o usuário que postou sua quinta rachadura primeiro é o vencedor) Depois de um tempo suficiente, aceitarei a resposta do vencedor com mais votos.

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.

  • 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, brinca com você! 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. Contanto 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)

Entre os melhores

Aqui está uma lista de todos os usuários com pelo menos um crack, ordenados por pontuação e depois pelo nome (em ordem alfabética). Se você enviar um crack, atualize sua pontuação de acordo.

#User                       #Score
Ilmari Karonen              8

Dennis                      5

Olivier Grégoire            4

Sisyphus                    3
Veedrac                     3

Arnold Palmer               2
Bruce Forte                 2
DJMcMayhem                  2
Dom Hastings                2
ppperry                     2

1bluston                    1
2012rcampion                1
Ben                         1
BlackCap                    1
Christian Sievers           1
Cody Gray                   1
HyperNeutrino               1
Joshua                      1
Kaz                         1
Mark                        1
Mayube                      1
Xnor                        1
zbw                         1

Respostas:


3

Java 8 por Olivier Grégoire

class A {
  public A() {
    String[] args = System.lineSeparator().split(",");
    System.out.print(Integer.parseInt(args[0]) + Integer.parseInt(args[1]));
  }
}

Experimente online!

Como o Olivier permitiu explicitamente passar a entrada por meio de propriedades definidas usando argumentos da VM, especificarei que a entrada deve ser fornecida no argumento da VM -Dline.separator=X,Y, onde Xe Ysão os números a serem adicionados. Ou seja, para, por exemplo, adicionar os números 17 e 25, o programa deve ser chamado como:

java -Dline.separator=17,25 Main

Eu acredito que isso deve funcionar em qualquer sistema que possa executar programas Java na linha de comando. Mesmo em sistemas que não possuem uma linha de comando, qualquer outro mecanismo equivalente para definir propriedades do sistema pode ser usado para passar a entrada para a VM.


Ps. Aqui está minha tentativa de cracking anterior, que foi considerada inválida devido ao uso de recursos específicos da JVM:

class SecurityManager extends sun.awt.AWTSecurityManager {
  static {
    String[] args = System.getProperty("sun.java.command").split(" ");
    int a = Integer.parseInt(args[args.length-2]);
    int b = Integer.parseInt(args[args.length-1]);
    System.out.println(a+b);
  }
}

Experimente online!

Isso ficou muito menos detalhado que o anterior . A parte difícil foi encontrar uma subclasse SecurityManagerque não residia em um espaço para nome começando com " java.". Suspeito que essa ainda não seja a solução pretendida, mas funciona. *

*) No TIO, pelo menos; a sun.awt.AWTSecurityManagerclasse e a sun.java.commandpropriedade não parecem estar oficialmente documentadas e podem não estar disponíveis em todas as JVMs.


Bom trabalho! Eu tentei isso, mas não consegui encontrar um SecurityManagerque estivesse no escopo ... Você também pode ler a partir System.indeste ponto, porque ainda não está fechado.
ZBW

Desculpe, esta é uma resposta dependente da plataforma em dois aspectos: ambos sun.awt.SecurityManagere "sun.awt.command"dependem da plataforma e não fazem parte do Java .
Olivier Grégoire

Sim, rachado! :) A solução pretendida foi passar pelo System.getProperties().get("blah")(já que eu apenas bloqueei o acesso System.getProperty, não System.getProperties), mas isso é bom o suficiente! Bem feito!
Olivier Grégoire

22

C (GCC / Linux) por Sisyphus

Esse trecho fecha a função fornecida e inicia uma nova (injeção clássica de código), que redefine closepara que, em vez de fechar o fd, execute o código desejado.

}
int close(int x) {
  int a, b;
  scanf("%d %d", &a, &b);
  printf("%d\n", a + b);

  exit(0);

20

Python, a solução do Wheat Wizard aqui

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\
:[]                                                      # my code starts here
sys.setrecursionlimit(1000)
print(int(input())+int(input()))

Quero dizer, você pode simplesmente definir o limite de recursão e nada de ruim acontece ...

Trabalhos em TIO

Nota

Este é meu primeiro envio de CnR, portanto, se isso quebrar alguma regra, informe-me e eu o excluirei.


4
Eu sou burro por sentir falta disso
Assistente de trigo

@WheatWizard :)
HyperNeutrino

@wheatwizard Não revele a solução pretendida ainda. Eu looove ver um policial melhor com a sua solução original que corrige esse problema.
DJMcMayhem

@Djmcmayhem Eu provavelmente vou repostar com um del sys.
Assistente de trigo

@WheatWizard Lembre- os.sysse, se isso faz diferença: P
HyperNeutrino 19/17/17

15

Haskell por Ben

import Prelude(getLine,print)
a=a
[]++s=s
(a:as)++s=a:(as++s)
r""=""
r(c:s)=(r s)++[c]
t(_:r)=r
ts l=l:ts(t l)
x[_](v:_)=v
x(_:r)(_:s)=x r s
d(a:_:_:_:_:_:_:_:_:_:r)=a:d r
(a:_)!!""=a
l!!(n:m)=d(x['0'..n](ts l))!!m
a+b=[[0..]!!a..]!!b
a-b=let n=[0..]!!a;m=[0..]!!b in
    case [n..m] of
      [] ->   x[m..n][0..]
      l  -> -(x l    [0..])
add('-':x)('-':y)= -(r x+r y)
add('-':x)y=r y-r x
add x('-':y)=r x-r y
add x y=x+y
main=do a<-getLine;b<-getLine;print(add a b)

Eu ainda tenho números literais e caracteres (eu uso 0, '0'e '-'), [a..]ee [a..b]quais são muito úteis. E eu tenho unário -, mas eu poderia prescindir.

Eu recrio ++para implementar r( reverse) e definir te tsquais são taile tails. x a bretorna o nth elemento de b, onde né o comprimento de amenos um. xgeralmente pode ser definido como snd.last.zip. A função dpega uma lista e retorna uma lista com os elementos dessas posições que são múltiplos de dez. l!!sretorna o nth elemento de l, onde sé a representação de string invertida de n. +retorna como inteiro a soma de dois números naturais dados como seqüências de caracteres invertidas, da mesma forma -para a diferença. addretorna como número inteiro a soma de dois números inteiros possivelmente negativos dados como seqüências de caracteres.

Eu me pergunto se isso é um pouco semelhante ao que Ben tinha em mente.


Sim, praticamente as mesmas idéias. Correspondência de padrões com literais para obter testes de igualdade e ramificação, sintaxe de enumeração de lista para obter uma forma de incremento. Fiquei bastante surpreso ao descobrir que :estava no escopo, mesmo com NoImplicitPreludee sem importar nada.
Ben

7

C (gcc) por Conor O'Brien


void post_main() __attribute__ ((destructor));

void post_main()
{
    int a, b;
    char sum[11];
    void *stdin = fdopen(0, "r");

    fscanf(stdin, "%u %u", &a, &b);
    sprintf(sum, "%u", a + b);
    write(1, sum, strlen(sum));
}

Experimente online!


ugggg eu esqueci de proibir fscanf e muitos daqueles outras funções>> bom trabalho.
Conor O'Brien

7

Python 2 pelo Wheat Wizard (quarta iteração)

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\
c,d:(`int([]in[])`[:[]in[]]).join([((c)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),c)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),((d)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),d)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),`(int([]in[]))`]).rfind(`(int([]in[]))`)

Experimente online!

Sem explorações, apenas uma função para adicionar usando apenas caracteres ' &)(,.:[]a`cdfijmonrt~', como pretendido (apenas na verdade '(),.:[]`acdfijmnort').

Não tentei encurtar; Acabei de escrever subexpressões para valores intermediários como 0 e a string vazia e a substitui em.

def f(c,d):
	FALSE = []in[]
	TRUE = []in[[]]
	ZERO = int([]in[])
	ONE = int(TRUE)
	EMPTY = `int([]in[])`[:[]in[]]
	ZERO_STR = `ZERO`
	ONE_STR = `ONE`

	ZERO_DICT = dict([(ZERO,ZERO)])
	ZERO_DICT_STR = `ZERO_DICT`

	OPEN_BRACE = ZERO_DICT_STR[ZERO]
	COLON = ZERO_DICT_STR[ONE:][ONE]
	CLOSE_BRACE = ZERO_DICT_STR[ONE:][ONE:][ONE:][ONE:][ONE]

	C_STR = `c`
	D_STR = `d`

	FORMAT_STR_C = ''.join([OPEN_BRACE, ZERO_STR, COLON, C_STR, CLOSE_BRACE])
	FORMAT_STR_D = ''.join([OPEN_BRACE, ZERO_STR, COLON, D_STR, CLOSE_BRACE])

	LENGTH_C_STR = c and FORMAT_STR_C.format(ONE_STR) or EMPTY
	LENGTH_D_STR = d and FORMAT_STR_D.format(ONE_STR) or EMPTY

	TOTAL_STR = EMPTY.join([LENGTH_C_STR, LENGTH_D_STR, ZERO_STR])
	RESULT = TOTAL_STR.find(ZERO_STR)

	return RESULT

Experimente online!

A idéia principal é que o formato da string '{0:5}'.format('1')preencha o número zero com um comprimento 5igual '1 '. Pela concatenação usando duas dessas cadeias ''.join, a soma de seu comprimento é a soma dos números de entrada. Então, aderimos a um0 até o final e chamamos .find()para a posição final, que é a soma.

A sequência '{0:5}'a ser formatada é produzida extraindo os {:}caracteres das repetições de sequência de dicionários, criadas com dict. A sequência repr de cada soma sucessiva é colocada onde os 5 estariam. Eu queria usar um ditado como{0:5} ele mesmo, mas seu repr inclui um espaço que estragou tudo.

Entradas de 0 atrapalham o processo porque a string sub tem um comprimento mínimo de 1. Temos aquelas com a and/orpara fornecer a string vazia neste caso.


1
Isso é bem diferente do que eu pretendia, adoraria ver uma explicação.
Assistente de trigo

Você pode golfe todo o seu int([]in[])simplesmente int()tanto como saída será 0.
Valor Ink


5

montagem em modo real de 16 bits x86, por Joshua

    int  0x3                  ; <---  this is the "robber" portion

    ; -- begin code to print numbers in real-mode asm using ROM BIOS video interrupts --
    add  dx, cx               ; add input values together
    mov  ax, dx               ; move result into AX
    push WORD 0xB800
    pop  ds                   ; DS == starting address of text-mode video buffer
    xor  cx, cx               ; digit counter
    xor  di, di               ; position counter
    mov  bx, 0xA              ; divisor

    test ax, ax               ; is number negative?
    jns  .GetDigits
    neg  ax                   ; convert negative number to positive
    mov  WORD ds:[di], 0x4F2D ; output leading negative sign, in white-on-red
    add  di, 2                ; increment position counter

.GetDigits:
    xor  dx, dx
    div  bx                   ; divide DX:AX by 10 (AX == quotient, DX == remainder)
    push dx                   ; push digit onto stack
    inc  cx                   ; increment digit counter
    test ax, ax
    jnz  .GetDigits           ; keep looping until we've got 'em all

.PrintDigits:
    pop  dx                   ; get digit off of stack
    dec  cx                   ; decrement digit counter
    mov  dh, 0x4F             ; high byte: color attribute (white-on-red)
    add  dl, 0x30             ; low  byte: convert to ASCII
    mov  WORD ds:[di], dx     ; output digit
    add  di, 2                ; increment position counter
    test cx, cx
    jnz  .PrintDigits         ; keep looping until we've printed 'em all

    cli
    hlt

captura de tela do despejo de código de depuração, junto com a saída no canto superior esquerdo

Explicação:

A "quebra" introduzida pelo código de Joshua é a configuração do sinalizador de interceptação (TF), que coloca a CPU no modo de etapa única. Isso significa que apenas uma única instrução será executada por vez, antes que a CPU pare (traps) com uma interrupção do tipo 1. É isso que permite que os depuradores implementem o passo único do código - bastante útil lá, mas uma PITA real, se você quiser executar o código fora do contexto de um depurador!

É a seguinte seção de código que ativa o sinalizador de interceptação:

pushf               ; push the FLAGS register onto the top of the stack
mov bp, sp          ; load the pointer to the top of the stack into BP
or word [bp], 256   ; bitwise-OR the WORD at the top of the stack (the copy of FLAGS)
                    ;  with 0x100, which turns on bit 8 (TF)
popf                ; pop the modified flags back off the stack into FLAGS

A implementação do sinalizador de interceptação significa que temos a chance de executar exatamente uma instrução antes dos traps da CPU - que é o que ocorre imediatamente após o POPF aqui. Então, precisamos fazer com que este conte.

O truque é a INT 3instrução, que chama a interrupção número 3. Há duas razões pelas quais isso funciona para "desobstruir" o código:

  1. O sinalizador de interceptação é limpo em manipuladores de interrupção. Isso é apenas parte do design da Intel, mas foi presumivelmente feito por razões básicas de sanidade. Lembre-se de que a implementação do sinalizador trap é que uma interrupção do tipo 1 é invocada após a execução de cada instrução; portanto, se o TF não foi limpo, INT 1ele próprio acionaria uma interrupção - seria interrupções até o fim. Além disso, a interrupção do TF claro facilita a depuração do código, como um IDE que passa automaticamente pelas chamadas para as funções da biblioteca.

  2. A maneira como interrompe o trabalho é essencialmente a mesma que distante CALL. Eles invocam o manipulador de interrupções cujo endereço é armazenado na posição correspondente na tabela de vetores de interrupção global. Como essa tabela começa no endereço 0x0000:0000e é armazenada em um arquivo de 4 bytessegment:offset formato de , calcular o endereço é tão simples quanto multiplicar 4 pelo vetor / número de interrupção. Nesse caso, invocamos a interrupção 3, de modo que seria 4 × 3 = 12.

    ... e você notará que Joshua pensativamente configurou isso para nós. Antes de ativar o sinalizador de interceptação, ele tem o seguinte código:

    mov  di, 12
    mov  [di], si
    mov  [di + 2], bp
    

    que define 0x0000:000C(o manipulador de interrupção para INT 3) como BP:SI. Isso significa que sempre que INT 3é chamado, ele envia o registro FLAGS para a pilha, seguido pelo endereço de retorno e depois ramifica para BP:SI, o que nos permite começar a executar o código novamente, em um contexto em que o sinalizador de trap é desativado.

É tudo ladeira abaixo depois INT 3. Tudo o que precisamos fazer é adicionar dois números e imprimir o resultado. Exceto que isso não é tão simples na linguagem assembly como seria em outros idiomas, então é aqui que a maior parte do código é gasta.

Joshua está permitindo que o ladrão especifique qualquer mecanismo de E / S que ele queira , então estou adotando a abordagem simplista de assumir que os valores são passados ​​no DXeCX registradores . Isso é razoável, uma vez que estes não são prejudicados em parte alguma pelo seu código de "prólogo".

A saída é feita armazenando bytes ASCII diretamente na memória de vídeo. O buffer de vídeo inicia 0xB800:0000em um modo de texto CGA, EGA e / ou VGA, então começamos a imprimir lá. O formato é: caractere no byte baixo e atributo de cor no byte alto. Isso significa que cada caractere está em um deslocamento de 2 bytes. Nós apenas iteramos através de cada um dos dígitos do número (base 10), convertendo-os em ASCII e imprimindo-os um de cada vez na tela. Sim, isso é muito código. Não há funções de biblioteca para nos ajudar na linguagem assembly. Isso quase certamente pode ser otimizado ainda mais, mas eu me cansei de trabalhar nisso ...

Depois que a saída é exibida, o código pode travar ou fazer o que for, então limpamos as interrupções e interrompemos a CPU.


Estou confuso; Não consigo descobrir como isso ultrapassa a instrução hlt no BP: SP + 1.
21717 Joshua

@ Joshua Hmm, esse é um bom ponto. Eu nem pensei nisso. Percorrendo o código no Debug, eu executo INT 3e acabo imediatamente de volta à instrução a seguir, então apenas o segui. Talvez tenha algo a ver com o meu ambiente de teste? CLIdesabilitaria apenas as interrupções de hardware, mas, mesmo HLTque passasse, você pensaria que ele passaria e executaria o código limediatamente depois.
Cody Gray

Oh, você estava pisando sozinho. Sim, isso faria isso. Vou checar novamente, mas acho que carreguei o código danificado.
21717 Joshua

Eu também testei sem uma etapa. Não faz diferença. Este é o FreeDOS mais recente no VM Virtualbox. Eu tenho hardware real disponível, mas não senti vontade de ligá-lo. @Joshua
Cody Gray

Bem, você claramente o quebrou então. Talvez você tenha encontrado uma maneira de aumentar essa MNI.
21717 Joshua


4

Python 3 , o segundo desafio de ppperry

Uau, isso foi divertido! Eu gostei de resolver isso.

Edit: OK, eu consertei. Parece que as classes estavam com um índice diferente na lista de subclasses no TIO e no meu computador, então eu fiz o trabalho para ambos e adicionei um TIO.

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

# My code begins here
str = "Hello!".__class__
int = (37).__class__
object = str.__base__

def find_subclass(superclass, name):
	for cls in superclass.__subclasses__():
		if cls.__name__ == name:
			return cls

_io_IOBase      = find_subclass(object, '_IOBase')        # <class '_io._IOBase'>
_io_RawIOBase   = find_subclass(_io_IOBase, '_RawIOBase') # <class '_io._RawIOBase'>
_ioFileIO       = find_subclass(_io_RawIOBase, 'FileIO')  # <class '_io.FileIO'>
stdout = _ioFileIO('stdout', mode='w', opener=lambda name,flags: 1) # FD for stdout is 1
stdin  = _ioFileIO('stdin',  mode='r', opener=lambda name,flags: 0) # FD for stdin is 0
nums = str(stdin.read(), encoding='utf-8').split()
stdout.write(str(int(nums[0]) + int(nums[1])).encode('utf-8') + b'\n')
stdout.flush()

Experimente online!


Eu recebo um erro. sys.excepthook is missing?
Rɪᴋᴇʀ

Hmm ... funciona para mim. Qual é o verdadeiro erro que você está recebendo? (Isso está acontecendo porque o código de ppperry destruiu praticamente tudo, incluindo saber como mostrar exceções, então essa é a sys.excepthook, mas haverá uma causa real listado em algum lugar lá.)
ZBW

Deixa pra lá, o verdadeiro erro é IndexError('list index out of range',). Está na linha com a definição de _io_RawIOBase.
Rɪᴋᴇʀ

O problema é que a ordem das subclasses não é fixa. _io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]deve funcionar em qualquer lugar.
Dennis

@ Dennis Sim, eu percebi isso e apenas consertei. Ele funciona no TIO agora!
ZBW

4

Haskell por zbw

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

import Language.Haskell.TH.Syntax
import System.IO.Unsafe

a = $( runIO $ TupE[] <$
              do x <- readLn :: IO Integer
                 y <- readLn
                 print $ x + y )

Não é possível executar o código em tempo de execução? Execute-o em tempo de compilação!

Foi muito divertido, eu não conhecia o modelo haskell antes desse desafio.



3

Python 2 por Wheat Wizard

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\
a,b:a+b
__import__('sysconfig').__dict__['os'].__dict__['sys'].setrecursionlimit(1000)
print(f(1,2))

Experimente online!


Isso está se tornando mais difícil do que eu pensava.
Assistente de trigo

3

Java por LordFarquaad

Bloquear o acesso aos objetos no nível de origem foi realmente inteligente (e irritante ao testar), muito bem!

public class java {
  public static void main(String[] s) {
    //there is no executable code in snippet one.
    //your code here.
    try {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      Object in = cl.loadClass("java.lang.System").getDeclaredField("in").get(null);
      Object out = cl.loadClass("java.lang.System").getDeclaredField("out").get(null);
      Object scanner = cl.loadClass("java.util.Scanner").getConstructor(cl.loadClass("java.io.InputStream")).newInstance(in);
      int i = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      int j = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      cl.loadClass("java.io.PrintStream").getMethod("println", Object.class).invoke(out, i+j);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  class Class {}
  class Method {}
  class System {}
  class FileDescriptor {}
  class Logger {}
  class Runtime {}
  class Scanner {}
}

Agradável! E se ClassLoadertivesse sido sombreado?
Jakob

1
@JakobCornell "".getClass().getClassLoader(). A sombra é geralmente apenas um problema em que você deve pensar uma vez e tudo bem. Você pode até sombra Object, eu ainda seria capaz de resolver isso. Ok, você pode me forçar a usar a solução de 1kb, mas é possível.
Olivier Grégoire


3

Inform 7, de Ilmari Karonen

Abuso flagrante de substantivos ambíguos ... Meu código começa com factory is a room. A linha anterior é o código do policial. Digite add 1 and 1para obter 2, por exemplo.

For reading a command: Rule fails

factory is a room.
The adder one is a thing. The adder two is a thing. The adder one is in factory. The adder two is in factory.
Before reading a command: change the text of the player's command to "examine adder"

For printing a parser error: 
    if the player's command includes "add [number] ":
        let N be the number understood;
        if the player's command includes "and [number]":
            say the number understood plus N;

2

Java, Roman Gräf

public class Main {
    public static void main(String... args){
        System.setOut(null);
        System.setErr(null);

        System.setOut(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out)));
        System.setErr(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.err)));
        System.out.println("This");
        System.err.println("works");
    }
}

Conjuntos stdout e stderrvolta aos seus valores iniciais.

Acredito que posso usar o nome completo em vez de uma importação, se estiver errado, corrija-me (esta é minha primeira postagem aqui.) Isso provavelmente poderia ser feito usando reflexão também.

Edit: aqui está uma solução reflexiva usando apenas java.lang.reflect.*:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test {
    public static void main(String... args) {
        System.setOut(null);
        System.setErr(null);

        try {
            Class<?> psClass = Class.forName("java.io.PrintStream");
            Class<?> fsClass = Class.forName("java.io.FileOutputStream");
            Class<?> osClass = Class.forName("java.io.OutputStream");
            Class<?> fdClass = Class.forName("java.io.FileDescriptor");
            Class<System> sClass = System.class;
            Constructor psCtor = psClass.getConstructor(osClass);
            Constructor fsCtor = fsClass.getConstructor(fdClass);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);

            Object sout = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("out").get(null)));
            Field outField = sClass.getDeclaredField("out");
            modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
            outField.set(null, sout);

            Object serr = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("err").get(null)));
            Field errField = sClass.getDeclaredField("err");
            modifiersField.setInt(errField, outField.getModifiers() & ~Modifier.FINAL);
            errField.set(null, serr);

            System.out.println("This");
            System.err.println("works");
        } catch (Exception ignore) {
        }
    }
}

Yep, stdin, stdoute stderrsão armazenados em outro lugar! Você nem precisa usar setOute, setErrcomo você pode simplesmente usar PrintStreamdiretamente.
Olivier Grégoire

Adicionado solução reflexivo, assim como eu sinto que este era o que estava inicialmente previsto
Moira

2

JavaScript por Daniel Franklin

location="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"

Isso pode ser considerado uma solução um pouco barata, mas funciona para mim no Chromium 59 / Linux, mesmo se eu também receber um aviso dizendo:

As próximas versões bloquearão as navegações de quadros superiores iniciadas pelo conteúdo para dados: URLs. Para mais informações, consulte https://goo.gl/BaZAea .

Ps. Aqui está outra rachadura, desta vez sem avisos:

Node.prototype.removeChild=function(){}
document.body.innerHTML='<iframe src="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"/>'

Eu acho que prompt()- -prompt()salva dois bytes
Marie

2

Java 8 por Olivier Grégoire

Uma rachadura extremamente detalhada para um desafio extremamente detalhado. :) A dor de trabalhar indiretamente com classes que você não pode nomear é palpável.

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class filein  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.io.FileInputStream");

      InputStream cmd = (InputStream) filein.getConstructor(String.class).newInstance("/proc/self/cmdline");
      byte[] buf = new byte[65536];
      int len = cmd.read(buf);
      String[] args = new String(buf, 0, len).split("\0");
      
      int a = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-2]);
      int b = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-1]);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

Experimente online!

Ps. Aqui está minha tentativa anterior, escrita antes de Olivier esclarecer que a entrada deveria ser obtida por meio de argumentos da linha de comando. Ao contrário do crack acima, este não é específico do Linux.

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class scanner = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.util.Scanner");

      InputStream in = (InputStream) system.getField("in").get(null);
      Object scanIn = scanner.getConstructor(InputStream.class).newInstance(in);

      int a = (int) scanner.getMethod("nextInt").invoke(scanIn);
      int b = (int) scanner.getMethod("nextInt").invoke(scanIn);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

Experimente online!


Se você quiser, aqui está o meu novo desafio .
Olivier Grégoire

Apenas para escrever aqui: como não tenho o direito de dizer "Entendi! Funciona apenas em um sistema", essa resposta não quebra totalmente o desafio, pois funciona apenas no Linux.
Olivier Grégoire

@ OlivierGrégoire: FWIW, eu criei uma solução alternativa String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");que não é específica do Linux, mas usa o que parece ser uma propriedade não documentada definida por algumas JVMs.
Ilmari Karonen

Isso ainda não é portátil. Não funcionará no IBM Java, por exemplo. No entanto, é uma boa ideia! :)
Olivier Grégoire

2

C # (.NET Core) por raznagul

Presumo que essa não foi a solução pretendida.

int a;
int b;

using (var f = new System.IO.FileStream("/dev/stdin", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (var fs = new System.IO.StreamReader(f))
{
a = int.Parse(fs.ReadLine());
b = int.Parse(fs.ReadLine());
}
}
using (var f = new System.IO.FileStream("/dev/stdout", System.IO.FileMode.Open, System.IO.FileAccess.Write))
{
using (var fs = new System.IO.StreamWriter(f))
{
fs.WriteLine((a + b).ToString());
}
}

Truque agradável com /dev/std*lá. Inicialmente, eu visava uma abordagem semelhante, mas não conseguia encontrar uma maneira fácil de abrir fluxos para stdin / out sem acesso ao System.Console, então optei pela reflexão. Obviamente, sua solução provavelmente só funciona no Linux e em outros sistemas Unixish com as /deventradas apropriadas , mas o raznagul não disse explicitamente que precisava trabalhar no Windows. E funciona no TIO.
Ilmari Karonen

@IlmariKaronen: De fato; e meu plano para se fosse o Windows teria falhado no TIO.
1937 Joshua

1

Java, por racer290

Este foi um aspecto básico de que os staticinicializadores são chamados antes do mainmétodo. Foi uma boa tentativa: fiquei desanimado com o throw new Error()começo, mas encontrei o caminho no final;)

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException {

    try {

        System.class.getField("in").set(null, null);
        System.class.getField("out").set(null, null);
        System.class.getField("err").set(null, null);

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

        File.class.getField("fs").set(null, null);

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

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                throw new Error("Muahaha!");

            }

            @Override
            public void checkLink(String s) {

                throw new Error("Not this way, my friend!");

            }

        };

        System.setSecurityManager(mngr);

    } catch (Throwable t) {

    }
    // My code here, I guess...
} static {
  java.util.Scanner s = new java.util.Scanner(System.in);
  System.out.println(s.nextInt()+s.nextInt());

    // End of my code
}

System.out.println("Hello World!");Não adiciona dois números inteiros? .. " 2. Um trecho de código que recebe dois números como entrada, os soma 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 juntos, eles devem formar um programa completo que adiciona dois números, ou definir uma função que adiciona dois números Este trecho provavelmente vai depender de comportamento obscuro, e ser difícil de encontrar.. "
Kevin Cruijssen

@KevinCruijssen O que posso dizer? Se os policiais não fazem o trabalho deles, por que devo fazer o deles? : P
Olivier Grégoire

1
@KevinCruijssen Lá, eu coloquei uma adição lá.
Olivier Grégoire

@ OlivierGrégoire o ponto principal é impedir a adição de números, removendo a capacidade de inserir, adicionar ou produzir.
21917 Stephen

@StepHen Sim, entendi um pouco mais depois. Verifique meus outros 3 rachaduras para ver que eu finalmente entendi que;)
Olivier Grégoire

1

Java por Kevin Cruijssen

Bem construído. Muito código para fazer alguém refletir adequadamente sobre como resolver esse desafio. Eu acho que o "coloque seu código depois" foi uma dica muito grande.

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);
  }
}

class System {
  static void exit(int n) {}
  static void setSecurityManager(SecurityManager sm) {
    java.util.Scanner scanner =new java.util.Scanner(java.lang.System.in);
    java.lang.System.out.println(scanner.nextInt() + scanner.nextInt());
  }
  static void setIn(Object o) {}
  static void setOut(Object o) {}
  static void setErr(Object o) {}
}

Experimente aqui.


Isso foi rápido .. Essa foi realmente a minha solução exata! Bem feito. :) EDIT: tomou a liberdade de adicionar o link TIO se você não se importa.
21817 Kevin Cruijssen

Bem, eu estava trabalhando nessa ideia com o desafio do piloto 290 quando você postou o seu. E, não, eu não me importo.
Olivier Grégoire

1

JavaScript por Grant Davis

document.body.innerHTML='<iframe/>'
w=frames[0]
w.console.log(1*w.prompt()+1*w.prompt())

Funciona no console JS da about:blankpágina (conforme especificado na publicação da polícia) no Chromium 59 / Linux.


Isso não demorou muito. Bom trabalho.
Grant Davis

1

cQuents , passo Hen , 3 bytes

+BC

Experimente online!

Conversou muito com Step Hen para descobrir como diabos sua linguagem estranha funciona, mas em resumo:

O código dele era #|1,1:A. #|1,1é a entrada padrão, ou seja, qualquer entrada fornecida ao programa é anexada por 2 1s. (Ou seja, se você passar um 47 e um 53, sua entrada é [47, 53, 1, 1].

:simplesmente define o modo, que produzirá o nth item na sequência, se nestiver definido, e produzirá a sequência inteira.

Finalmente Aobtém a primeira entrada.

Como temos 4 entradas [47, 53, 1, 1], adicionar BCao final também buscará a 2ª e a 3ª entrada, e a quarta entrada implicitamente se tornarán .

Porque a nossa sequência é ABC, é analisada algebricamente, o que significa que se torna A*B*C. Não queremos isso, mas se inserirmos um +entre A e B, torna-se A+B*C, onde Ae Bsão nossas entradas, e Cé 1.


how the hell his weird language workstalvez uma vez eu terminá-lo poderia fazer mais algum sentido
Stephen

@StepHen não me interpretem mal, é uma linguagem interessante, mas estranha como o inferno #
Skidsdev

1

C # (.NET Core) por raznagul

var console = typeof(System.ConsoleCancelEventArgs).Assembly.GetType("System.Console");
var readLine = console.GetMethod("ReadLine");
var writeLine = console.GetMethod("WriteLine", new Type[] { typeof(int) });
int a = Int32.Parse((string) readLine.Invoke(null, null));
int b = Int32.Parse((string) readLine.Invoke(null, null));
writeLine.Invoke(null, new object[] {a+b});

Experimente online!

Provavelmente isso levaria menos tempo se eu realmente conhecesse C #. No entanto, com alguma navegação na documentação e um pouco de ajuda de Jon Skeet , consegui juntar algo que funcionasse.


1

Vim challenge por @DJMcMayhem

Já faz um tempo desde que não consegui sair do vim , eis a minha solução (observe que é muito mais que 23bytes - portanto, provavelmente não é a solução pretendida):

i
echo "
12
39
"|awk '{s'$(python -c "print(''.join([chr(43),chr(61)]))")'$1} END {print s}'<Esc>vgg!bash

Experimente online!

A idéia é simplesmente canalizar os dois números inteiros para awkvia bash, uma vez que, =e +foram desativados, tive que usar uma pequena solução alternativa. A awklinha se expande para:

"|awk '{s'+='} END {print s}

Editar : A intenção original era que a entrada já estivesse no buffer, mas isso não seria mais difícil - a principal dificuldade era fazer a adição funcionar.

Aqui está a correção sugerida por @DJMcMayhem: Experimente online!


Eu acho que não acho que você pode fazer [insert your number here]no modo de inserção. Em vez disso, ele já está no buffer. Mas você pode contornar isso Oecho "<esc>Go"|awk..., então acho que isso conta. Bem feito! Esta não é a rachadura que eu tinha em mente (eu esperava uma resposta pura do vim), então provavelmente postarei uma nova resposta que corrige comandos externos e !.
DJMcMayhem

1
Aqui está um exemplo que leva a entrada da maneira correta: Experimente online!
DJMcMayhem

Sim, eu não tinha certeza sobre a entrada. Mas a solução alternativa seria realmente fácil. Vou editar da maneira oficial .
ბიმო

BTW, minha abordagem corrigida está aqui: codegolf.stackexchange.com/a/133441/31716
DJMcMayhem

1

Java 7 por Poke

  }
  public static void main(java.lang.String[]a) throws Exception {
    int x = Integer.parseInt(a[0]);
    int y = Integer.parseInt(a[1]);
    java.lang.System.out.println(x+y);
  }
}
class String {
}
class System {
  public static java.io.InputStream in = new java.io.ByteArrayInputStream(new byte[0]), out = in, err = in;
  public static void setProperties (Object o) {

Experimente online!

Não são necessários truques específicos do Linux, apenas mascaramento simples de nomes não qualificados Stringe de Systemclasse. Provavelmente, essa não é a solução pretendida, mas funciona.



1

RProgN2 por @ATaco

"+-/*÷^"{²[[\=};
{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"={"d"="g"=g~d&gd~&|}"±"={"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"={"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=

Experimente online!

Essa não é, de longe, a melhor resposta que eu poderia ter dado, mas permite adicionar números novamente. Se eu tivesse feito o manuseio adequado da pilha, provavelmente poderia jogar um pouco de golfe, mas a partir de agora estou feliz com a resposta.

No post original do ATaco, ele efetivamente acabou de reatribuir todos os principais operadores aritméticos para destruir suas entradas. Para corrigir esse problema, redefini o que era adição em termos de operações binárias, o que foi uma dor porque o RProgN2 não possui um operador de negação binária ou xor.

Nota: Se você deseja testar a entrada, os números com mais de um dígito precisam estar no formato "XX..." npara serem convertidos em um número real, já que o RProgN2 assume cada caractere como está, a menos que seja um conceito ou sequência. Edit: @ATaco observou que adicionar um '$' antes de um número de vários dígitos fará a mesma coisa.

EDIT: Aqui está a lógica da minha solução. Como você pode ver, definitivamente não é o código mais refinado, mas funciona.

{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"= # Defines the ~ operator which negates a number
{"D"=                                                                   }     # Remove the top of the stack and assign D with the popped value
     11                                                                       # Push 2 1's to the stack.  The first is used as a counter, the second if the initial truthy value for the loop
       {             }:                                                       # Start a while loop if the top of the stack (popped) is truthy (removes final falsey value)
        ‹                                                                     # Left shift the counter variable
         1D&¬                                                                 # Push negation of last bit of D
             \                                                                # Swap the counter (index 1) and the negated bit (index 0)
              D›]"D"=                                                         # Push D, right shift it, duplicate the value on the stack, then pop and assign the top to D
                       ]1\                                                    # Duplicate the counter, push 1, and swap the counter to the top of the stack
                          2\Š                                                 # Push 2, swap with the counter, then take the log (log_2(counter))
                             1{         };                                    # Run the for loop "for (i=1;i<=log_2(counter);i+=1)"
                               [\                                             # Pop off i, then swap the original counter with the next bit to append
                                 D‹|"D"=                                      # Left shift D, or it with the next bit, then assign D the new value
                                          D¬                                  # Need to check if D was 0 or not (in the case of 0b11...1~)
                                            {                     }{ }?       # Conditional on the truthiness of not D
                                             1"D"=                            # If D was 0, we assign it as 1, then start to bit shift it up
                                                  1\2\Š1{       };            # Same for loop as earlier since the original counter is still on the top of the stack
                                                         [D‹"D"=              # Pop off i, left shift D, then reassign it
                                                                    [         # Else D was non-zero, so just pop off the counter we've been carrying around
                                                                       D      # Push the final value to the top of the stack as a return
                                                                         "~"= # Assign the function between the {}'s to the character '~'

{"d"="g"=g~d&gd~&|}"±"=                                                       # Defines the ± operator which performs a single bit xor
{"d"="g"=         }                                                           # Assign d and g the first and second values on the stack respectively
         g~d&                                                                 # Push ~g&d to the top of the stack
             gd~&                                                             # Push g&~d to the top of the stack
                 |                                                            # Or the top 2 values giving us (~g&d)|(g&~d)
                   "±"=                                                       # Assign this function to the ± operator

{"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"=             # Defines the × operator which performs a full number xor
{"H"="I"=                                                   }                 # Store the top 2 stack values in H and I (in that order)
         11{                            }:                                    # Another while loop with the first one being a counter for later, and the second is our truthy value to start the loop
            ‹H1&I1&±                                                          # Left shift the counter, then push the bit xor of H's and I's lowest bit ((H&1)±(I&1) in infix notation)
                    \                                                         # Swap the calculated bit and the counter
                     H›"H"=I›"I"=                                             # Right shift both variables and store the values back in them
                                 H¬¬I¬¬|                                      # Effectively pushing the value (H!=0 | I != 0)
                                          1\2\Š1{        };                   # Same for loop as the ones above
                                                 [H‹|"H"=                     # Pop off the for loop counter, left shift H, or it with the next bit, and reassign
                                                           H                  # Push the final computed xor value to the top of the stack
                                                             "×"=             # Assign this whole function to the × operator

{"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=                                         # Finally, a function redefining addition as the "+" operator
{"J"="K"=                       }                                             # Store the top 2 stack values in J and K respectively
         1{                }:                                                 # An initial truthy value to start the while loop and the loop itself
           JK&‹                                                               # Push (J&K)<<1 to the stack
               JK×                                                            # Compute the full xor of J and K (J^K in Python)
                  "K"=                                                        # Assign K the value of J xor K
                      ]"J"=                                                   # Duplicate (J&K)<<1 and assign 1 copy to J, leaving (J&K)<<1 as our while check (while ((J&K)<<1))
                             JK|                                              # Finally push the value J|K to the stack to get the addition
                                 "+"=                                         # Assign this function to the "+" operator, restoring it

Fornecer um $ antes de uma picada de números também grupos de TI como um número, por exemplo, 56$46$12vai empurrar os números 5, 6, 46 e 12. Vou postar minha solução real e tal tommorow
Ataco

Não sabia disso. Eu meio que olhei através dos seus callables para descobrir o que eram as coisas.
Arnold Palmer

Na verdade, posso escrever alguma documentação por causa desse desafio.
ATaco 20/07

Isso seria maravilhoso. Consegui encontrar uma lista de comandos para o RProgN, mas o perdi ... E isso só ajudou muito, já que as funções são todas diferentes. Eu tive que aprender suas funções através da sua antiga página de tutorial do RProgN e de suas classes de chamada. Era divertido brincar mesmo que não fosse imediatamente óbvio como tudo funcionava.
Arnold Palmer

1

JavaScript (Node.js) por jrich , 298 bytes

Sinto que essa não é a solução pretendida, mas se for, bem feito, passei um tempo tentando descobrir como obter o nome da função declarada! :)

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)})();
process.stderr.write.call(process.stdout,''+((0|process.argv[2])+(0|process.argv[3])));

Experimente online!


1
Não é a solução pretendida, mas muito inteligente! Agradável rachadura +1
jrich

@ jrich Sim, imaginei, sinta-se à vontade para corrigir isso, vou ter certeza de tentar outra vez a solução pretendida!
Dom Hastings

gritos ... tarde demais! Fiquei satisfeito com a criatividade da sua solução!
jrich
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.