33
\$\begingroup\$

colors.rgb("blue") yields "#0000FF". colors.rgb("yellowish blue") yields NaN. colors.sort() yields "rainbow"

Using the rules set out in the image and its title text (quoted here), create a program that accepts all the given input and displays the appropriate output.

  • Input can be taken with stdin or nearest equivalent. There should be a line like [n]> on which to type it, and n increases by 1 each command. It should start at 1.

  • The result should be displayed using stdout or nearest equivalent. There should be a => on each line of output.

All 13 conditions, plus the 3 in the title (quoted) must work.

This is code golf, so shortest answer wins.

\$\endgroup\$
  • 16
    \$\begingroup\$ How general should the interface be? For instance, does the floor function have to work for any provided float or can we assume it will only ever be passed 10.5? \$\endgroup\$ – ankh-morpork Jul 10 '15 at 22:52
  • 1
    \$\begingroup\$ Are the > for the output aligned with the > for the input, as n grows and the input > moves farther to the right? \$\endgroup\$ – Sparr Jul 10 '15 at 22:54
  • 1
    \$\begingroup\$ This comic can potentially be interpreted in several ways. Could you provide a list of what specific types and operations we need to implement? \$\endgroup\$ – BrainSteel Jul 11 '15 at 2:09
  • 5
    \$\begingroup\$ Why should n increase by 1? That's not what the comic does... ;-) \$\endgroup\$ – WolframH Jul 11 '15 at 23:46
  • 3
    \$\begingroup\$ @WolframH It is - but he made 2 = 4 in command 11 so it displays 14 not 12. \$\endgroup\$ – Tim Jul 12 '15 at 9:48
21
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Very neat. I think, on #10, it seems that the "+A" is intended to output the line number + A, rather than just prepending 1. \$\endgroup\$ – BrainSteel Jul 11 '15 at 2:06
  • \$\begingroup\$ Ahh yes, obvious now that its pointed out. Well that means that int will be better as a single letter function. Might save a byte or two. \$\endgroup\$ – Daniel Wakefield Jul 11 '15 at 2:12
  • \$\begingroup\$ re #9: RANGE(" ") is a range of characters from the double quote character \x22 to the space character \x20 and back. \$\endgroup\$ – John Dvorak Jul 11 '15 at 5:11
  • 3
    \$\begingroup\$ re the jump: because Randall set 2 to 4 in line 11, 2 is now 4 and 12 is now 14. This also applies to line numbers. \$\endgroup\$ – John Dvorak Jul 11 '15 at 5:15
  • 1
    \$\begingroup\$ You could save some bytes by using space, tab and tab + space for your indentation. \$\endgroup\$ – Tyilo Jul 11 '15 at 20:34
15
\$\begingroup\$

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$
\$\endgroup\$
7
\$\begingroup\$

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___
\$\endgroup\$
5
\$\begingroup\$

Python 3, 298

Everything is hardcoded, but the input is turned into a number that is then converted to a string and looked up in a large string that contains all these numbers followed by their answers.

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=>"))
\$\endgroup\$
1
\$\begingroup\$

Python 3, 542 484 bytes

Since there was no mention of absolute hardcoding here's my solution.

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
\$\endgroup\$
  • \$\begingroup\$ Hardcoding is fine, but I think the loopholes that are forbidden by default are forbidden by default. :P \$\endgroup\$ – lirtosiast Jul 11 '15 at 4:05
  • \$\begingroup\$ @ThomasKwa I don't see anything here that is a forbidden loophole. Is there? \$\endgroup\$ – Ethan Bierlein Jul 11 '15 at 4:08
  • 1
    \$\begingroup\$ Everything looks compliant to me. I earlier assumed you were exploiting a loophole because you said there was "no mention of [...] standard loopholes". \$\endgroup\$ – lirtosiast Jul 11 '15 at 4:54
  • 1
    \$\begingroup\$ I think it's creative, but not an answer. The question clearly talks about input and output: "create a program that accepts all the given input and displays the appropriate output" \$\endgroup\$ – agtoever Jul 11 '15 at 6:02
  • 2
    \$\begingroup\$ You can save a good amount by using both quotes. "2+\"2\"" becomes '2+"2"'. Importing count could also be removed if you add a counter variable. \$\endgroup\$ – Daniel Wakefield Jul 11 '15 at 9:32

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.