Erstellen Sie eine Schnittstelle, die zu den XKCD-Typen passt

34

colors.rgb ("blue") ergibt "# 0000FF". colors.rgb ("gelblich blau") ergibt NaN. colors.sort () liefert "rainbow"

Erstellen Sie unter Verwendung der im Bild festgelegten Regeln und des Titeltexts (hier zitiert) ein Programm, das alle angegebenen Eingaben akzeptiert und die entsprechenden Ausgaben anzeigt.

  • Die Eingabe kann mit stdin oder einem äquivalenten Wert erfolgen. Es sollte eine Zeile geben, [n]>in die Sie es eingeben können, und sie nwird bei jedem Befehl um 1 erhöht. Es sollte um 1 beginnen.

  • Das Ergebnis sollte mit stdout oder einem gleichwertigen Wert angezeigt werden. In =>jeder Ausgabezeile sollte ein vorhanden sein.

Alle 13 Bedingungen plus die 3 im Titel (zitiert) müssen funktionieren.

Dies ist Codegolf, also gewinnt die kürzeste Antwort.

Tim
quelle
16
Wie allgemein soll die Schnittstelle sein? Muss die Bodenfunktion zum Beispiel für einen bestimmten Schwimmer funktionieren, oder können wir davon ausgehen, dass sie immer nur bestanden wird 10.5?
Ankh-Morpork
1
Stimmt das> für die Ausgabe mit dem> für die Eingabe überein, wenn n größer wird und die Eingabe> weiter nach rechts verschoben wird?
Sparr
1
Dieser Comic kann möglicherweise auf verschiedene Arten interpretiert werden. Können Sie eine Liste der spezifischen Typen und Operationen bereitstellen, die wir implementieren müssen?
BrainSteel
5
Warum sollte man num 1 erhöhen? Das ist nicht das, was der Comic macht ... ;-)
Reinstate Monica
3
@WolframH Es ist - aber er machte 2 = 4 in Befehl 11, so dass es 14 nicht 12 anzeigt.
Tim

Antworten:

21

Python 3, 700 698 697 689 683 639 611

Tabulatoren als Einzug.

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

Da dies ein nacktes verwendet, können Sie es nicht Strg-C. Strg-Z und Kill %% funktionieren jedoch

Einige der Bedingungen sind verallgemeinert und andere funktionieren nur mit genauen Eingaben.

  1. A+"B" funktioniert mit jedem A und B nicht nur wenn A == B
  2. "A"+[] funktioniert für jedes A, das in ein int konvertiert werden kann (einschließlich hexadezimaler und binärer Zeichenfolgen, z. B. 0xff und 0b01010)
  3. (A/0)funktioniert für alle A, Eval Ursachen, DivideByZeroErrordie in der Ausnahme behandelt werden
  4. (A/0)+Bfunktioniert mit jedem A oder B. literal_eval(E) wirft einen Fehler auf.
  5. ""+""funktioniert nur für das + Zeichen. Alles andere druckt NaN, NaP oder NaN.00 ...
  6. [A, B, C]+DDies funktioniert, indem überprüft wird, ob D == C+1dies für eine beliebige Länge der Liste und für beliebige Zahlen funktioniert.
  7. ^^
  8. 2/(2-(3/2+1/2)), Alles, was nicht -mit +irgendwo danach geparst werden kann, gibt NaN.000 ... 13 aus
  9. RANGE(" ") Hardcoded
  10. +A funktioniert für alle A. Ouputs "current_line_number+A"
  11. A+A funktioniert für jedes A, solange sie gleich sind und vom Typ Bulitin Python sind
  12. RANGE(1,5) Hardcoded.
  13. FLOOR(A) funktioniert für jede A.
  14. colors.rgb("blue")Der lstrip in eval schaltet dies um, in gb("blue")dem eine fest codierte Antwort vorliegt .
  15. colors.rgb("yellowish blue")Der lstrip in eval dreht dies um, gb("yellowish blue")wobei versucht wird, eine nicht existierende Variable zu verwenden, wenn ysie in der Argumentation vorhanden ist, was einen Fehler verursacht, der vom except in NaN umgewandelt wird
  16. colors.sort()Der lstrip wandelt dies in t()eine fest codierte Antwort um.

Brainsteel wies auf einen Fehler in meiner Annahme für Regel 10 hin.

Daniel Wakefield
quelle
Sehr gepflegt. Ich denke, auf # 10 scheint das "+ A" die Zeilennummer + A auszugeben, anstatt nur vor 1 zu stehen.
BrainSteel
Ahh ja, jetzt ist es offensichtlich, dass es darauf hingewiesen wird. Nun, das bedeutet, dass int als Einzelbuchstabenfunktion besser ist. Könnte ein oder zwei Bytes speichern.
Daniel Wakefield
re # 9: RANGE(" ")ist ein Bereich von Zeichen vom doppelten Anführungszeichen \ x22 bis zum Leerzeichen \ x20 und zurück.
John Dvorak
3
erneut den Sprung: weil Randall eingestellt 2auf 411 in Zeile 2 ist nun auf 4 und 12 ist jetzt 14. Dies gilt auch für die Zeilennummern.
John Dvorak
2
Sie können einige Bytes einsparen, indem Sie Leerzeichen, Tabulatoren und Tabulatoren + Leerzeichen für Ihre Einrückung verwenden.
Tyilo,
16

Python, 1110 Bytes

Bedienerüberladung ist nicht böse, oder?

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

Mein Ziel war (offensichtlich) nicht so viel zu gewinnen, da es es so allgemein wie möglich macht. Sehr wenig ist fest codiert. Versuchen Sie solche Sachen RANGE(10), 9*1und RANGE("A"), (2/0)+14und "123"für Spaß Ergebnisse!

Hier ist eine Beispielsitzung:

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
quelle
7

C 412 Bytes

Dies ist im Grunde genommen hartcodiert, aber allen anderen Antworten fehlte bisher etwas ...

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

Ausgabe:

[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
quelle
5

Python 3, 298

Alles ist fest codiert, aber die Eingabe wird in eine Zahl umgewandelt, die dann in eine Zeichenfolge umgewandelt und in einer großen Zeichenfolge nachgeschlagen wird, die alle diese Zahlen enthält, gefolgt von ihren Antworten.

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=>"))
Setzen Sie Monica wieder ein
quelle
1

Python 3, 542 484 Bytes

Da von absoluter Hardcodierung keine Rede war, hier meine Lösung.

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
quelle
Hardcoding ist in Ordnung, aber ich denke, die Lücken, die standardmäßig verboten sind , sind standardmäßig verboten. : P
Lirtosiast
@ThomasKwa Ich sehe hier nichts, was eine verbotene Lücke darstellt. Gibt es?
Ethan Bierlein
1
Alles sieht für mich konform aus. Ich habe früher angenommen, dass Sie eine Lücke ausnutzen, weil Sie sagten, es gebe "keine Erwähnung von [...] Standardlücken".
Lirtosiast
1
Ich denke, es ist kreativ, aber keine Antwort. In der Frage geht es eindeutig um Ein- und Ausgabe: "Erstellen Sie ein Programm, das alle angegebenen Eingaben akzeptiert und die entsprechende Ausgabe anzeigt"
11.07.15
2
Sie können einen guten Betrag sparen, indem Sie beide Anführungszeichen verwenden. "2+\"2\""wird '2+"2"'. Der Import von count kann auch entfernt werden, wenn Sie eine Zählervariable hinzufügen.
Daniel Wakefield