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

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.

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

# 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!

• @PaulR: Now changed to register void; The register is there to prevent &; the void is there to prevent *. Jan 2, 2012 at 21:38
• OK... correct me if this is invalid C, but it just worked on my VS2010. Insert a ; between puts and (. Jan 3, 2012 at 10:58
• +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.) Jan 3, 2012 at 14:06
• @IlmariKaronen: Heh, that's a lot of effort; thanks for going through all that. :) Jan 3, 2012 at 14:14
• @Titus: If you mean switching == for != in the ternary, that gets you nowhere; instead of outputting a it now outputs "2012". Jan 23, 2017 at 12:00

(\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  • I'm afraid this compiles just fine modified, although an exception is thrown at runtime. Jan 3, 2012 at 19:13 • @JeffBurdges: sure, I take this to be included in "and will not cause it to crash". Jan 3, 2012 at 21:30 • For the a=map(head.show.length)[[a,a],[],[a],[a,a]] solution, insert a between []. I really like this post, though! Very clever solutions. Jan 4, 2012 at 0:15 • 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 :) Jan 4, 2012 at 0:30 • [a] -> [] in the 64-char solution Sep 14, 2014 at 16:28 ## 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'. • Ugh, brainfuck! You just HAD to, didn't you? XD Mar 20, 2012 at 16:15 • would you have preferred he used whitespace instead? Sep 28, 2012 at 22:16 • Fail if adding . after any ]. You can claim . don't output 0 to resolve – l4m2 Jun 24 at 6:47 ## 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. • Breaks with Perl 5.28 where print starts returning 'true' instead of 1 :-P – J B Jan 3, 2012 at 21:39 • @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.) Jan 3, 2012 at 21:47 ## 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) }  • Because 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. Jan 3, 2012 at 8:23 • Same thing as the C solution - insert a ; between eval and (. Jan 3, 2012 at 11:00 • For the comment readers, the semicolon vulnerability is fixed, I believe the code to be clean now. Jan 3, 2012 at 23:38 • Not 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 Jan 11, 2012 at 0:34 • Adding a ! after eval( breaks it. Feb 28, 2015 at 1:00 ## 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, {}, {})  • Great! You make it! – Ray Feb 6, 2013 at 6:49 # 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. • Ha! The right language for the challenge. Jan 23, 2017 at 4:37 # 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. • Good one! I can't think of a way to circumvent this. "A" for effort from me, that's for sure! :) Jan 23, 2017 at 10:08 # T-SQL 2012, 55 DECLARE @n CHAR(4)='2012'PRINT IIF(@n='2012',@n,'2012')  • What SQL dialect is this? Looks like Transact-SQL (aka SQL Server), but it has invalid syntax for that. May 3, 2012 at 10:22 • @Vilx-: I tested it in SQL Server 2008 myself when I was trying to break it, and it worked just fine. May 4, 2012 at 14:23 • @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). May 4, 2012 at 18:15 • @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: sqlfiddle.com/#!6/d41d8/27 May 7, 2012 at 14:10 • OK, congratulations, I can't find any obvious ways of breaking this! :) That's not to say there aren't any. ;) May 7, 2012 at 15:12 ## Ruby 1.9 - 43 chars qq=[:p,2012] b if qq!=[:p,2012] send( *qq)  Not tested, so break away. 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. # 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. # 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). • What is a negative sign is inserted in path 4 before the a? Will the program still output 2012, or will it output -2012? Jan 23, 2017 at 14:30 • @KritixiLithos It's a String, so you can't insert a - before the a or b. Here is a screenshot of the Compile error. Jan 23, 2017 at 14:34 ## 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. # 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. • OK... I don't know anything about SmileBASIC, so this is purely a guess: ?-A$VAR C - could this output -2012? Mar 4, 2018 at 9:58
• That won't work because A$is a string. Mar 4, 2018 at 15:39 • Wait, I have an idea! What about: ?B$VAR C? :) Mar 4, 2018 at 15:58
• That will trigger an error because "B$" hasn't been declared. Mar 4, 2018 at 16:12 # 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.

# Rust, 105 bytes

fn main(){use std::io::{Write,stdout};stdout().write_all({let a=b"2012";if a==b"2012"{a}else{b"2012"}});}


Try it online

Most of the length comes from writing directly to stdout vs using the print! macro. Unfortunately, the format string in print!("{}", x); can be easily modified and is checked at compile time so you can't pass in the value as a string directly.

• I don't know any Rust, so this looks solid. One question - the place where it goes {a} - can't something be done with that? Like {!a} or {~a} or something? I'm just shooting blind here, but perhaps there's some operator that can be used on a string? Aug 1, 2020 at 0:11
• @Vilx- Neither of those operators are valid in that location. a's type is &[u8] (which is a slice) and write_all is expecting a &[u8] so it's not really possible with a single character change to modify a in that location without causing a compiler error, as far as I can tell at least. Aug 2, 2020 at 3:39

## Tcl, 55 chars.

if {$a=={puts 2012}} [set a {puts 2012}] { 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.

# Lenguage, 176848577745260300319721504 bytes

Not really fun though.

No modification/edit a byte: ----------[+>+++++<]>.--.+.+.+

Add a byte: ----------[+>+++++<]>.--.+.+.-

Remove a byte: ----------[+>+++++<]>.--.+.+<]

# JavaScript, 48 bytes

q="e=alert(2012)"


Try it online!

• This language almost feels like cheating here. :D Jun 25 at 17:58

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;

• You Perl solution can be broken by replacing the first $& with something like $0. Jan 3, 2012 at 8:29
• And the Haskell one breaks if you replace the comma with a plus sign. Valiant attempt though. Jan 3, 2012 at 9:33
• I think nub$filter(\x->x==2012||x==2012)(2012:[2012]) might be safe for the Haskell solution. Jan 3, 2012 at 9:35 • I forgot the use English in perl, that'll fix it. I think several fixes work for Haskell, including switching to strings. Jan 3, 2012 at 13:12 • 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. Jan 6, 2012 at 12:26

# C# .NET, 83 bytes

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


Try Online

• 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. Aug 20, 2019 at 18:30
• I feel stupid now Aug 20, 2019 at 19:49
• Aaand this version fails because I can do "2012"=="2012"?"2014":"2012". You need the var. :) Aug 20, 2019 at 20:21
• Well I should probably stop trying to make this shorter then xD Aug 20, 2019 at 21:55