Constrained programming
I’ve enjoyed constrained writing (e.g. Oulipo) for a long time and am going to be trying to practice constrained programming in Advent of Code for as long as I can maintain interest this year. In particular, my plan is to go through each day as a lipogram of the nth-most-frequent letter in English. For the first twelve, even though English letter frequency is slightly different than ETAOIN SHRDLU, I’ll use that iconic order.
So my day 1 solution will not include the letter ‘e’, day 2 will not include the letter ‘t’, and so on. I’m excited to try this out. Here’s day 1:
Day 1 | Ruby | Avoiding fifth glyph
# part 1 digits = inputs.map { |input| input.gsub(/\D/, '')} calibrations = digits.map { |digit| digit.chars.first.to_i * 10 + digit.chars.last.to_i } p calibrations.sum # part 2 glyph_to_avoid = "d".succ @trigrams = {"two" => 2, "six" => 6} @trigrams["onz".gsub(/z/, glyph_to_avoid)] = 1 @quadragrams = {"four" => 4} @quadragrams["fivz".gsub(/z/, glyph_to_avoid)] = 5 @quadragrams["ninz".gsub(/z/, glyph_to_avoid)] = 9 @quintagrams = {} @quintagrams["thrzz".gsub(/z/, glyph_to_avoid)] = 3 @quintagrams["szvzn".gsub(/z/, glyph_to_avoid)] = 7 @quintagrams["zight".gsub(/z/, glyph_to_avoid)] = 8 calibrations = inputs.map { |input| first_digit = nil (0..input.chars.count - 1).map { |idx| first_digit = input[idx].to_i if !first_digit && /\d/ =~ input[idx] tri = input[idx-2, 3] if idx >= 2 first_digit = @trigrams[tri] if !first_digit && tri && @trigrams[tri] quad = input[idx-3, 4] if idx >= 3 first_digit = @quadragrams[quad] if !first_digit && quad && @quadragrams[quad] quint = input[idx-4, 5] if idx >= 4 first_digit = @quintagrams[quint] if !first_digit && quint && @quintagrams[quint] } last_digit = nil (1..input.chars.count).map { |idx| last_digit = input[-idx].to_i if !last_digit && /\d/ =~ input[-idx] tri = input[-idx, 3] if idx >= 2 last_digit = @trigrams[tri] if !last_digit && tri && @trigrams[tri] quad = input[-idx, 4] if idx >= 3 last_digit = @quadragrams[quad] if !last_digit && quad && @quadragrams[quad] quint = input[-idx, 5] if idx >= 4 last_digit = @quintagrams[quint] if !last_digit && quint && @quintagrams[quint] } first_digit * 10 + last_digit } p calibrations.sum
Not using control flow words was tough to work around. I initially had ‘x’ for a proxy glyph until I got to ‘six’.