Buat antarmuka yang sesuai dengan Jenis XKCD

34

colors.rgb ("blue") menghasilkan "# 0000FF". colors.rgb ("blue kekuningan") menghasilkan NaN. colors.sort () menghasilkan "pelangi"

Dengan menggunakan aturan yang ditetapkan dalam gambar dan teks judulnya (dikutip di sini), buat program yang menerima semua input yang diberikan dan menampilkan output yang sesuai.

  • Input dapat diambil dengan stdin atau setara terdekat. Harus ada garis seperti [n]>di mana untuk mengetiknya, dan nbertambah 1 setiap perintah. Itu harus dimulai pada 1.

  • Hasilnya harus ditampilkan menggunakan stdout atau setara terdekat. Harus ada =>pada setiap baris output.

Semua 13 kondisi, ditambah 3 dalam judul (dikutip) harus berfungsi.

Ini kode golf, jadi jawaban tersingkat menang.

Tim
sumber
16
Seberapa umum seharusnya antarmuka itu? Misalnya, apakah fungsi lantai harus berfungsi untuk float yang disediakan atau bisakah kita menganggapnya hanya akan dilewati 10.5?
ankh-morpork
1
Apakah> untuk output sejajar dengan> untuk input, saat n tumbuh dan input> bergerak lebih jauh ke kanan?
Sparr
1
Komik ini berpotensi ditafsirkan dalam beberapa cara. Bisakah Anda memberikan daftar jenis dan operasi spesifik apa yang perlu kami terapkan?
BrainSteel
5
Mengapa harus nbertambah 1? Bukan itu yang dilakukan komik ... ;-)
Pasang kembali Monica
3
@ WolframH Itu - tapi dia membuat 2 = 4 di perintah 11 sehingga menampilkan 14 bukan 12.
Tim

Jawaban:

21

Python 3, 700 698 697 689 683 639 611

Tab sebagai lekukan.

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

Karena ini menggunakan telanjang Kecuali Anda tidak dapat Ctrl-C itu. Ctrl-Z dan matikan%% work

Beberapa kondisi digeneralisasikan dan yang lainnya hanya akan bekerja dengan input yang tepat.

  1. A+"B" akan bekerja dengan A dan B tidak hanya kapan A == B
  2. "A"+[] akan bekerja untuk semua A yang dapat dikonversi ke int (Termasuk string hex dan binary misalnya 0xff dan 0b01010)
  3. (A/0)akan bekerja untuk A, Penyebab Eval DivideByZeroErroryang ditangani dalam pengecualian
  4. (A/0)+Bakan bekerja dengan A atau B. literal_eval(E) memunculkan kesalahan.
  5. ""+""hanya berfungsi untuk tanda +. Yang lain akan mencetak NaN, NaP atau NaN.00 ...
  6. [A, B, C]+Dbekerja dengan memeriksa bahwa D == C+1itu juga akan bekerja untuk setiap daftar panjang dan nomor apa pun.
  7. ^^
  8. 2/(2-(3/2+1/2)), Apa pun yang gagal mengurai yang ada -dengan suatu +tempat setelah itu akan menghasilkan NaN.000 ... 13
  9. RANGE(" ") Hardcoded
  10. +A akan bekerja untuk semua A. Ouputs "current_line_number+A"
  11. A+A bekerja untuk setiap A asalkan mereka sama dan merupakan tipe python bulitin
  12. RANGE(1,5) Hardcoded.
  13. FLOOR(A) bekerja untuk A.
  14. colors.rgb("blue")The lstrip in eval ternyata ini di gb("blue")mana memiliki respon hardcoded.
  15. colors.rgb("yellowish blue")Lstrip dalam eval mengubah ini di gb("yellowish blue")mana upaya untuk menggunakan variabel tidak ada jika yhadir dalam argumen yang menyebabkan kesalahan yang kecuali berubah menjadi NaN
  16. colors.sort()Lstrip mengubah ini menjadi t()yang memiliki respons hardcode.

Brainsteel menunjukkan kesalahan dalam asumsi saya untuk aturan 10.

Daniel Wakefield
sumber
Sangat rapi. Saya pikir, pada # 10, tampaknya "+ A" dimaksudkan untuk menampilkan nomor baris + A, daripada hanya menambahkan 1.
BrainSteel
Ahh ya, jelas sekarang yang ditunjukkan. Nah itu berarti int akan lebih baik sebagai fungsi satu huruf. Mungkin menghemat satu atau dua byte.
Daniel Wakefield
kembali # 9: RANGE(" ")adalah rentang karakter dari karakter kutipan ganda \ x22 ke karakter spasi \ x20 dan kembali.
John Dvorak
3
kembali lompat: karena Randall diatur 2ke4 dalam baris 11, 2 sekarang 4 dan 12 sekarang 14. Ini juga berlaku untuk nomor baris.
John Dvorak
2
Anda bisa menghemat beberapa byte dengan menggunakan spasi, tab dan tab + ruang untuk lekukan Anda.
Tyilo
16

Python, 1110 byte

Kelebihan operator tidak jahat, kan ??

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

Tujuan saya tidak sebanyak menang (jelas) karena menjadikannya sebagai generik mungkin. Sangat sedikit hardcoded. Cobalah hal-hal seperti RANGE(10), 9*1, dan RANGE("A"), (2/0)+14, dan "123"untuk hasil menyenangkan!

Inilah sesi sampel:

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

C, 412 byte

Ini pada dasarnya hardcoded, tetapi semua jawaban lain sejauh ini kehilangan sesuatu ...

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

Keluaran:

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

Python 3, 298

Semuanya hardcoded, tetapi input diubah menjadi angka yang kemudian dikonversi menjadi string dan melihat ke dalam string besar yang berisi semua angka-angka ini diikuti oleh jawaban mereka.

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=>"))
Pasang kembali Monica
sumber
1

Python 3, 542 484 byte

Karena tidak disebutkan hardcoding absolut, inilah solusi saya.

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
sumber
Hardcoding baik-baik saja, tapi saya pikir celah yang dilarang secara default dilarang secara default. : P
lirtosiast
@ ThomasKwa saya tidak melihat apa pun di sini yang merupakan celah terlarang. Disana?
Ethan Bierlein
1
Semuanya terlihat sesuai untuk saya. Saya sebelumnya berasumsi Anda mengeksploitasi celah karena Anda mengatakan ada "tidak menyebutkan [...] lubang standar".
lirtosiast
1
Saya pikir itu kreatif, tetapi bukan jawaban. Pertanyaannya dengan jelas berbicara tentang input dan output: "buat program yang menerima semua input yang diberikan dan menampilkan output yang sesuai"
agtoever
2
Anda dapat menghemat jumlah yang baik dengan menggunakan kedua kutipan. "2+\"2\""menjadi '2+"2"'. Mengimpor jumlah juga dapat dihapus jika Anda menambahkan variabel penghitung.
Daniel Wakefield