{"id":17965235,"url":"https://github.com/tokenrove/advent-of-code-2016","last_synced_at":"2026-02-01T19:34:04.106Z","repository":{"id":147612895,"uuid":"75674030","full_name":"tokenrove/advent-of-code-2016","owner":"tokenrove","description":"Suggested name: legendary-octo-carnival","archived":false,"fork":false,"pushed_at":"2018-06-04T11:54:22.000Z","size":40,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-17T14:52:18.636Z","etag":null,"topics":["advent-of-code","personal","practice"],"latest_commit_sha":null,"homepage":null,"language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tokenrove.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-05T23:01:05.000Z","updated_at":"2018-06-29T13:35:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"f17b2c70-7b00-429e-b490-5e39870b2113","html_url":"https://github.com/tokenrove/advent-of-code-2016","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tokenrove/advent-of-code-2016","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokenrove%2Fadvent-of-code-2016","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokenrove%2Fadvent-of-code-2016/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokenrove%2Fadvent-of-code-2016/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokenrove%2Fadvent-of-code-2016/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tokenrove","download_url":"https://codeload.github.com/tokenrove/advent-of-code-2016/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokenrove%2Fadvent-of-code-2016/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28987279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T18:17:03.387Z","status":"ssl_error","status_checked_at":"2026-02-01T18:16:57.287Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["advent-of-code","personal","practice"],"created_at":"2024-10-29T12:10:35.585Z","updated_at":"2026-02-01T19:34:04.087Z","avatar_url":"https://github.com/tokenrove.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nMy [Advent of Code 2016](http://adventofcode.com) solutions.\n\nMy goal was to finish each day in a different language, although I\ndon't know if I'll go through with that.  I did make a list of 46\nlanguages I had at least written a trivial program in before that\nwould be usable for solving problems.\n\nIn the end it was all a horrible rush and it's mostly hacks.  Such is\nlife.\n\n## Requirements\n\n - bats, prove for testing\n - day 1: Common Lisp: sbcl and buildapp\n - day 2: JavaScripts: node.js\n - day 3: GNU APL\n - day 4: ruby 2.x\n - day 5: Java\n - day 6: [J 8](http://jsoftware.com)\n - day 7: perl 5\n - day 8: C: any reasonable C compiler\n - day 9: Modula-3: [cm3](https://modula3.elegosoft.com/cm3/)\n - day 10: OCaml\n!- day 11: Prolog? should use Picat\n?- day 12: Tcl?  CL\n?- day 13: CL? something with arrays, recursion, and popcount\n - day 14: Python\n?- day 15: J\n?- day 16: CL\n - day 17: Erlang\n?- day 18: CL\n!- day 19:\n!- day 20: Haskell\n!- day 21: should use icon\n!- day 22: Prolog\n?- day 23: CL\n?- day 24: CL\n?- day 25: CL\n\n## Notes\n\nI don't know why I started using `--initial` as the argument to switch\nbetween the first and second halves of the problems.  It's dumb, I\nknow, and then I decided to stay consistent.\n\n### Day 1\n\nInitially I wanted to do this in x86 assembly abusing the BCD\ninstructions (in particular `FBSTP`), to demonstrate what compact code\nthey can produce.  I also thought that maybe keeping the coordinates\nin Morton Z-ordering might be fun.\n\nBut I didn't finish this implementation, and a few days later, I went\nback, and decided to implement this using complex numbers to represent\npoints.  Except for the text processing, this would be a nice short\none-liner in J, which has complex support built-in, but I decided to\nuse Common Lisp which I like almost as much as J for interactively\nplaying with problems, and which also has great complex support.\n\nWhen I got to the second part, I was glad I hadn't gone through with\nmy assembly implementation.  Already, I was a little screwed as\nobviously it would have been easier if I could have marked a bitmap or\nsomething with visited points.  (At this scale, even keeping a hash\ntable of each point might be okay, as long as you actually store each\ngrid point visited, not just the end points.)  However I wanted to go\nall the way and so implemented line collision detection.\n\nI realized this might be a fun one to implement in PostScript or\nLaTeX, where one could have a visual output that could be inspected to\nget the answer.  (Draw lines, annotate each endpoint with\ncoordinates.)\n\n### Day 2\n\nThe idea of doing this as a functional graph appealed to me, with the\nedges looping back on themselves.  I thought about using Prolog, where\nexpressing the graph relationship as functions would have been\nelegant, but decided to use JavaScript as a contrast to x86 assembly\n(which was supposed to be the implementation language of day 1).\n\nI liked the idea that with JS objects, I could easily call functions\ndirectly from the characters in the input.  I also could have had a\nclever (awful) hack where, since I or `0x20` to the input to downcase\nit, I could also have had `*` in the object and had that done the work\nof printing a value.  However it soon became clear that just using\nintegers would be less cumbersome, so I scrapped my fun hack and added\nan `if`, especially as I came up with what seemed like a clever way of\ngenerating the connections in the grid.\n\nFor the second part, it was logical to just use hex so little else in\nmy program would have to change.  The means of wiring up the grid was\nless elegant, but what can you do.\n\nAfter writing this, I decided to go back and insert my awful `*` hack,\nsince I could use ES6 arrow notation to make things more terse.\n\n### Day 3\n\nReally simple in an array-oriented language.  Even simpler if one\nrealizes that one can test `2*max(a b c) \u003c sum(a b c)`.  First sketch\nwas in J since I hadn't yet figured out how to write scripts with GNU\nAPL, which allowed me to use the nice backtick reduce construct in J,\nbut then I went back and wrote it in APL.  One-liner modulo argument\nand input handling:\n\n```apl\nin ← (⍉⍤2) in ⍴⍨ (9÷⍨⍴in),3 3 ⋄ +/ (,2×⌈/ in) \u003c (,+/⍤1 in)\n```\n\n### Day 4\n\nThought about using a language where I'd be forced to do a clever\nstate machine implementation here, but I was trying to catch up, so I\nwent with Ruby-pretending-to-be-Perl, which was actually pleasant to\nwrite.\n\n### Day 5\n\nOne of the first ones I wrote.  I knew that there would be something\nlike this, like there was last year, and it would make an all-J or\nall-assembly run inconvenient, so I planned to use something where MD5\nwas in the standard library.  I wanted to implement an in-place\ncounter so the program didn't generate a ton of garbage as it\ngenerated codes; I setup the interface for this, but then just\nimplemented the simple thing and let it burn CPU cycles.\n\nI tried to avoid getting bitten by Java's lack of unsigned types and\ngot bitten anyway.\n\nLater I revisited this and avoided generating garbage.  It probably\nwould have been more productive to parallelize this, however.  Even\njust using a `synchronized` variable would probably work, since the\ncontention on it shouldn't be high.\n\n### Day 6\n\nThis kind of problem is just designed for vector languages.  Ignoring\nargument and input handling, this is just a one-liner:\n```j\n, (~.\"1 t) {\"1~ |: ,: (i.\u003c./)\"1 (#/.~\"1 t)\n```\n\n### Day 7\n\nI often make fun of perl's context-sensitive irregular expressions, so\nthis seemed like a safe opportunity to demonstrate their abuse.  I\ndidn't really sink to any depths with it, though, since the problem\nended up more restrained than I expected (no deep nesting, et cetera).\n\n### Day 8\n\nI decided to do this in C since I figured a bitmap would be an obvious\nrepresentation for this and C would make the bit-twiddling easy.  It\nended up less terse and less interesting than I had hoped, although I\nthrew in a few C abuses to make it more fun.\n\nDoing this in a vector language probably would have been more\nsatisfying.  And doing this in CL would have avoided a bunch of bugs\nthat caused pain, due to things like C's modulo semantics and negative\nnumbers, implicit conversions of numbers that truncate or sign extend,\net cetera.\n\n### Day 9\n\nI wrote a prototype in Python before deciding to use Modula-3.  This\ndoesn't show off anything interesting about Modula-3, unfortunately.\n\nI realized as I was writing it that, like many of these\nimplementations, it's broken with respect to some valid input which\ndoesn't occur in the test inputs.\n\n### Day 10\n\nTransitive closure; could use a graph representation and propagate\nrecursively.\n\nLogic languages would probably make this trivial.  I used OCaml\nbecause it looked like an interpreter pattern would be important here,\nbut it turned out that Prolog would have been a much better choice.\n\n### Day 11\n\nPiCat, Prolog, or Mercury seems like the obvious choice here.  I\nstarted in Prolog, and parsing the input with DCGs was great, but\ncouldn't seem to construct a suitable backtracking solver that didn't\nblow up.\n\n### Day 12\n\nThis was such a simple interpreter pattern that I immediately dashed\nit off in Common Lisp, with an array holding the instructions, and\nabusing `symbol-value` slightly for the registers.\n\nMy next thought was to do it in Tcl, where I could take that kind of\neval cheating to an extreme (maybe even safely with `interp`).  While\nI was determining how to store the instructions in Tcl, I realized a\nfun Scheme implementation might be to use a list and make all jump\ntargets point into the list, since they're all static, so we can avoid\nthe O(n) search at interpretation time.\n\n### Day 13\n\nColored by day 11, I started approaching this as a classic AI search\nproblem and started implementing another BFS in Prolog.\n\nPopcount modulo 2 is the parity of a word.\n\nFlood fill is a better solution, especially once we get to part 2.\n\n### Day 14\n\nIt would have been nice to do this with bit shifting tricks, but most\nof the languages where working with 128-bit numbers is easy don't have\nbuilt-in MD5 primitives.\n\nErlang came to mind as a possibility (easy to work with large numbers,\nand has built-in MD5), but I ended up just hacking out a quick Python\nsolution.\n\nIf I had done it in Erlang, I could have parallelized it, at least\nsearching each five-digit number separately\n\n### Day 15\n\nThe Chinese Remainder Theorem immediately came to mind when I saw the\npuzzle, and a quick check of the input for coprime bases confirmed it,\nso my first approach was just to feed the values into\n[maxima](http://maxima.sourceforge.net/docs/manual/maxima_29.html#chinese);\nof course the initial positions actually need to have their position\nadded to their value (`init+1+⍳⍴init`).  But this wasn't giving me a\nreasonable answer, so I brute forced it in a line of J.  We just need\nto check `0 = bases | init+y` We know by the CRT that we don't need to\ncheck any higher than `×/bases`.\n\nI realized after brute forcing it that in order to use existing CRT\nsolvers, I needed to use `(bases|bases-init+1+i.$init)` as the\nremainders.  A good CRT solver (like\n[this one in J](http://code.jsoftware.com/wiki/Essays/Chinese_Remainder_Theorem))\nsolves the problem instantly.\n\n### Day 16\n\nIt shouldn't be hard to figure out how to compute this without\nactually executing the dragon curve, but once again, the numbers are\nsmall enough for us to take a naïve approach.\n\nThere are some excuses to use fancy bit-twiddling tricks here,\nespecially Morton Z-order decoding.\n\nIt is hard to resist using Common Lisp given its profusion of bit\ntwiddling features and the ease of working with arbitrary-length bit\nvectors.\n\n### Day 17\n\nBreadth-first search, then depth-first search.  Still need to\nparallelize this.\n\n### Day 18\n\n```j\n3 ({.={:);._3 (|.0,|.0,('^'='...^^.'))\n```\n\n### Day 19\n\nI knew I had seen this before but I couldn't remember where. Then I\nwas talking with Vincent in the kitchen and he mentioned the elves\nkilling themselves, which was clue enough for me to suddenly realize\nthis was the Josephus problem.\n\n### Day 22\n\nLooks like a graph problem, although we see that we actually have\nanother Von Neumann-neighborhood-connected array like many of the\nother search problems.\n\n### Day 23\n\nAlthough it's possible to run the second case without anything fancy,\nas the instructions hint, it would be nice to speed this up.  I was\nimmediately reminded of strength reduction although of course this\nwouldn't be that; more the opposite.  Detect induction variables and\nstrength \"increase\" their operations.\n\n### Day 24\n\nAlthough an early thought from seeing the example is to turn it into a\ngraph, collapsing corridors into edges with a weight equal to their\nlength, after seeing the actual input and knowing that the number of\npoints to hit was much smaller than the total space, what about BFS\nfor all pairs to find the shortest paths between points, then choose\nthe route from 0 that minimizes the distance?\n\nAgain, once you've constructed one path (perhaps the obvious one),\nalthough you have to check every permutation, you can immediately\ndiscard those paths that would be longer than the shortest path found.\nI guess BFS again is possible but it's probably faster to use some\nkind of dynamic programming formulation.\n\n### Day 25\n\nJust walked through the assembly by hand and then, although clearly\nthere was a closed-form way to figure out a value a smallest value\nwith appropriate remainders (should have alternating bits), I just\ndecided to run the inner loop with my simulator, bailing out if we\ndidn't emit the right pattern.  This quickly found the smallest value\nwith alternating 1/0 bits, from which I then removed the initial\noffset.\n\n## Quotes\n\n```\n   /:~\u0026.\u003e\"1 ({.;#)/.\"1~ |: t\n\nProcess J segmentation fault\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftokenrove%2Fadvent-of-code-2016","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftokenrove%2Fadvent-of-code-2016","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftokenrove%2Fadvent-of-code-2016/lists"}