Créer une interface qui correspond aux types XKCD

34

colors.rgb ("blue") donne "# 0000FF". colors.rgb ("bleu jaunâtre") donne NaN. colors.sort () donne "arc-en-ciel"

En utilisant les règles énoncées dans l'image et son titre (cités ici), créez un programme qui accepte toutes les entrées données et affiche la sortie appropriée.

  • La saisie peut être effectuée avec stdin ou son équivalent le plus proche. Il devrait y avoir une ligne comme celle [n]>sur laquelle taper, et naugmente de 1 chaque commande. Il devrait commencer à 1.

  • Le résultat devrait être affiché en utilisant stdout ou son équivalent le plus proche. Il devrait y avoir un =>sur chaque ligne de sortie.

Les 13 conditions, plus les 3 dans le titre (cité) doivent fonctionner.

C'est le code de golf, donc la réponse la plus courte gagne.

Tim
la source
16
À quel point l'interface devrait-elle être générale? Par exemple, la fonction d'étage doit-elle fonctionner pour n'importe quel float fourni ou pouvons-nous supposer qu'il ne sera jamais adopté 10.5?
ankh-morpork
1
Le> pour la sortie est-il aligné sur le> pour l'entrée, à mesure que n grandit et que l'entrée> se déplace plus loin vers la droite?
Sparr
1
Cette bande dessinée peut potentiellement être interprétée de plusieurs manières. Pourriez-vous fournir une liste des types et opérations spécifiques que nous devons implémenter?
BrainSteel
5
Pourquoi devrait naugmenter de 1? Ce n'est pas ce que le comique fait ... ;-)
Rétablir Monica
3
@WolframH Il est - mais il a fait 2 = 4 en commande 11 donc il affiche 14 pas 12.
Tim

Réponses:

21

Python 3, 700 698 697 689 683 639 611

Onglets comme indentation.

from ast import*
E=literal_eval
O='=>%s\n'
P=print
I=int
def Q(a):P(O%a)
def W(a):Q('"%s"'%str(a))
def gb(a):W(_ if'y'in a else'#0000FF')
def t():W('rainbow')
def FLOOR(n):P(O%'|'*3+(O%'|{:_^10}').format(n))
def RANGE(*a):Q([('"','!',' ','!','"'),(1,4,3,4,5)][len(a)])
c=0
while 1:
    try:
        c+=1;A,*B=input('[%d]>'%c).split('+')
        if not A:W(c+I(B[0]))
        elif A=='""':Q("'\"+\"'")
        elif B:
            A=E(A);B=E(B[0])
            if A==B:Q('DONE')
            elif type(A)==list:Q(A[-1]==B-1)
            elif type(B)==list:W([I(A)])
            else:W(A+I(B))
        else:eval(A.lstrip('colrs.'))
    except:Q('Na'+['N','P','N.%s13'%('0'*13)][('-'in A)+len(B)])

Puisque cela utilise un nu, sauf que vous ne pouvez pas le faire en Ctrl-C. Ctrl-Z et kill %% fonctionnent bien

Certaines conditions sont généralisées et d’autres ne fonctionneront qu’avec une saisie exacte.

  1. A+"B" travaillera avec tout A et B pas seulement quand A == B
  2. "A"+[] fonctionnera pour tout A pouvant être converti en int (comprend les chaînes hexadécimales et binaires, par exemple 0xff et 0b01010)
  3. (A/0)fonctionnera pour tout A, Eval Causes DivideByZeroErrorqui est traité dans le sauf
  4. (A/0)+Bfonctionnera avec tout A ou B. literal_eval(E) soulève une erreur.
  5. ""+""ne fonctionne que pour le signe +. Tout le reste imprimera NaN, NaP ou NaN.00 ...
  6. [A, B, C]+Dfonctionne en vérifiant que D == C+1cela fonctionnera pour toutes les longueurs de liste et tous les nombres.
  7. ^^
  8. 2/(2-(3/2+1/2)), Tout ce qui ne parvient pas à analyser -avec un +endroit après sa sortie NaN.000 ... 13
  9. RANGE(" ") Codé en dur
  10. +A fonctionnera pour tout A. Ouputs "current_line_number+A"
  11. A+A fonctionne pour tout A tant qu'ils sont identiques et qu'ils sont de type python bulitin
  12. RANGE(1,5) Codé en dur.
  13. FLOOR(A) fonctionne pour tout A.
  14. colors.rgb("blue")Le lstrip dans eval transforme cela en gb("blue")une réponse codée en dur.
  15. colors.rgb("yellowish blue")Le lstrip dans eval tourne ceci dans gb("yellowish blue")lequel tente d'utiliser une variable inexistante si yest présent dans l'argument causant une erreur que except transforme en NaN
  16. colors.sort()Le lstrip transforme ceci en t()une réponse codée en dur.

Brainsteel a signalé une erreur dans mon hypothèse pour la règle 10.

Daniel Wakefield
la source
Très propre. Je pense que, sur le n ° 10, il semble que le "+ A" ait pour but d'afficher le numéro de ligne + A, plutôt que de précéder le 1.
BrainSteel
Ahh oui, évident maintenant que sa souligné. Eh bien, cela signifie que int sera mieux comme fonction à une seule lettre. Peut sauver un octet ou deux.
Daniel Wakefield
re # 9: RANGE(" ")est une plage de caractères allant du caractère guillemet double \ x22 au caractère espace \ x20 et inversement.
John Dvorak
3
2concernant le saut: parce que Randall est réglé sur la 4ligne 11, 2 est maintenant 4 et 12 est maintenant 14. Ceci s’applique également aux numéros de ligne.
John Dvorak
2
Vous pouvez économiser des octets en utilisant espace, tabulation et tabulation + espace pour votre mise en retrait.
Tyilo
16

Python, 1110 octets

La surcharge des opérateurs n’est pas un mal, non?

from re import*
class V(str):
 def __add__(s,r):return s[:-1]+chr(ord(s[-1])+r)
class S(str):
 def __str__(s):return "'"+s+"'"if '"'in s else'"'+s+'"'
 def __repr__(s):return str(s)
 def __add__(s,r):s=str(s)[1:-1];return S('['+s+']'if type(r)==L else '"+"' if(s,r)==('','')else s+r)
class I(int):
 def __add__(s,r):return type(r)(int(s)+int(r))if s!=r else V('DONE')
 def __div__(s,r):return N if r==0 else int(s)/int(r)
 def __pos__(s):return s+c*10
 def __mul__(s,r):return V('NaN.'+'0'*13+'13')if r==1 else int(s)*int(r)
class L(list):
 def __add__(s,r):return V(str(r==s[-1]+1).upper())
def RANGE(a,b=0):return 2*(a,S(chr(ord(a)+1)))if b==0 else tuple([a]+[b-1,a+2]*((b-a)/4)+[b-1,b])
def FLOOR(n):return V('|\n|\n|\n|___%s___'%n)
def colorsrgb(c):
 m={'blue':V('#0000FF')}
 return m.get(c,N)
def colorssort():return V('rainbow')
N=V('NaN')
c=1
while True:
 try:l=raw_input('[%d] >'%c)
 except:break
 l=sub(r'(?<!"|\.)(\d+)(?!\.|\d)',r'I(\1)',l)
 l=sub(r'"(.*?)"',r'S("\1")',l)
 l=sub(r'\[(.*?)\]',r'L([\1])',l)
 l=sub(r'/\(','*(',l)
 l=sub('s\.','s',l)
 for x in str(eval(l)).split('\n'):print ' =',x
 c+=1

Mon objectif n’était pas autant de gagner (évidemment) que de le rendre aussi générique que possible. Très peu est codé en dur. Essayez des choses comme RANGE(10), 9*1, et RANGE("A"), (2/0)+14et "123"des résultats amusants!

Voici un exemple de session:

ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >1+1
 = DONE
[2] >2+"2"
 = "4"
[3] >"2"+2
Traceback (most recent call last):
  File "xktp.py", line 31, in <module>
    for x in str(eval(l)).split('\n'):print ' =',x
  File "<string>", line 1, in <module>
  File "xktp.py", line 7, in __add__
    def __add__(s,r):s=str(s)[1:-1];return S('['+s+']'if type(r)==L else '"+"' if(s,r)==('','')else s+r)
TypeError: cannot concatenate 'str' and 'I' objects
ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >ryan@DevPC-LX:~/golf/xktp$
ryan@DevPC-LX:~/golf/xktp$
ryan@DevPC-LX:~/golf/xktp$
ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >2+"2"
 = "4"
[2] >"2"+[]
 = "[2]"
[3] >"2"+[1, 2, 3]
 = "[2]"
[4] >(2/0)
 = NaN
[5] >(2/0)+2
 = NaP
[6] >(2/0)+14
 = Na\
[7] >""+""
 = '"+"'
[8] >[1,2,3]+2
 = FALSE
[9] >[1,2,3]+4
 = TRUE
[10] >[1,2,3,4,5,6,7]+9
 = FALSE
[11] >[1,2,3,4,5,6,7]+8
 = TRUE
[12] >2/(2-(3/2+1/2))
 = NaN.000000000000013
[13] >9*1
 = NaN.000000000000013
[14] >RANGE(" ")
 = (" ", "!", " ", "!")
[15] >RANGE("2")
 = ("2", "3", "2", "3")
[16] >RANGE(2)
Traceback (most recent call last):
  File "xktp.py", line 31, in <module>
    for x in str(eval(l)).split('\n'):print ' =',x
  File "<string>", line 1, in <module>
  File "xktp.py", line 15, in RANGE
    def RANGE(a,b=0):return 2*(a,S(chr(ord(a)+1)))if b==0 else tuple([a]+[b-1,a+2]*((b-a)/4)+[b-1,b])
TypeError: ord() expected string of length 1, but I found
ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >ryan@DevPC-LX:~/golf/xktp$ # oops
ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >RANGE("2")
 = ("2", "3", "2", "3")
[2] >RANGE(2*1)
Traceback (most recent call last):
  File "xktp.py", line 31, in <module>
    for x in str(eval(l)).split('\n'):print ' =',x
  File "<string>", line 1, in <module>
  File "xktp.py", line 15, in RANGE
    def RANGE(a,b=0):return 2*(a,S(chr(ord(a)+1)))if b==0 else tuple([a]+[b-1,a+2]*((b-a)/4)+[b-1,b])
TypeError: ord() expected a character, but string of length 19 found
ryan@DevPC-LX:~/golf/xktp$ python xktp.py # oops again
[1] >RANGE(1,20)
 = (1, 19, 3, 19, 3, 19, 3, 19, 3, 19, 20)
[2] >RANGE(1,5)
 = (1, 4, 3, 4, 5)
[3] >RANGE(10,20)
 = (10, 19, 12, 19, 12, 19, 20)
[4] >RANGE(10,200)
 = (10, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 12, 199, 200)
[5] >+2
 = 52
[6] >+"99"
Traceback (most recent call last):
  File "xktp.py", line 31, in <module>
    for x in str(eval(l)).split('\n'):print ' =',x
  File "<string>", line 1, in <module>
TypeError: bad operand type for unary +: 'S'
ryan@DevPC-LX:~/golf/xktp$ python xktp.py # oops again and again!
[1] >FLOOR(200)
 = |
 = |
 = |
 = |___200___
[2] >2+2
 = DONE
[3] >3+#
Traceback (most recent call last):
  File "xktp.py", line 31, in <module>
    for x in str(eval(l)).split('\n'):print ' =',x
  File "<string>", line 1
    I(3)+#
         ^
SyntaxError: unexpected EOF while parsing
ryan@DevPC-LX:~/golf/xktp$ python xktp.py
[1] >3+3
 = DONE
[2] >ryan@DevPC-LX:~/golf/xktp$
kirbyfan64sos
la source
7

C, 412 octets

C'est fondamentalement codé en dur, mais toutes les autres réponses manquaient jusqu'à présent ...

i;char b[99];main(){for(;;){printf("[%d]>",abs(++i));gets(b);i-=b[2]==50?26:0;printf("=>");puts(*b==82?b[6]==34?"('\"',\"!\",\" \",\"!\",'\"')":"(1,4,3,4,5)":*b==70?"|\n=>|\n=>|\n=>|___10.5___":*b==43?"12":*b==91?b[8]==50?"FALSE":"TRUE":*b==34?b[1]==34?"'\"+\"'":"\"[2]\"":*b==40?b[5]==43?"NaP":"NaN":*b==99?b[7]=='s'?"rainbow":b[12]==98?"#0000FF":"NaN":b[1]==43?b[2]==34?"\"4\"":"DONE":"NaN.000000000000013");}}

Sortie:

[1]>2+"2"
=>"4"
[2]>"2"+[]
=>"[2]"
[3]>(2/0)
=>NaN
[4]>(2/0)+2
=>NaP
[5]>""+""
=>'"+"'
[6]>[1,2,3]+2
=>FALSE
[7]>[1,2,3]+4
=>TRUE
[8]>2/(2-(3/2+1/2))
=>NaN.000000000000013
[9]>RANGE(" ")
=>('"',"!"," ","!",'"')
[10]>+2
=>12
[11]>2+2
=>DONE
[14]>RANGE(1,5)
=>(1,4,3,4,5)
[13]>FLOOR(10.5)
=>|
=>|
=>|
=>|___10.5___
Cole Cameron
la source
5

Python 3, 298

Tout est codé en dur, mais l'entrée est transformée en un nombre qui est ensuite converti en chaîne et recherché dans une grande chaîne contenant tous ces nombres suivis de leurs réponses.

B="""53"#0000FF"~62DONE~43NaN.000000000000013~25(1,4,3,4,5)~26"rainbow"~49"4"~21"[2]"~29FALSE~15|*|*|*|___10.5___~17'"+"'~1212~60('"',"!"," ","!",'"')~24NaN~31TRUE~64NaN~76NaP"""
i=0
while 1:i+=1;s=input("[%s]>"%i);print("=>"+B[B.find(str(sum(map(ord,s))%81))+2:].split("~")[0].replace("*","\n=>"))
Rétablir Monica
la source
1

Python 3, 542 484 octets

Puisqu'il n'y avait aucune mention de codage absolu, voici ma solution.

a={'2+"2"':'"4"','"2"+[]':'"[2]"',"(2/0)":"NaN","(2/0)+2":"NaP",'""+""':"'\"+\"'","[1,2,3]+2":"FALSE","[1,2,3]+4":"TRUE","2/(2-(3/2+1/2))":"NaN.000000000000013",'RANGE(" ")':'(\'"\',"!"," ","!",\'"\')',"+2":"12","2+2":"DONE","RANGE(1,5)":"(1,4,3,4,5)","FLOOR(10.5)":"|\n|\n|\n|___10.5___",'colors.rgb("blue")':'"#0000FF"','colors.rgb("yellowish blue")':"NaN","colors.sort()":'"rainbow"'}
i=1
while 1:b=a[input("[%i]>"%i).replace("\t","")].split("\n");print("=> "+"\n=> ".join(b));i+=1
Ethan Bierlein
la source
Le codage en dur est correct, mais je pense que les failles interdites par défaut sont interdites par défaut. : P
lirtosiast
@ThomasKwa Je ne vois rien ici qui soit une échappatoire interdite. Y a-t-il?
Ethan Bierlein
1
Tout me semble conforme. J'ai déjà supposé que vous exploitiez une échappatoire parce que vous avez dit qu'il n'y avait "aucune mention des échappatoires standard".
lirtosiast
1
Je pense que c'est créatif, mais pas une réponse. La question parle clairement d’entrée et de sortie: "créer un programme qui accepte toutes les entrées données et affiche la sortie appropriée"
agtoever
2
Vous pouvez économiser un bon montant en utilisant les deux guillemets. "2+\"2\""devient '2+"2"'. Le nombre d'importations peut également être supprimé si vous ajoutez une variable de compteur.
Daniel Wakefield