{"id":23531702,"url":"https://github.com/ryanprior/advent-of-code","last_synced_at":"2025-05-14T14:34:17.016Z","repository":{"id":77898362,"uuid":"227480141","full_name":"ryanprior/advent-of-code","owner":"ryanprior","description":"Advent of Code puzzle-solving code","archived":false,"fork":false,"pushed_at":"2020-12-02T05:17:25.000Z","size":53,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-07T23:03:36.324Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Crystal","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/ryanprior.png","metadata":{"files":{"readme":"README.org","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,"zenodo":null}},"created_at":"2019-12-11T23:32:11.000Z","updated_at":"2021-03-07T04:30:27.000Z","dependencies_parsed_at":"2023-03-04T09:30:27.006Z","dependency_job_id":null,"html_url":"https://github.com/ryanprior/advent-of-code","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanprior%2Fadvent-of-code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanprior%2Fadvent-of-code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanprior%2Fadvent-of-code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanprior%2Fadvent-of-code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryanprior","download_url":"https://codeload.github.com/ryanprior/advent-of-code/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254160647,"owners_count":22024574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-12-25T22:20:08.324Z","updated_at":"2025-05-14T14:34:17.010Z","avatar_url":"https://github.com/ryanprior.png","language":"Crystal","funding_links":[],"categories":[],"sub_categories":[],"readme":"This is the code and documentation for my [[https://adventofcode.com/][Advent of Code]] adventures. Thanks for\ntaking a look! I welcome your thoughts and feedback.\n\n* Advent of Code 2020\n\n\n\n* Advent of Code 2019\n\nSanta is stranded at the edge of the Solar System and it's up to me to save\nChristmas using quick thinking and the power of the [[https://crystal-lang.org][Crystal programming\nlanguage]]. I've been slowly learning Crystal for a while \u0026 am feeling ready to\nuse it to tackle some actual challenges and build proficiency.\n\nFor each day, I plan to build or extend a well-behaved CLI tool that allows me\nto solve the puzzle using a Bash one-liner. I'm challenging myself to follow a\nset of priorities that align with how I want to write code:\n\n*** Do:\n- utilize a pure functional style\n- use immutable, persistent data structures\n- write readable, semantically meaningful code\n- provide a well-behaved command line interface\n\n*** Don't:\n- rely on global or mutable state\n- switch back arbitrarily to imperative style\n- optimize prematurely\n- obsess over minimal (or even DRY) code\n\n** Day 1\nI wrote the ~rocket-fuel~ utility to calculate fuel requirements.\n- implementation: [[./2019/rocket-fuel/rocket-fuel.cr]]\n- build: ~make bin/rocket-fuel~\n- solve part 1: ~bin/rocket-fuel data/day-1/puzzle-input.mod~\n- solve part 2: ~bin/rocket-fuel -x data/day-1/puzzle-input.mod~\n\n** Day 2\nOn the second day of Christmas begins the saga of the /intcode computer!/\n- implementation: [[./2019/src/computer/computer.cr]]\n- build: ~make bin/computer~\n- solve part 1:\n  #+BEGIN_SRC bash\n  bin/computer run -s 1,12 -s 2,2 data/day-2/puzzle-input.ic \\\n    | head -n1 \\\n    | cut -d' ' -f1\n  #+END_SRC\n- solve part 2:\n  #+BEGIN_SRC bash\n  bin/computer search --domain 0,99 \\\n                      --target 19690720 \\\n                      data/day-2/puzzle-input.ic\n  #+END_SRC\n\n** Day 3\nThis challenge required calculating the location of intersections and the\nlengths of paths. I wrote the ~trace-wires~ utility to assist.\n- implementation: [[./2019/src/trace-wires/trace-wires.cr]]\n- build: ~make bin/trace-wires~\n- solve part 1: ~bin/trace-wires nearest-intersection data/day-3/puzzle-input.wire~\n- solve part 2: ~bin/trace-wires nearest-intersection data/day-3/puzzle-input.wire~\n\n** Day 4\nElves vaguely remember an important password \u0026 it's time to crack it using the\n~password~ utility.\n- implementation: [[./2019/src/password/password.cr]]\n- build: ~make bin/password~\n- solve part 1: ~bin/password [PUZZLE INPUT MIN] [MAX]~\n- solve part 2: ~bin/password --cap-run-length [PUZZLE INPUT MIN] [MAX]~\n\n** Day 5\nIntcode Part 2: Thermoelectric Boogaloo. This challenge prompted me to refactor\n~computer.cr~, eliminating a number of previous simplifying assumptions. Then I\nadded the new functions necessary to solve the puzzle.\n- implementation: [[./2019/src/computer/computer.cr]]\n- build: ~make bin/computer~\n- solve part 1: ~bin/computer run -q data/day-5/puzzle-input.ic \u003c\u003c\u003c1~\n- solve part 2: ~bin/computer run -q data/day-5/puzzle-input.ic \u003c\u003c\u003c5~\n\n** Day 6\nIn order to plot an orbital path to Santa, we stop by a mapping station to\nprocess some maps with the ~orbit~ utility.\n- implementation: [[./2019/src/orbit/orbit.cr]]\n- build: ~make bin/orbit~\n- solve part 1: ~bin/orbit sum data/day-6/puzzle-input.map~\n- solve part 2: ~bin/orbit path-distance data/day-6/puzzle-input.map~\n\n** Day 7\nThis challenge involves running an intcode program in many configurations, with\nchained inputs \u0026 outputs, in order to find the maximum possible output of a\nseries. I believe I could have done this in ~bash~ without any changes to the\n~computer~ utility, using standard UNIX pipes to handle I/O. Maybe I should have\ndone that, because it would have reduced I/O complexity in the ~computer~\nprogram itself.\n\nHowever, after all this time using functional Crystal \u0026 persistent data\nstructures, I've been itching for an opportunity to leverage parallelism, and I\nfigured this optimization problem could be a nail for that hammer if you look at\nit funny.\n\nTo warm-up, since I've never used Crystal's parallel features before \u0026 they're\nin preview anyhow, I updated my day 2 \"search\" solution to use multiple threads.\nEt voila, it ran ~4 times as fast on my 4-core machine. Now we're living the\ndream!!\n\nAs a fortunate side-effect of refactoring the solution to run in parallel,\nimplementing part 2 was a minor change: add a new ~--loop~ option to the CLI,\nloop the I/O structures, and wait for all the IC programs to terminate before\nreading the final output.\n\n- implementation: mostly in [[./2019/src/computer/main.cr]], but with some added facilities\n  for choosing whether to use stdin/stdout or internal data structures for I/O.\n- build: ~make bin/computer~\n- solve part 1: ~bin/computer optimize --domain 0,4 data/day-7/puzzle-input.ic~\n- solve part 2: ~bin/computer optimize --domain 5,9 --loop data/day-7/puzzle-input.ic~\n\n** Day 8\nThis challenge lent itself to a satisfyingly compact representation in Crystal.\nI also found out that the \"colorize\" module is cute and easy to use.\n\n- implementation: [[./2019/src/image/image.cr]]\n- build: ~make bin/image~\n- solve part 1: ~bin/image check -d 25x6 data/day-8/puzzle-input.sif~\n- solve part 2: ~bin/image show -d 25x6 data/day-8/puzzle-input.sif~\n\n** Day 9\nTo solve this puzzle, we need a \"complete\" intcode computer. This requires\nsatisfying a few new operational constraints \u0026 adding a new opcode and\ninstruction mode.\n\nTo satisfy the requirement that intcode computers handle \"big numbers,\" I\nswitched from using Int32 for values throughout the codebase to using BigInts.\nThis required a decent number of changes throughout the codebase, but that\nprocess highlighted for me how Crystal's compiler and type checker make\nrefactoring less risky.\n\nTo satisfy the requirement that programs be allowed to write outside of the\ninitial program memory, I segmented the program space into two parts: ~data~,\nthe initial program memory, and ~extra~, a map of memory addresses to values.\nThis allows us to set a value at some far-out address without having to allocate\na ton of memory, which is nice.\n\nIt's interesting to note during part 2, where the performance of the intcode\ncomputer is stress-tested, that release builds are /much/ faster than dev\nbuilds. To test this yourself, time it with each build instruction below.\n\nOn my computer, this results in a 4x speedup, resulting in a speedy sub-second\nruntime. (~=t_d / t_r * 100~ where ~t_r~ is release runtime and ~t_d~ is dev\nruntime)\n\nI haven't been profiling or optimizing much beyond gut-level instincts, so it's\npossible I may be missing something that would actually speed up execution again\ndramatically.\n\n- implementation: [[./2019/src/computer/computer.cr]]\n- dev build: ~make bin/computer~\n- release build: ~crystal build --release -o bin/computer computer/main.cr~\n- solve part 1: ~bin/computer run -q data/day-9/puzzle-input.ic \u003c\u003c\u003c1~\n- solve part 2: ~bin/computer run -q data/day-9/puzzle-input.ic \u003c\u003c\u003c2~\n\n** Day 10\nIn order to help distressed elves in an asteroid field I built the ~asteroid~\ntool which can optimize for the best asteroid surveillance location and\ncalculate the order in which asteroids will be vaporized by a laser beam. It\ndoes all this with vector math. I didn't look very hard for a vector library in\nCrystal's shards collection, but I didn't see anything obvious so I wrote my\nown with enough functionality to solve this puzzle.\n\n- implementation: [[./2019/src/asteroid/asteroid.cr]]\n- build: ~make bin/asteroid~\n- solve part 1: ~bin/asteroid optimize data/day-10/puzzle-input.map~\n- solve part 2:\n  #+BEGIN_SRC shell\n  bin/asteroid optimize -c $center \\\n  --number 200 \\\n  data/day-10/puzzle-input.map\n  #+END_SRC\n  (where ~$center~ is the output from part 1, in my case \"29,28\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanprior%2Fadvent-of-code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryanprior%2Fadvent-of-code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanprior%2Fadvent-of-code/lists"}