Crea un'interfaccia adatta ai tipi XKCD


34

colors.rgb ("blue") produce "# 0000FF". colors.rgb ("blu giallastro") produce NaN. colors.sort () restituisce "arcobaleno"

Utilizzando le regole stabilite nell'immagine e il testo del titolo (citato qui), creare un programma che accetta tutto l'input dato e visualizza l'output appropriato.

  • L'input può essere preso con stdin o l'equivalente più vicino. Dovrebbe esserci una riga come [n]>su cui digitarla, e naumenta di 1 ogni comando. Dovrebbe iniziare da 1.

  • Il risultato dovrebbe essere visualizzato usando stdout o l'equivalente più vicino. Dovrebbe esserci un =>su ogni linea di output.

Tutte le 13 condizioni, più le 3 nel titolo (citato) devono funzionare.

Questo è il golf del codice, quindi vince la risposta più breve.


16
Quanto dovrebbe essere generale l'interfaccia? Ad esempio, la funzione floor deve funzionare per qualsiasi float fornito o possiamo supporre che sarà sempre passata 10.5?
ankh-morpork,

1
> Per l'output sono allineati con> per l'input, man mano che n cresce e l'input> si sposta più a destra?
Sparr,

1
Questo fumetto può potenzialmente essere interpretato in diversi modi. Potresti fornire un elenco di quali tipi e operazioni specifici dobbiamo implementare?
BrainSteel,

5
Perché dovrebbe naumentare di 1? Non è quello che fa il fumetto ... ;-)
Ripristina Monica l'

3
@WolframH Lo è - ma ha fatto 2 = 4 nel comando 11, quindi visualizza 14 non 12.
Tim

Risposte:


21

Python 3, 700 698 697 689 683 639 611

Schede come rientro.

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

Dal momento che questo utilizza un nudo Tranne che non è possibile Ctrl-C esso. Ctrl-Z e kill %% funzionano però

Alcune condizioni sono generalizzate e altre funzioneranno solo con input esatti.

  1. A+"B" funzionerà con qualsiasi A e B, non solo quando A == B
  2. "A"+[] funzionerà per qualsiasi A che può essere convertito in un int (include stringhe esadecimali e binarie, ad es. 0xff e 0b01010)
  3. (A/0)funzionerà per qualsiasi A, Eval Cause DivideByZeroErrorche viene gestita nell'eccezione
  4. (A/0)+Bfunzionerà con qualsiasi A o B. literal_eval(E) genera un errore.
  5. ""+""funziona solo per il segno +. Qualsiasi altra cosa stamperà NaN, NaP o NaN.00 ...
  6. [A, B, C]+Dfunziona verificando che D == C+1funzionerà per qualsiasi lunghezza dell'elenco e di tutti i numeri.
  7. ^^
  8. 2/(2-(3/2+1/2)), Tutto ciò che non riesce ad analizzare quello che ha -con un +da qualche parte dopo che genererà NaN.000 ... 13
  9. RANGE(" ") hardcoded
  10. +A funzionerà per qualsiasi A. Ouputs "current_line_number+A"
  11. A+A funziona per qualsiasi A purché siano uguali e siano tipi di pitone bulitinico
  12. RANGE(1,5) Hardcoded.
  13. FLOOR(A) funziona per qualsiasi A.
  14. colors.rgb("blue")La striscia in eval trasforma questo in gb("blue")cui ha una risposta codificata.
  15. colors.rgb("yellowish blue")L'strip in eval trasforma questo in gb("yellowish blue")cui tenta di utilizzare una variabile inesistente se ypresente nell'argomento causando un errore che l'eccezione trasforma in NaN
  16. colors.sort()L'strip trasforma questo in t()cui ha una risposta codificata.

Brainsteel ha sottolineato un errore nel mio presupposto per la regola 10.


Molto pulito. Penso che, al numero 10, sembra che "+ A" abbia lo scopo di produrre il numero di riga + A, piuttosto che semplicemente anteporre 1.
BrainSteel

Ahh sì, ovvio ora che è stato sottolineato. Bene, ciò significa che int sarà migliore come funzione a lettera singola. Potrebbe salvare un byte o due.
Daniel Wakefield,

re # 9: RANGE(" ")è un intervallo di caratteri dal carattere di doppia virgoletta \ x22 al carattere di spazio \ x20 e ritorno.
John Dvorak,

3
per quanto riguarda il salto: poiché Randall è impostato 2sulla 4riga 11, 2 è ora 4 e 12 è ora 14. Questo vale anche per i numeri di riga.
John Dvorak,

2
È possibile salvare alcuni byte utilizzando spazio, tab e tab + spazio per il rientro.
Tyilo,

16

Python, 1110 byte

Il sovraccarico dell'operatore non è male, vero ??

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

Il mio obiettivo non era quello di vincere (ovviamente) quanto di renderlo il più generico possibile. Molto poco è codificato. Provare cose come RANGE(10),9*1 e RANGE("A"), (2/0)+14e "123"per i risultati di divertimento!

Ecco una sessione di esempio:

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$

7

C, 412 byte

Questo è fondamentalmente codificato, ma tutte le altre risposte finora mancavano qualcosa ...

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

Produzione:

[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___

5

Python 3, 298

Tutto è codificato, ma l'input viene trasformato in un numero che viene quindi convertito in una stringa e cercato in una stringa di grandi dimensioni che contiene tutti questi numeri seguiti dalle loro risposte.

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=>"))

1

Python 3, 542 484 byte

Dal momento che non si parlava di hardcoding assoluto, ecco la mia soluzione.

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

L'hardcoding va bene, ma penso che le scappatoie vietate per impostazione predefinita siano vietate per impostazione predefinita. : P
lirtosiast,

@ThomasKwa Non vedo nulla qui che sia una scappatoia proibita. È lì?
Ethan Bierlein, l'

1
Tutto mi sembra conforme. In precedenza pensavo che stessi sfruttando una scappatoia perché avevi detto che "non si parlava di [...] scappatoie standard".
lirtosiast,

1
Penso che sia creativo, ma non una risposta. La domanda parla chiaramente di input e output: "crea un programma che accetta tutti gli input dati e visualizza l'output appropriato"
agtoever

2
Puoi risparmiare un buon importo usando entrambe le virgolette. "2+\"2\""diventa '2+"2"'. L'importazione del conteggio potrebbe anche essere rimossa se aggiungi una variabile contatore.
Daniel Wakefield, l'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.