[HN Gopher] Xmas.c, winner of the 1988 International Obfuscated ...
___________________________________________________________________
Xmas.c, winner of the 1988 International Obfuscated C Code Contest
Author : evah
Score : 357 points
Date : 2023-12-23 16:56 UTC (6 hours ago)
(HTM) web link (udel.edu)
(TXT) w3m dump (udel.edu)
| queuebert wrote:
| One of my favorite things about the IOCCC is that Larry Wall won
| it twice and then went on to design Perl, which explains a lot.
| someplaceguy wrote:
| Related: https://www.mcmillen.dev/sigbovik/
| FredPret wrote:
| I'd love to see what obfuscated Perl looks like!
| NelsonMinar wrote:
| I'm still hoping to see unobfuscated Perl.
| anthk wrote:
| - Any module from CPAN
|
| - Pixpang (or Pangzero, can't remember which one used Perl
| and SDL)
|
| - Frozen Bubble?
| sidlls wrote:
| I think you missed the joke. Or maybe I did.
| codetrotter wrote:
| (Insert "The Office" meme with Pam saying "they are the same
| picture".)
| rwmj wrote:
| That time we managed to sneak some (semi-)obfuscated Perl
| into the very serious Red Hat Enterprise Linux 6 customer
| documentation:
|
| https://access.redhat.com/documentation/en-
| us/red_hat_enterp...
| chris_wot wrote:
| That's a very old version of C. The function signature of main
| uses the old K&R style for function parameters.
|
| I doubt it would compile currently!
| bawolff wrote:
| It literally has 1988 in the title.
| chris_wot wrote:
| One self evident statement does not invalidate the other :-)
| uxp8u61q wrote:
| It does compile, even with `-std=c17` under GCC. With a few
| warnings about implicit `int`s, of course. Even `-Wall` only
| adds a single warning (about !0<t not meaning what you could
| think it means.)
| arp242 wrote:
| > I doubt it would compile currently!
|
| It compiles (and runs!) fine with just "gcc a.c"; nothing more
| needed. clang does throw some fatal errors, but there's
| probably some combination of flags to make it work; I couldn't
| be bothered to look further.
|
| I've compiled plenty of code from the 80s; I can't recall a
| single example where it didn't work that wasn't due to OS-
| specific stuff. Tons of warnings and maybe some special-flags?
| Sure. But it works.
|
| There's even some modern (well, "modern") code around today
| that uses K&R style function parameters.
| throwawaymobule wrote:
| I'm sure a few compiler maintainers take pride in making sure
| certain 'famous' code snippets still compile as time goes on.
| orf wrote:
| What modern code are you referencing?
| arp242 wrote:
| Most if not all of bash.
|
| zlib changed it just a few months ago (1.3 release from
| August): https://github.com/madler/zlib/issues/633
|
| I've also seen it in some FreeBSD code, but that was quite
| a few years ago and I don't know to what degree that's been
| cleaned up - not so easy to grep for, but a quick check in
| git log shows e.g. https://github.com/freebsd/freebsd-
| src/commit/e5d0d1c5fbbc and some other things, so it seems
| there's still some K&R around.
|
| Probably others as well, this is what I happen to know from
| the top of my head.
| Cockbrand wrote:
| TIL that on macOS, both `gcc` and `clang` are present, but
| `/usr/bin/gcc` is in fact just a hard link to
| `/usr/bin/clang`. So I couldn't compile it with gcc (which is
| clang) on the Mac, but it compiles just fine with gcc on
| Linux.
|
| It's really astonishing that we can compile 35 years old code
| with our current tooling. I somehow doubt that we'll be able
| to compile 35 years old Java/Go/Rust/... code without changes
| in the futue.
| arp242 wrote:
| That's surprising! But I kind of get why they do that, as
| so many tools hard-code "gcc" rather than using "cc" or
| "$CC".
|
| I'm not all that familiar with Java or Rust, but Go is very
| compatible; it's hard to predict the future, but it's
| already a third on its way to "35 years of compatibility".
|
| JavaScript is pretty compatible as well; crummy JS from the
| 90s typically still works today (arguably it's compatible
| to a fault, with things like arr[-1] not being fixed).
| HeckFeck wrote:
| I tried -std=c89 with clang; no luck. If anyone gets further
| do let us know.
| sdkgames wrote:
| >The program is smaller than even the 'compressed' form of its
| output,
|
| >and thus represents a new departure in text compression
| standards.
|
| 7z and gzip disagree with this statement.
| ecesena wrote:
| I just checked, gzip is from 1992, 7z from 1999.
| theideaofcoffee wrote:
| This particular entry to the IOCCC was for 1988, those two
| algorithms didn't come about for a few more years after that,
| gzip in the early nineties and 7z later that decade. The note
| is probably correct when comparing against the state of the art
| at the time.
| sdkgames wrote:
| gzip is based on the DEFLATE algorithm, which is a
| combination of LZ77(1977) and Huffman coding(1952).(
| https://en.wikipedia.org/wiki/Gzip )
| 1986 wrote:
| DEFLATE was created / implemented / speced / whatever word
| you want to apply by Phil Katz no earlier than 1989
| arp242 wrote:
| "Based on" is not the same as "identical".
| acqq wrote:
| You are right. Here is the source of "compress" that existed
| at that time. It compresses the produced song to 1048 bytes,
| not less.
|
| https://www.nic.funet.fi/index/minix/compress.c
|
| The program that produces the song, without the introductory
| comment, is 913 bytes, as presented in the article. Removing
| whitespaces it uses just 800 bytes and produces the song
| which is 2359 chars here. The whole C is: m
| ain(t,_,a)char*a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
| main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&
| t==
| 2?_<13?main(2,_+1,"%s%d%d\n"):9:16:t<0?t<-72?main(_,t,
| "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,
| /n{n+,/+#n+,/#;\ #q#n+,/+k#;*+,/'r :'d*'3,}{w+K
| w'K:'+}e#';dq#'l q#'+d'K#!/+k#;\
| q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;#
| ){nl]!/n{n#'; \ r{#w'r nc{nl]'/#{l,+'K {rw'
| iK{;[{nl]'/w#q#\ \ n'wk nw'
| iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c ;;\
| {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\ #'rdq#w!
| nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/") :t<-50?_==*a?put
| char(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1):
| 0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,
| "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m
| .vpbks,fxntdCeghiry"),a+1);}
|
| It compiles and links even without #include.
| arp242 wrote:
| % gcc xmas.c xmas.c:2:1: warning: return type defaults to
| 'int' [-Wimplicit-int] 2 | main(t,_,a) |
| ^~~~ xmas.c: In function 'main': xmas.c:2:1:
| warning: type of 't' defaults to 'int' [-Wimplicit-int]
| xmas.c:2:1: warning: type of '_' defaults to 'int' [-Wimplicit-
| int] % wc -c <xmas.c 913 % ./a.out
| | wc -c 2359 % ./a.out | compress | wc -c
| 1048
| jrockway wrote:
| zstd -19 compresses the text of the song to 309 bytes.
|
| To be a fair comparison, though, you'd have to write zstd -d
| in 604 bytes. I suppose to be REALLY fair, though, you have
| to count the bytes of code in the compiler itself. A
| convenient enough implementation of compression could index
| into the C compiler binary to find the bytes it needs. (For
| example, my GCC contains "first", "second", and "third" in
| the binary, which a sufficiently clever implementation could
| make use of. "Exit on the first error occurred.", "Append a
| second underscore if the name already contains an
| underscore.", "Warn about suspicious calls to memset where
| the third argument is constant literal zero and the second is
| not.", etc. I didn't check but I doubt turtle doves or maids-
| a-milking come up that often in the description of warning
| flags.)
| arp242 wrote:
| zstd didn't exist in 1988.
| jrockway wrote:
| This article was posted to HN today, in 2023!
| o11c wrote:
| It's only "compressed" if it was made by compress(1) in France.
| Otherwise it's just sparkling entropy coding.
|
| For reference: 1490 xmas-with-leading-
| comment.c 913 xmas-without-leading-comment.c
| 2357 xmas.out 1297 xmas.out.9.Z 1038
| xmas.out.10.Z # actually better than with more bits!
| 1048 xmas.out.11.Z # compression with 11..16 bits have the same
| size 319 xmas.out.1.gz # compression levels 1..2 has
| same size 317 xmas.out.3.gz 307 xmas.out.4.gz
| # compression levels 4..9 have same size
|
| Note that despite looking hard I haven't found a version of
| `compress` that supports `-H`, which is referenced and
| decompressable by gzip. I'm not sure how common it was in the
| wild.
| natch wrote:
| Since the word 'compressed' is in quotes they are probably
| suggesting that they mean when processed by the 'compress'
| command as available on UNIX at the time, as opposed to some
| other compression available at the time.
| adrianmonk wrote:
| "New departure" simply doesn't mean "record-breaking
| compression ratio".
| magerleagues wrote:
| Great explanation! And looks like the IOCCC is still going strong
| in 2023: https://www.ioccc.org/years.html
| NelsonMinar wrote:
| That page shows the last IOCCC was 2020. But the home page has
| an update from May 2023: "We do plan to hold a 28th IOCCC."
| Much like Nethack releases, some things are worth waiting for.
| queuebert wrote:
| Hopefully it is more like Nethack and less like Kingkiller
| Chronicles.
| anthk wrote:
| But thanks to the long wait for Nethack we got great
| Slashem releases...
| anonymousiam wrote:
| I grabbed this when it was originally published, but somehow the
| file name I have is different from the one in this article. Mine
| is called "carol.c" and I just compiled and ran it on a modern
| system. The compiler spat out the following warnings:
|
| gcc -o carol carol.c
|
| carol.c:2:1: warning: return type defaults to 'int' [-Wimplicit-
| int] 2 | main(t,_,a ) | ^~~~
|
| carol.c: In function 'main':
|
| carol.c:2:1: warning: type of 't' defaults to 'int' [-Wimplicit-
| int]
|
| carol.c:2:1: warning: type of '_' defaults to 'int' [-Wimplicit-
| int]
| sebtron wrote:
| Surprisingly few warnings, and all on the same line!
| rwmj wrote:
| GCC 14 won't permit implicit int any more ...
| https://fedoraproject.org/wiki/Changes/PortingToModernC#Remo...
| darknavi wrote:
| Good. It's almost as bad as not returning a value from a
| function being a warning and not an error.
| bonzini wrote:
| Just compile with -std=c89
| anonymousiam wrote:
| I guess I got lucky then. This Ubuntu 23.10 install has gcc
| 13.2.0-4ubuntu3 installed from the repo. Given that the code
| is pre-ANSI C, and that it won in the category of "Least
| likely to compile successfully", it's surprising that there
| are no other issues.
|
| I wouldn't normally run such a radioactive distro, but this
| laptop is so new that there is no LTS distro that works on
| it. (AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics)
| ramesh31 wrote:
| The issue is calling xmas() in main before it's defined.
| Compiling with GCC on macOS gives the error:
| xmas.c:16:5: error: call to undeclared function 'xmas'; ISO C99
| and later do not support implicit function declarations
| [-Wimplicit-function-declaration] xmas(2, 2, "");
|
| Moving main() to the bottom compiles and executes with the
| proper output.
| shimonabi wrote:
| Our professor in college got us this in the printed study
| materials about the C language, so I remember that I typed it in
| by hand once.
| kazinator wrote:
| There is a similar task in Rosetta Code: a program to produce the
| "Old Lady Swallowed a Fly" iteratively growing song.
|
| https://rosettacode.org/wiki/Old_lady_swallowed_a_fly
| merelysounds wrote:
| I like how Tcl is just the lyrics, compressed:
|
| > puts [zlib inflate [binary decode base64
| "7VRNa8MwDL3nV2(...)"]]
|
| https://rosettacode.org/wiki/Old_lady_swallowed_a_fly#Tcl
|
| Python, Nim, Julia and likely others have similar versions too.
| GrabbinD33ze69 wrote:
| This resurfaced a good memory of my last two semesters of
| university (2022), professor showed us this code snippet right at
| the start of one lecture.
| svat wrote:
| The equivalent from the TeX world is `xii.tex`:
| \let~\catcode~`76~`A13~`F1~`j00~`P2jdefA71F~`7113jdefPALLF
| PA''FwPA;;FPAZZFLaLPA//71F71iPAHHFLPAzzFenPASSFthP;A$$FevP
| A@@FfPARR717273F737271P;ADDFRgniPAWW71FPATTFvePA**FstRsamP
| AGGFRruoPAqq71.72.F717271PAYY7172F727171PA??Fi*LmPA&&71jfi
| Fjfi71PAVVFjbigskipRPWGAUU71727374 75,76Fjpar71727375Djifx
| :76jelse&U76jfiPLAKK7172F71l7271PAXX71FVLnOSeL71SLRyadR@oL
| RrhC?yLRurtKFeLPFovPgaTLtReRomL;PABB71 72,73:Fjif.73.jelse
| B73:jfiXF71PU71 72,73:PWs;AMM71F71diPAJJFRdriPAQQFRsreLPAI
| I71Fo71dPA!!FRgiePBt'el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
| ;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
| s$;z zLqs'.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
| LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.'oL.Rtrul;e
| doTsW,Wk;Rri@stW aHAHHFndZPpqar.tridgeLinZpe.LtYer.W,:jbye
|
| Put that in a .tex file and run `pdftex` on it, then look at the
| resulting PDF file, which will look like this:
| https://shreevatsa.net/post/xii/
| nullhole wrote:
| It's like a form of especially logical compression
| mattgodbolt wrote:
| Still works on trunk (if you turn off the warning :))
|
| https://compiler-explorer.com/z/hGvs1e9jo
| fbodz wrote:
| This makes me think about kolmogorov complexity. The program here
| looks like gibberish but produces the desired output, would there
| be even shorter programs that don't look like they make sense but
| produce the same output? How would you search for these programs?
___________________________________________________________________
(page generated 2023-12-23 23:00 UTC)