Advent of Code #1 (in Crystal)
Caleb Weeks
Posted on December 1, 2023
Wow! This year started out hard...
I am attempting to solve Advent of Code this year in Crystal. Although I am new to the language, the problem for day 1 was intrinsically difficult, particularly part 2.
Well, I got there in the end. It's interesting to use Crystal as a scripting language. Typically it is used in an OOP style with code organized in classes and methods.
Since Crystal is a compiled language, going from making a change to testing the code isn't all that fast, especially compared to Lua which I was just using earlier today. I've heard that there is a somewhat functional interpreter for Crystal, so maybe I'll give that a try.
It's really frustrating to me when I have code that I'm certain works, but it's giving me the wrong answer. Usually that means that I missed something in the question, or made a bad assumption about the input data. Sure enough, there are some edge cases in part 2 that I didn't consider, and I had to consult the subreddit for a hint.
Anyway, here's my final solution in all its glory:
require "string_scanner"
input = File.read("input").strip
part1 = input.split("\n").map do |line|
digits = line.scan(/\d/).map(&.[0])
(digits[0] + digits[digits.size - 1]).to_i
end.sum
puts part1
ordinal = {
"one" => "1",
"two" => "2",
"three" => "3",
"four" => "4",
"five" => "5",
"six" => "6",
"seven" => "7",
"eight" => "8",
"nine" => "9"
}
part2 = input.split("\n").map do |line|
digits = [] of String
scanner = StringScanner.new(line)
while !scanner.eos?
match = scanner.scan_until(/\d|one|two|three|four|five|six|seven|eight|nine/)
digit = scanner[0]?
break if digit.nil?
if digit.size > 1
scanner.offset = scanner.offset - digit.size + 1
end
digits.push(ordinal[digit]? || digit)
end
(digits[0] + digits[digits.size - 1]).to_i
end.sum
puts part2
Posted on December 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.