Rendi la tua lingua * per lo più * inutilizzabile (thread del ladro)


31

Ispirato da questo commento ...

Grazie agli utenti Step Hen , Wheat-Wizard e Dennis per avermi aiutato a consolidare le specifiche di questa sfida prima di inviarla!

Questo è il filo del ladro! Per il thread della polizia, vai qui


In questa sfida , ti viene assegnato il compito di eseguire un codice che lo rende in modo che il tuo linguaggio non soddisfi più i nostri criteri di essere un linguaggio di programmazione. In quella sfida, ciò significa far sì che la lingua non possa più ...

  • Accetta input e output numerici

  • Aggiungi due numeri insieme

  • Verifica se un determinato numero è un numero primo o no.

Questa è una sfida di , in cui ci sono due sfide diverse con due obiettivi diversi: i poliziotti proveranno a scrivere del codice che rende la lingua per lo più inutilizzabile, e i ladri cercheranno di trovare la soluzione alternativa nascosta che consente ai poliziotti per recuperare la loro lingua.

I poliziotti scriveranno due frammenti di codice:

  1. Uno che rende la loro lingua per lo più inutilizzabile, ad esempio rimuovendo le funzioni integrate per eseguire input / output e operazioni numeriche. Questo codice non può bloccarsi o uscire. Dovrebbe essere possibile aggiungere il codice alla fine di questo frammento e quel codice verrà valutato . E

  2. Uno snippet di codice che accetta due numeri come input, li somma e genera la loro somma. Questo snippet deve funzionare correttamente anche dopo aver eseguito il primo snippet. Quando i due frammenti sono combinati insieme, devono formare un programma completo che aggiunge due numeri o definire una funzione che aggiunge due numeri. Questo frammento probabilmente farà affidamento su comportamenti oscuri ed è difficile da trovare.

I poliziotti sceglieranno anche qualsiasi metodo standard di input e output . Tuttavia, devono rivelare esattamente quale formato (input e output) stanno utilizzando. Per decifrare la loro risposta, è necessario seguire lo stesso formato di input / output, altrimenti il ​​crack non conta.

Una risposta della polizia rivelerà sempre

  • Il primo frammento (ovviamente non il secondo).

  • Lingua (inclusa la versione minore, poiché la maggior parte degli invii si baserà probabilmente su strani casi limite)

  • Formato IO, incluso se si tratta di una funzione o di un programma completo. I ladri devono usare lo stesso formato per essere un crack valido.

  • Eventuali strani casi limite necessari affinché la loro risposta funzioni. Ad esempio, funziona solo su Linux o richiede una connessione a Internet .

Nei panni di un ladro, devi guardare uno degli invii della polizia e tentare di decifrarlo. Puoi decifrarlo scrivendo qualsiasi snippet valido che possa funzionare come snippet 2 (sommando due numeri insieme dopo che la lingua è diventata per lo più inutilizzabile). Questo non deve essere lo stesso frammento che il poliziotto ha originariamente scritto. Dopo aver risolto una risposta, pubblica il tuo codice come risposta su questa discussione e pubblica un link alla tua risposta come commento sulla risposta del poliziotto. Quindi, quel post verrà modificato per indicare che è stato crackato.

Ecco un esempio Per il primo frammento, potresti vedere il seguente programma python 3 come risposta alla polizia:

Python 3

print=None

Riceve input da STDIN e output su STDOUT

Potrebbe essere un secondo frammento valido

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

Questo è valido perché prenderà due numeri come input e produrrà la loro somma anche se unisci i due frammenti insieme, ad es.

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

Questa è una crepa valida per la loro risposta.

Se la risposta di un poliziotto rimane senza crack per un'intera settimana, può modificare nel secondo frammento e indicare che la sua risposta è ora sicura . Una volta modificato per sicurezza, non è più possibile tentare di decifrarlo. Se non lo modificano come sicuro, puoi continuare a provare a romperlo fino a quando non lo fanno.

Il vincitore del thread del ladro è l'utente che ha decifrato il maggior numero di risposte, con il tie-breaker che ha raggiunto N volte . (quindi se due diversi utenti hanno ciascuno 5 crepe, ad esempio, l'utente che ha pubblicato per primo la sua 5a crepa è il vincitore) Dopo che è trascorso un tempo sufficiente, accetterò la risposta del vincitore con il maggior numero di voti.

Divertiti!

Chiarimenti sulle regole

  • Il primo frammento deve essere eseguito correttamente senza accettare alcun input . Potrebbe emettere qualsiasi cosa tu voglia, e questa uscita verrà ignorata. Finché il frammento è terminato, il secondo frammento viene eseguito correttamente.

  • Il secondo frammento deve essere effettivamente eseguito affinché la risposta sia valida. Questo significa una risposta come

    import sys
    sys.exit()
    

    non è valido perché non rompe la lingua. Si chiude semplicemente.

  • Dopo essere sicuro, il tuo punteggio è il conteggio dei byte di entrambi i frammenti .

  • Questo torna a Si prega di rivelare eventuali strani casi limite necessari affinché la tua risposta funzioni ... La tua presentazione deve contenere abbastanza informazioni prima di essere rivelata per essere riproducibile dopo essere stata rivelata. Ciò significa che se la tua risposta diventa sicura, e poi modifichi in: Ecco la mia risposta. Oh ya, a proposito questo funziona solo se lo esegui su Solaris, scherzi su di te! la tua risposta non è valida e verrà eliminata e non considerata idonea alla vincita.

  • Il secondo frammento può arrestarsi in modo anomalo dopo aver emesso la somma. Finché l'output è ancora corretto (ad esempio, se si sceglie di eseguire l'output su STDERR e quindi si ottengono un sacco di informazioni sull'arresto anomalo, questo non è valido)

Classifica

Ecco un elenco di ogni utente con almeno un crack, ordinato per punteggio e quindi nome (in ordine alfabetico). Se invii una crack, aggiorna il tuo punteggio di conseguenza.

#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

Risposte:


3

Java 8 di Olivier Grégoire

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

Provalo online!

Dato che Olivier ha esplicitamente permesso di passare l'input tramite le proprietà impostate usando argomenti VM, specificherò che l'input dovrebbe essere indicato nell'argomento VM -Dline.separator=X,Y, dove Xe quali Ysono i numeri da aggiungere. Cioè, per esempio per aggiungere i numeri 17 e 25, il programma dovrebbe essere invocato come:

java -Dline.separator=17,25 Main

Credo che questo dovrebbe funzionare su qualsiasi sistema in grado di eseguire programmi Java sulla riga di comando. Anche su sistemi che non dispongono di una riga di comando, è possibile utilizzare qualsiasi altro meccanismo equivalente per impostare le proprietà del sistema per passare l'input alla VM.


Ps. Ecco il mio precedente tentativo di cracking, ritenuto non valido a causa dell'utilizzo delle funzionalità specifiche di 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);
  }
}

Provalo online!

Ciò si è rivelato molto meno dettagliato di quello precedente . La parte difficile era trovare una sottoclasse SecurityManagerche non viveva in uno spazio dei nomi che inizia con "java. ". Sospetto che questa non sia ancora la soluzione prevista, ma funziona. *

*) Su TIO, almeno; la sun.awt.AWTSecurityManagerclasse e la sun.java.commandproprietà non sembrano essere ufficialmente documentate e potrebbero non essere disponibili su tutte le JVM.


Bel lavoro! Ho provato questo, ma non sono riuscito a trovare uno SecurityManagerche fosse nell'ambito ... Puoi anche leggere da System.inquesto punto, perché non è ancora chiuso.
zbw,

Siamo spiacenti, questa è una risposta dipendente dalla piattaforma per due motivi: entrambi sun.awt.SecurityManagere "sun.awt.command"sono dipendenti dalla piattaforma e non fanno parte di Java .
Olivier Grégoire,

Sì, incrinato! :) La soluzione prevista era quella di passare attraverso System.getProperties().get("blah")(poiché ho bloccato solo l'accesso a System.getProperty, non System.getProperties), ma questo è abbastanza buono! Molto bene!
Olivier Grégoire,

22

C (GCC / Linux) di Sisyphus

Questo frammento chiude la funzione fornita e ne avvia una nuova (classica iniezione di codice), che a sua volta ridefinisce in closemodo che invece di chiudere la fd, esegua il codice desiderato.

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

  exit(0);

20

Python, la soluzione del mago del grano qui

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()))

Voglio dire, puoi semplicemente ripristinare il limite di ricorsione e non succede nulla di brutto ...

Funziona su TIO

Nota

Questa è la mia prima presentazione in CnR, quindi se questo infrange qualsiasi regola, per favore dimmelo e lo cancellerò.


4
Sono stupido per aver perso questo
Wheat Wizard,

@WheatWizard :)
HyperNeutrino,

@wheatwizard Non rivelare ancora la soluzione prevista. Mi piacerebbe looove di vedere un poliziotto migliore con la vostra soluzione originale che risolve questo problema.
DJMcMayhem

@Djmcmayhem Probabilmente ripubblicherò con un del sys.
Wheat Wizard,

@WheatWizard Ricorda os.sys, se questo fa la differenza: P
HyperNeutrino

15

Haskell di 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)

Ho ancora numeri e caratteri letterali (io uso 0, '0'e '-') [a..]e [a..b]che sono molto utili. E ho unario -, ma potrei farne a meno.

Ricreare ++per implementare r( reverse) e definire te tsquali sono taile tails. x a brestituisce il nth elemento di b, dove nè la lunghezza di ameno uno. xdi solito può essere definito come snd.last.zip. La funzione dprende un elenco e restituisce un elenco con gli elementi di quelle posizioni che sono multipli di dieci. l!!srestituisce l' nelemento th di l, dove sè la rappresentazione di stringa invertita di n. +restituisce come numero intero la somma di due numeri naturali dati come stringhe invertite, allo stesso modo -per la differenza. addrestituisce come numero intero la somma di due numeri interi potenzialmente negativi dati come stringhe.

Mi chiedo se questo sia in qualche modo simile a quello che Ben aveva in mente.


Sì, praticamente le stesse idee. Corrispondenza del modello rispetto ai valori letterali per ottenere test di uguaglianza e ramificazione, elencare la sintassi di enumerazione per ottenere una forma di incremento. Sono stato piuttosto sorpreso di scoprire che :era in campo anche con NoImplicitPreludee senza importare nulla.
Ben

7

C (gcc) di 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));
}

Provalo online!


Ho dimenticato di vietare fscanf e molte altre funzioni>.> buon lavoro
Conor O'Brien,

7

Python 2 di Wheat Wizard (quarta iterazione)

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[]))`)

Provalo online!

Nessun exploit, solo una funzione da aggiungere usando solo caratteri ' &)(,.:[]a`cdfijmonrt~', come previsto (in realtà solo '(),.:[]`acdfijmnort').

Non ho fatto alcun tentativo di farla breve; Ho appena scritto sottoespressioni per valori intermedi come 0 e la stringa vuota e quelle sostituite con stringa.

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

Provalo online!

L'idea di base è che il formato stringa '{0:5}'.format('1')inserisce il numero zero in una lunghezza 5simile '1 '. Concatenando due di queste stringhe usando ''.join, la somma della loro lunghezza è la somma dei numeri di input. Quindi, ci attacchiamo 0alla fine e chiamiamo .find()la posizione finale, che è la somma.

La stringa '{0:5}'da formattare viene prodotta estraendo i {:}caratteri dai reprs di stringhe dei dizionari, creati con dict. Il repr di stringa di ogni summand successivo viene posizionato dove si troverebbe il 5. Volevo usare un dict come {0:5}se stesso, ma il suo repr include uno spazio che lo ha incasinato.

Gli input di 0 rovinano il processo perché la stringa sub ha una lunghezza minima di 1. Abbiamo quelli con un and/orper dare la stringa vuota in questo caso.


1
Questo è abbastanza diverso da quello che avevo previsto, mi piacerebbe vedere una spiegazione.
Wheat Wizard,

Puoi giocare a golf int([]in[])semplicemente int()perché entrambi produrranno 0.
Value Ink


5

x86 assembly in modalità reale a 16 bit, di 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

screenshot del dump del codice di debug, insieme all'output nell'angolo in alto a sinistra

Spiegazione:

La "rottura" introdotta dal codice di Joshua è l'impostazione del trap flag (TF), che mette la CPU in modalità single-step. Ciò significa che verrà eseguita una sola istruzione alla volta, prima che la CPU si arresti (trap) con un interrupt di tipo 1. Questo è ciò che consente ai debugger di implementare il single-stepping del codice - abbastanza utile lì, ma un vero PITA se si desidera eseguire il codice al di fuori del contesto di un debugger!

È la seguente sezione di codice che attiva il flag trap:

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

L'implementazione del flag trap significa che abbiamo la possibilità di eseguire esattamente un'istruzione prima delle trap della CPU, quella che viene immediatamente dopo quella POPFqui. Quindi, dobbiamo far valere questo.

Il trucco è l' INT 3istruzione, che invoca l'interruzione numero 3. Ci sono due motivi per cui questo funziona per "decomprimere" il codice:

  1. Il flag trap viene cancellato nei gestori di interrupt. Questo è solo una parte del design di Intel, ma è stato presumibilmente fatto per motivi di sanità mentale di base. Ricordare che l'attuazione della bandiera trappola è che un tipo-1 interrupt viene richiamato dopo l'esecuzione di ciascuna istruzione, quindi se TF non è stato eliminato, INT 1sarebbe attivare un interrupt sarebbe interruzioni fino in fondo. Inoltre, l'interruzione di TF chiaro semplifica il debug del codice, proprio come un IDE che passa automaticamente alle chiamate alle funzioni della libreria.

  2. Il modo in cui interrompe il lavoro è sostanzialmente lo stesso di un lontano CALL. Invocano il gestore di interrupt il cui indirizzo è memorizzato nella posizione corrispondente nella tabella vettoriale di interrupt globale. Poiché questa tabella inizia all'indirizzo 0x0000:0000e viene memorizzata in un segment:offsetformato a 4 byte , il calcolo dell'indirizzo è semplice come moltiplicare 4 per il vettore / numero di interrupt. In questo caso, invochiamo l'interrupt 3, quindi sarebbe 4 × 3 = 12.

    ... e noterai che Giosuè ci pensò attentamente. Prima di abilitare il flag trap, ha il seguente codice:

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

    che imposta 0x0000:000C(il gestore di interrupt per INT 3) su BP:SI. Ciò significa che ogni volta che INT 3viene invocato, inserisce il registro FLAGS nello stack, seguito dall'indirizzo di ritorno, quindi si dirama verso BP:SI, il che ci consente di ricominciare l'esecuzione del codice, in un contesto in cui il flag trap è disattivato.

Dopo è tutto in discesa INT 3. Tutto quello che dobbiamo fare è aggiungere due numeri insieme e stampare il risultato. Solo che questo non è così semplice nel linguaggio assembly come lo sarebbe in altre lingue, quindi è qui che viene spesa la maggior parte del codice.

Joshua sta permettendo al ladro di specificare qualsiasi meccanismo I / O che desidera , quindi sto adottando l'approccio semplicistico di supporre che i valori siano passati nei registri DXe CX. Questo è ragionevole, dal momento che questi non sono bloccati da nessuna parte dal suo codice "prologo".

L'output viene quindi effettuato memorizzando i byte ASCII direttamente nella memoria video. Il buffer video inizia in 0xB800:0000modalità CGA, EGA e / o VGA in modalità testo, quindi iniziamo a stampare lì. Il formato è: carattere nel byte basso e attributo color nel byte alto. Ciò significa che ogni carattere ha un offset di 2 byte. Esaminiamo semplicemente ciascuna delle cifre del numero (base-10), convertendole in ASCII e stampandole una alla volta sullo schermo. Sì, questo è un sacco di codice. Non ci sono funzioni di libreria per aiutarci nel linguaggio assembly. Questo può quasi sicuramente essere ulteriormente ottimizzato, ma mi sono stancato di lavorarci su ...

Dopo la visualizzazione dell'output, il codice può arrestarsi in modo anomalo o fare qualsiasi cosa, quindi eliminiamo semplicemente gli interrupt e arrestiamo la CPU.


Sono perplesso; Non riesco a capire come questo superi l'istruzione hlt in BP: SP + 1.
Giosuè,

@Joshua Hmm, questo è un buon punto. Non ci ho nemmeno pensato. Scorrendo il codice in Debug, eseguo INT 3e finisco immediatamente con le istruzioni che lo seguono, quindi ci sono appena andato. Forse ha qualcosa a che fare con il mio ambiente di test? CLIdisabiliterebbe solo gli interrupt di processo, ma anche se superasse il valore HLT, penseresti che fallisse ed eseguisse il codice limmediatamente dopo.
Cody Gray,

Oh, eri un singolo passo. Sì, lo farebbe. Ho intenzione di ricontrollare, ma penso di aver caricato il codice di Whacked.
Giosuè,

Ho anche testato senza step singolo. Nessuna differenza. Questo è su FreeDOS più recente in Virtualbox VM. Ho un vero hardware disponibile, ma non mi andava di accenderlo. @Joshua
Cody Grey,

Bene, allora l'hai chiaramente decifrato. Forse hai trovato il modo di sollevare quel NMI.
Giosuè,


4

Python 3 , la seconda sfida di ppperry

Wow, è stato divertente! Mi è piaciuto risolverlo.

Modifica: OK, l'ho risolto. Sembra che le classi si trovassero in un indice diverso nell'elenco delle sottoclassi su TIO rispetto al mio computer, quindi l'ho fatto funzionare per entrambi e ho aggiunto un 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()

Provalo online!


Ho ricevuto un errore sys.excepthook is missing?
Rɪᴋᴇʀ

Hmm ... funziona per me. Qual è il vero errore che stai riscontrando? (Sta succedendo perché il codice di Ppperry ha distrutto praticamente tutto, incluso sapere come mostrare le eccezioni, quindi questo è il sys.excepthook, ma ci sarà una vera causa elencata da qualche parte lì dentro.)
zbw

Non importa, il vero errore è IndexError('list index out of range',). È in linea con la definizione di _io_RawIOBase.
Rɪᴋᴇʀ

Il problema è che l'ordine delle sottoclassi non è stato risolto. _io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]dovrebbe funzionare ovunque.
Dennis,

@Dennis Sì, l'ho capito e l'ho appena risolto. Funziona su TIO ora!
zbw,

4

Haskell di 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 )

Non è possibile eseguire il codice in fase di esecuzione? Eseguilo in fase di compilazione!

È stato molto divertente, non conoscevo il modello haskell prima di questa sfida.



3

Python 2 di 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))

Provalo online!


Questo si sta rivelando più difficile di quanto pensassi.
Wheat Wizard,

3

Java di LordFarquaad

Bloccare l'accesso agli oggetti a livello di sorgente è stato davvero intelligente (e fastidioso durante i test), ben fatto!

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 {}
}

Bello! E se ClassLoaderfosse stato oscurato?
Jakob,

1
@JakobCornell "".getClass().getClassLoader(). L'ombreggiatura di solito è solo un problema a cui devi pensare una volta e poi va bene. Potresti anche oscurare Object, sarei ancora in grado di risolverlo. Ok, potresti forzarmi nella soluzione da 1kb, ma è possibile.
Olivier Grégoire il


3

Inform 7, di Ilmari Karonen

Abuso spontaneo di nomi ambigui ... Il mio codice inizia con factory is a room. La riga precedente è il codice del poliziotto. Digitare add 1 and 1per ottenere 2, ad esempio.

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

Imposta stdoute stderrtorna ai loro valori iniziali.

Credo di essere in grado di usare il nome completo invece di un'importazione, se sbaglio correggimi (questo è il mio primo post qui.) Probabilmente questo potrebbe essere fatto anche usando la riflessione.

Modifica: ecco una soluzione riflettente usando solo 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 stderrsono memorizzati altrove! Non hai nemmeno bisogno di usare setOute setErrcome puoi semplicemente usare PrintStreamdirettamente.
Olivier Grégoire,

Aggiunta una soluzione riflessiva e ritengo che questo era ciò che inizialmente si aspettava
Moira,

2

JavaScript di Daniel Franklin

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

Questa potrebbe essere considerata una soluzione leggermente economica, ma funziona per me su Chromium 59 / Linux, anche se ricevo anche un avviso che dice:

Le prossime versioni bloccheranno la navigazione verso i frame principali dei contenuti: URL. Per ulteriori informazioni, consultare https://goo.gl/BaZAea .

Ps. Ecco un'altra crepa, questa volta senza avvertimenti:

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

Penso che prompt()- -prompt()salva due byte
Marie,

2

Java 8 di Olivier Grégoire

Una crepa estremamente prolissa per una sfida estremamente prolissa. :) Il dolore di lavorare indirettamente con classi che non puoi nominare è palpabile.

    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;

Provalo online!

Ps. Ecco il mio tentativo precedente, scritto prima che Olivier chiarisse che l'input doveva essere preso tramite argomenti della riga di comando. A differenza del crack sopra, questo non è specifico di 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;

Provalo online!


Se sei pronto, ecco la mia nuova sfida .
Olivier Grégoire,

Solo per scriverlo qui: dato che non ho il diritto di dire "Gotcha! Funziona solo su un sistema", questa risposta non risolve completamente la sfida perché funziona solo su Linux.
Olivier Grégoire,

@ OlivierGrégoire: FWIW, ho trovato una soluzione alternativa usando String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");quella non specifica per Linux, ma usa quella che sembra essere una proprietà non documentata impostata da alcune JVM.
Ilmari Karonen,

Non è ancora portatile. Non funzionerà su IBM Java, per esempio. Comunque è una bella idea! :)
Olivier Grégoire,

2

C # (.NET Core) di raznagul

Presumo che questa non fosse la soluzione prevista.

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

Bel trucco con /dev/std*lì. Inizialmente miravo a un approccio simile, ma non riuscivo a trovare un modo semplice per aprire flussi per stdin / out senza accesso a System.Console, quindi ho optato per la riflessione. Ovviamente, la tua soluzione presumibilmente funziona solo su Linux e altri sistemi Unixish con le /devvoci appropriate , ma raznagul non ha detto esplicitamente che doveva funzionare su Windows. E funziona su TIO.
Ilmari Karonen,

@IlmariKaronen: Infatti; e il mio piano per Windows sarebbe fallito su TIO.
Giosuè,

1

Java, di racer290

Questo era piuttosto un aspetto fondamentale che gli staticinizializzatori sono chiamati prima del mainmetodo. È stato un bel tentativo: all'inizio sono rimasto sgomento throw new Error(), ma alla fine ho trovato la strada;)

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!");Non aggiunge due numeri interi? .. " 2. Uno snippet di codice che accetta due numeri come input, li somma e genera la loro somma. Questo snippet deve ancora funzionare correttamente anche dopo aver eseguito il primo snippet. Quando i due snippet sono combinati insieme, devono formare un programma completo che aggiunge due numeri o definire una funzione che aggiunge due numeri. Questo frammento probabilmente si baserà su comportamenti oscuri e sarà difficile da trovare. "
Kevin Cruijssen,

@KevinCruijssen Cosa posso dire? Se i poliziotti non fanno il loro lavoro, perché dovrei fare il loro? : P
Olivier Grégoire,

1
@KevinCruijssen Ecco, ho inserito un'aggiunta.
Olivier Grégoire,

@ OlivierGrégoire il punto è prevenire l'aggiunta di numeri, rimuovendo la possibilità di inserire, aggiungere o produrre.
Stephen,

@StepHen Yep, dopo l'ho capito un po 'di più. Controlla le mie altre 3 crepe per vedere che finalmente l'ho capito;)
Olivier Grégoire,

1

Java di Kevin Cruijssen

Ben costruito. Un sacco di codice per indurre qualcuno a meditare correttamente su come risolvere questa sfida. Immagino che "metti il ​​tuo codice dopo" sia stato un grande, grande suggerimento.

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

Provalo qui.


È stato veloce .. Era davvero la mia soluzione esatta prevista! Molto bene. :) EDIT: ha preso la libertà di aggiungere il link TIO se non ti dispiace.
Kevin Cruijssen,

Beh, in realtà stavo lavorando a quell'idea con la sfida del pilota 290 quando hai pubblicato la tua. E no, non mi dispiace.
Olivier Grégoire,

1

JavaScript di Grant Davis

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

Funziona nella console JS sulla about:blankpagina (come specificato nel post della polizia) su Chromium 59 / Linux.


Non ci volle molto. Buon lavoro.
Grant Davis,

1

cQuents , Step Hen , 3 byte

+BC

Provalo online!

Ho parlato molto con Step Hen per capire come diavolo funziona la sua strana lingua, ma in breve:

Il suo codice era #|1,1:A. #|1,1è l'input predefinito, ovvero ogni input fornito al programma è aggiunto da 2 1. (IE se passi un 47 e un 53, il tuo input è [47, 53, 1, 1].

:imposta semplicemente la modalità, che produrrà l' nelemento th nella sequenza ifn è impostato, e altrimenti emetterà l'intera sequenza.

Finalmente Aottiene il primo input.

Poiché abbiamo 4 ingressi [47, 53, 1, 1], l'aggiunta BCalla fine recupera anche il 2o e 3o ingresso, e il 4o ingresso diventa implicitamente n.

Perché la nostra sequenza è ABC, è analizzata algebricamente, nel senso che diventa A*B*C. Non lo vogliamo, ma se inseriamo a +tra A e B, diventa A+B*C, dove Ae Bsono i nostri input, ed Cè 1.


how the hell his weird language worksforse, una volta finito, potrebbe avere più senso
Stephen,

@StepHen non fraintendermi è un linguaggio pulito, ma strano da
morire

1

C # (.NET Core) di 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});

Provalo online!

Ciò avrebbe probabilmente impiegato meno tempo se avessi effettivamente conosciuto C #. Tuttavia, con un po 'di navigazione nella documentazione e un po' di aiuto da Jon Skeet , sono riuscito a mettere insieme qualcosa che funziona.


1

Vim challenge di @DJMcMayhem

È passato un po 'di tempo da quando non sono stato in grado di uscire da VIM , ecco la mia soluzione (nota che è molto più di 23byte - quindi probabilmente non è la soluzione prevista):

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

Provalo online!

L'idea è semplicemente di reindirizzare i due numeri interi su awkvia bash, dato che =e quando +sono stati disabilitati ho dovuto usare una piccola soluzione. La awklinea si espande in:

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

Modifica : l'intenzione originale era che l'input fosse già nel buffer, ma non sarebbe stato più difficile: la difficoltà principale era far funzionare l'aggiunta.

Ecco la soluzione suggerita da @DJMcMayhem: provala online!


Penso che non penso che tu possa fare [insert your number here]in modalità insert. Invece, è già nel buffer. Ma potresti aggirarlo con quello Oecho "<esc>Go"|awk..., quindi penso che questo conta. Ben fatto! Questa non è la crepa che avevo in mente (speravo in una risposta vim pura) quindi probabilmente posterò una nuova risposta che corregge i comandi esterni e !.
DJMcMayhem

1
Ecco un esempio che prende input nel modo corretto: provalo online!
DJMcMayhem

Sì, non ero sicuro dell'input. Ma la soluzione alternativa sarebbe davvero facile. Modificherò in modo ufficiale .
ბიმო

A proposito, il mio approccio con le patch è qui: codegolf.stackexchange.com/a/133441/31716
DJMcMayhem

1

Java 7 di 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) {

Provalo online!

Non sono necessari trucchi specifici di Linux, solo una semplice mascheratura dei nomi non qualificati Stringe di Systemclasse. Questa probabilmente non è la soluzione prevista, ma funziona.



1

RProgN2 di @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|}"+"=

Provalo online!

Questa non è di gran lunga la migliore risposta che avrei potuto dare, ma permette di aggiungere nuovamente numeri. Se avessi effettivamente provato e gestito correttamente lo stack, probabilmente avrei potuto giocare a golf un po ', ma per ora sono contento della risposta.

Nel post originale di ATaco ha effettivamente riassegnato tutti i principali operatori aritmetici per distruggere i loro input. Per risolvere questo problema ho ridefinito quale aggiunta era in termini di operazioni binarie, il che è stato un dolore perché RProgN2 non ha un operatore binario di negazione o xor.

Nota: se si desidera testare l'input, i numeri con più di una cifra devono essere nel modulo "XX..." n per essere convertiti in un numero reale poiché RProgN2 accetta ogni carattere così com'è a meno che non sia un concetto o una stringa. Modifica: @ATaco ha notato che l'aggiunta di un '$' prima di un numero a più cifre farà la stessa cosa.

EDIT: ecco la logica per la mia soluzione. Come puoi vedere, sicuramente non è il codice più raffinato, ma funziona.

{"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

Fornire un $ prima di una puntura di numeri lo raggruppa anche come un numero, ad esempio 56$46$12spingerà i numeri 5, 6, 46 e 12. Pubblica la mia soluzione effettiva e tale domani
ATaco

Non lo sapevo. Ho appena cercato i tuoi callable per capire quali fossero le cose.
Arnold Palmer

Potrei davvero scrivere della documentazione a causa di questa sfida.
ATaco

Sarebbe meraviglioso. Sono riuscito a trovare un elenco di comandi per RProgN, ma l'ho perso ... E mi è stato di grande aiuto solo perché le funzioni sono tutte diverse. Ho dovuto imparare le tue funzioni tramite la tua vecchia pagina tutorial di RProgN e le tue lezioni richiamabili. È stato divertente giocare anche se non era immediatamente ovvio come tutto funzionasse.
Arnold Palmer,

1

JavaScript (Node.js) di jrich , 298 byte

Sento che questa non è la soluzione prevista, ma se lo è, ben fatto, ho passato un po 'a cercare di capire come ottenere il nome della funzione dichiarata! :)

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

Provalo online!


1
Non è la soluzione prevista ma molto intelligente! Bel crack +1
jrich

@jrich Sì, ho pensato, sentiti libero di rimediare che sarò sicuro di provare un'altra soluzione!
Dom Hastings,

whoops ... troppo tardi! Sono rimasto soddisfatto della creatività della tua soluzione!
jrich
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.