Crie uma interface adequada aos tipos XKCD

34

colors.rgb ("blue") produz "# 0000FF". colors.rgb ("azul amarelado") produz NaN. colors.sort () produz "arco-íris"

Usando as regras definidas na imagem e seu texto de título (citado aqui), crie um programa que aceite toda a entrada fornecida e exiba a saída apropriada.

  • A entrada pode ser feita com stdin ou equivalente mais próximo. Deve haver uma linha [n]>na qual digitar e naumenta em 1 cada comando. Deve começar em 1.

  • O resultado deve ser exibido usando stdout ou equivalente mais próximo. Deve haver um =>em cada linha de saída.

Todas as 13 condições, mais as 3 no título (citadas), devem funcionar.

Isso é código de golfe, então a resposta mais curta vence.

Tim
fonte
16
Quão geral deve ser a interface? Por exemplo, a função de piso precisa funcionar para qualquer flutuador fornecido ou podemos assumir que ela só será aprovada 10.5?
Ankh-morpork 10/07/2015
1
O> da saída está alinhado com o> da entrada, à medida que n cresce e a entrada> se move mais para a direita?
Sparr
1
Essa história em quadrinhos pode ser interpretada de várias maneiras. Você poderia fornecer uma lista de quais tipos e operações específicos precisamos implementar?
BrainSteel
5
Por que naumentar em 1? Isso não é o que os quadrinhos fazem ... ;-) #
686807 Reinstate Monica
3
@WolframH É - mas ele fez 2 = 4 no comando 11 para exibir 14 e não 12.
Tim

Respostas:

21

Python 3, 700 698 697 689 683 639 611

Guias como recuo.

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

Como isso usa um Except, exceto que você não pode pressionar Ctrl-C. Ctrl-Z e matar %% funcionam embora

Algumas das condições são generalizadas e outras funcionarão apenas com a entrada exata.

  1. A+"B" funcionará com qualquer A e B, não apenas quando A == B
  2. "A"+[] funcionará para qualquer A que possa ser convertido em um int (inclui cadeias hexadecimais e binárias, por exemplo, 0xff e 0b01010)
  3. (A/0)funcionará para quaisquer causas A, Eval DivideByZeroErrortratadas na exceção
  4. (A/0)+Bfuncionará com qualquer A ou B. literal_eval(E) gera um erro.
  5. ""+""só funciona para o sinal +. Qualquer outra coisa imprimirá NaN, NaP ou NaN.00 ...
  6. [A, B, C]+Dfunciona verificando se D == C+1isso funcionará para qualquer tamanho de lista e qualquer número.
  7. ^^
  8. 2/(2-(3/2+1/2)), Qualquer coisa que não consiga analisar -com um+ consiga algum lugar depois da saída NaN.000 ... 13
  9. RANGE(" ") Codificado
  10. +A funcionará para qualquer A. Ouputs "current_line_number+A"
  11. A+A funciona para qualquer A, desde que sejam iguais e sejam do tipo bulitin python
  12. RANGE(1,5) Codificado.
  13. FLOOR(A) funciona para qualquer A.
  14. colors.rgb("blue")O lstrip em eval transforma isso em gb("blue")que tem uma resposta codificada.
  15. colors.rgb("yellowish blue")O lstrip em eval transforma isso em gb("yellowish blue")que tentativas de usar uma variável inexistente se yestá presente no argumento causando um erro que o exceto se transforma em NaN
  16. colors.sort()O lstrip transforma isso em t()que tem uma resposta codificada.

Brainsteel apontou um erro na minha suposição para a regra 10.

Daniel Wakefield
fonte
Muito arrumado. Eu acho que, no nº 10, parece que o "+ A" é destinado para a saída do número de linha + A, em vez de apenas prepending 1.
BrainSteel
Ahh sim, óbvio agora que está indicado. Bem, isso significa que int será melhor como uma única função de letra. Pode salvar um byte ou dois.
Daniel Wakefield
re # 9: RANGE(" ")é um intervalo de caracteres, do caractere de aspas duplas \ x22 ao caractere de espaço \ x20 e vice-versa.
John Dvorak
3
re o salto: Randall porque definido 2para 4a linha 11, é agora 2 4 e 12 é agora 14. Isto também se aplica para os números de linha.
John Dvorak
2
Você pode salvar alguns bytes usando espaço, tabulação e tab + espaço para o seu recuo.
Tyilo 11/07
16

Python, 1110 bytes

Sobrecarga de operador não é ruim, certo?

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

Meu objetivo não era tanto ganhar (obviamente), mas torná-lo o mais genérico possível. Muito pouco é codificado. Tente coisas assim RANGE(10), 9*1e RANGE("A"), (2/0)+14e,"123" para os resultados divertidos!

Aqui está uma sessão de amostra:

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

C, 412 bytes

Isso é basicamente codificado, mas todas as outras respostas até agora estavam faltando alguma coisa ...

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

Saída:

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

Python 3, 298

Tudo é codificado permanentemente, mas a entrada é transformada em um número que é convertido em uma sequência e pesquisada em uma sequência grande que contém todos esses números seguidos por suas respostas.

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=>"))
Restabelecer Monica
fonte
1

Python 3, 542 484 bytes

Como não houve menção a códigos absolutos absolutos, aqui está minha solução.

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
fonte
A codificação está correta, mas acho que as brechas proibidas por padrão são proibidas por padrão. : P
lirtosiast
@ThomasKwa Não vejo nada aqui que seja uma brecha proibida. Existe?
Ethan Bierlein
1
Tudo parece compatível comigo. Eu supus anteriormente que você estava explorando uma brecha porque disse que "não havia menção de brechas [...] comuns".
lirtosiast
1
Eu acho que é criativo, mas não uma resposta. A questão fala claramente sobre a entrada e saída: "criar um programa que aceita todas as entradas e exibe dada a saída apropriada"
agtoever
2
Você pode economizar uma boa quantia usando as duas aspas. "2+\"2\""torna-se '2+"2"'. A contagem de importação também pode ser removida se você adicionar uma variável de contador.
Daniel Wakefield