Sortie de la chaîne de code

18

Vous devez écrire un programme ou une fonction qui, lorsqu'il est administré une nonvide chaîne S de N caractères ASCII imprimables , émet un programme qui se termine avec le code de sortie C , où C est le point de code ASCII à la position 0 dans S . Ce programme que vous écrivez en outre un programme de sortie P , de telle sorte que, lorsqu'il est exécuté, il sort avec le code de sortie C ' , où C' est le point de code ASCII en position 1 dans S . Le programme P sortira un autre programme P ' . Ce processus se répète jusqu'à ce qu'il ne reste plus de caractères dans S. Après cela, vous ne devez rien produire, suivi d'un retour à la ligne facultatif; et doit quitter avec le code de sortie 0.

Les caractères entre 0x20et 0x7einclus.

Quelques règles supplémentaires:

  • Les programmes auto-modifiables ne sont pas autorisés: vous devez sortir la source vers STDOUT (ou, retourner la valeur initialement)
  • Vous ne pouvez pas lire votre propre code source.

Le programme le plus court en octets gagnera.

Pour certains tests rudimentaires, ce script rubis peut être utilisé. (Le premier argument est la façon dont vous invoquez le script, le second le programme et le troisième la chaîne d'entrée.)

Exemple hypothétique

Disons que le programme l'est FOO. Lorsqu'on lui donne la chaîne "ABC", il sort BARA. Ce programme se termine avec du code 65et des sorties BARB. Cela se termine à son tour avec du code 66et des sorties BARC. Ce programme se termine avec du code 67et des sorties BAR!. Cela ne produit rien et se termine avec du code 0.

Conor O'Brien
la source
Est-ce que cela serait considéré comme des codes de sortie à Forth? Modifiez le paramètre pour voir d'autres erreurs du système d'exploitation. 0est le succès. tio.run/nexus/…
mbomb007
@ mbomb007 Je ne sais pas grand chose sur Forth. Est-ce ainsi que l'on utiliserait classiquement un "code d'erreur" dans Forth?
Conor O'Brien
Cela dépend si votre objectif est d'avoir des codes d'erreur au niveau du système d'exploitation. Si seul le nombre compte, vous pouvez simplement faire quelque chose comme 33 throwlancer un nombre arbitraire. Vous utilisez des négatifs pour le niveau OS et le décalage est -512. Idk beaucoup non plus, mais je regarde ici: complang.tuwien.ac.at/forth/gforth/Docs-html/…
mbomb007

Réponses:

6

Python 2, 126 101 94 octets

En faisant cela, j'ai trouvé que le code Python ne peut pas contenir d'octets NUL littéraux.

lambda i,s='''i=%r;s=%r
try:print s%%(i[1:],s,i[0])
except:0
exit(ord(%r))''':s%(i[1:],s,i[0])

Essayez-le en ligne (affiche le code de sortie dans les informations de débogage)


Notez que chacun des programmes non vides ci-dessous a un saut de ligne de fin.

Pour l'entrée Hello, les sorties ci-dessus:

i='ello';s='i=%r;s=%r\ntry:print s%%(i[1:],s,i[0])\nexcept:print s%%(0,s,"\\0")*(i>0)\nexit(ord(%r))'
try:print s%(i[1:],s,i[0])
except:0
exit(ord('H'))

qui imprime

...

qui imprime

i='o';s='i=%r;s=%r\ntry:print s%%(i[1:],s,i[0])\nexcept:print s%%(0,s,"\\0")*(i>0)\nexit(ord(%r))'
try:print s%(i[1:],s,i[0])
except:0
exit(ord('l'))

qui imprime

i='';s='i=%r;s=%r\ntry:print s%%(i[1:],s,i[0])\nexcept:print s%%(0,s,"\\0")*(i>0)\nexit(ord(%r))'
try:print s%(i[1:],s,i[0])
except:0
exit(ord('o'))

qui n'imprime rien (le programme vide)

qui n'imprime rien et se termine avec le code 0.

mbomb007
la source
4

Python 3, 77 octets

p='exit(0)'
for c in input()[::-1]:p='print(%r);exit(ord(%r))'%(p,c)
print(p)

Ce code prend l'entrée de STDIN et sort le premier programme vers STDOUT.

Si l'entrée est ABCDE, les résultats sont

 0 print('print(\'print(\\\'print("print(\\\\\\\'exit(0)\\\\\\\');exit(ord(\\\\\\\'E\\\\\\\'))");exit(ord(\\\\\\\'D\\\\\\\'))\\\');exit(ord(\\\'C\\\'))\');exit(ord(\'B\'))');exit(ord('A'))
65 print('print(\'print("print(\\\'exit(0)\\\');exit(ord(\\\'E\\\'))");exit(ord(\\\'D\\\'))\');exit(ord(\'C\'))');exit(ord('B'))
66 print('print("print(\'exit(0)\');exit(ord(\'E\'))");exit(ord(\'D\'))');exit(ord('C'))
67 print("print('exit(0)');exit(ord('E'))");exit(ord('D'))
68 print('exit(0)');exit(ord('E'))
69 exit(0)
 0 

où chaque ligne contient le code de sortie et la sortie du programme précédemment exécuté (la première ligne est le premier programme).

vaultah
la source
Votre réponse est comme la mienne ... juste que vous l'avez fait dans la direction opposée ... Je me plains pour cela.
Nonne qui fuit
67 octets
mbomb007
@LeakyNun oui, mais je n'ai pas utilisé votre réponse comme point de départ, si c'est ce que vous voulez dire
vaultah
Je dis simplement que j'aurais dû y penser.
Nonne qui fuit
@vaultah Vous allez jouer au golf à 67 octets, ou devrais-je le poster comme une réponse séparée?
mbomb007
3

Python 3 , 115 108 100 octets

i=input()
r="%s"
k=""
for c in i:r%="print(%s\"%%s%s\");exit(%i)"%(k,k,ord(c));k+=k+"\\"
print(r%"")

Essayez-le en ligne!


Pour l'entrée Hello, le programme imprime:

print("print(\"print(\\\"print(\\\\\\\"print(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\");exit(111)\\\\\\\");exit(108)\\\");exit(108)\");exit(101)");exit(72)

Le programme ci-dessus imprime:

print("print(\"print(\\\"print(\\\\\\\"\\\\\\\");exit(111)\\\");exit(108)\");exit(108)");exit(101)

et sort avec le code 72.

Essayez-le en ligne!


Le programme ci-dessus imprime

print("print(\"print(\\\"\\\");exit(111)\");exit(108)");exit(108)

et sort avec le code 101.

Essayez-le en ligne!


Le programme ci-dessus imprime:

print("print(\"\");exit(111)");exit(108)

et sort avec le code 108.

Essayez-le en ligne!


Le programme ci-dessus imprime:

print("");exit(111)

et sort avec le code 108.

Essayez-le en ligne!


Le programme ci-dessus n'imprime rien et se termine avec le code 111 .

Essayez-le en ligne!


Le programme vide n'imprime rien et se termine avec le code 0 .

Essayez-le en ligne!

Leaky Nun
la source
2
Un lien TIO pour le programme vide? C'est votre dévouement!
Neil
2

C, 156 octets

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";main(i,t)char**t;{printf(s,34,s,34,0,34,t[1],34);}

Essayez-le en ligne!(Ouvrez l'onglet de débogage pour voir le code de sortie.)

Prend l'entrée comme argument de ligne de commande.

Pour l'entrée "ABC", cela sort le programme

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=0;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

qui renvoie 65 et sorties

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=1;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

qui renvoie 66 et sorties

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=2;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

qui renvoie 67 et sorties

char*s="char*s=%c%s%c;n=%d;char*t=%c%s%c;main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}";n=3;char*t="ABC";main(){n<strlen(t)&&printf(s,34,s,34,n+1,34,t,34);return t[n];}

qui ne produit rien et renvoie 0.

Steadybox
la source
@ mbomb007 Merci, c'est corrigé maintenant (et il est devenu plus court dans le processus).
Steadybox
2
Je dois l'aimer quand ça arrive.
mbomb007
2

Python 2, 67 octets

Basé sur cette réponse , mais modifié pour utiliser Python 2, avec un programme trivial 0pour ne rien imprimer et quitter.

p=0
for c in input()[::-1]:p='print %r;exit(ord(%r))'%(p,c)
print p

Essayez-le en ligne

mbomb007
la source
1

RPL, 73 octets

Avec la page de codes hp8.

Allumez votre HP48 ou similaire, ou lancez droid48 . N'oubliez pas de -52 SFpour une meilleure visualisation de la pile. Je suppose que vous avez déjà poussé la chaîne, par exemple "ABC", sur la pile. Saisissez ensuite la fonction suivante:

→ x«{LAST}x{DUP NUM 3ROLLD 2OVER SIZE DUP{SUB 2SWAP PUT}{4DROPN}IFTE}+ +»

(Pour plus de commodité, je suggère d'appuyer deux fois sur la touche α avant de taper quoi que ce soit, ce qui verrouille le mode de saisie alpha. Plus tard, utilisez simplement la touche DEL pour annuler les délimiteurs de fermeture insérés automatiquement. Utilisez simplement la touche ENTER pour valider. N'oubliez pas l'espace après le poignarder l'opérateur.)

Cette fonction pousse immédiatement sur la pile un programme auto-modifiable, sous forme de liste. (Mais la fonction ci-dessus ne se modifie pas). Comme le L dans RPL signifie à l'origine LISP, appuyer sur la touche EVAL évaluera en effet ce programme. Il retourne le code de sortie au niveau de pile deux, et se laisse modifié (oui, ici c'est discutable), pour un dernier EVAL. Appuyez donc plusieurs fois sur EVAL jusqu'à ce que le programme s'arrête enfin pour se déposer au niveau de pile un. Le code de sortie final 0 apparaît donc au niveau un, avec les codes de sortie précédents ci-dessus. Si vous avez oublié d'-52 SF , vous pouvez naviguer dans la pile après chaque EVAL en appuyant sur la touche ▴ (quitter ce mode de navigation avec la touche ON). La fonction ci-dessus accepte les chaînes avec des caractères 0x0 à l'intérieur, pour créer de telles chaînes 0 CHRet+êtes vous amis. L'auto-modification consiste à supprimer le caractère utilisé de la chaîne incorporée (la SUB 2 SWAP PUTbranche). Par conséquent, le programme abandonné est plus court après chaque EVAL. La 4 DROPNbranche s'assure que l' rien de sortie seront interdits. Pour toujours.l'instruction du PO est respectée, abandonnant entre autres le programme lui-même. Bien sûr, tout cela suppose que votre note est un -55 SFadepte. Utilisateurs de-55 SF

Je suppose qu'une solution RPL / 2 existe et pourrait comporter un véritable code de sortie Unix, mais afaik RPL / 2 a une introspection limitée et ne peut pas évaluer les listes.

Nacre
la source
Je ne pense pas que l'utilisation de code auto-modifiant compte comme une quine valide selon notre consensus, car il a accès à son propre code source. Je vais demander au PO dans un commentaire. Voir les méta-messages associés: Qu'est - ce qui constitue un quine approprié? ; L'utilisation de SMBF est-elle considérée comme une quine de triche? <- celui-ci est celui qui s'applique
mbomb007
1
Seul le programme généré est auto-modifiable, pas la fonction qui répond au défi. Mais je suis d'accord, c'est discutable! Ajout de quelques modifications pour mettre cela en évidence.
Nacre
1

sed , 467 461 octets

Les codes de caractères sont difficiles:

s:^:Y:
:b
s:ZY[ (2<FPZdnx]:0_Y:
s:ZY[ )3=GQ[eoy]:1_Y:
s:ZY[ *4>HR\fpz]:2_Y:
s:ZY[]!+5?ISgq{]:3_Y:
s:ZY[",6@JT^hr|]:4_Y:
s:ZY[-#7AKU_is}]:5_Y:
s:ZY[$.8BLV`jt~]:6_Y:
s:ZY[%/9CMWaku]:7_Y:
s:ZY[&0:DNXblv]:8_Y:
s:ZY['1;EOYcmw]:9_Y:
s:Y[ -']:3Z&:
s:Y[(-1]:4Z&:
s:Y[2-9:;]:5Z&:
s:Y[<=>?@A-E]:6Z&:
s:Y[F-O]:7Z&:
s:Y[P-Y]:8Z&:
s:Y[]Z\-`abc]:9Z&:
s:Y[d-m]:10Z&:
s:Y[n-w]:11Z&:
s:Y[xyz{-~]:12Z&:
tb
s/([^_]+)_Y$/ q\1/
:
s/[/\]/\\&/g
s/([^_]+)_ (.*)/ s\/^\/\2\/;q\1/
/^\S/b

Essayez-le en ligne!

Sinon, la logique est plutôt simple: (1) échapper les caractères spéciaux (il y en a deux), (2) encapsuler s/^/…/;q\1 couche , (3) répéter.

Voici la sortie pour hello:

 s/^/s\/^\/s\\\/^\\\/s\\\\\\\/^\\\\\\\/q111\\\\\\\/;q108\\\/;q108\/;q101/;q104

Et un petit script que j'ai utilisé:

#!/bin/bash
set -uo pipefail
IFS=$'\n'

P=$(echo $1 | sed -rf q.sed)
echo $P

echo $1 | od -An -tuC

for char in $(echo $1 | sed 's:.:&\n:g'); do
    P=$(echo | sed $P)
    printf ' %3d' $?
done
eush77
la source
Vous n'avez pas à vous soucier des nouvelles lignes, car la publication dit que vous ne recevrez que des caractères entre 0x20 et 0x7E. Bonne solution! :)
Conor O'Brien
@ ConorO'Brien Oh, c'est vrai. Merci!
eush77
1

PowerShell, 172 156 octets.

param($i)
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f$i.replace("'","''"),"$s`n"

L' h3l}'{l0entrée donnera la sortie suivante

Essayez-le en ligne!

if($i='h3l}''{l0'){
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}
exit

Qui à son tour sortira

Essayez-le en ligne!

if($i='3l}''{l0'){
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}
exit

La dernière exécution ne produira rien et le code de sortie sera 0.

Essayez-le en ligne!

if($i=''){
$s=@'
if($i='{0}'){{
$s=@'
{1}'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}}
exit
'@
$s-f($i-replace'^.'-replace"'","''"),"$s`n"
$host.setshouldexit($i[0])
}
exit
Andrei Odegov
la source