Create an interface that fits the XKCD Types

Python 3, 700 698 697 689 683 639 611

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

Since this uses a bare Except you can't Ctrl-C it. Ctrl-Z and kill %% work though

Some of the conditions are generalized and others will only work with exact input.

  1. A+"B" will work with any A and B not just when A == B
  2. "A"+[] will work for any A that can be converted to an int (Includes hex and binary strings e.g 0xff and 0b01010)
  3. (A/0) will work for any A, Eval Causes DivideByZeroError which is handled in the except
  4. (A/0)+B will work with any A or B. literal_eval (E) raises an error.
  5. ""+"" only works for the + sign. Anything else will print NaN, NaP or NaN.00...
  6. [A, B, C]+D works by checking that D == C+1 so will work for any length of list and any numbers.
  7. ^^
  8. 2/(2-(3/2+1/2)), Anything that fails to parse that has - with a + somewhere after it will output NaN.000...13
  9. RANGE(" ") Hardcoded
  10. +A will work for any A. Ouputs "current_line_number+A"
  11. A+A works for any A as long as they are the same and are bulitin python types
  12. RANGE(1,5) Hardcoded.
  13. FLOOR(A) works for any A.
  14. colors.rgb("blue") The lstrip in eval turns this in gb("blue") which has a hardcoded response.
  15. colors.rgb("yellowish blue") The lstrip in eval turns this in gb("yellowish blue") which attempts to use a non existent variable if y is present in the arguement causing an error which the except turns into NaN
  16. colors.sort() The lstrip turns this into t() which has a hardcoded response.

Brainsteel pointed out an error in my assumption for rule 10.


Python, 1110 bytes

Operator overloading isn't evil, right??

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

My goal wasn't as much winning (obviously) as it is making it as generic as possible. Very little is hardcoded. Try stuff like RANGE(10), 9*1, and RANGE("A"), (2/0)+14, and "123" for fun results!

Here's a sample 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$

C, 412 bytes

This is basically hardcoded, but all the other answers so far were missing something...

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

Output:

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

Tags:

Code Golf