Write a program that always outputs "2012" - even if it's modified!

117

20

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.

Vilx-

Posted 2012-01-02T15:54:09.203

Reputation: 1 509

@Vilx-, how much output is allowed? 20122012 would work for PHP/HTML. Does 2012 just need to appear in the output, or should it be the only output? – zzzzBov – 2012-04-25T03:53:19.533

@zzzzBov - it has to be the ONLY output. Just the 4 characters "2012" - no more, no less. – Vilx- – 2012-04-25T06:31:05.360

I think this is where you get most of your rep... (right now +488) – Erik the Outgolfer – 2016-09-10T15:39:49.563

@EriktheGolfer - Umm, ok? – Vilx- – 2016-09-10T18:04:24.910

@Vilx- I mean, this is the post that has granted you most of your rep points. If you made this post CW, you will entirely transform to an almost-low-rep user. (Don't do it) – Erik the Outgolfer – 2016-09-10T21:26:15.760

@EriktheGolfer - I don't have a button to do that anyway. :) Also, I don't care much about rep. – Vilx- – 2016-09-10T21:40:37.833

It's funny how everyone instinctively puts the program size in their answer even though this is not code golf. – 12Me21 – 2018-03-04T01:55:38.953

I worked pretty hard to make this work in my fungoid esolang, but as ; (terminate with no output) could be inserted (or replace) just about anywhere and having to detect that (and not produce doubled output) was basically impossible. eg. if >"2012"@ prints correctly (and assume partially hardened), then >;"2012"@ prints nothing. >">"2012"@"... with ... being some kind of validation check would catch a similarly inserted semicolon...but it would also detect most other changes and output 20122012. Oof. – Draco18s no longer trusts SE – 2019-08-20T20:03:44.977

Would a proof that this task is impossible in some language be a valid submission? – Khuldraeseth na'Barya – 2019-08-20T22:18:09.210

@Khuldraesethna'Barya - Well, it's not what I had in mind, but why not? It's certainly on topic as far as I'm concerned. – Vilx- – 2019-08-20T22:26:36.863

How about runtime errors like reading a most likely invalid address? – aaaaaaaaaaaa – 2012-01-02T21:15:11.123

@PeterTaylor - There are 3 answers already, the C one with heavy revising. You can look for inspiration there. – Vilx- – 2012-01-02T21:58:45.723

@eBusiness - Slippery slope. For an interpreted language syntax errors can also be "runtime errors". However I'm on the side of the contestant. Runtime errors are also disallowed (that is, the changed character will not make those). – Vilx- – 2012-01-02T21:58:58.970

@Vilx-: Adding link-time errors to that list might be useful as well. ;) – Williham Totland – 2012-01-02T22:30:16.890

Hint: In theory, your code should have 2012 written twice. :) – Mateen Ulhaq – 2012-01-03T07:47:35.430

@muntoo: You're going to have to prove that; I can't see the number of "2012"s going below 3. – Williham Totland – 2012-01-03T07:55:00.287

You need not write 2012 even once, just write 2011+1 instead. I donno if you could encode 2012 as a series of mathematical operations so that 2012 isn't ever even "encoded twice". – Jeff Burdges – 2012-01-03T08:02:48.900

2Anyone figured out if this is impossible in APL or GolfScript or similarly terse? – Jeff Burdges – 2012-01-03T08:03:35.483

15This has got me thinking about DNA and redundancy and the potential for cosmic rays to flip bits in my programs. Interesting stuff. – Jon Purdy – 2012-01-03T08:55:15.530

12... You need some sleep. – Vilx- – 2012-01-03T08:57:22.050

@Vilx- Not until I finish listening to Dream Theater! (But yeah... [GMT-8:00].) – Mateen Ulhaq – 2012-01-03T09:07:38.763

@muntoo: And I'm saying that you need at least 3. Even if 3 is bigger than 2, "at least" implies that it is doable at least. In any case, one could get cute and say "you only need 2011+1" or similar, but that's besides the point, and not likely helpful in code golf, in any case. – Williham Totland – 2012-01-03T09:26:47.127

Well... actually... this wasn't really meant as a golf... but seems like people enjoy doing that, so have fun! :) – Vilx- – 2012-01-03T10:53:29.793

@Vilx-: Now you tell me. :P – Williham Totland – 2012-01-03T11:06:58.440

Well, I didn't really mention the word "golf" anywhere, did I? XD – Vilx- – 2012-01-03T11:37:07.667

@Vilx-: Indeed. – Williham Totland – 2012-01-03T12:00:32.890

The original version where the program had to output 2012 was interesting, but now that you also allow for the program to crash, it’s much less interesting. – Timwi – 2012-01-04T17:20:55.473

@timwi. I think you misread it, it's not allowed to crash. Also, if a modification causes the program to print/echo 2012 twice does it fail? – mellamokb – 2012-01-11T00:33:14.493

@mellamokb: The question as phrased clearly allows programs in which a single-character modification may make it compile and then crash. – Timwi – 2012-01-11T21:39:47.857

From OP (in Added section): The allowed modifications will leave your program syntactically valid and will not cause it to crash. I read that as you can't crash it with your one-character modification. However that was a clarification to the question that probably wasn't present when you wrote your previous comment :) – mellamokb – 2012-01-11T22:06:13.957

Actually it was already present when he wrote the previous comment, and yes, that's exactly what I mean - you don't have to worry that the modification will make your program crash. Or even cause it to behave in an "undefined way" (which is often the case with C/C++). – Vilx- – 2012-01-12T09:17:20.777

Answers

65

C, 53 characters

main(){register*a="2012";(puts("2012"==a?a:"2012"));}

A bit longer than the scripting language answers, and follows the same basic principle. Relies on the fact that due to the constraints of C's syntax, the only letters that would be possible to change without making the program invalid are within the strings!

Edit: Shaved off 4 characters.

Reedit: Robustness increased, shaved off one character.

Re-redit: Longer, but more robust. Just try your & now! (Correctly this time).

Update: Shortened a bit; defeats most approaches seen so far.

Update: Changed int to void; should defeat the last possible approach to break it I can think of.

Update: I thunk of another approach; replacing the last a (may it rot) with 0; using two-letter names should deal with that problem.

Update: Last update revoked; assuming changes causing runtime errors are disallowed; a will work just fine.

Update: Backtracking some more; attempting to dereference *a will also segfault; so using void to tease a compile error out of it should not be necessary.

Update: And a final shortening; that relies on the string "2012" being placed at but one address (which is common); and that literal strings are read-only (also common).

Update: It cost me two characters, but I defeated your puny semi-colon!

Williham Totland

Posted 2012-01-02T15:54:09.203

Reputation: 1 186

putc ruins the show. – Fors – 2013-04-23T19:12:15.843

@Fors: In my test, making puts putc throws a compile error. – Williham Totland – 2013-04-23T19:23:19.187

When I compile it using Clang and GCC it doesn't throw a compile error, but it does using ICC (but then ICC throws an error on main(){putc(48);} as well). – Fors – 2013-04-23T19:40:17.887

I guess that in the end it is odd that Clang and GCC accepts putc(a). Oh well, putc as least ruins the show using Clang or GCC, as they are showing some odd behaviour. – Fors – 2013-04-23T19:47:54.353

putc requires a stream as second parameter; as does fputs. But what about "2012"!=a? – Titus – 2017-01-23T11:53:39.830

1@Titus: If you mean switching == for != in the ternary, that gets you nowhere; instead of outputting a it now outputs "2012". – Williham Totland – 2017-01-23T12:00:03.033

Some env. main(){register*a="2012";(puts("2012"==a?0:"2012"));} print nothing – l4m2 – 2017-12-09T17:08:24.787

@IlmariKaronen You should mention which compiler (and compiler settings) you used. For example, this program is easily invalidated on a compiler that doesn't merge string literals, so that "2012"==a is false and the output can be changed by changing the last string literal. I think replacing the last "2012" by 1 ? "2012" : "2012" would fix that. – Gilles 'SO- stop being evil' – 2014-09-17T15:22:25.343

main(){int a="2012";puts(strcmp(a,"2012")?"2012":&a);} – Joanis – 2012-01-02T20:50:56.640

@M.Joanis: Excellent point; addressed. :) – Williham Totland – 2012-01-02T20:56:13.237

1-a instead of the last -a gives output 012. – Howard – 2012-01-02T21:02:52.917

@Howard: That last a is nothing but trouble, no matter how I phrase it. :P – Williham Totland – 2012-01-02T21:04:41.460

Out of interest, why register int ? – Paul R – 2012-01-02T21:33:36.107

@PaulR: Good point. – Williham Totland – 2012-01-02T21:36:35.043

2@PaulR: Now changed to register void; The register is there to prevent &; the void is there to prevent *. – Williham Totland – 2012-01-02T21:38:59.410

I can still put a ! before the last st, although that causes a runtime error on my VC++2008, so I guess it don't count. Not sure what the puts() should do according to the C standard. – Vilx- – 2012-01-02T22:21:55.810

@Vilx-: Putting a ! before the last st returns 0; which is NULL; and any attempt to dereference that should quite rightly give a segmentation fault. puts() needs to dereference the pointer to do it's thing, so it's well-behaved. – Williham Totland – 2012-01-02T22:25:44.340

Well, I expected that. Though it's also feasible (intuitive) that it could have detected the special case of NULL and output nothing. But you're right. – Vilx- – 2012-01-02T22:30:24.330

@Vilx-: C doesn't really "do" special cases; especially not of NULL. ;) – Williham Totland – 2012-01-02T22:31:54.330

Now a small mistake: you have to invert the ternary otherwise you may just change the literal string. – Howard – 2012-01-02T22:37:18.430

main(){register*a="2012";puts("2012"==a?&a:"2012");} This doesn't work on ideone, but it works on my cygwin installation. Hm. – Joanis – 2012-01-02T22:39:19.503

@Howard: Did that. :) – Williham Totland – 2012-01-03T06:37:11.873

@M.Joanis: Hate to break it to you, but the cygwin is wrong: Using & with a register variable is explicitly verboten by the standard. – Williham Totland – 2012-01-03T06:38:06.413

@WillihamTotland: Yeah, it doesn't make any sense... I'm just suprized it works the exact same way it did when I compiled de version in my very first comment above. /me sad @ cygwin – Joanis – 2012-01-03T06:49:30.847

@M.Joanis: It's understandable, tho'; what the cygwin compiler is doing is probably treating the register keyword as auto; which in and of itself isn't all that terrible; most compilers probably that anyway. The issue is that it imbues register with the semantics of auto; and forgets that while most other compilers might deal with it like that; that doesn't make it any more right. – Williham Totland – 2012-01-03T07:57:08.707

Using "2012"-=a or "2012"=-a results in UB. – Mateen Ulhaq – 2012-01-03T09:00:25.577

@muntoo: Getting compile errors for both of those from where I'm sitting. – Williham Totland – 2012-01-03T09:23:51.653

6OK... correct me if this is invalid C, but it just worked on my VS2010. Insert a ; between puts and (. – Vilx- – 2012-01-03T10:58:22.670

@Vilx-: That is indeed correct and legal. Attempting to defeat it as we speak. – Williham Totland – 2012-01-03T11:10:06.217

@Vilx-: And it's defeated. :) – Williham Totland – 2012-01-03T11:21:26.713

Arrrrgh! *Returns to the shadows to plot his revenge* – Vilx- – 2012-01-03T11:35:53.597

How about using a comma instead of a semicolon? – Peter Taylor – 2012-01-03T13:06:52.497

@PeterTaylor That gives me a compiler error. – aaaaaaaaaaaa – 2012-01-03T13:41:22.273

39+1, Congratulations, I think you've nailed it. I wrote a simple test harness that tried to compile and run every possible one-char variation of your code, and every single one of them either did not compile, crashed or printed 2012! (I only used printable ASCII characters for the insertion and substitution tests, but I doubt expanding the repertoire would help.) – Ilmari Karonen – 2012-01-03T14:06:09.000

Wow... awesome... This will highly likely be the accepted answer, but I'll wait a while before accepting so that people don't lose interest. – Vilx- – 2012-01-03T14:12:42.653

3@IlmariKaronen: Heh, that's a lot of effort; thanks for going through all that. :) – Williham Totland – 2012-01-03T14:14:48.397

38

Haskell, 19

(\xx@2012->xx)$2012

or, as a full program,

29

main=print$(\xx@2012->xx)2012


For a bit more fun:

(\l@(_:_:t:[])->t:l)['0'..'2']


To get one that can't be modified in such a way that yields merely a runtime error, we can encode the information in the lengths of lists which can't be modified using just one-character-changes, i.e.

map(head.show.length)[[(),()],[],[()],[(),()]]

To make it more modifiable (safely), we can also use the number itself as list element – just need to make it strings to prevent exchanging commas for plus':

map(head.show.length)[["2012","2012"],[],["2012"],["2012","2012"]]

As this string is just the result of the expression, we can also again substitute it with that – not a problem thanks to Haskell's lazyness

64 72

a=map(head.show.length.init)[[a,a,a],[a],[a,a],[a,a,a]]
main=putStrLn a

The init acts as "minus one, but non-negative" here.


We can also include the type system in the redundancy scheme and then write the number in a way that could be modified with one-character changes...

u :: Enum a => (a,[b])->(a,b)
u(a,[b]) = (succ a , b)
p :: (a,b)->(a,[b])
p(a,b) = (a,[b])

ι :: (Int,())           -- Integral type to make sure you can't make it 0/0
ι = (\n -> (n-n,()))0

twothousandandtwelve = map(head.show.fst) [ u.p.u.p$ι , ι , u.p$ι , u.p.u.p$ι ]

(GHCi> twothousandandtwelve ≡> "2012")

You could now change any one u to p vice versa, but that would always mess up the deepness of list stackings in the second tuple element and thereby trigger a compile-time error.

This idea could be expanded further in such a way that whole texts could be encoded compactly, easy to read and edit, and still safe from modifing single characters.


And yet another one...

main = print N2012
data Counter = Τv |Πy |Υj |Cε |Ho |Φϑ |Ωm |Sg |Πl |Pt |Yϑ |Γσ |Km |Φz |Εα |Av |Ζρ |Ηρ |Εv |Κs |Rζ |Γϑ |Οc |Dι |Rυ |Λd |Bγ |Wt |Xε |Ωη |Ιa |Hζ |Ed |Qj |Wπ |Κw |Qu |Γο |Oι |Mσ |Ωκ |Yg |Kυ |Aj |Du |Λζ |Nζ |Θτ |Pε |Yf |Βa |Τγ |Qx |Jη |Pδ |Iq |Ωn |Fv |Kl |Ψη |Δj |Θσ |Hd |Θq |Υs |Ht |Fρ |Jh |Lζ |Hμ |Υι |Ρζ |Ρv |Dυ |Wo |Iχ |Iζ |Γy |Kr |Sσ |Iμ |Μο |Xw |Εμ |Cσ |Yξ |Aq |Jf |Hσ |Oq |Hq |Nυ |Lo |Jκ |Ρz |Οk |Θi |Θα |Αη |Gh |Lξ |Jm |Ων |Zu |Μc |Qη |Κγ |Αψ |Χζ |Hρ |Γρ |Uϑ |Rj |Χγ |Rw |Mω |Πζ |Θρ |Ωd |Υh |Nt |Tη |Qψ |Θω |Εχ |Iw |Σx |Ηn |Mτ |Xt |Yx |Φε |Hh |Wη |Mf |Ψχ |Νγ |Βξ |Aϑ |Qp |Τϑ |Φm |Uy |Gy |Cd |Bχ |Λl |Οτ |Εa |Df |Li |Aι |Yi |Νκ |Vc |Γx |Φρ |Φp |Nξ |Kf |Tw |Λξ |Φn |Λa |Oψ |Υχ |Fψ |Xω |Τq |Οσ |Σj |Θψ |Το |Νr |Ιπ |Τi |Dτ |Φf |Μn |Χm |Ηε |Wa |Αχ |Uδ |Λf |Ρu |Qk |Wα |Uρ |Τζ |Lg |Qy |Τν |Jϑ |Βδ |Mε |Μι |Πβ |Bη |Eκ |Κz |Ηh |Fδ |Σp |Εγ |Qφ |Μτ |Νχ |Ψν |Pw |Χz |Εϑ |We |Nπ |Tυ |Wg |Bh |Tρ |Ζν |Λm |Ag |Dσ |Πι
                |Oη |Nν |Χl |Χp |Sξ |Πt |Οϑ |Wο |Yη |Cp |Tm |Ξs |Εβ |Ιb |Ρρ |Fs |Um |Ep |Jλ |Rρ |Ρξ |Ua |Οq |Γξ |Zη |Nη |Qτ |Nc |Ez |Xσ |Yφ |Ρy |Yε |Ετ |Φκ |Λω |Ωα |Μκ |Φw |Mt |Tk |Sf |Ηξ |Οb |Νπ |Κε |Mι |Kz |Vi |Ξx |Ψs |Αο |Qδ |Kt |Aσ |Οm |Ψδ |Λγ |Ακ |Hα |Wϑ |Τμ |Γγ |Jδ |Ικ |Ηϑ |Μp |Zo |Κn |Qz |Δe |Pe |Jο |Qι |Tu |Jν |Ξμ |Πω |Αm |Θw |Nε |Dy |Zξ |Υα |Dβ |Hο |Χv |Gr |Ωl |Jb |Σl |Vζ |Ξ  |Nx |Qs |Βh |Qg |Νx |Co |Rσ |Νυ |Χg |Ρt |Wy |Ηκ |Οa |Yμ |Uj |Uξ |Op |Μr |Ζα |Ξw |Mυ |Ar |Ργ |Zζ |Sv |Vy |Βo |Κι |Vϑ |Ξι |Uζ |Fμ |Su |Ιξ |Fϑ |Hi |Hw |Mv |Χχ |Θg |Sν |Pp |Mπ |Pk |Bκ |Lυ |Ρλ |Ιr |Uλ |Νo |Κο |Nh |Lε |Sw |Ξλ |Zυ |Mr |Bv |Κπ |Aγ |Dv |Pd |Ξσ |Μg |Oπ |Χξ |Nj |Kψ |Ξπ |Mκ |Gn |Ωe |Gγ |Pν |Yz |Nl |Οο |Ic |Pz |Ξf |Νω |Υμ |Ηq |Nw |Θm |Μx |Jε |Φy |Οz |Ξz |Ti |Οψ |Φγ |Tψ |Oγ |Zϑ |Ιk |Σw |Rf |Υi |Ωp |Vr |Υτ |Xl |Οβ |Πb |Δν |Οu |Jα |Ττ |Κl |Pf |Iκ |Gk |Πe |Σu |Δβ |Ωh |Nλ |Ξt |My |Πs |Βr |Mγ |Δω |Le |Zρ |Θv |Σs |Ηd |
               Bn |Κu |Δξ |Pτ |Ηα |Δu |Πμ |Ρh |Bω |Τλ |Gt |Αρ |Sh |Aο |Θδ |Δπ |Wq |Tφ |Γo |Γf |Λβ |Xυ |Mη |Δw |Qυ |Vν |Βτ |Γα |Μm |Μπ |Κζ |Θd |Fε |Ρτ |Οn |Αs |Wu |Ξh |Μz |Αν |Aε |Yq |Τε |Cz |Ωu |Ec |Ds |Wρ |Θϑ |Κp |Τδ |Mδ |Ηy |Go |Sb |Rξ |Σϑ |Yο |Jg |Vh |Kσ |Nδ |Ηψ |Γh |Rk |Eο |Μk |Ζk |Ψο |Ψμ |Zσ |Pβ |Ρd |Us |Hυ |Βi |Mχ |Σr |Βι |Sχ |Zγ |Δα |Sτ |Γp |Ns |Sn |Νn |Pξ |Νa |Sω |Σi |Τφ |Xο |Eδ |Ba |To |Vj |Sl |Κκ |Δh |Τχ |Gυ |Ρϑ |Bs |Dh |Μσ |Vd |Iϑ |Kg |Νμ |Dμ |Σγ |Πg |Γg |Εt |Fa |Ψn |Ρx |Αj |Mβ |Kλ |Ξψ |Fω |Qζ |Θj |Kπ |Gf |Oe |Yυ |Κk |Wω |Bδ |Lο |Cβ |Nf |Ol |Σo |Fn |Τβ |Βω |Dn |Ha |Πλ |Ss |Σy |Kϑ |Lp |Dδ |Dψ |Ωo |Xγ |Χk |Ωσ |Δa |Sκ |Jμ |Κt |Rc |Ηc |Lχ |Oε |Μλ |Cs |Il |Tι |Ra |Zα |Ωr |Ob |Wβ |Ον |Γν |St |Xλ |Kv |No |Rε |Kd |Mν |Np |Ωc |Δζ |Nβ |Zπ |Ok |Vι |Tδ |Vδ |Γz |Χα |Μs |Βυ |Xc |Xo |Vp |Γχ |Υf |Θπ |Πj |Pi |Γj |By |Φk |Υq |Ny |Rο |Γd |Ωj |Αy |Εo |Κy |Uc |Rm |Ph |Αδ |Ιl |Ιx |Δτ |Zt |Nq |Ct |Φi |Uv |Eπ
                |Κm |Rλ |Vu |Χσ |Τn |Μe |Φη |Ξβ |Εz |Σω |Bb |Ψε |Sε |Ρm |Δο |Vξ |Φo |Ωε |Zb |Σc |Dζ |Ξp |Rη |Ιψ |Δσ |Χη |Kj |Eμ |Qν |Ri |Ip |La |Νξ |Αγ |As |Nr |Δi |Oν |Ζx |Xκ |Pr |Ελ |Λb |Ψk |Ωβ |Pl |Ιy |Cμ |Ζc |Αg |Σρ |Dw |Ρq |Ιη |Pζ |Σa |Uq |Ρμ |Lω |Fh |Ζδ |Αd |Cψ |Κσ |It |Qκ |Fν |Αb |Ηg |Ιν |Ls |Jr |Ow |Je |Zx |Ld |Jl |Ζd |Μo |Χτ |Kα |Μβ |Mo |Σλ |Xρ |Μq |Ψb |Νd |Ρβ |Wδ |Μf |Κρ |Ηb |Ξτ |Qα |Λv |Zψ |Φt |Sδ |Εh |Rκ |Rμ |Χι |Κυ |Ηj |Pχ |Pη |Jσ |Ρσ |Ιχ |Kζ |Εδ |Nω |Iψ |Γμ |Vσ |Ψρ |Χυ |Αw |Kn |Al |Gj |Zj |Αc |Aζ |Ζi |Bz |Vπ |Πw |Αu |Qf |Bf |Ξo |Ρε |Λy |En |Ey |Wi |Σχ |Τc |Dχ |Fg |Ρo |Zm |Ψω |Fq |Μa |Ηt |Wc |Kε |Κτ |Χψ |Κβ |Λφ |Κq |Υm |Πx |Pj |Mi |Δy |Κχ |Lϑ |Wτ |Lη |Nd |Ωk |Iπ |Tα |Bο |Uε |Lc |Rp |Θx |Ρη |Lu |Μζ |Εd |Gρ |Χμ |Vγ |Ιζ |Πυ |El |Uk |Hc |Ξξ |Λx |Ιο |Μy |Ζm |Jw |Iε |Σφ |Αk |Σf |Ac |Ab |Αq |Δf |Θκ |Υa |Ζτ |Jc |Xμ |Sι |Κv |Ζj |Ει |Oω |Ηδ |Φv |Dα |Fτ |Ko |Et |Ψζ |Jx |Mk |Th |Βλ |Λχ |Οo |Υπ |
               Cζ |Θy |Λk |Γδ |Iυ |Σξ |Υϑ |Cι |Cχ |Εσ |Βψ |Iα |Τη |Eυ |Lφ |Lδ |Υw |Ξο |Uσ |Δb |Nϑ |Ζγ |Δz |Cο |Mb |Ξy |Γυ |Εk |Αζ |Vα |Τυ |Ιω |Wυ |Cτ |Ιγ |Yω |Ωy |Ηp |Ψψ |Ah |Dq |Βv |Ιw |Ox |Ξv |Οζ |Tχ |Πψ |Qb |Rδ |Aψ |Zμ |Ζg |Ψφ |Nφ |Δρ |Χe |Vχ |Ηυ |Ml |Σσ |Ζμ |Sz |Πκ |Sγ |Kq |Dη |Υk |Dt |Ξe |Sc |Νs |Μv |Ev |Ji |Rχ |Xπ |Αo |Lμ |Gδ |Fσ |Λϑ |Λe |Σb |Id |Hb |Γι |Βz |Sβ |Tg |Ζο |Δk |Dl |Λσ |Κϑ |Aw |Uγ |Lx |Uψ |Hs |Ωχ |Δφ |Wσ |Π  |Εe |Ro |Λο |Ud |Fχ |Δψ |Νh |Θμ |Zd |Kb |Οδ |Ex |Να |Φσ |Φω |Pm |Λυ |Xq |Si |Σδ |Gα |Bu |Βw |Eχ |Ρι |Gβ |Vο |Yh |Σε |Χq |Hι |Re |Zχ |Ζp |Eρ |Ωγ |Bξ |Hδ |Oξ |Γc |Μγ |Wφ |Πη |Wj |Ιq |Γs |Πο |Κj |Un |Rι |Dφ |Τl |Ωz |Pμ |Wr |Gω |Gi |Εu |Σq |Ρl |Iν |Zy |Rb |Νk |Ky |Uκ |Ησ |Hy |Ir |Tp |Εc |Bw |Εο |Cm |Εw |Ψf |Yχ |Ιρ |Hβ |Ιz |Vλ |Εj |Oδ |Qρ |Θν |Aρ |Ov |Zω |Gψ |Ij |Ξη |Ps |Φh |Οg |Dp |Ta |Ty |Οe |Uο |Rγ |Οr |Θp |Hλ |Νι |Vk |Νz |Tl |Ψi |Λs |Hη |Ζκ |Rz |Hx |Fξ |Ξn |Φe |Sπ |Ηw |Dκ |Ζω
                |Sr |Vψ |Ντ |Vω |Lv |Νg |Fκ |Jψ |Ζs |Oβ |Υζ |Δg |Fυ |Yκ |Χd |Zf |Φμ |Lt |Ξd |Oφ |Τp |Κh |Ψx |Vυ |Qπ |Θφ |Nψ |Ρχ |Rx |Υz |Ξκ |Ξχ |Qn |Pu |Υψ |Az |Xj |Σd |Φξ |Ws |Xα |Βm |Βf |Lh |Hv |Aω |Hν |Kχ |Ρψ |Aδ |Χx |Sη |Φx |Cκ |Jz |Dr |Xu |Ηζ |Ξζ |Gτ |Ca |Af |Aν |Bι |Mc |Ψg |Ωv |Ωs |Qω |Mψ |Lλ |Μα |Kμ |Vl |Yσ |Οι |Ve |Dν |Eg |Ιυ |Xι |Zν |Xϑ |Νζ |Ni |Sφ |Se |Ζa |Xδ |Νv |Wι |Jv |Jt |Ιh |Υv |Cη |Τd |Ψι |Τu |Ge |Πc |Bυ |Mϑ |Χλ |Δλ |Σψ |Μϑ |Απ |Vg |Κα |Sψ |Ζz |Λδ |Aκ |Λκ |Ga |Κb |Db |Jo |Τa |Fw |Τs |Βϑ |Eτ |Wk |Ξu |Ψl |Αι |Νψ |Δι |Qμ |Υn |Bτ |Ηs |Yw |Ye |Iο |Dο |Γe |Rβ |Qv |Xs |Ηη |Yo |Χj |Dω |Οπ |Uβ |Mλ |Qh |Fο |Βd |Ζr |Οv |Zφ |Αi |Dλ |Pb |Οx |Rv |Uz |Εν |Ψτ |Na |Aη |Βu |Ιd |Ηm |Υd |Wn |Qσ |Οp |Αr |Ηλ |Σι |Br |Cu |Ωζ |Θγ |Qo |Bρ |Bψ |Zβ |Πφ |Ρκ |Qϑ |Bj |Vε |Zz |Ζϑ |Za |Θt |Τψ |Ρο |Jq |Πf |Jφ |Τα |Xχ |Χn |Vo |Αt |Bg |Gs |Bi |Rϑ |Nι |Ρa |Υr |Υν |Λo |Γφ |Δo |Yρ |Χc |Ξα |Gq |Γm |Ωμ |Ζυ |Wζ |At |Mw |
               Cf |Επ |Fo |Οh |Tσ |Ηv |Sα |Ζq |Dk |Jπ |Ιm |Mj |Oi |Ψa |Qγ |Rn |Dξ |De |Γk |Ψm |Lα |Cl |Θο |Γq |Λc |Tx |Nm |Ki |Υο |Χr |Φs |Κi |Φλ |Vq |Αω |Ch |Tμ |Xb |Ζπ |Ym |Ζn |Eω |Ξj |Υκ |Τg |Uo |Ai |Sy |Τe |Ητ |Tτ |Λg |Bp |Δq |Χo |Pπ |Dγ |Δγ |Yπ |Ys |Ωδ |Ψσ |Sζ |Πξ |Rφ |Hj |Uf |Td |Ξk |Xψ |Οj |Cx |Φπ |Gλ |Φδ |Ej |Yψ |Ae |Φφ |Jγ |Qχ |Ξγ |Δp |Σg |Is |Eσ |Λπ |Cδ |Ιe |Cυ |Oh |Hm |Tb |Qi |Οl |Bε |Eψ |Hn |Ja |Σν |Γr |Ηu |Ζξ |Ζb |Nu |Θξ |Κd |Qο |Lq |Λw |Ηf |Kξ |Ευ |Rr |Τm |Εξ |Ψp |Χh |Ξi |Fπ |Μφ |Fu |Cξ |Aα |Pγ |Sk |Cω |Ηr |Αp |Ββ |Bx |Fp |Tζ |Pω |Λp |Lm |Jp |Bl |Φc |Vf |Τz |Εy |Λμ |Rd |Νf |Πρ |Ηx |Μψ |Γη |Bα |Συ |Iσ |Γt |Κξ |Io |Ζφ |Γl |Θf |Γλ |Υγ |Ψh |Xg |Tn |Iu |Bφ |Πχ |Λq |Χπ |Bϑ |Εm |Κφ |Λt |Ιu |Ρs |Ιβ |Ωg |Yν |Lσ |Ζι |Eι |Aτ |Φa |Pα |Θz |Ψκ |Θs |Θη |Ηl |Φζ |Bt |Ρυ |On |Ξε |Tf |Gp |Mα |Μi |Kβ |Σο |Ωξ |Νl |Iz |Fk |Dj |Bπ |Nz |Xr |Mp |Χω |Sϑ |Hu |Αμ |Js |Βn |If |Τw |Ηz |Σz |Po |Yj |Ημ |Yβ |Σm |Do
                |Ηχ |Κg |Θo |Ζh |Ψj |Ψu |Ωφ |Δμ |Γa |Bν |Ιε |Oz |Νq |Υp |Qλ |Υc |Υy |Kc |Kh |Ew |Wγ |Νβ |Ωλ |Οξ |Zι |Yr |Sυ |Γπ |Bm |Μj |Pa |Os |Χδ |Κδ |Εx |Iγ |Eη |Fλ |Tγ |Yλ |Hξ |Φq |Τξ |Ql |Δn |Zn |Ot |Sa |Φψ |Nμ |Ξr |Ξc |Φj |Gl |Oλ |Rπ |Am |Mο |Gx |Fd |Cg |Χu |Lι |Wv |Ζt |Jυ |Pσ |Σκ |Wκ |Pv |Ιg |Ωι |Δx |Φl |Eb |Δυ |Cr |Nχ |Ογ |Νφ |Gu |Ασ |Λi |Rτ |Eh |Xη |Md |Wm |Tt |Πα |Υe |Βk |Ju |Dρ |Χβ |Οs |Γi |Kι |Κe |Mm |Χf |Oκ |Vb |Γβ |Οy |Vv |Νϑ |Hl |Λα |Wξ |Om |Βφ |Ρp |Φβ |Βb |Αυ |Υδ |Χφ |Pλ |Νρ |Υλ |Ul |Kγ |Qc |Νm |Πz |Hφ |Es |Ψπ |Xm |Xξ |Tν |Eλ |Ao |Ak |Ka |Ζη |Xk |Γψ |Βπ |Fβ |Βρ |Xx |Βζ |Iτ |Pϑ |Εb |Ψγ |Τk |Gm |Yn |Xν |Νu |Hϑ |Εr |Τπ |Uw |Mh |Og |Μυ |Tj |Λν |Qm |Xn |Ην |Νi |Kη |Zv |Ιι |Ση |Yk |Dx |Aχ |Ou |Fy |Cα |Θl |Γκ |Ax |Vκ |Cn |Cλ |Ξϑ |Wε |Υl |Ψt |Ωa |Θe |Ξω |Ηo |Ll |Bζ |Kw |Αβ |Δc |Oυ |Βj |Jβ |Νε |Eϑ |Ξg |Tz |Cc |Ry |Sρ |Ψz |Yα |Pq |Υg |Jn |Vμ |Σk |Ck |Ωt |Zg |Pι |Hω |Λλ |Aμ |Wλ |Ιλ |Βc |Ξa |
               Jk |Πϑ |Ιt |Εψ |Hε |Ωϑ |Εη |Ie |Κω |Yc |Iβ |Ου |Hg |Θr |Nn |Uμ |Ζv |Ζχ |Jρ |Pο |Ng |Be |Δv |Fζ |Ρe |Qe |Cq |Κf |Θλ |Tϑ |Ξq |Me |Βq |Oα |Θc |Qr |Δt |Dm |Yu |Ru |Σh |Λr |Yy |Εε |Μχ |Mφ |Δδ |Kφ |Cγ |Ζσ |Iω |Au |Wb |Κc |Πq |Ωω |Pυ |Γn |Nγ |Cv |Βχ |Φg |Gο |Ug |Kο |Βκ |Wμ |Hτ |Hχ |Ue |Οw |Sμ |Sm |Υω |Yb |Χa |Ιi |Κν |Πu |Κψ |Uτ |Lβ |Fj |Pn |Εf |Τσ |Qε |Ψo |Λρ |Oϑ |Πν |Ts |Ηο |Μρ |Ff |Ψβ |Ne |Nκ |Bλ |Bσ |Mx |Πp |Υσ |Ιn |Αz |Fz |Ηa |Uν |Mζ |Δϑ |Yι |Ζe |Ψα |Tο |Βg |Lπ |Ζf |Αλ |Em |Θh |Gπ |Γω |Kω |Tξ |Σn |So |Im |Φυ |Ξb |Ii |Λι |Xz |Kδ |Μω |Uυ |Wf |Χb |Sλ |Lγ |Οη |Ιs |Xβ |Pκ |Bc |Ιp |Od |Αn |Va |Tω |Ζw |Ιτ |Θε |Ρi |Gι |Τh |Υx |Nτ |Δη |Εφ |Kx |Xa |Gν |Ft |Yt |Qd |Gσ |Ξυ |Εs |Nσ |Νc |Λj |Υu |Ρc |Ψξ |Δm |Qβ |Μu |Υb |Nk |Ωτ |Κr |Δd |Iλ |Πa |Ωρ |Χν |Μh |Jξ |Μμ |Fc |Iφ |Zr |Ux |Φb |Πo |Gd |Eζ |Αα |Νν |Λz |Vη |Pψ |Ωf |Lρ |Cb |Ν |Α |Χ |Ω |Zτ |Τκ |Αε |Bβ |Uι |Fi |Ui |Βx |Ωq |Βp |Λh |Uu |Ωw |Xp |Ζβ |Λτ
 | N2012 deriving(Enum); instance Show Counter where show = show . fromEnum

ceased to turn counterclockwis

Posted 2012-01-02T15:54:09.203

Reputation: 5 200

Couldn't you make it two characters less by using x instead of xx? – Frerich Raabe – 2014-01-03T23:37:38.727

@FrerichRaabe: sure, but it wouldn't be modification-safe anymore. – ceased to turn counterclockwis – 2014-01-04T00:06:19.497

1[a] -> [] in the 64-char solution – John Dvorak – 2014-09-14T16:28:22.560

on this solution (\l@(_:_:t:[])->t:l)['0'..'2'] if you would change @ to a space the solution would be still be syntactically valid (and in fact will have a type of Num a=>[a]->[a]) but would not be a string of "2012". – proud haskeller – 2014-09-14T19:42:55.407

1this also disqualifies your first solution :( although note this doesn't change the full program solutions as there is no Function Show instance :) – proud haskeller – 2014-09-14T19:45:03.110

on the 72 solution you could also write a=[[a,a,a],[a],[a,a],[a,a,a]]>>=show.length.init which is shorter - but i'm not sure if it's unmodifiable... – proud haskeller – 2014-09-14T19:49:52.107

1I'm afraid this compiles just fine modified, although an exception is thrown at runtime. – Jeff Burdges – 2012-01-03T19:13:09.550

3@JeffBurdges: sure, I take this to be included in "and will not cause it to crash". – ceased to turn counterclockwis – 2012-01-03T21:30:56.870

1For the a=map(head.show.length)[[a,a],[],[a],[a,a]] solution, insert a between []. I really like this post, though! Very clever solutions. – Dillon Cower – 2012-01-04T00:15:39.000

9

I've verified that all 5825 variations of your 29-character program (replacing or inserting ASCII characters 32-126) work as expected. Here's the test script I used. It can easily be tweaked to test other programs, including other languages. Warning: It took almost 1 hour to run on my laptop :)

– hammar – 2012-01-04T00:30:12.327

14

JavaScript

I believe this is runtime error proof, any single change should either result in a compile error or a single alert saying 2012.

Edit: Code would make a runtime error on something like if("alert(2012 "==r), I moved the try section to deal with it.

Edit: Nice one Vilx-, but fixable :-) Now there is a bracket mismatch for inserting that semicolon.

Edit: But then a comma could do the same thing as the semicolon, that is a host of options, I think I have fixed it, but there is an awful lot of code now.

Edit: Simplified a bit.

Edit: One more in an infinite series of bugfixes.

Edit: This kinda feels more long and complicated than bulletproof, but it should at least take care of ~eval and !eval.

var q="alert(2012 "
var p=1
try{
    if("alert(2012 "==q){
        if(eval(((p=5,q+")")||alert(2012)))){
            if(p!==5){
                alert(2012)
            }
        }
    }
    else{
        alert(2012)
    }
}
catch(e){
    alert(2012)
}

aaaaaaaaaaaa

Posted 2012-01-02T15:54:09.203

Reputation: 4 365

2Adding a ! after eval( breaks it. – jimmy23013 – 2015-02-28T01:00:55.887

1Adding a semicolon after else also alerts "2012" twice :P – Doorknob – 2013-06-23T00:47:16.340

Wow that's impressive. I spent a few minutes trying to break it but I couldn't, congratulations, but why the ||alert(2012)? – None – 2012-01-03T04:07:04.340

1Because for instance q-")" returns NaN, which eval convert to "NaN" before evaling it, which simply turns it back to NaN. Strange thing to do, but technically legit, so that doesn't invoke the catch. – aaaaaaaaaaaa – 2012-01-03T08:23:23.533

4Same thing as the C solution - insert a ; between eval and (. – Vilx- – 2012-01-03T11:00:59.293

1For the comment readers, the semicolon vulnerability is fixed, I believe the code to be clean now. – aaaaaaaaaaaa – 2012-01-03T23:38:51.107

4Not sure if this counts or not, but putting a ~ in front of the eval causes it to echo 2012 twice instead of once. Not sure if that disobeys the rules or not :P – mellamokb – 2012-01-11T00:34:50.373

13

Perl, 49 chars

  do{
use strict;$_=2012;;2012==$_&&0-print||die}

Based on J B's answer, but this one actually satisfies the spec. An exhaustive check indicates that every one-character deletion, insertion or replacement either leaves the output unchanged or causes the program to crash when run (as indicated by a non-zero return value and output to stderr), at least as long as insertions and replacements are restricted to printable ASCII characters.

(Without the restriction, the task is impossible in Perl: a little-known feature of the Perl parser is that it stops when it encounters a Ctrl-D or a Ctrl-Z character, so inserting either of those in front of any file turns it into a valid Perl program that does nothing.)

Edit: Shaved off one more char by replacing 1==print with 0-print.

Ilmari Karonen

Posted 2012-01-02T15:54:09.203

Reputation: 19 513

Breaks with Perl 5.28 where print starts returning 'true' instead of 1 :-P – J B – 2012-01-03T21:39:35.140

3

@JB: Well, you can downvote it when that happens. :) (For the benefit of other readers, this is a joke. As far as I know, there are no plans to change the return value of print in any version of Perl 5, even if it isn't explicitly documented.)

– Ilmari Karonen – 2012-01-03T21:47:49.077

13

Brainfuck

I am trying to convince myself that this is possible, and I am fairly certain I may have stretched it a bit too far. I have made a few assumptions about my environment:

  1. An infinite loop is considered a 'crash'. A similar condition could possibly be achieved by decrementing past zero or to the left of memory location zero in certain interpreters. Many interpreters are difficult to crash at runtime. I avoid the halting problem by using only the simplest, most obvious infinite loop.
  2. Unmatched square braces are considered a compile error.
  3. This will only work in an environment where the program's output is piped back to it's own input. I use that to verify that it did indeed output '2012'. This is the only way I could get around simply deleting one of the output characters.

Unfortunately, if you get any stricter I fear this will be impossible. Here is my solution:

++++++++++++++++++++++++++++++++++++++++++++++++++
.--.+.+.
,--------------------------------------------------[]
,------------------------------------------------[]
,-------------------------------------------------[]
,--------------------------------------------------[]
,[]EOF = 0

Basically, you can change the output code, or the verification code, but not both. One of them is guaranteed to work. If one of them doesn't it will 'crash'.

captncraig

Posted 2012-01-02T15:54:09.203

Reputation: 4 373

5Ugh, brainfuck! You just HAD to, didn't you? XD – Vilx- – 2012-03-20T16:15:57.877

8would you have preferred he used whitespace instead? – NRGdallas – 2012-09-28T22:16:41.953

7

Python2

import sys;xx='2012';(
1/(sys.stdout.write(xx=='2012' and xx or 2012)==None))

I had to change Ray's test script slightly to test this as the stdout redirect was breaking it. Passing empty dicts to exec avoids polluting the namespace

exec(prog, {}, {})

gnibbler

Posted 2012-01-02T15:54:09.203

Reputation: 14 170

Great! You make it! – Ray – 2013-02-06T06:49:01.760

6

Brain-Flak, 44 + 3 = 47 bytes [Non-Competing]

This uses Brain-Flak's -A flag and outputs the characters 2012 to STDOUT

((((((((()()()){}){}){}()){})[()])[()])()())

Try it online!

Alternative, 50 bytes

(((((()()()()){}){}){}){})({({}[()])}{}[()()()()])

Try it online!

Explanation

Any single character modification to either of the codes above will cause the program to error.

Post Rock Garf Hunter

Posted 2012-01-02T15:54:09.203

Reputation: 55 382

3Ha! The right language for the challenge. – DLosc – 2017-01-23T04:37:59.450

4

Sisi, non-competing

Finally I think I found one of my languages that works. It's horrendously long, and the language is newer than the question, but it still feels like an accomplishment.

1 set xx 2012
2 set y xx=2012
3 jumpif y 55
4 set xx 2012
828 set x xx
829 set ax xx
830 set xa xx
831 set axx xx
832 set xax xx
833 set xxa xx
834 set bx xx
835 set xb xx
836 set bxx xx
837 set xbx xx
838 set xxb xx
839 set cx xx
840 set xc xx
841 set cxx xx
842 set xcx xx
843 set xxc xx
844 set dx xx
845 set xd xx
846 set dxx xx
847 set xdx xx
848 set xxd xx
849 set ex xx
850 set xe xx
851 set exx xx
852 set xex xx
853 set xxe xx
854 set fx xx
855 set xf xx
856 set fxx xx
857 set xfx xx
858 set xxf xx
859 set gx xx
860 set xg xx
861 set gxx xx
862 set xgx xx
863 set xxg xx
864 set hx xx
865 set xh xx
866 set hxx xx
867 set xhx xx
868 set xxh xx
869 set ix xx
870 set xi xx
871 set ixx xx
872 set xix xx
873 set xxi xx
874 set jx xx
875 set xj xx
876 set jxx xx
877 set xjx xx
878 set xxj xx
879 set kx xx
880 set xk xx
881 set kxx xx
882 set xkx xx
883 set xxk xx
884 set lx xx
885 set xl xx
886 set lxx xx
887 set xlx xx
888 set xxl xx
889 set mx xx
890 set xm xx
891 set mxx xx
892 set xmx xx
893 set xxm xx
894 set nx xx
895 set xn xx
896 set nxx xx
897 set xnx xx
898 set xxn xx
899 set ox xx
900 set xo xx
901 set oxx xx
902 set xox xx
903 set xxo xx
904 set px xx
905 set xp xx
906 set pxx xx
907 set xpx xx
908 set xxp xx
909 set qx xx
910 set xq xx
911 set qxx xx
912 set xqx xx
913 set xxq xx
914 set rx xx
915 set xr xx
916 set rxx xx
917 set xrx xx
918 set xxr xx
919 set sx xx
920 set xs xx
921 set sxx xx
922 set xsx xx
923 set xxs xx
924 set tx xx
925 set xt xx
926 set txx xx
927 set xtx xx
928 set xxt xx
929 set ux xx
930 set xu xx
931 set uxx xx
932 set xux xx
933 set xxu xx
934 set vx xx
935 set xv xx
936 set vxx xx
937 set xvx xx
938 set xxv xx
939 set wx xx
940 set xw xx
941 set wxx xx
942 set xwx xx
943 set xxw xx
944 set yx xx
945 set xy xx
946 set yxx xx
947 set xyx xx
948 set xxy xx
949 set zx xx
950 set xz xx
951 set zxx xx
952 set xzx xx
953 set xxz xx
954 set xxx xx
955 print xx

About Sisi

Sisi is a toy language inspired by assembly and QBasic. It is good for this challenge because its syntax is extremely limited.

  • It has only four commands: set, print, jump, and jumpif.
  • All commands have fixed arity.
  • All lines must have line numbers, which are strictly increasing.
  • Expressions are only allowed in set statements. They can only contain (at most) one operation, which must be binary. In particular: changing print xx to print -xx is a syntax error.
  • Variable names must be composed of lowercase letters.
  • Most importantly: there is no comment syntax!

The program

The core of the program is this part:

1 set xx 2012
2 set y xx=2012
3 jumpif y 55
4 set xx 2012
955 print xx

We store 2012 in xx, then test whether that was successful and store the test result in y. If y is truthy, jump to line 55. (Jumps to nonexistent line numbers simply fast-forward to the next line.)

Radiation hardening

  • If the assignment in line 1 is modified, then y is falsey, the jump doesn't happen, and line 4 sets xx to 2012.
  • If the assignment in line 2 or the jump condition in line 3 is modified, we don't care: xx will get set to 2012 whether we take the jump or not.
  • The jump target in line 3 can be changed to as small as 5 or as large as 955. Any possible modification gets it to the print on line 955 sooner or later. It isn't possible with one modification to jump backwards (creating a loop) or past the end of the program.
  • If the assignment in line 4 is modified, we don't care: line 1's assignment will be correct and we will jump past line 4.
  • If line 955 is modified, we may have a problem. The one unfortunate thing about Sisi is that uninitialized variables default to 0, so a modification like print ax isn't an error. The ugly but effective solution is lines 828-954, which assign 2012 to every possible variable with an edit distance of 1 from xx. This ensures that any modification to the final print xx will still print 2012.
  • If a line number is modified, either: 1) it will be out of order and be a syntax error, or 2) it won't affect the program flow. The main modification we might be worried about--changing line 4 to 94, thereby inserting it after the jump to 55--doesn't matter because all it does is assign 2012 to xx again.

DLosc

Posted 2012-01-02T15:54:09.203

Reputation: 21 213

Good one! I can't think of a way to circumvent this. "A" for effort from me, that's for sure! :) – Vilx- – 2017-01-23T10:08:07.723

3

Python

A little verbose (now with a fix for that pesky semicolon between print and (!):

a=[0]
(lambda x:print(
set(['2012']).intersection(set(["2012"])).pop()))(
*a)

Dillon Cower

Posted 2012-01-02T15:54:09.203

Reputation: 2 192

1inserting a comma after pop outputs <built-in method pop of set object at 0xb6fe93ac> () – gnibbler – 2013-02-04T23:23:53.760

@Jeff Burdges: Yeah, with this one I'm banking on runtime errors being disallowed as well. :) – Dillon Cower – 2012-01-03T07:05:58.430

I'm afraid it's still syntactically correct if the intersection yields the empty set and pop throws a runtime error. Add more 2012s on both sides. – Jeff Burdges – 2012-01-03T07:10:01.983

@DC: I would say that an exception is not the same as a runtime error, although it seems exceptions are called errors in Python. pop()ing the empty set isn't an error in and of itself, but it does raise an 'Error'. – Williham Totland – 2012-01-03T09:37:30.353

The task specifies that the change will not cause the program to crash, which makes this solution valid - in my understanding, a runtime error that stops program execution is practically the definition of a crash. Therefore, +1 for the nice trick. – cemper93 – 2012-01-03T22:14:18.630

1An exception becomes an error when it's not caught. – Ilmari Karonen – 2012-01-07T00:27:44.983

3

Mathematica, 23 chars

Note: "/." means "replace"

2012/.Except@2012->2012

Dr. belisarius

Posted 2012-01-02T15:54:09.203

Reputation: 5 345

@DillonCower Good catch! – Dr. belisarius – 2013-03-08T12:53:08.353

2This might be kind of a weak answer/defeat, but change /. to // (postfix form). – Dillon Cower – 2012-01-08T19:31:26.670

3

T-SQL 2012, 55

DECLARE @n CHAR(4)='2012'PRINT IIF(@n='2012',@n,'2012')

mizer

Posted 2012-01-02T15:54:09.203

Reputation: 311

What SQL dialect is this? Looks like Transact-SQL (aka SQL Server), but it has invalid syntax for that. – Vilx- – 2012-05-03T10:22:17.283

@Vilx-: I tested it in SQL Server 2008 myself when I was trying to break it, and it worked just fine. – mellamokb – 2012-05-04T14:23:46.657

@mellamokb - That's odd. It's exactly what I did, and it complained that you cannot assign a default value to variable (you need a separate SET statement), and there is no IIF (only CASE). – Vilx- – 2012-05-04T18:15:08.300

1

@Vilx-: Ah, you are correct. I realize now I was actually testing on SQL Azure. With SQL Server 2008 I get those same errors as you. However, it seems to work fine in SQL Server 2012/Azure. Here's a demo with SQL 2012: http://www.sqlfiddle.com/#%216/d41d8/27

– mellamokb – 2012-05-07T14:10:32.477

OK, congratulations, I can't find any obvious ways of breaking this! :) That's not to say there aren't any. ;) – Vilx- – 2012-05-07T15:12:05.890

Note: linked fiddle now gives an error, possibly because SQLfiddle is using SQL Server 2014 and doesn't offer 2012 anymore. – DLosc – 2017-01-23T04:20:20.373

3

I've make a python script to judge all the python solutions. The script breaks the first and the third python solutions, with many different methods. And the second solution use lambda to guard itself, is unbreakable. The second python solution is in python 3. I modified it into python 2 format and then judge program broke it.

Here is the judge script.

from StringIO import StringIO
import sys

def run(prog, atexp=True):
    stdout = sys.stdout
    fakeOut = StringIO()
    try:
        sys.stdout = fakeOut
        # exec prog # running exec directly will break some solutions by mistake
        exec(prog, {}, {}) 
        return fakeOut.getvalue().rstrip() == '2012'
    except:
        return atexp
    finally:
        sys.stdout = stdout
    return True

def judge(prog):
    RED = '\x1b[31m'
    WHITE = '\x1b[37m'
    ans = True
    chars = """abcdefghijklmnopqABCDEFGHIJKLMNOP`~1234567890!@#$%^&*()_+-=[]{};:'"<>,./?"""
    # attack by replace
    if not run(prog):
        print "Are you joking...This program don't print 2012 itself."
        return False
    p = list(prog)
    for i in xrange(len(prog)):
        for c in chars:
            p[i] = c
            r = run(''.join(p))
            if not r:
                print 'Attack by replace success'
                print 'origin:\n'+prog
                print 'modified:\n'+''.join(p[:i])+RED+c+WHITE+''.join(p[i+1:])
                ans = False
        p[i] = prog[i]
    # attack by delete
    for i in xrange(len(prog)):
        p = prog[:i]+prog[i+1:]
        r = run(''.join(p))
        if not r:
            print 'Attack by delete success'
            print 'origin:\n'+prog
            print 'modified:\n'+''.join(p[:i])+RED+'{|}'+WHITE+''.join(p[i:])
            ans = False
    # attack by insert
    for i in xrange(len(prog)+1):
        p = list(prog)
        p.insert(i, ' ')
        for c in chars:
            p[i] = c
            r = run(''.join(p))
            if not r:
                print 'Attack by insert success'
                print 'origin:\n'+prog
                print 'modified:\n'+''.join(p[:i])+RED+c+WHITE+''.join(p[i+1:])
                ans = False
    if ans: 
        print 'Amazing! judgement passed'
    return ans

p1="""xx='2012'
print(xx if xx=='2012' else
'2012')
"""
p2="""import sys
a=[0]
(lambda x:sys.stdout.write(
set(['2012']).intersection(set(["2012"])).pop()))(
*a)
"""

p3="""print sorted(['2012',
'2012','2012']).__getitem__(1)
"""
p4="""print 2012
"""
judge(p3) 

Ray

Posted 2012-01-02T15:54:09.203

Reputation: 1 946

cool! my answer sucks and blows at the same time – gnibbler – 2013-02-04T22:34:41.403

p2 always throws an exception for Python2. The output is never 2012. Your judge program won't run under Python3 as it uses print statements. – gnibbler – 2013-02-04T22:51:22.883

@gnibbler I don't noticed that p2 is in python 3. – Ray – 2013-02-05T15:10:56.750

I've worked out a new answer for Python2 that passes your script

– gnibbler – 2013-02-05T23:08:43.500

2

Java 7

class M{
  static String c(){
    String a = "2012",
           b = "2012";
    return a.equals(b)           // 1
            ? a                  // 2
            : a.equals("2012")   // 3
               ? a               // 4
               : b;              // 5
  }

  public static void main(String[]a){
    System.out.print(c());
  }
}

Explanation:

  1. Without changing anything it will take the following path: 1 → 2 (and it will return a's value of 2012).
  2. If the content of String a is modified in any way it will take the following path: 1 → 3 → 5 (and it will return b's unchanged value of 2012).
  3. If the content of String b is modified in any way it will take the following path: 1 → 3 → 4 (and it will return a's unchanged value of 2012).
  4. If a.equals(b) on @1 is modified to a.equals(a), b.equals(b), or !a.equals(b) it will still take the same following path: 1 → 2 (and it will return a's unchanged value of 2012).
  5. If a on @2 is changed to b it will still take the following path: 1 → 2 (and it will return b's unchanged value of 2012).
  6. If either a or b is changed to the opposite on the lines 3, 4 or 5 it will still take the following path: 1 → 2 (and it will return a's unchanged value of 2012)
  7. If the content of the String on @3 is modified in any way it will still take the following path: 1 → 2 (and it will return a's unchanged value of 2012)
  8. Changing M in class M or a in main(String[]a) to another valid character can be done without any changes to the functionality of the code.
  9. Any other change will result in a Compile-error (excluding some of the enters/whitespaces, which can be removed/added).

Try all these modifications here, to verify they all still print 2012.

If you can find any way to break it following OP's rules I'd love to know, so I can think of something to fix it.
Unlike most similar questions where a single char is modified, this question allows the basic structure of the programming language in question to be intact, so Java can finally compete in one enter one (let's face it, Java will -almost- never win anything on this SE xD).

Kevin Cruijssen

Posted 2012-01-02T15:54:09.203

Reputation: 67 575

What is a negative sign is inserted in path 4 before the a? Will the program still output 2012, or will it output -2012? – user41805 – 2017-01-23T14:30:34.243

@KritixiLithos It's a String, so you can't insert a - before the a or b. Here is a screenshot of the Compile error.

– Kevin Cruijssen – 2017-01-23T14:34:10.330

2

Javascript - 68, 77, 84, 80 chars

Here's a solution that should work this year :)

a="eval(alert(new Date().getFullYear()))" 
a.length==37?eval(a||a||a):alert(2012)

Here's the test fiddle.

Update 1: Fixed issue where eval(+a) broke it (thanks eBusiness).

Update 2: Fixed for the '|' case (thanks again eBusiness).

Update 3: Fixed for the '>' case (thanks again eBusiness). And broke for the '1' case :(

Briguy37

Posted 2012-01-02T15:54:09.203

Reputation: 2 616

5Breaks if you change the first alert to aler=. – jimmy23013 – 2014-09-14T23:25:37.807

You didn't guard your eval. eval(+a) and a lot of other modifications run perfectly fine but doesn't do a whole lot. – aaaaaaaaaaaa – 2012-01-03T23:33:12.287

@eBusiness: Thanks for pointing out the eval(+a) case, that should now be fixed. Also, I've been unable to find one of the modification cases where it runs fine but doesn't output 2012, so will you please give me an example? – Briguy37 – 2012-01-04T15:06:09.550

eval(0) and eval(-a) for instance does the same thing. – aaaaaaaaaaaa – 2012-01-04T15:40:09.730

Post edit it can at least be broken by replacing || with |. – aaaaaaaaaaaa – 2012-01-04T15:45:59.177

@eBusiness: Thanks, that should be fixed now. The flexibility of JavaScript definitely does not help here, as I'm sure you know. Nice going with your solution, and please let me know if you see anything else :) – Briguy37 – 2012-01-04T16:09:20.460

Here is a fun one: a>')', turns out that evaluates to true :-) – aaaaaaaaaaaa – 2012-01-04T16:30:47.853

And yeah, JavaScript is the challenge mode for this puzzle. Still not as bad as GolfScript though. – aaaaaaaaaaaa – 2012-01-04T16:32:23.267

@eBusiness: That is a fun one. I fixed that but then noticed it broke another case. I have a feeling if we keep going that my answer will look suspiciously like yours, so unless I think of something unique I'll leave it as is. – Briguy37 – 2012-01-04T18:09:44.320

2

Ruby 1.9 - 43 chars

qq=[:p,2012]
b if qq!=[:p,2012]
send(
*qq)

Not tested, so break away.

histocrat

Posted 2012-01-02T15:54:09.203

Reputation: 20 600

2

Excel, 14 characters (cheating slightly):

{=2012} (in a 2x1 array with one cell hidden)

Any valid change to the array will affect the contents of both cells, and attempting to change just one cell triggers an error message.

Of course, this breaks down if you take the view that it's really only one formula, as opposed to 2 formulas that are constrained to be identical.

user3490

Posted 2012-01-02T15:54:09.203

Reputation: 809

1

PHP, 30

<?=$i=2012;$i==2012?$i:2012;?>

jsa

Posted 2012-01-02T15:54:09.203

Reputation: 11

Welcome to PPCG! Nice first post! Can you add an explanation also? – Rɪᴋᴇʀ – 2017-01-22T16:02:38.613

2And here's how I'd defeat it: <?=$i=2012;$i==2012?-$i:2012;?> – Vilx- – 2017-01-22T16:11:35.893

@Vilx- Nice, I hadn't thought about that. – jsa – 2017-01-28T15:25:39.863

A lame defeat for any one-line PHP solution: put the whole code in a comment <?#$i=2012;$i==2012?$i:2012;?> Solution against that: insert a newline after $i=2012. – Titus – 2018-03-05T00:01:45.463

1

Taxi, 396 bytes

2012 is waiting at Starchild Numerology.2012 is waiting at Starchild Numerology.Go to Starchild Numerology: w 1 r 3 l 2 l 3 l 2 r.Pickup a passenger going to Equal's Corner.Pickup a passenger going to Equal's Corner.Go to Equal's Corner: w 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery: n 3 r 1 r 1 r.Pickup a passenger going to Post Office.Go to Post Office: n 1 l 1 r.

Formatted for humans, that's:

2012 is waiting at Starchild Numerology.
2012 is waiting at Starchild Numerology.
Go to Starchild Numerology: w 1 r 3 l 2 l 3 l 2 r.
Pickup a passenger going to Equal's Corner.
Pickup a passenger going to Equal's Corner.
Go to Equal's Corner: w 1 l.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: n 3 r 1 r 1 r.
Pickup a passenger going to Post Office.
Go to Post Office: n 1 l 1 r.

From reading other answers, the solution seems to be to pick a fragile language, set the value, check the value, print the value.

Engineer Toast

Posted 2012-01-02T15:54:09.203

Reputation: 5 769

1

SmileBASIC

OPTION STRICT
VAR A$=@2012
GOTO A$@2012
IF SHIFT(A$)THEN VAR B
?A$VAR C
B=C

First, we enable strict mode. This forces you to declare all variables before using them, and prevents things like changing ?A$ to ?B$.

Next, a string variable called "A$" is created, and the value is set to "@2012". To make sure the value of A$ hasn't been messed with, the program will try to jump to a label, and the only label in the program is @2012.

Now, A$ is definitely "@2012", but before printing it, the @ needs to be removed. SHIFT() removes the first item in a string or array (just like pop(), but from the other end). To discard the value returned by SHIFT, it is passed to an IF/THEN block, which does nothing. Just in case someone tries to comment out that line, we declare a variable "B", which is used later. If the VAR is commented out, the last line will throw an Undefined variable error.

Now, A$ is printed, and there's another VAR to prevent comments. The final line just makes sure the variables B and C have both been declared.

12Me21

Posted 2012-01-02T15:54:09.203

Reputation: 6 110

OK... I don't know anything about SmileBASIC, so this is purely a guess: ?-A$VAR C - could this output -2012? – Vilx- – 2018-03-04T09:58:52.920

That won't work because A$ is a string. – 12Me21 – 2018-03-04T15:39:06.070

Wait, I have an idea! What about: ?B$VAR C? :) – Vilx- – 2018-03-04T15:58:01.057

That will trigger an error because "B$" hasn't been declared. – 12Me21 – 2018-03-04T16:12:06.187

1

C#

Surely its not this simple, is it? ...

class program
{
    static void Main()
    {
        var result = "2012";

        if (result == "2012")
            Console.WriteLine(result);
        else
            Console.WriteLine("2012");
    }
}

Ok what I miss?

War

Posted 2012-01-02T15:54:09.203

Reputation: 111

6Adding a ; after else makes it outputs two times. – jimmy23013 – 2015-02-28T02:29:38.843

1What happens if you change the 8th line to "Console.WriteLine(-result);"? – Glenn Randers-Pehrson – 2014-09-15T15:25:37.867

No C# compiler here, but shouldn't changing line 7 to if (result += "2012") make it output 20122012? – Philipp – 2014-09-15T15:26:49.733

hmmmm ... i hadn't thought of that ... back to the drawing board – War – 2014-09-15T15:28:42.393

@Philipp - Nop, that wouldn't compile. You need a boolean as a value for an if statement, not a string. – Vilx- – 2014-09-15T22:51:18.163

I think this actually works. I can't find anything. – Vilx- – 2014-09-15T22:57:14.767

Hmmm looks like you're right @Vilx I might be better at this than I thought :) – War – 2014-09-16T08:16:30.047

1

Ruby 1.9

puts (
rx=2012
)==2012?rx:2012.send(
:abs)

I build this short but simple program which you are invited to break according to above rules. I couldn't even find a position where the output is changed (without breaking the code) if a # is inserted in order to comment out the rest of the line.

Howard

Posted 2012-01-02T15:54:09.203

Reputation: 23 109

2Changing puts to putc causes this to output a ? in Ruby 1.9. – histocrat – 2012-12-12T18:39:01.120

puts ( rx=2012 )==20,12?rx:2012.send( :abs) – jimmy23013 – 2014-09-14T23:20:07.240

puts (r = 2012) == 2012 ? -r : 2012.send(:abs) prints "-2012" – Joanis – 2012-01-02T20:31:38.713

@M.Joanis But you need two additional characters: a space character and a minus. A minus alone will not work. – Howard – 2012-01-02T20:40:48.350

Ah, you're right! Compilation error. I know nothing about Ruby, I should be more careful. Sorry! – Joanis – 2012-01-02T20:47:37.750

@PeterTaylor I don't think this should count. But of course reading the sentence literally you're right. – Howard – 2012-01-02T21:07:00.413

1According to irb, adding a minus before the rx results in a valid program that outputs -2012 – Konrad Rudolph – 2012-01-04T14:14:29.647

@KonradRudolph Gives a syntax error (see also comments above) – Howard – 2012-01-04T14:44:08.607

@Howard It does not give a syntax error for me (Ruby 1.8.7). It runs just fine. And why should it give a synax error? Or does Ruby define a ?- operator anywhere? – Konrad Rudolph – 2012-01-04T15:11:22.707

@KonradRudolph With 1.9 it does. I am trying to find out what happens here. – Howard – 2012-01-04T15:14:30.227

@KonradRudolph I suppose it comes from the introduction of the new single-colon-symbol has syntax introduced with 1.9. The parser now seems to bind the colon with the rx symbol which then does not make sense any more. – Howard – 2012-01-04T15:38:00.267

On irb 0.9.5(05/04/13), )==2012?!rx:2012.send( results in false. (Btw.: 05/04/13? what's that?) – user unknown – 2012-01-06T03:50:20.760

As said before you need Ruby 1.9. I edited the answer to show this directly. Then you may not insert any char. – Howard – 2012-01-06T08:42:08.687

1

Scala, 95

(or 54 if skip non-meaningful parts)

object Main{def main(ar:Array[String]){print(((s:String)=>if(s=="2012")s else"2012")("2012"))}}

Display Name

Posted 2012-01-02T15:54:09.203

Reputation: 654

I don't know Scala, but (...),("2012") seemed to break it. – jimmy23013 – 2015-02-28T01:45:52.210

I'm afraid I don't know enough about Scala to find any flaws. :( Can other people, please, take a look? – Vilx- – 2012-09-26T09:07:52.787

It's not hard at this level. Most of Scala hardness is due to complexity of its type system (which I still cannot understand fully :D ) – Display Name – 2012-09-26T13:44:23.490

0

Lua

print(- -(function(ab,ba)assert(ab==ba)return- -ab end)(2012,2012))

mniip

Posted 2012-01-02T15:54:09.203

Reputation: 9 396

1What if you delete one of those - signs? – Vilx- – 2013-01-15T15:30:05.360

Oh, and if you change one of those 2012 to something else, the assert will raise an error. Hmm... well, I guess you deserve creativity points for abusing the rules. But seriously, that's not how it was meant. – Vilx- – 2013-01-15T15:35:15.433

0

Ruby, 40

p(([2012]+[2012]+[2012]).sort[1]||
2012)

LBg

Posted 2012-01-02T15:54:09.203

Reputation: 130

2Deleting 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. – histocrat – 2013-02-04T21:02:45.230

0

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.

spacemit

Posted 2012-01-02T15:54:09.203

Reputation: 41

0

Javascript 40

Math.abs(((yr=2012) == 2012)? yr : 2012)

Professor Allman

Posted 2012-01-02T15:54:09.203

Reputation: 261

3Foiled by putting a - at the beginning. Also, it's missing IO. – histocrat – 2013-04-22T20:43:50.823

Forgot to test the simplest case, back to the drawing board! – Professor Allman – 2013-04-22T22:21:41.673

0

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.

Johannes Kuhn

Posted 2012-01-02T15:54:09.203

Reputation: 7 122

It doesn't work for me. $a is used before definition. If that's fixed, $a, would still break it. – jimmy23013 – 2015-02-28T02:20:17.227

0

C# .NET, 83 bytes

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

Try Online

canttalkjustcode

Posted 2012-01-02T15:54:09.203

Reputation: 131

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. – Vilx- – 2019-08-20T18:30:13.527

I feel stupid now – canttalkjustcode – 2019-08-20T19:49:13.193

Aaand this version fails because I can do "2012"=="2012"?"2014":"2012". You need the var. :) – Vilx- – 2019-08-20T20:21:21.413

Well I should probably stop trying to make this shorter then xD – canttalkjustcode – 2019-08-20T21:55:32.060

0

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.

Shaun Bebbers

Posted 2012-01-02T15:54:09.203

Reputation: 1 814

0

OCaml, 66

let x="2012"
let x=if x="2012" then x else "2012";;
print_string x

icedvariables

Posted 2012-01-02T15:54:09.203

Reputation: 453

I don't know OCaml, but print_string,x seemed to break it. – jimmy23013 – 2015-02-28T02:53:46.130

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). – None – 2016-12-07T21:59:48.313

0

Haskell, 65

import Data.List
nub$filter(\x->x==2012||x==2012)([2012]++[2012])

Perl, 84

use strict;use English;$ARG=
2032;s/.*/2012/unless$ARG eq 2012;$SUBSEP=2012;print;

Failed approach :

use strict;use English;"2012 2012"=~
/2012|2012|2012/;print$MATCH||$MATCH;

Jeff Burdges

Posted 2012-01-02T15:54:09.203

Reputation: 445

You Perl solution can be broken by replacing the first $& with something like $0. – Howard – 2012-01-03T08:29:30.123

And the Haskell one breaks if you replace the comma with a plus sign. Valiant attempt though. – Jeff Burka – 2012-01-03T09:33:20.150

I think nub$filter(\x->x==2012||x==2012)(2012:[2012]) might be safe for the Haskell solution. – Jeff Burka – 2012-01-03T09:35:02.957

I forgot the use English in perl, that'll fix it. I think several fixes work for Haskell, including switching to strings. – Jeff Burdges – 2012-01-03T13:12:00.450

Replacing the first $MATCH with *MATCH gives the output *main::&. – Ilmari Karonen – 2012-01-03T13:45:20.587

Does use strict even count as compile time in Perl? I'd vote no myself. – Jeff Burdges – 2012-01-03T19:38:22.033

1

The Perl solution is still pretty fragile. Some ways to break it (found while testing my own answer) include replacing print with *rint, prin:, p:int or #rint, prepending = to the first line, or even replacing s/.*/ with s/./ or y/.*/ (which would be fixed by initializing $ARG to 2012 to begin with). Also, your $SUBSEP trick still doesn't protect against inserting a * before the final semicolon, but a much easier solution is to just remove that unnecessary semicolon.

– Ilmari Karonen – 2012-01-06T12:26:46.987

Ahh, thanks! Perl isn't the optimal language for this one I guess. lol – Jeff Burdges – 2012-01-06T15:54:29.747

Indeed, it's too flexible. I'd actually half convinced myself that a correct Perl solution was impossible before I hit upon the trick of testing the return value of print (which is not explicitly documented, but hey, this is code golf). – Ilmari Karonen – 2012-01-07T00:30:15.077

0

PHP, 43 48

 $a='2012';echo($a==date('Y')?abs($a):date('Y'));

The Coder

Posted 2012-01-02T15:54:09.203

Reputation: 101

Inserting a - between the ? and the $a results in -2012 being printed. – Gareth – 2012-01-09T15:05:44.677

Cute attempt with the date(), but the program has to work beyond 2012 as well. ;) – Vilx- – 2012-01-10T08:51:21.517

@Gareth - hmm :) – The Coder – 2012-01-11T20:24:19.110

1@Vilx-"The task is to write a program in your favorite language that outputs 2012" where does it say it has to work beyond 2012? :) – The Coder – 2012-01-11T20:24:53.383

1@TheCoder Ok, now I'm going to insert my - between the ? and the abs. ;-) – Gareth – 2012-01-11T20:46:24.757

Where does it say that it has to work only in 2012? ;) – Vilx- – 2012-01-12T09:10:28.697

Oh, and -abs still breaks it. ;) – Vilx- – 2012-01-12T09:11:19.147

@Vilx-it says it has to output "2012", that's what it does, you're free to re-open the discussion when it stops doing that :). – The Coder – 2012-01-17T08:30:18.903

@Gareth OK, now I'm beginning to hate you :), I guess this demonstrates why beta testers are needed. – The Coder – 2012-01-17T08:31:16.247

0

Ruby (57 36)

EDIT And another one in 36 chars.

p((x,y='2012','2012';x=='2012'?x:y)) 

I guess using strings is pretty failsafe because that minus thing doesn't work any more.


EDIT next try (36 chars) [never mind, adding a - after p results in -2012]

p [2012,2012].find(2012).first||2012


This one will only work this year, but also for similar contests in the future :) (15.chars)

p Time.now.year

Note that this substitution is also working:

p Time.new.year

57 chars. If you count the newlines, too it is 76 chars, though.

p( 
#
#
#
#
#
#
#
#
#
#
__LINE__.to_s.prepend(
#
#
#
#
#
#
#
__LINE__.to_s))

Patrick Oscity

Posted 2012-01-02T15:54:09.203

Reputation: 765

First two solutions - add a # at the start of the line. Last solution - enter a newline before p. (Note - I don't know Ruby myself, so perhaps I'm wrong). – Vilx- – 2012-04-25T13:02:26.900

damn :) you're right – Patrick Oscity – 2012-04-25T13:30:24.647

Prints "2012" for me. The quotes aren't conform - are they? – user unknown – 2012-05-10T03:37:18.520

Yeah you are right. You could use $><< or puts instead. Whatever, i'm not gonna try this any more, i gave up :) – Patrick Oscity – 2012-05-10T07:02:39.643

0

Q, 23

{$[2012~m:2012;m;2012]}

.

q){$[2012~m:2012;m;2012]}`
2012
q){$[1012~m:2012;m;2012]}`
2012
q){$[2012~m:1012;m;2012]}`
2012
q){$[2012~m:2012;m;1012]}`
2012
q){$[2012~\m:2012;m;2012]}`
2012
q){$[2012~/m:2012;m;2012]}`
2012
q){$[2012~'m:2012;m;2012]}`
2012

etc

tmartin

Posted 2012-01-02T15:54:09.203

Reputation: 3 917

And adding a negative (-)? -- {$[-2012~m:2012;m;2012]} -- {$[2012~m:-2012;m;2012]} -- {$[2012~m:2012;m;-2012]} – Gaffi – 2012-05-22T21:07:16.513

it still outputs 2012 q){$[-2012~m:2012;m;2012]}\ 2012--q){$[2012~m:-2012;m;2012]}` 2012--q){$[2012~m:2012;m;-2012]}` 2012` – tmartin – 2012-05-23T09:18:06.010

This can be defeated by switching out the ;m; for something like ;1; or ;x;. – streetster – 2017-06-23T14:48:50.710

0

Hmm.. let me try:

class a {
  int i=2012, j=2012;
  public static void main(String[] args){if (i==j)
    {System.out.println(i);}else{System.out.println(i);}
  }
}

128 chars without the whitespace.

class a{int i=2012, j=2012;public static void main(String[] args){if(i==j){System.out.println(i);}else{System.out.println(i);}}}

Soham Chowdhury

Posted 2012-01-02T15:54:09.203

Reputation: 1 449

1Broken by inserting "-", i.e. System.out.println(-i) (for the first println). Also broken by e.g. replacing the first println(i) with e.g. println(1). Also potentially broken by changing i == j to i += j (or -=, etc.). – TLW – 2019-01-07T02:09:19.063

0

PHP

I hope it's unbreakable :)

$a="2012";ob_start();function c(){ob_clean();return"2012";}function ee($s){return crc32($s)+printf($s);}
print(ee($a)==1367825560?die()
:c());

Stanislav Yaglo

Posted 2012-01-02T15:54:09.203

Reputation: 141

printf(~$s) breaks it. – jimmy23013 – 2015-02-28T01:55:47.683

I add one character to the end of this line: echo(printf("%s",$a)==4)?die(3 and I get 20123. – Vilx- – 2012-09-27T10:59:06.437

Hmm… PHP 5.4.7 works correctly with die(3. – Stanislav Yaglo – 2012-09-27T11:00:56.453

You're right. My bad. Continuing the search... – Vilx- – 2012-09-27T11:06:16.707

PHP 5.3.3 — correct as well. die() outputs only strings, it doesn't output numbers. – Stanislav Yaglo – 2012-09-27T11:06:27.133

Wait, DUH, found it! Just change ."2012" to ."FAIL". :) – Vilx- – 2012-09-27T11:08:43.240

Oh, so simple :) Working on it! – Stanislav Yaglo – 2012-09-27T11:21:04.213

New version is out :) – Stanislav Yaglo – 2012-09-27T11:41:40.083

The die should be replaced with an empty string in a variable that, when modified, breaks the crc. crc32($s.$GLOBALS[e]) should work. Replace printf with print and subtract 3 from the comparison value (printf returns length of output, print returns 1) ... and let´s see what the robbers come up with. – Titus – 2017-01-23T12:21:48.100

0

Groovy: 26

x=2012;print x^2012?2012:x

Armand

Posted 2012-01-02T15:54:09.203

Reputation: 499

I don't know Groovy much, but would this work? x=2012;print x^2012?2012:-x – Vilx- – 2012-09-27T14:48:58.857

what's the - for? – Armand – 2012-09-27T15:39:36.383

@Alison The - is to try and modify your code with one character so that it no longer works. – Gareth – 2012-10-30T09:11:41.710

1x=2012;print x^=2012?2012:x (changing ^ to ^=) changes the output to 0. – histocrat – 2012-12-12T19:23:28.853

-1

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

Matt

Posted 2012-01-02T15:54:09.203

Reputation: 129

a='2012';print a=='2012'and a or 2012 shorter – AMK – 2012-12-16T05:59:32.783

@AMK as gnibbler mentioned in http://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

– jsvk – 2013-02-06T02:33:22.163

1I don't know much about Python, but can you insert a - before the last a? – Vilx- – 2012-01-03T14:45:42.163

so it does... this calls for a rethink – Matt – 2012-01-03T14:49:18.980

-1

Python (45 49 52 chars)

nn='2012'
if nn=='2012':
    print nn
else:
    print 2012

elssar

Posted 2012-01-02T15:54:09.203

Reputation: 579

@hammar fixed. Made n a string – elssar – 2012-01-04T06:27:29.553

Oh that still leaves it susceptible to changing print n to print any constant This needs a complete rethink – elssar – 2012-01-04T06:29:44.637

Wait a second. @hammar I don't think changing n to -n is legal. The problem states that one character can be modified, but it doesn't say anything about adding a character. – elssar – 2012-01-04T06:35:26.047

Yes it does: The modification can be either insertion, deletion or replacement. – hammar – 2012-01-04T06:39:43.857

Damn, how did I not see that! Okay, fixed agian. – elssar – 2012-01-04T06:45:13.097

It's still susceptible to replacing n by a constant, e.g. print 9, or to commenting it out: print #n. – hammar – 2012-01-04T06:55:45.093

I know, still rethinking the code to fix it. – elssar – 2012-01-04T06:57:24.497

@hammar fixed! Wow, in the end the fix turned out to be pretty simple – elssar – 2012-01-04T09:53:21.747

Will it still print 2012 if I change the n1 on line 3 to 21? – Gareth – 2012-01-04T11:46:13.717

@Gareth no, but the instructions state that "The allowed modifications will leave your program syntactically valid and will not cause it to crash". Changing the variable name anywhere would violate that. – elssar – 2012-01-04T12:26:01.123

But if print 2012 is syntactically valid then surely print 21 is too? – Gareth – 2012-01-04T12:31:54.483

oh that, I thought you'd change the name of the variable. If you change the value of n1, then the else condition kicks in & it still prints 2012 – elssar – 2012-01-04T12:34:56.743

I have changed the name of the variable. I've changed it from n1 to an integer constant 21 on line 3, so by my reckoning (which may be faulty, I don't know much Python) it should print 21. – Gareth – 2012-01-04T12:44:05.043

@Gareth damn. Right, I'll change it to nn. That should fix it. – elssar – 2012-01-04T12:53:36.353

1It's still susceptible to commenting out the variable: print #nn. – hammar – 2012-01-04T18:45:58.957

1.. and to commenting out the else :) – hammar – 2012-01-04T19:25:34.837

5I hate you guys >_< – elssar – 2012-01-05T07:24:37.457

-1

Lua, 33 36

xx=2012
print(xx==2012
and xx or 2012)

greatwolf

Posted 2012-01-02T15:54:09.203

Reputation: 129

I think changing and x to and 1 will break it. :( – Dillon Cower – 2012-01-06T06:13:48.227

@DC gah I guess I do have to use 2 xx's. – greatwolf – 2012-01-06T06:16:42.877

2Change and xx to and -xx.. eeeeeeek! – Dillon Cower – 2012-01-06T06:33:16.500

-1

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

gnibbler

Posted 2012-01-02T15:54:09.203

Reputation: 14 170

What's wrong with just print sorted([2012,2012,2012])[1]? – jsvk – 2013-02-04T21:23:01.413

@jsvk, print sorted([2012,2012,2012])[1:] – gnibbler – 2013-02-04T22:31:37.613

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 – jsvk – 2013-02-05T03:16:57.620

Changing the first comma to a + results in 20122012. – histocrat – 2013-02-05T15:20:10.243

@histocrat, if you run the program in Ray's answer, you'll see that there are many many problems – gnibbler – 2013-02-05T22:34:33.087

I think you might have forgotten some parentheses.. so, assuming they're present, add ; after sorted. I like where this one is going, though! – Dillon Cower – 2012-01-12T04:24:19.253

@DC also can put a : after the 1 :( maybe i need to use __getitem__ – gnibbler – 2012-01-12T04:47:18.877

-1

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

Sargun Dhillon

Posted 2012-01-02T15:54:09.203

Reputation: 99

And this can still be beaten by a single hash mark at the start of the line... – Vilx- – 2012-03-25T19:52:26.993

@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. – Sargun Dhillon – 2012-03-25T21:33:03.640

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 – Vilx- – 2012-03-26T07:53:10.320

1No output with exe=(...). – jimmy23013 – 2014-09-14T23:13:44.160