116
\$\begingroup\$

This idea is not mine, though I don't know where it originated. I once met it in a programming contest very long ago (1998, if I remember correctly). The task is to write a program in your favorite language that outputs 2012 and only 2012. The catch is that the program must still output 2012 after any one of its characters is modified. The modification can be either insertion, deletion or replacement. Of course, the modification will be such that the program is still syntactically valid.

Since I don't know all the programming languages, I have to ask the audience to help me and test the answers submitted.

Added: Many have commented that my definition of acceptable modifications is too vague. Here's my second attempt: The allowed modifications will leave your program syntactically valid and will not cause it to crash. There, I think that should cover all the compile-time, link-time and run-time errors. Though I'm sure that there will be some odd edge case in some language anyway, so when that comes up we'll look at it individually.

\$\endgroup\$
  • \$\begingroup\$ How about runtime errors like reading a most likely invalid address? \$\endgroup\$ – aaaaaaaaaaaa Jan 2 '12 at 21:15
  • \$\begingroup\$ @PeterTaylor - There are 3 answers already, the C one with heavy revising. You can look for inspiration there. \$\endgroup\$ – Vilx- Jan 2 '12 at 21:58
  • 2
    \$\begingroup\$ Anyone figured out if this is impossible in APL or GolfScript or similarly terse? \$\endgroup\$ – Jeff Burdges Jan 3 '12 at 8:03
  • 14
    \$\begingroup\$ This has got me thinking about DNA and redundancy and the potential for cosmic rays to flip bits in my programs. Interesting stuff. \$\endgroup\$ – Jon Purdy Jan 3 '12 at 8:55
  • 11
    \$\begingroup\$ ... You need some sleep. \$\endgroup\$ – Vilx- Jan 3 '12 at 8:57

42 Answers 42

0
\$\begingroup\$

Ruby, 40

p(([2012]+[2012]+[2012]).sort[1]||
2012)
\$\endgroup\$
  • 2
    \$\begingroup\$ Deleting the p causes this to run successfully but output nothing, or inserting a p after the first two characters causes it to output [2012, 2012, 2012] first. \$\endgroup\$ – histocrat Feb 4 '13 at 21:02
0
\$\begingroup\$

Javascript 40

Math.abs(((yr=2012) == 2012)? yr : 2012)
\$\endgroup\$
  • 3
    \$\begingroup\$ Foiled by putting a - at the beginning. Also, it's missing IO. \$\endgroup\$ – histocrat Apr 22 '13 at 20:43
  • \$\begingroup\$ Forgot to test the simplest case, back to the drawing board! \$\endgroup\$ – Professor Allman Apr 22 '13 at 22:21
0
\$\begingroup\$

Tcl, 55 chars.

if {[set a {puts 2012}]=={puts 2012}} $a {
puts 2012
#}

Check if the code is unmodified, then execute it, or print 2012.
I consider accessing a undefined variable as syntax error.

Tcl, 138 Characters

set a {set a {$a};if {\$a=={$a}} {puts 2012}};if {[info ex a]&&$a=={set a {$a};if {\$a=={$a}} {puts 2012}}} [subst -noc $a] {
puts 2012
#}

Ok, this is a quine variant: either the code is unmodified, then execute it, or simply print 2012

The last line is a little bit special: It is a comment, but the } closes the brace.

\$\endgroup\$
  • \$\begingroup\$ It doesn't work for me. $a is used before definition. If that's fixed, $a, would still break it. \$\endgroup\$ – jimmy23013 Feb 28 '15 at 2:20
0
\$\begingroup\$

OCaml, 66

let x="2012"
let x=if x="2012" then x else "2012";;
print_string x
\$\endgroup\$
  • \$\begingroup\$ I don't know OCaml, but print_string,x seemed to break it. \$\endgroup\$ – jimmy23013 Feb 28 '15 at 2:53
  • \$\begingroup\$ I do know OCaml, and that would indeed break it (the compiler would warn about the statements with no effect, but they aren't technically wrong). \$\endgroup\$ – user62131 Dec 7 '16 at 21:59
0
\$\begingroup\$

Mathematica 24

this is a simple fix to @Dr.belisarius answer (unfortunately, I can't add comments yet)

2012//.Except@2012->2012

Changing Replace (/.) to RepeatedReplace (//.) fixes the problem @Dillon found, since /// is a syntax error.

\$\endgroup\$
0
\$\begingroup\$

C# .NET, 83 bytes

class P{static void Main(){var q="2012";System.Console.Write(q=="2012"?q:"2012");}}

Try Online

\$\endgroup\$
  • \$\begingroup\$ Aaand it fails. Should output 2012, not 2014. XD But, yes, the approach seems to be valid. I cannot think of a way to break it. \$\endgroup\$ – Vilx- Aug 20 at 18:30
  • \$\begingroup\$ I feel stupid now \$\endgroup\$ – canttalkjustcode Aug 20 at 19:49
  • \$\begingroup\$ Aaand this version fails because I can do "2012"=="2012"?"2014":"2012". You need the var. :) \$\endgroup\$ – Vilx- Aug 20 at 20:21
  • \$\begingroup\$ Well I should probably stop trying to make this shorter then xD \$\endgroup\$ – canttalkjustcode Aug 20 at 21:55
0
\$\begingroup\$

Sinclair ZX81/Timex TS1000/1500 BASIC, 54 tokenized BASIC bytes used

 1 LET A$="2012"
 2 PRINT "2012" AND A$="2012";"2012" AND A$<>"2012"

Regardless of the value in A$ 2012 is still shown on the screen. I have used string literals because it's faster for writing to the screen (in BASIC at least) and also saves BASIC bytes. So A$ can contain any string value possible on the ZX81 tokenized "one-touch" entry system.

\$\endgroup\$
-1
\$\begingroup\$

Python 40 characters

a='2012';print(2012
)if a!='2012'else a

I don't think it's possible to get it any smaller with this approach in python.

edit: added 4 quotes to counter effects of -a on the end edit: removed space

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't know much about Python, but can you insert a - before the last a? \$\endgroup\$ – Vilx- Jan 3 '12 at 14:45
  • \$\begingroup\$ so it does... this calls for a rethink \$\endgroup\$ – Matt Jan 3 '12 at 14:49
  • \$\begingroup\$ a='2012';print a=='2012'and a or 2012 shorter \$\endgroup\$ – AMK Dec 16 '12 at 5:59
  • \$\begingroup\$ @AMK as gnibbler mentioned in codegolf.stackexchange.com/a/4614/6687, you can just replace the t in print with = making a='2012';prin= a=='2012'and a or 2012 \$\endgroup\$ – jsvk Feb 6 '13 at 2:33
-1
\$\begingroup\$

Python (45 49 52 chars)

nn='2012'
if nn=='2012':
    print nn
else:
    print 2012
\$\endgroup\$
  • \$\begingroup\$ @hammar fixed. Made n a string \$\endgroup\$ – elssar Jan 4 '12 at 6:27
  • \$\begingroup\$ Oh that still leaves it susceptible to changing print n to print any constant This needs a complete rethink \$\endgroup\$ – elssar Jan 4 '12 at 6:29
  • 1
    \$\begingroup\$ It's still susceptible to commenting out the variable: print #nn. \$\endgroup\$ – hammar Jan 4 '12 at 18:45
  • 1
    \$\begingroup\$ .. and to commenting out the else :) \$\endgroup\$ – hammar Jan 4 '12 at 19:25
  • 5
    \$\begingroup\$ I hate you guys >_< \$\endgroup\$ – elssar Jan 5 '12 at 7:24
-1
\$\begingroup\$

Lua, 33 36

xx=2012
print(xx==2012
and xx or 2012)
\$\endgroup\$
  • \$\begingroup\$ I think changing and x to and 1 will break it. :( \$\endgroup\$ – Dillon Cower Jan 6 '12 at 6:13
  • \$\begingroup\$ @DC gah I guess I do have to use 2 xx's. \$\endgroup\$ – greatwolf Jan 6 '12 at 6:16
  • 2
    \$\begingroup\$ Change and xx to and -xx.. eeeeeeek! \$\endgroup\$ – Dillon Cower Jan 6 '12 at 6:33
-1
\$\begingroup\$

Python - 50 41 40 41 chars

x='2012'
if x=='2012': print x
else: print '2012'

exec('cHJpbnQgMjAxMg=='.decode('base64'))

exec('x\x9c+(\xca\xcc+Q0204\x02\x00\x13\xfa\x03\x13'.decode('zip')

)

Yes, I know you can modify 'print x' into "print 1" or something similar, but not sure how to beat that..

\$\endgroup\$
  • \$\begingroup\$ And this can still be beaten by a single hash mark at the start of the line... \$\endgroup\$ – Vilx- Mar 25 '12 at 19:52
  • \$\begingroup\$ @Vilx- If I break it into two lines, it will throw an error with a comment, but it'll increase my byte count by 1. \$\endgroup\$ – Sargun Dhillon Mar 25 '12 at 21:33
  • \$\begingroup\$ I guess now would be the time for you to discover that which others already did in the comments - this is NOT code golf. XD \$\endgroup\$ – Vilx- Mar 26 '12 at 7:53
  • 1
    \$\begingroup\$ No output with exe=(...). \$\endgroup\$ – jimmy23013 Sep 14 '14 at 23:13
-1
\$\begingroup\$

Python - does not work

print sorted(['2012',
'2012','2012']).__getitem__(1)

I think it's basically impossible to prevent all the possible attacks against the print statement. eg.

prin=...        # changed t to =
print;...       # inserted ;
print(...,)     # inserted ,

So I tried a new approach using sys.stdout

\$\endgroup\$
  • \$\begingroup\$ I think you might have forgotten some parentheses.. so, assuming they're present, add ; after sorted. I like where this one is going, though! \$\endgroup\$ – Dillon Cower Jan 12 '12 at 4:24
  • \$\begingroup\$ @DC also can put a : after the 1 :( maybe i need to use __getitem__ \$\endgroup\$ – gnibbler Jan 12 '12 at 4:47
  • \$\begingroup\$ What's wrong with just print sorted([2012,2012,2012])[1]? \$\endgroup\$ – jsvk Feb 4 '13 at 21:23
  • \$\begingroup\$ @jsvk, print sorted([2012,2012,2012])[1:] \$\endgroup\$ – gnibbler Feb 4 '13 at 22:31
  • \$\begingroup\$ Ah sorry, I should've read the question more closely. I thought it was just replacement, I didn't know it could be insertion or deletion too \$\endgroup\$ – jsvk Feb 5 '13 at 3:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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