Posts tagged programming
Advent of Code 2023 is starting on December 1. This will be my fourth year, after participating in 2022, 2021 and 2020.
My primary programming language is Racket, so I expect to code most of the solutions in it; however, the rest of my language stack includes Python, Javascript and C++, so I’ll code some of the solutions using them also.
|
#lang iracket/lang #:require racket
(require "../advent.rkt")
|
Tuning Trouble
Today’s puzzle has very similar parts! For both parts, our input is a single string, and the task is to determine how many characters we need to consume before finding a contiguous group of N unique characters. The only difference is the value of N
.
|
#lang iracket/lang #:require racket
(require "../advent.rkt")
|
Supply Stacks We’re given the following sample input:
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2
And, fortunately for us, the first part has lines padded with spaces to be of equal length - this makes parsing just a little bit easier :) Even so, the built-in parsers we have for AoC are insufficient, so we’ll just use a custom parser that reads the file into a string, splits it on "\n\n", and then maps the string-split
function over both parts - the stack lines and the command lines:
|
#lang iracket/lang #:require racket
(require "../advent.rkt")
|
Camp Cleanup
Before we get started with today’s puzzle, I have some cleanup of my own to do!
1. all-from-out
At the beginning of each day, the second line of the prelude above is:
(require "../advent.rkt")
This is Racket’s way of importing a module. Rather than also having to import common modules I typically use, such as the threading
module, e.g. (require "../advent.rkt" threading)
, I’d like to be able to just import my advent.rkt
module and get access to threading
as well. I learned a long time ago that the answer to the question, “Can Racket do <X>”, is almost always, “yes”, and this is no exception; it’s accomplished with the all-from-out
macro. My advent.rkt
module already had (require threading)
for it’s own purposes, so I just needed a directive to have it export all of the exports from threading
as if they were defined in advent.rkt
:
(provide (all-from-out threading))
2. A parsing fix
One of the parsers I got from Peter Norvig is the numbers
parser, and it allows parsing input such as 1,2 | -3,4
into a list of numbers, '(1 2 -3 4)
; however, today’s input was like 49-51,31-50
, and the numbers
parser would output '(49 -51 31 -50
. The -
chars were meant to be separators, not negative signs. The original numbers
parser used the regex pattern -?[0-9.]+
. Modifying the regex pattern to be ((?<![0-9])-)?[0-9.]+
instead, which uses a negative lookbehind pattern, correctly outputs '(49 51 31 50)
.
The negative lookbehind pattern (?<![0-9])
is used in front of the -
, so that the -
will only match if it’s not preceded by a numeric digit. This is a very handy regex technique.
Ok, with the modified numbers
parser in place, let’s parse today’s input!
|
#lang iracket/lang #:require racket
(require "../advent.rkt" threading)
|
Rucksack Reorganization
We’re given some sample input:
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
The first half of each list contains items for one compartment of the backpack, and the second half contains items for the other compartment. Each backpack has, erroneously, one item in both compartments/halves.
Lower case items have priorities 1 to 26; upper case items 27 to 52.
Find the item type that appears in both compartments of each rucksack. What is the sum of the priorities of those item types?
|
#lang iracket/lang #:require racket
(require "../advent.rkt")
|
Rock, Paper, Scissors
For example, suppose you were given the following strategy guide:
A Y
B X
C Z
We’re told that A=Rock, B=Paper and C=Scissors, and it’s proposed that X=Rock, Y=Paper and Z=Scissors.
We’re also told the score is computed as follows: add the score of the shape (1 for Rock, 2 for Paper and 3 for Scissors) to the outcome (0 if we lost, 3 if a draw and 6 if we won).
What would your total score be if everything goes exactly according to your strategy guide?
Each day will have some preliminary setup code:
|
#lang iracket/lang #:require racket
(require "../advent.rkt")
(require threading)
|
We’re given the following sample data:
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
This list represents the Calories of the food carried by five Elves:
- The first Elf is carrying food with 1000, 2000, and 3000 Calories, a total of 6000 Calories.
- The second Elf is carrying one food item with 4000 Calories.
- The third Elf is carrying food with 5000 and 6000 Calories, a total of 11000 Calories.
- The fourth Elf is carrying food with 7000, 8000, and 9000 Calories, a total of 24000 Calories.
- The fifth Elf is carrying one food item with 10000 Calories.
Find the Elf carrying the most Calories. How many total Calories is that Elf carrying?
I recently started experimenting with the Racket notebook package, IRacket. Notebooks are handy for experimentation and visualization, so I wanted to be able to display a plot. I discovered that (require plot)
did not work, but if I changed that slightly to (require plot/pict)
, I was able to display a plot in the notebook.
Table of Contents
Now that I have a couple years experience with Advent of Code, I’d like to get a little more organized prior to the contest. I’m hoping to create a blog post for most of the days, and I think I’ll make use of Ryan Culpepper’s IRacket package this year. IRacket allows creating Jupyter notebooks, and by exporting them as markdown files, they can be copy/pasted directly into a Frog static site generator file for a blog post. I thought about using only a notebook this year, but I think I would miss having a clutter-free version of just the code.
Advent of Code 2022 will start on December 1. This will be my third year, after participating in 2021 and 2020.
I hope to have time to code all of the solutions in Racket, my favorite programming language, and I should be able to translate some of them into Python and/or Javascript as a learning exercise.
My primary goal is to create an elegant Racket solution for each day’s puzzle that is clear, commented and tested. For some of the days, I may also create variants that emphasize performance or conciseness.