Rendre votre langue * principalement * inutilisable (fil du voleur)

31

Inspiré par ce commentaire ...

Merci aux utilisateurs Step Hen , Wheat-Wizard et Dennis pour m'avoir aidé à solidifier les spécifications de ce défi avant de le poster!

Ceci est le fil du voleur! Pour le fil des flics, allez ici


Dans ce défi , vous êtes chargé d'exécuter du code qui fait en sorte que votre langage ne réponde plus à nos critères d'être un langage de programmation. Dans ce défi, cela signifie faire en sorte que la langue ne puisse plus ...

  • Prendre l'entrée et la sortie numériques

  • Additionnez deux nombres ensemble

  • Testez si un certain nombre est un nombre premier ou non.

C'est un défi de , où il y a deux défis différents avec deux objectifs différents: Les flics vont essayer d'écrire du code qui rend le langage principalement inutilisable, et le voleurs vont essayer de trouver la solution cachée qui permet aux flics pour récupérer leur langue.

Les flics écriront deux extraits de code:

  1. Celui qui rend leur langage pratiquement inutilisable, par exemple en supprimant les fonctions intégrées pour effectuer des opérations d'entrée / sortie et numériques. Ce code n'est pas autorisé à planter ou à quitter. Il devrait être possible d'ajouter du code à la fin de cet extrait, et ce code sera évalué . Et

  2. Un extrait de code qui prend deux nombres en entrée, les additionne et génère leur somme. Cet extrait doit toujours fonctionner correctement même après avoir exécuté le premier extrait. Lorsque les deux extraits sont combinés ensemble, ils doivent former un programme complet qui ajoute deux nombres ou définir une fonction qui ajoute deux nombres. Cet extrait de code s'appuiera probablement sur un comportement obscur et sera difficile à trouver.

Les flics choisiront également n'importe quelle méthode standard d'entrée et de sortie . Cependant, ils doivent révéler exactement le format (entrée et sortie) qu'ils utilisent. Pour que vous puissiez cracker leur réponse, vous devez suivre le même format d'entrée / sortie, sinon votre crack ne compte pas.

Une réponse de flics révélera toujours

  • Le premier extrait (évidemment pas le second).

  • Langue (y compris la version mineure, car la plupart des soumissions s'appuieront probablement sur d'étranges cas marginaux)

  • Format IO, y compris s'il s'agit d'une fonction ou d'un programme complet. Les voleurs doivent utiliser le même format pour être un crack valide.

  • Tout cas de bord étrange requis pour que leur réponse fonctionne. Par exemple, ne fonctionne que sur Linux ou nécessite une connexion Internet .

En tant que voleur, vous devez regarder l'une des soumissions des flics et tenter de la casser. Vous pouvez le casser en écrivant tout extrait valide qui pourrait fonctionner comme l'extrait 2 (en ajoutant deux nombres ensemble après que la langue est rendue inutilisable). Il n'est pas nécessaire que ce soit le même extrait que le flic a écrit à l'origine. Une fois que vous avez une réponse craquée, postez votre code comme réponse sur ce fil et postez un lien vers votre réponse en tant que commentaire sur la réponse du flic. Ensuite, ce message sera modifié pour indiquer qu'il a été craqué.

Voici un exemple. Pour le premier extrait, vous pouvez voir le programme python 3 suivant comme une réponse des flics:

Python 3

print=None

Prend l'entrée de STDIN et la sortie vers STDOUT

Un deuxième extrait valide peut être

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

Ceci est valide car il prendra deux nombres en entrée et affichera leur somme même si vous joignez les deux extraits, par exemple

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

C'est une fissure valable à leur réponse.

Si la réponse d'un policier reste non fissurée pendant une semaine entière, il peut modifier son deuxième extrait de code et indiquer que sa réponse est désormais sûre. . Une fois qu'il est modifié pour être sûr, vous ne pouvez plus tenter de le casser. S'ils ne le modifient pas comme sûr, vous pouvez continuer à essayer de le casser jusqu'à ce qu'ils le fassent.

Le gagnant du fil du voleur est l'utilisateur qui a obtenu le plus de réponses, le bris d'égalité étant le moment où il a atteint N fissures. (donc si deux utilisateurs différents ont chacun 5 fissures par exemple, l'utilisateur qui a affiché sa 5ème fissure en premier est le gagnant) Après un laps de temps suffisant, j'accepterai la réponse du gagnant avec le plus de votes.

S'amuser!

Clarifications des règles

  • Le premier extrait doit s'exécuter correctement sans prendre aucune entrée . Il peut produire ce que vous voulez et cette sortie sera ignorée. Tant que l'extrait est terminé, le deuxième extrait s'exécute correctement.

  • Le deuxième extrait doit en fait être exécuté pour que votre réponse soit valide. Cela signifie une réponse comme

    import sys
    sys.exit()
    

    n'est pas valide car il ne rompt pas la langue. Il s'arrête simplement.

  • Après avoir été en sécurité, votre score est le nombre d'octets des deux extraits .

  • Cela remonte à Veuillez révéler tout cas de bord étrange requis pour que votre réponse fonctionne ... Votre soumission doit contenir suffisamment d'informations avant d' être révélée pour être reproductible après avoir été révélée. Cela signifie que si votre réponse devient sûre, puis vous modifiez dans: Voici ma réponse. Oh ouais, BTW cela ne fonctionne que si vous l'exécutez sur Solaris, blagues sur vous! votre réponse n'est pas valide et sera supprimée et ne sera pas considérée comme éligible pour gagner.

  • Le deuxième extrait est autorisé à se bloquer après la sortie de la somme. Tant que la sortie est toujours correcte (par exemple, si vous choisissez de sortir vers STDERR, puis que vous obtenez un tas d'informations sur les plantages, cela n'est pas valide)

Classement

Voici une liste de chaque utilisateur avec au moins une fissure, triée par score puis par nom (alphabétique). Si vous soumettez un crack, veuillez mettre à jour votre score en conséquence.

#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
DJMcMayhem
la source

Réponses:

3

Java 8 par Olivier Grégoire

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

Essayez-le en ligne!

Étant donné qu'Olivier a explicitement autorisé le passage de l'entrée via des propriétés définies à l'aide d'arguments VM, je spécifierai que l'entrée doit être donnée dans l'argument VM -Dline.separator=X,Y, où Xet Ysont les nombres à ajouter. C'est-à-dire, pour ajouter par exemple les numéros 17 et 25, le programme doit être appelé comme:

java -Dline.separator=17,25 Main

Je crois que cela devrait fonctionner sur n'importe quel système qui peut exécuter des programmes Java sur la ligne de commande. Même sur les systèmes qui n'ont pas de ligne de commande, tout autre mécanisme équivalent pour définir les propriétés du système pourrait être utilisé pour transmettre l'entrée à la machine virtuelle.


Ps. Voici ma tentative de craquage antérieure, qui a été jugée non valide en raison de l'utilisation de fonctionnalités spécifiques à 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);
  }
}

Essayez-le en ligne!

Cela s'est avéré beaucoup moins verbeux que le précédent . La partie difficile a été de trouver une sous-classe SecurityManagerqui ne vivait pas dans un espace de noms commençant par " java.". Je soupçonne que ce n'est toujours pas la solution prévue, mais cela fonctionne. *

*) Sur TIO, au moins; la sun.awt.AWTSecurityManagerclasse et la sun.java.commandpropriété ne semblent pas être officiellement documentées et peuvent ne pas être disponibles sur toutes les machines virtuelles Java.

Ilmari Karonen
la source
Bon travail! J'ai essayé cela, mais je n'ai pas pu trouver un SecurityManagerqui était dans le champ d'application ... Vous pouvez également lire System.inà ce stade, car il n'est pas encore fermé.
zbw
Désolé, ceci est une réponse dépendante de la plate - forme sur deux égards: les deux sun.awt.SecurityManageret "sun.awt.command"dépendent plate - forme et ne sont pas partie de Java .
Olivier Grégoire
Ouais, craqué! :) La solution envisagée était de passer par le System.getProperties().get("blah")(puisque je n'ai bloqué l'accès qu'à System.getProperty, non System.getProperties), mais c'est assez bien! Bien joué!
Olivier Grégoire
22

C (GCC / Linux) par Sisyphe

Cet extrait ferme la fonction fournie et en démarre une nouvelle (injection de code classique), qui se redéfinit de closesorte qu'au lieu de fermer le fd, exécute notre code souhaité.

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

  exit(0);
2012rcampion
la source
20

Python, la solution de Wheat Wizard ici

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

Je veux dire, vous pouvez simplement rétablir la limite de récursivité, et rien de mauvais ne se produit ...

Fonctionne sur TIO

Remarque

Ceci est ma toute première soumission CnR, donc si cela enfreint les règles, dites-le-moi et je supprimerai cela.

HyperNeutrino
la source
4
Je suis stupide d'avoir raté ça
Wheat Wizard
@WheatWizard :)
HyperNeutrino
@wheatwizard Ne révélez pas encore la solution que vous envisagez. Je looove de voir un meilleur flic avec votre solution originale qui résout ce problème.
DJMcMayhem
@Djmcmayhem Je vais probablement republier avec un del sys.
Wheat Wizard
@WheatWizard Rappelez os.sys- vous , si cela fait une différence: P
HyperNeutrino
15

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

J'ai toujours des nombres littéraux et des caractères (j'utilise 0, '0'et '-'), [a..]et [a..b]qui sont très utiles. Et j'ai unaire- , mais je pourrais m'en passer.

Je recrée ++pour implémenter r( reverse) et définir tet tsqui sont tailet tails. x a brenvoie le ne élément de b, où nest la longueur de amoins un.xpourrait généralement être défini comme snd.last.zip. La fonction dprend une liste et renvoie une liste avec les éléments de ces positions qui sont des multiples de dix. l!!srenvoie le ne élément de l, où sest la représentation sous forme de chaîne inversée de n. +renvoie comme entier la somme de deux nombres naturels donnés sous forme de chaînes inversées, de même -pour la différence.addrenvoie comme entier la somme de deux entiers éventuellement négatifs donnés sous forme de chaînes.

Je me demande si cela ressemble un peu à ce que Ben avait en tête.

Christian Sievers
la source
Oui, à peu près les mêmes idées. Correspondance de modèle avec les littéraux pour obtenir des tests d'égalité et de branchement, lister la syntaxe d'énumération pour obtenir une forme d'incrément J'ai été assez surpris de constater que la :portée était même avec NoImplicitPreludeet sans rien importer.
Ben
7

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

Essayez-le en ligne!

Dennis
la source
ugggg J'ai oublié d'interdire fscanf et beaucoup d'autres fonctions>.> bon travail
Conor O'Brien
7

Python 2 par Wheat Wizard (quatrième itération)

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

Essayez-le en ligne!

Aucun exploit, juste une fonction à ajouter en utilisant uniquement des caractères ' &)(,.:[]a`cdfijmonrt~', comme prévu (en fait seulement'(),.:[]`acdfijmnort' ).

Je n'ai pas essayé de faire court; Je viens d'écrire des sous-expressions pour des valeurs intermédiaires comme 0 et la chaîne vide et les chaînes substituées dans.

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

Essayez-le en ligne!

L'idée de base est que le format de chaîne '{0:5}'.format('1')remplit le nombre zéro à une longueur 5similaire '1 '. En concaténant deux de ces chaînes en utilisant ''.join, la somme de leur longueur est la somme des nombres d'entrée. Ensuite, nous clouons sur un0 à la fin et appelons.find() à la position finale, qui est la somme.

La chaîne '{0:5}'à formater est produite en extrayant les {:}caractères des représentations de chaîne des dictionnaires créés avec dict. La chaîne de repr de chaque sommation successive est placée là où serait le 5. Je voulais utiliser un dict comme{0:5} lui, mais sa repr comprend un espace qui l'a gâché.

Les entrées de 0 gâchent le processus car la chaîne sub a une longueur minimale de 1. Nous avons celles avec un and/orpour donner la chaîne vide dans ce cas.

Xnor
la source
1
C'est assez différent de ce que j'avais prévu, j'aimerais voir une explication.
Wheat Wizard
Vous pouvez jouer au golf tout int([]in[])simplement int()car les deux afficheront 0.
Value Ink
5

assemblage en mode réel x86 16 bits, par 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

capture d'écran du débogage du vidage de code, avec sortie dans le coin supérieur gauche

Explication:

La «casse» introduite par le code de Joshua est la définition du drapeau de déroutement (TF), qui met le processeur en mode à étape unique. Cela signifie qu'une seule instruction sera exécutée à la fois, avant que le CPU ne s'arrête (intercepte) avec une interruption de type 1. C'est ce qui permet aux débogueurs d'implémenter le code pas à pas - assez pratique là-bas, mais un vrai PITA si vous voulez exécuter le code en dehors du contexte d'un débogueur!

C'est la section de code suivante qui active l'indicateur d'interruption:

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'implémentation de l'indicateur d'interruption signifie que nous avons la possibilité d'exécuter exactement une instruction avant les interruptions du processeur, c'est-à-dire celle qui vient immédiatement après la POPF ici. Donc, nous devons faire en sorte que cela compte.

L'astuce est l' INT 3instruction, qui appelle l'interruption numéro 3. Il y a deux raisons pour lesquelles cela fonctionne pour "décomposer" le code:

  1. L'indicateur d'interruption est effacé dans les gestionnaires d'interruption. Ce n'est qu'une partie de la conception d'Intel, mais cela a probablement été fait pour des raisons de santé mentale de base. Rappelez-vous que l'implémentation de l'indicateur d'interruption est qu'une interruption de type 1 est invoquée après l'exécution de chaque instruction, donc si TF n'était pas effacé, déclencherait luiINT 1 - même une interruption — ce serait des interruptions jusqu'en bas. De plus, le fait d'interrompre TF en clair facilite simplement le débogage du code, un peu comme un IDE qui passe automatiquement les appels aux fonctions de bibliothèque.

  2. La façon dont interrompt le travail est essentiellement la même que dans la mesure du possible CALL. Ils invoquent le gestionnaire d'interruption dont l'adresse est stockée à la position correspondante dans la table vectorielle d'interruption globale. Étant donné que cette table commence à l'adresse 0x0000:0000et est stockée dans un octet 4segment:offset format à , le calcul de l'adresse est aussi simple que la multiplication de 4 par le vecteur / numéro d'interruption. Dans ce cas, nous invoquons l'interruption 3, de sorte que ce serait 4 × 3 = 12.

    … Et vous remarquerez que Joshua a réfléchi à cela pour nous. Avant d'activer l'indicateur d'interruption, il a le code suivant:

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

    qui définit 0x0000:000C(le gestionnaire d'interruption pour INT 3) sur BP:SI. Cela signifie que chaque fois qu'il INT 3est invoqué, il pousse le registre FLAGS sur la pile, suivi de l'adresse de retour, puis se ramifie vers BP:SI, ce qui nous permet de recommencer à exécuter du code, dans un contexte où l'indicateur d'interruption est désactivé.

Tout est en descente après INT 3. Tout ce que nous devons faire est d'ajouter deux nombres ensemble et d'imprimer le résultat. Sauf que ce n'est pas aussi simple en langage assembleur que dans d'autres langues, c'est donc là que la majeure partie du code est dépensée.

Joshua autorise le voleur à spécifier les mécanismes d'E / S qu'il souhaite , je prends donc l'approche simpliste en supposant que les valeurs sont passées dans les DXetCX registres . C'est raisonnable, car ceux-ci ne sont encombrés nulle part par son code "prologue".

La sortie se fait ensuite en stockant des octets ASCII directement dans la mémoire vidéo. Le tampon vidéo commence 0xB800:0000sur un CGA, EGA et / ou VGA en mode texte, nous commençons donc à y imprimer. Le format est: caractère dans l'octet bas et attribut couleur dans l'octet haut. Cela signifie que chaque caractère est sur un décalage de 2 octets. Nous parcourons simplement chacun des chiffres du nombre (base-10), les convertissant en ASCII et les imprimant un par un à l'écran. Oui, c'est beaucoup de code. Il n'y a pas de fonctions de bibliothèque pour nous aider en langage d'assemblage. Cela peut presque certainement être optimisé davantage, mais je suis fatigué de travailler dessus ...

Une fois la sortie affichée, le code est autorisé à planter ou à faire quoi que ce soit, donc nous effaçons simplement les interruptions et arrêtons le CPU.

Cody Grey
la source
Je suis perplexe; Je ne peux pas comprendre comment cela passe au-delà de l'instruction hlt chez BP: SP + 1.
Joshua
@Joshua Hmm, c'est un bon point. Je n'y ai même pas pensé. En parcourant le code dans Debug, j'exécute et je INT 3reviens immédiatement à l'instruction qui le suit, donc je suis juste allé avec. Cela a peut-être quelque chose à voir avec mon environnement de test? CLIne désactiverait que les interruptions matérielles, mais même si elle dépassait la HLT, vous penseriez qu'elle tomberait et exécuterait le code limmédiatement après.
Cody Gray
Oh, tu étais simple. Ouais, ça le ferait. Je vais vérifier, mais je pense que j'ai téléchargé du code piraté.
Joshua
J'ai aussi testé sans pas à pas. Aucune différence. C'est sur FreeDOS le plus récent de VM Virtualbox. J'ai du vrai matériel disponible, mais je n'avais pas envie de le mettre sous tension. @Joshua
Cody Gray
Eh bien, vous l'avez clairement craqué alors. Vous avez peut-être trouvé un moyen d'augmenter ce NMI.
Joshua
4

Python 3 , le deuxième défi de Ppperry

Wow, c'était amusant! J'ai aimé résoudre ce problème.

Edit: OK, je l'ai corrigé. Il semble que les classes étaient à un index différent dans la liste des sous-classes sur TIO que sur mon ordinateur, donc je l'ai fait fonctionner pour les deux, et j'ai ajouté 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()

Essayez-le en ligne!

zbw
la source
J'ai une erreur. sys.excepthook is missing?
Rɪᴋᴇʀ
Hmm ... ça marche pour moi. Quelle est la vraie erreur que vous obtenez? (Cela se produit parce que le code de ppperry a détruit à peu près tout, y compris savoir montrer les exceptions, c'est donc le sys.excepthook, mais il y aura une vraie cause quelque part là-dedans.)
zbw
Peu importe, la vraie erreur est IndexError('list index out of range',). Cela correspond à la définition de _io_RawIOBase.
Rɪᴋᴇʀ
Le problème est que l'ordre des sous-classes n'est pas fixe. _io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]devrait fonctionner partout.
Dennis
@ Dennis Yep, je l'ai réalisé et je l'ai juste corrigé. Cela fonctionne sur TIO maintenant!
zbw
4

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

Impossible d'exécuter du code au moment de l'exécution? Exécutez-le au moment de la compilation!

C'était très amusant, je ne connaissais pas le modèle haskell avant ce défi.

BlackCap
la source
3

Gelée par hyper neutrino


+

Super simple. La nouvelle ligne empêche le premier lien d'être appelé.

Essayez-le en ligne!

DJMcMayhem
la source
Vous pouvez également adhérer à la règle de non-nouvelle ligne comme celle-ci
Jonathan Allan
Ouais, je pensais que ce serait trop facile.
HyperNeutrino
3

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

Essayez-le en ligne!

Sisyphe
la source
Cela s'avère plus difficile que je ne le pensais.
Wheat Wizard
3

Java par LordFarquaad

Bloquer l'accès aux objets au niveau source était vraiment intelligent (et ennuyeux lors des tests), bravo!

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 {}
}
Olivier Grégoire
la source
Agréable! Et si ClassLoaderj'avais été observé?
Jakob
1
@JakobCornell "".getClass().getClassLoader(). L'observation n'est généralement qu'un problème auquel vous devez penser une fois, puis c'est ok. Vous pourriez même observer Object, je serais toujours en mesure de résoudre ce problème. D'accord, vous pourriez me forcer à utiliser la solution de 1 Ko, mais c'est possible.
Olivier Grégoire
3

Inform 7, par Ilmari Karonen

Abus flagrant de noms ambigus ... Mon code commence par factory is a room. La ligne précédente est le code du flic. Tapez add 1 and 1pour obtenir 2, par exemple.

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

Définit stdoutet stderrrevient à leurs valeurs initiales.

Je crois que je suis capable d'utiliser le nom complet au lieu d'une importation, si je me trompe, corrigez-moi (c'est mon premier post ici.) Cela pourrait probablement être fait en utilisant la réflexion également.

Edit: voici une solution réfléchissante utilisant uniquement 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) {
        }
    }
}
Moira
la source
Oui, stdin, stdoutet stderrsont stockés ailleurs! Vous n'avez même pas besoin d'utiliser setOutet setErrcomme vous pouvez simplement utiliser PrintStreamdirectement.
Olivier Grégoire
Ajout d'une solution réfléchissante et je pense que c'était ce qui était initialement prévu
Moira
2

JavaScript par Daniel Franklin

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

Cela peut être considéré comme une solution légèrement tricheuse, mais cela fonctionne pour moi sur Chromium 59 / Linux, même si je reçois également un avertissement disant:

Les versions à venir bloqueront les navigations du cadre supérieur initiées par le contenu vers les données: URL. Pour plus d'informations, voir https://goo.gl/BaZAea .

Ps. Voici une autre fissure, cette fois sans avertissements:

Node.prototype.removeChild=function(){}
document.body.innerHTML='<iframe src="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"/>'
Ilmari Karonen
la source
Je pense que prompt()- -prompt()sauve deux octets
Marie
2

Java 8 par Olivier Grégoire

Une fissure extrêmement verbeuse pour un défi énormément verbeux. :) La douleur de travailler indirectement avec des classes que vous ne pouvez pas nommer est palpable.

    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;

Essayez-le en ligne!

Ps. Voici ma tentative précédente, écrite avant qu'Olivier ne précise que l'entrée devait être prise via des arguments de ligne de commande. Contrairement à la fissure ci-dessus, celle-ci n'est pas spécifique à 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;

Essayez-le en ligne!

Ilmari Karonen
la source
Si vous êtes prêt, voici mon nouveau défi .
Olivier Grégoire
Juste pour le plaisir de l'écrire ici: comme je n'ai pas le droit de dire "Gotcha! Cela ne fonctionne que sur un seul système", cette réponse ne relève pas entièrement le défi car elle ne fonctionne que sur Linux.
Olivier Grégoire
@ OlivierGrégoire: FWIW, j'ai trouvé une solution alternative utilisant ce String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");qui n'est pas spécifique à Linux, mais utilise ce qui semble être une propriété non documentée définie par certaines machines virtuelles Java .
Ilmari Karonen
Ce n'est toujours pas portable. Cela ne fonctionnera pas sur IBM Java, par exemple. Cependant, c'est une bonne idée! :)
Olivier Grégoire
2

C # (.NET Core) par raznagul

Je suppose que ce n'était pas la solution envisagée.

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());
}
}
Josué
la source
Belle astuce avec /dev/std*là-bas. Au départ, je visais une approche similaire, mais je n'ai pas trouvé de moyen facile d'ouvrir des flux pour stdin / out sans accès à System.Console, j'ai donc opté pour la réflexion à la place. Bien sûr, votre solution ne fonctionne probablement que sur Linux et d'autres systèmes Unixish avec les /deventrées appropriées , mais raznagul n'a pas explicitement dit qu'elle devait fonctionner sur Windows. Et cela fonctionne sur TIO.
Ilmari Karonen
@IlmariKaronen: En effet; et mon plan si c'était Windows aurait échoué sur TIO.
Joshua
1

Java, par racer290

Il s'agissait plutôt d'un aspect basique que les staticinitialiseurs sont appelés avant la mainméthode. C'était une belle tentative: j'ai été consterné par le throw new Error()premier, mais j'ai finalement trouvé le chemin;)

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
}
Olivier Grégoire
la source
System.out.println("Hello World!");N'ajoute pas deux entiers? .. " 2. Un extrait de code qui prend deux nombres en entrée, les ajoute ensemble et génère leur somme. Cet extrait doit toujours fonctionner correctement même après avoir exécuté le premier extrait. Lorsque les deux extraits sont combinés ensemble, ils doivent former un programme complet qui ajoute deux nombres, ou définir une fonction qui ajoute deux nombres. Cet extrait de
code
@KevinCruijssen Que puis-je dire? Si les flics ne font pas leur travail, pourquoi devrais-je faire le leur? : P
Olivier Grégoire
1
@KevinCruijssen Là, j'ai mis un ajout là-dedans.
Olivier Grégoire
@ OlivierGrégoire, le but est d'empêcher l'ajout de numéros, que ce soit en supprimant la capacité d'entrée, d'ajout ou de sortie.
Stephen
@StepHen Oui, je l'ai compris un peu plus après. Vérifiez mes 3 autres fissures pour voir que j'ai finalement compris cela;)
Olivier Grégoire
1

Java par Kevin Cruijssen

Bien construit. Beaucoup de code pour que quiconque réfléchisse correctement à la façon de résoudre ce défi. Je suppose que le "mettre votre code après" était un très gros indice.

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

Essayez ici.

Olivier Grégoire
la source
C'était rapide .. C'était en effet ma solution exacte prévue! Bien joué. :) EDIT: pris la liberté d'ajouter le lien TIO si cela ne vous dérange pas.
Kevin Cruijssen
Eh bien, je travaillais sur cette idée avec le défi du coureur 290 lorsque vous avez publié le vôtre. Et non, ça ne me dérange pas.
Olivier Grégoire
1

JavaScript par Grant Davis

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

Fonctionne dans la console JS sur la about:blankpage (comme spécifié dans le post cop) sur Chromium 59 / Linux.

Ilmari Karonen
la source
Ça n'a pas pris longtemps. Bon travail.
Grant Davis
1

cQuents , Step Hen , 3 octets

+BC

Essayez-le en ligne!

Il a fallu beaucoup de discussions à Step Hen pour comprendre comment fonctionne son langage étrange, mais en bref:

Son code était #|1,1:A. #|1,1est l'entrée par défaut, ce qui signifie que toute entrée donnée au programme est ajoutée par 2 1. (IE si vous passez un 47 et un 53, votre entrée est[47, 53, 1, 1] .

:définit simplement le mode, qui affichera le ne élément de la séquence sin est défini, et sinon émettra la séquence entière.

finalement AObtient la première entrée.

Parce que nous avons 4 entrées [47, 53, 1, 1], l'ajout BCà la fin récupérerait également les 2e et 3e entrées, et la 4e entrée devient implicitementn .

Parce que notre séquence est ABC, elle est analysée algébriquement, ce qui signifie qu'elle devient A*B*C. Nous ne voulons pas cela, mais si nous insérons un +entre A et B, il devient A+B*C, où Aet Bsont nos entrées, et Cest 1.

Skidsdev
la source
how the hell his weird language workspeut-être qu'une fois que je l'aurai terminé, cela pourrait avoir plus de sens
Stephen
@StepHen ne vous méprenez pas, c'est une langue soignée, mais bizarre comme l'enfer
Skidsdev
1

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

Essayez-le en ligne!

Cela aurait probablement pris moins de temps si je connaissais réellement un C #. Cependant, avec un peu de navigation dans la documentation et un peu d'aide de Jon Skeet , j'ai réussi à bricoler quelque chose qui fonctionne.

Ilmari Karonen
la source
1

Défi Vim par @DJMcMayhem

Cela fait un moment que je n'ai pas pu quitter vim , voici ma solution (notez que c'est beaucoup plus que des 23octets - donc ce n'est probablement pas la solution prévue):

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

Essayez-le en ligne!

L'idée est simplement de diriger les deux entiers vers awkvia bash, car =et +étant désactivés, j'ai dû utiliser une petite solution de contournement. La awkligne s'étend à:

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

Edit : L'intention initiale était que l'entrée soit déjà dans le tampon, mais ce ne serait pas plus difficile - la principale difficulté était de faire fonctionner l'addition.

Voici le correctif suggéré par @DJMcMayhem: Essayez-le en ligne!

ბიმო
la source
Je pense que vous ne pouvez pas faire [insert your number here]en mode insertion. Au lieu de cela, il est juste déjà dans le tampon. Mais vous pouvez contourner cela avec Oecho "<esc>Go"|awk..., donc je pense que cela compte. Bien fait! Ce n'est pas la fissure que j'avais en tête (j'espérais une réponse pure vim) donc je posterai probablement une nouvelle réponse qui corrige les commandes externes et !.
DJMcMayhem
1
Voici un exemple qui prend la saisie de la bonne façon: Essayez-le en ligne!
DJMcMayhem
Ouais, je n'étais pas sûr de l'entrée. Mais la solution de contournement serait en effet facile. Je vais éditer de manière officielle .
ბიმო
BTW, mon approche corrigée est ici: codegolf.stackexchange.com/a/133441/31716
DJMcMayhem
1

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

Essayez-le en ligne!

Aucune astuce spécifique à Linux n'est nécessaire, juste un simple masquage des noms de classe Stringet non qualifiés System. Ce n'est probablement pas la solution envisagée, mais cela fonctionne.

Ilmari Karonen
la source
1

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

Essayez-le en ligne!

Ce n'est de loin pas la meilleure réponse que j'aurais pu donner, mais cela permet à nouveau d'ajouter des chiffres. Si j'avais réellement traversé et fait une bonne manipulation de la pile, je pourrais probablement jouer au golf un peu, mais pour l'instant je suis satisfait de la réponse.

Dans le poste d'origine d'ATaco, il vient en fait de réaffecter tous les principaux opérateurs arithmétiques pour détruire leurs entrées. Pour résoudre ce problème, j'ai redéfini ce que l'ajout était en termes d'opérations binaires, ce qui était pénible car RProgN2 n'a pas d'opérateur de négation binaire ou xor.

Remarque: Si vous souhaitez tester l'entrée, les nombres avec plus d'un chiffre doivent être dans le formulaire "XX..." n pour être convertis en un nombre réel car RProgN2 prend chaque caractère tel quel sauf s'il s'agit d'un concept ou d'une chaîne. Edit: @ATaco a noté que l'ajout d'un «$» avant un numéro à plusieurs chiffres fera la même chose.

EDIT: Voici la logique de ma solution. Comme vous pouvez le voir, ce n'est certainement pas le code le plus raffiné, mais cela fonctionne.

{"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
Arnold Palmer
la source
Fournir un $ avant une piqûre de chiffres le regroupe également en un seul numéro, par exemple, 56$46$12il poussera les chiffres 5, 6, 46 et 12. Je
posterai
Je ne le savais pas. J'ai en quelque sorte simplement regardé à travers vos callables pour comprendre quelles étaient les choses.
Arnold Palmer
Je pourrais en fait écrire de la documentation à cause de ce défi.
ATaco
Ce serait merveilleux. J'ai réussi à trouver une liste de commandes pour RProgN, mais je l'ai perdue ... Et cela n'a beaucoup aidé que parce que les fonctions sont toutes différentes. J'ai dû apprendre vos fonctions via votre ancienne page de tutoriel RProgN et vos classes appelables. C'était amusant de jouer avec, même s'il n'était pas immédiatement évident de savoir comment tout fonctionnait.
Arnold Palmer
1

JavaScript (Node.js) par jrich , 298 octets

J'ai l'impression que ce n'est pas la solution prévue, mais si c'est le cas, bien fait, j'ai passé un certain temps à essayer de comprendre comment obtenir le nom de la fonction déclarée! :)

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

Essayez-le en ligne!

Dom Hastings
la source
1
Not the intended solution but very clever! Nice crack +1
jrich
@jrich Yeah, I figured, feel free to patch that out I'll be sure to have another go at the intended solution!
Dom Hastings
whoops... too late! I was satisfied with your solution's creativity though!
jrich