advent-of-code/advent-of-code.org
2015-12-11 13:11:45 -05:00

61 KiB

Advent of Code

Day 1: Not Quite Lisp

Santa was hoping for a white Christmas, but his weather machine's "snow" function is powered by stars, and he's fresh out! To save Christmas, he needs you to collect fifty stars by December 25th.

Collect stars by helping Santa solve puzzles. Two puzzles will be made available on each day in the advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!

Here's an easy puzzle to warm you up.

Santa is trying to deliver presents in a large apartment building, but he can't find the right floor - the directions he got are a little confusing. He starts on the ground floor (floor 0) and then follows the instructions one character at a time.

An opening parenthesis, (, means he should go up one floor, and a closing parenthesis, ), means he should go down one floor.

The apartment building is very tall, and the basement is very deep; he will never find the top or bottom floors.

For example:

  • (()) and ()() both result in floor 0.
  • ((( and (()(()( both result in floor 3.
  • ))((((( also results in floor 3.
  • ()) and ))( both result in floor -1 (the first basement level).
  • ))) and )())()) both result in floor -3.

To what floor do the instructions take Santa?


((((()(()(((((((()))(((()((((()())(())()(((()((((((()((()(()(((()(()((())))()((()()())))))))))()((((((())((()))(((((()(((((((((()()))((()(())()((())((()(()))((()))()))()(((((()(((()()))()())((()((((())()())()((((())()(()(()(((()(())(()(())(((((((())()()(((())(()(()(()(())))(()((((())((()))(((()(()()(((((()()(()(((()(((((())()))()((()(()))()((()((((())((((())(()(((())()()(()()()()()(())((((())((())(()()))()((((())))((((()())()((((())((()())((())(())(((((()((((()(((()((((())(()(((()()))()))((((((()((())()())))(((()(()))(()()(()(((()(()))((()()()())((()()()(((())())()())())())((()))(()(()))(((((()(()(())((()(())(())()((((()())()))((((())(())((())())((((()(((())(())((()()((((()((((((()(())()()(()(()()((((()))(())()())()))(())))(())))())()()(())(()))()((()(()(())()()))(()())))))(()))(()()))(())(((((()(()(()()((())()())))))((())())((())(()(())((()))(())(((()((((((((()()()(()))()()(((()))()((()()(())(())())()(()(())))(((((()(())(())(()))))())()))(()))()(()(((((((()((((())))())())())())()((((((((((((((()()((((((()()()())())()())())())(())(())))())((()())((()(()))))))()))))))))))))))))())((())((())()()))))))(((()((()(()()))((())(()()))()()())))(())))))))(()(((())))())()())))()()(())()))()(()))())((()()))))(()))))()))(()()(())))))))()(((()))))()(()))(())())))))()))((()))((()))())(())))))))))((((())()))()))()))())(())()()(())))())))(()())()))((()()(())))(())((((((()(())((()(((()(()()(())))()))))))()))()(()((()))()(()))(()(((())((((())())(())(()))))))))())))))))())())))))())))))()()(((())()(()))))))))())))))(())()()()))()))()))(()(())()()())())))))))())()(()(()))))()()()))))())(()))))()()))))()())))))(((())()()))(()))))))))))()()))))()()()))))(()())())()()())()(()))))()(()))(())))))))(((((())(())())()()))()()))(())))))()(()))))(())(()()))()())()))()))()))()))))())()()))())())))(()))(()))))))())()(((())()))))))))()))()())))())))())))()))))))))))()()))(()()))))))(())()(()))))())(()))))(()))))(()())))))())())()()))))())()))))))))(()))))()))))))()(()())))))))()))())))())))())))())))))))())(()()))))))(()())())))()())()))))))))))))))())))()(())))()))())()()(())(()()))(())))())()())(()(()(()))))())))))))))))())(()))()))()))))(())()())()())))))))))))()()))))))))))))())())))))(()())))))))))))())(())))()))))))))())())(()))()))(())))()))()()(())()))))))()((((())()))())())))))()))()))))((()())()))))())))(())))))))))))))))))()))))()()())()))()()))))())()))((()())))())))(()))(()())))))))()))()))))(())))))))(())))))())()()(()))())()))()()))))())()()))))())()))())))))))(()))))()())()))))))))(()))())))(()))()))))(())()))())())(())())())))))))((((())))))()))()))()())()(())))()))()))()())(()())()()(()())()))))())())))))(()))()))))())(()()(())))))(())()()((())())))))(())(())))))))())))))))))()(())))))))()())())())()(()))))))))(()))))))))())()()))()(()))))))()))))))())))))))(())))()()(())()())))))(((())))()((())()))())))(()()))())(())())))()(((()())))))()(()()())))()()(()()(()()))())()(()()()))())()()))()())(()))))())))))())))(())()()))))(()))))(())(()))(())))))()()))()))))())()))()()(())())))((()))())()))))))()()))))((()(()))))()()))))))())))))())(()((()())))))))))))()())())))()))(()))))))(()))(())()())))(()))))))))())()()()()))))(()())))))))((())))()))(()))(())(())()())()))))))))(())))())))(()))()()))(()()))(()))())))()(())))())((()((()(())))((())))()))))((((())())()())))(())))()))))))())(()()((())))())()(()())))))(()())()))())))))))((())())))))))(()(()))())()()(()()(((()(((()())))))()))))))()(())(()()((()()(())()()))())()())()))()())())())))))))(((())))))))()()))))))(((())()))(()()))(()()))))(()(()()((((())()())((()()))))(()(())))))()((()()()())()()((()((()()))(()))(((()()()))(((())))()(((())()))))))((()(())())))(()())(((((()(()))(()((()))(()())()))))(()(()))()(()))(())(((())(()()))))()()))(((()))))(()()()()))())))((()()()(())()))()))))()()))()))))))((((((()()()))))())((()()(((()))))(()(())(()()())())())))()(((()()))(())((())))(()))(()()()())((())())())(()))))()))()((()(())()(()()(())(()))(())()))(())(()))))(())(())())(()()(()((()()((())))((()))()((())))(((()()()()((((()))(()()))()()()(((())((())())(()()(()()()))()((())(())()))())(((()()(())))()((()()())()())(()(())())(((())(())())((())(())()(((()()))(())))((())(()())())(())((()()()((((((())))((()(((((())()))()))(())(()()))()))(())()()))(())((()()())()()(()))())()((())))()((()()())((((()())((())())())((()((()))()))((())((()()(()((()()(((())(()()))))((()((())()(((())(()((())())((())(()((((((())())()(()())()(())(((())((((((()(())(()((()()()((()()(()()()())))()()(((((()()))()((((((()))()(()(()(()(((()())((()))())()((()))(())))()))()()))())()()))())((((())(()(()))(((((((())(((()(((((()(((()()((((())(((())())))(()()()(()(()))()))((((((()))((()(((()(())((()((((()((((((())(((((())))(((()(()))))(((()(((())()((())(()((()))(((()()(((())((((()(()(((((()))(((()(((((((()(()()()(()(()(()()())(())(((((()(())())()())(()(()(()))()(()()()())(()()(()((()))()((())())()(()))((())(()))()(()))()(((()(()(()((((((()()()()())()(((((()()(((()()()((()(((((()))((((((((()()()(((((()))))))(()()()(())(()))(()()))))(())()))(((((()(((((()()(()(()())(((()))((((()((()(()(()((()(()((())))()(((()((()))((()))(((((((((()((()((()(())))()((((()((()()))((())(((()(((((()()(()(()()((()(()()()(((((((())())()())))))((((()()(()))()))(()((())()(()(((((((((()()(((()(()())(()((()())((())())((((()(((()(((()((((()((()((((()(()((((((())((((((((((((()()(()()((((((((((((((()((()()))()((((((((((((())((((()(()())((()(()(()))()(((((()()(((()()))()())(())((()(((((()((())(((((()((()(((((()))()()((((())()((((())(((((((((()(())(()(())))())(()((())(((())(())(())())(()(()(())()()((()((())()(((()(((((()(())))()(((()((())))((()()()(((()(((()((()(()(())(()((()())(()(()(((()(((((((((())(()((((()()))(()((((()()()()(((()((((((((()(()()((((((()(()()(()((()((((((((((()()(((((((()())(())))(((()()))(((((()((()()())(()()((((())((()((((()))))(())((()(()()(((()(()(((()((((()(((((()))())())(()((())()))(((()())((())((())((((()((()((((((())(()((((()()))((((((())()(()))((()(((())((((((((((()()(((((()(((((()((()()()((((())))(()))()((()(())()()((()((((((((((()((())(())(((((()(()(()()))((((()((((()()((()(((()(((((((((()(()((()((()))((((((()(((())()()((()(((((((()())))()()(()((()((()()(((()(()()()()((((()((())((((()(((((((((()(((()()(((()(()(((()(((()((())()(()((()(()(()(()))()(((()))(()((((()((())((((())((((((())(()))(()((((())((()(()((((((((()()((((((()(()(()()()(())((()((()()(((()(((((((()()((()(((((((()))(((((()(((()(()()()(()(((()((()()((())(()(((((((((()(()((()((((((()()((())()))(((((()((())()())()(((((((((((()))((((()()()()())(()()(()(()()))()))(()))(()(((()()))())(()(()))()()((())(()())()())()(()))()))(()()(()((((((())((()(((((((((((()(())()((()(()((()((()(()((()((((((((((()()())((())()(())))((())()())()(((((()(()())((((()((()(())(()))(((())()((()))(((((())(()))()()(()))(((())((((()((((()(())))(((((((()))))())()())(())((())()(()()((()(()))()(()()(()()((()())((())((()()))((((()))()()))(()()(())()()(((((()(())((()((((()))()))(()())())(((()()(()()))(())))))(()))((())(((((()((((()))()((((()))()((())(((())))(((()())))((()(()()((
  (defun day1/parse-directions (directions)
    (seq-map
                   (lambda (char)
                     (cond ((eq char ?\() 1)
                           ((eq char ?\)) -1)
                           (t 0)))
                   directions))

  (seq-reduce #'+
              (day1/parse-directions input)
              0)
74

Part 2

Now, given the same instructions, find the position of the first character that causes him to enter the basement (floor -1). The first character in the instructions has position 1, the second character has position 2, and so on.

For example:

  • ) causes him to enter the basement at character position 1.
  • ()()) causes him to enter the basement at character position 5.

What is the position of the character that causes Santa to first enter the basement?


  (defun day1/steps-until (predicate reduce-fn sequence initial-value)
    (car (seq-reduce
          (lambda (acc next)
            (let ((counter (car acc))
                  (value (cdr acc)))
              (if (funcall predicate value) acc
                (cons (+ 1 counter)
                      (funcall reduce-fn value next)))))
          sequence
          (cons 0 initial-value))))

  (day1/steps-until
   (lambda (floor) (= floor -1))
   #'+
   (day1/parse-directions input)
   0)
1795

Day 2: I Was Told There Would Be No Math

The elves are running low on wrapping paper, and so they need to submit an order for more. They have a list of the dimensions (length l, width w, and height h) of each present, and only want to order exactly as much as they need.

Fortunately, every present is a box (a perfect right rectangular prism), which makes calculating the required wrapping paper for each gift a little easier: find the surface area of the box, which is 2*l*w + 2*w*h + 2*h*l. The elves also need a little extra paper for each present: the area of the smallest side.

For example:

  • A present with dimensions 2x3x4 requires 2*6 + 2*12 + 2*8 = 52 square feet of wrapping paper plus 6 square feet of slack, for a total of 58 square feet.
  • A present with dimensions 1x1x10 requires 2*1 + 2*10 + 2*10 = 42 square feet of wrapping paper plus 1 square foot of slack, for a total of 43 square feet.

All numbers in the elves' list are in feet. How many total square feet of wrapping paper should they order?


  20x3x11
  15x27x5
  6x29x7
  30x15x9
  19x29x21
  10x4x15
  1x26x4
  1x5x18
  10x15x23
  10x14x20
  3x5x18
  29x23x30
  7x4x10
  22x24x29
  30x1x2
  19x2x5
  11x9x22
  23x15x10
  11x11x10
  30x28x5
  22x5x4
  6x26x20
  16x12x30
  10x20x5
  25x14x24
  16x17x22
  11x28x26
  1x11x10
  1x24x15
  13x17x21
  30x3x13
  20x25x17
  22x12x5
  22x20x24
  9x2x14
  6x18x8
  27x28x24
  11x17x1
  1x4x12
  5x20x13
  24x23x23
  22x1x25
  18x19x5
  5x23x13
  8x16x4
  20x21x9
  1x7x11
  8x30x17
  3x30x9
  6x16x18
  22x25x27
  9x20x26
  16x21x23
  5x24x17
  15x17x15
  26x15x10
  22x16x3
  20x24x24
  8x18x10
  23x19x16
  1x21x24
  23x23x9
  14x20x6
  25x5x5
  16x3x1
  29x29x20
  11x4x26
  10x23x24
  29x25x16
  27x27x22
  9x7x22
  6x21x18
  25x11x19
  14x13x3
  15x28x17
  14x3x12
  29x8x19
  30x14x20
  20x23x4
  8x16x5
  4x11x18
  20x8x24
  21x13x21
  14x26x29
  27x4x17
  27x4x25
  5x28x6
  23x24x11
  29x22x5
  30x20x6
  23x2x10
  11x4x7
  27x23x6
  10x20x19
  8x20x22
  5x29x22
  16x13x2
  2x11x14
  6x12x4
  3x13x6
  16x5x18
  25x3x28
  21x1x5
  20x16x19
  28x30x27
  26x7x18
  25x27x24
  11x19x7
  21x19x17
  2x12x27
  20x5x14
  8x5x8
  6x24x8
  7x28x20
  3x20x28
  5x20x30
  13x29x1
  26x29x5
  19x28x25
  5x19x11
  11x20x22
  4x23x1
  19x25x12
  3x10x6
  3x14x10
  28x16x12
  23x12x2
  23x12x19
  20x28x10
  9x10x25
  16x21x16
  1x18x20
  9x4x26
  3x25x8
  17x16x28
  9x28x16
  27x3x12
  17x24x12
  13x21x10
  7x17x13
  6x10x9
  7x29x25
  11x19x30
  1x24x5
  20x16x23
  24x28x21
  6x29x19
  25x2x19
  12x5x26
  25x29x12
  16x28x22
  26x26x15
  9x13x5
  10x29x7
  1x24x16
  22x2x2
  6x16x13
  3x12x28
  4x12x13
  14x27x21
  14x23x26
  7x5x18
  8x30x27
  15x9x18
  26x16x5
  3x29x17
  19x7x18
  16x18x1
  26x15x30
  24x30x21
  13x20x7
  4x12x10
  27x20x11
  28x29x21
  20x14x30
  28x12x3
  19x1x8
  4x8x6
  21x14x2
  27x19x21
  17x24x14
  15x18x11
  18x7x26
  25x28x29
  27x26x9
  18x12x17
  24x28x25
  13x24x14
  26x9x28
  9x3x30
  9x2x9
  8x1x29
  18x30x10
  18x14x5
  26x8x30
  12x1x1
  30x5x28
  26x17x21
  10x10x10
  20x7x27
  13x17x6
  21x13x17
  2x16x8
  7x9x9
  15x26x4
  11x28x25
  10x6x19
  21x6x29
  15x5x6
  28x9x16
  14x3x10
  12x29x5
  22x19x19
  25x15x22
  30x6x28
  11x23x13
  20x25x14
  26x1x13
  6x14x15
  16x25x17
  28x4x13
  10x24x25
  4x13x10
  9x15x16
  15x24x6
  22x9x19
  11x11x8
  4x19x12
  24x5x4
  27x12x13
  7x27x16
  2x6x9
  29x27x15
  18x26x23
  19x16x15
  14x5x25
  9x16x30
  4x6x4
  13x10x10
  1x8x29
  23x5x17
  19x20x20
  11x27x24
  27x15x5
  15x11x12
  21x11x3
  1x13x22
  17x8x8
  13x14x14
  17x22x7
  9x5x8
  2x6x3
  25x9x15
  11x8x13
  9x25x12
  3x16x12
  12x16x8
  16x24x17
  4x6x26
  22x29x11
  14x17x19
  28x2x27
  24x22x19
  22x20x30
  23x28x4
  16x12x14
  22x24x22
  29x1x28
  26x29x16
  3x25x30
  27x3x13
  22x24x26
  25x3x2
  7x24x2
  10x5x3
  28x8x29
  25x6x4
  12x17x14
  24x3x5
  23x27x7
  26x23x30
  11x10x19
  23x7x11
  26x14x15
  14x3x25
  12x24x14
  2x14x12
  9x12x16
  9x2x28
  3x8x2
  22x6x9
  2x30x2
  25x1x9
  20x11x2
  14x11x12
  7x14x12
  24x8x26
  13x21x23
  18x17x23
  13x6x17
  20x20x19
  13x17x29
  7x24x24
  23x8x6
  19x10x28
  3x8x21
  15x20x18
  11x27x1
  11x24x28
  13x20x11
  18x19x22
  27x22x12
  28x3x2
  13x4x29
  26x5x6
  14x29x25
  7x4x7
  5x17x7
  2x8x1
  22x30x24
  22x21x28
  1x28x13
  11x20x4
  25x29x19
  9x23x4
  30x6x11
  25x18x10
  28x10x24
  3x5x20
  19x28x10
  27x19x2
  26x20x4
  19x21x6
  2x12x30
  8x26x27
  11x27x10
  14x13x17
  4x3x21
  2x20x21
  22x30x3
  2x23x2
  3x16x12
  22x28x22
  3x23x29
  8x25x15
  9x30x4
  10x11x1
  24x8x20
  10x7x27
  7x22x4
  27x13x17
  5x28x5
  30x15x13
  10x8x17
  8x21x5
  8x17x26
  25x16x4
  9x7x25
  13x11x20
  6x30x9
  15x14x12
  30x1x23
  5x20x24
  22x7x6
  26x11x23
  29x7x5
  13x24x28
  22x20x10
  18x3x1
  15x19x23
  28x28x20
  7x26x2
  9x12x20
  15x4x6
  1x17x21
  3x22x17
  9x4x20
  25x19x5
  9x11x22
  14x1x17
  14x5x16
  30x5x18
  19x6x12
  28x16x22
  13x4x25
  29x23x18
  1x27x3
  12x14x4
  10x25x19
  15x19x30
  11x30x4
  11x22x26
  13x25x2
  17x13x27
  11x30x24
  15x1x14
  17x18x4
  26x11x3
  16x22x28
  13x20x9
  1x18x3
  25x11x12
  20x21x1
  22x27x4
  8x28x23
  7x13x27
  17x9x26
  27x27x20
  11x20x12
  26x21x11
  29x14x12
  27x25x1
  28x29x25
  21x23x28
  5x18x18
  19x5x4
  7x6x30
  27x8x11
  12x24x12
  16x25x22
  26x11x29
  25x22x17
  15x23x23
  17x9x6
  30x10x16
  21x3x5
  18x27x2
  28x21x14
  16x18x17
  4x18x2
  9x1x14
  9x1x9
  5x27x12
  8x16x30
  3x19x19
  16x26x24
  1x6x9
  15x14x3
  11x7x19
  8x19x3
  17x26x26
  6x18x11
  19x12x4
  29x20x16
  20x17x23
  6x6x5
  20x30x19
  18x25x18
  2x26x2
  3x1x1
  14x25x18
  3x1x6
  11x14x18
  17x23x27
  25x29x9
  6x25x20
  20x10x9
  17x5x18
  29x14x8
  14x25x26
  10x15x29
  23x19x11
  22x2x2
  4x5x5
  13x23x25
  19x13x19
  20x18x6
  30x7x28
  26x18x17
  29x18x10
  30x29x1
  12x26x24
  18x17x26
  29x28x15
  3x12x20
  24x10x8
  30x15x6
  28x23x15
  14x28x11
  10x27x19
  14x8x21
  24x1x23
  1x3x27
  6x15x6
  8x25x26
  13x10x25
  6x9x8
  10x29x29
  26x23x5
  14x24x1
  25x6x22
  17x11x18
  1x27x26
  18x25x23
  20x15x6
  2x21x28
  2x10x13
  12x25x14
  2x14x23
  30x5x23
  29x19x21
  29x10x25
  14x22x16
  17x11x26
  12x17x30
  8x17x7
  20x25x28
  20x11x30
  15x1x12
  13x3x24
  16x23x23
  27x3x3
  26x3x27
  18x5x12
  12x26x7
  19x27x12
  20x10x28
  30x12x25
  3x14x10
  21x26x1
  24x26x26
  7x21x30
  3x29x12
  29x28x5
  5x20x7
  27x11x2
  15x20x4
  16x15x15
  19x13x7
  7x17x15
  27x24x15
  9x17x28
  20x21x14
  14x29x29
  23x26x13
  27x23x21
  18x13x6
  26x16x21
  18x26x27
  9x3x12
  30x18x24
  12x11x29
  5x15x1
  1x16x3
  14x28x11
  2x18x1
  19x18x19
  18x28x21
  2x3x14
  22x16x5
  28x18x28
  24x16x18
  7x4x10
  19x26x19
  24x17x7
  25x9x6
  25x17x7
  20x22x20
  3x3x7
  23x19x15
  21x27x21
  1x23x11
  9x19x4
  22x4x18
  6x15x5
  15x25x2
  23x11x20
  27x16x6
  27x8x5
  10x10x19
  22x14x1
  7x1x29
  8x11x17
  27x9x27
  28x9x24
  17x7x3
  26x23x8
  7x6x30
  25x28x2
  1x30x25
  3x18x18
  28x27x15
  14x14x1
  10x25x29
  18x12x9
  20x28x16
  26x27x22
  8x26x1
  21x2x12
  25x16x14
  21x19x5
  12x9x22
  16x5x4
  5x4x16
  25x29x3
  4x29x13
  15x16x29
  8x11x24
  30x11x20
  17x21x14
  12x24x10
  10x12x6
  3x26x30
  15x14x25
  20x12x21
  13x11x16
  15x13x3
  5x17x29
  6x3x23
  9x26x11
  30x1x8
  14x10x30
  18x30x10
  13x19x19
  16x19x17
  28x7x10
  28x29x4
  3x21x10
  4x28x24
  7x28x9
  2x4x9
  25x27x13
  6x12x15
  4x18x20
  20x1x16
  5x13x24
  11x11x10
  12x9x23
  1x9x30
  17x28x24
  9x5x27
  21x15x16
  17x4x14
  8x14x4
  13x10x7
  17x12x14
  9x19x19
  2x7x21
  8x24x23
  19x5x12
  11x23x21
  13x3x1
  5x27x15
  12x25x25
  13x21x16
  9x17x11
  1x15x21
  4x26x17
  11x5x15
  23x10x15
  12x17x21
  27x15x1
  4x29x14
  5x24x25
  10x10x12
  18x12x9
  11x24x23
  24x23x3
  28x12x15
  29x9x14
  11x25x8
  5x12x2
  26x26x29
  9x21x2
  8x8x25
  1x16x30
  17x29x20
  9x22x13
  7x18x16
  3x3x23
  26x25x30
  15x23x24
  20x23x5
  20x16x10
  23x7x8
  20x18x26
  8x27x6
  30x23x23
  7x7x24
  21x11x15
  1x30x25
  26x27x22
  30x28x13
  20x13x13
  3x1x15
  16x7x1
  7x25x15
  12x7x18
  16x9x23
  16x12x18
  29x5x2
  17x7x7
  21x17x5
  9x9x17
  26x16x10
  29x29x23
  17x26x10
  5x19x17
  1x10x1
  14x21x20
  13x6x4
  13x13x3
  23x4x18
  4x16x3
  16x30x11
  2x11x2
  15x30x15
  20x30x22
  18x12x16
  23x5x16
  6x14x15
  9x4x11
  30x23x21
  20x7x12
  7x18x6
  15x6x5
  18x22x19
  16x10x22
  26x20x25
  9x25x25
  29x21x10
  9x21x24
  7x18x21
  14x3x15
  18x19x19
  4x29x17
  14x10x9
  2x26x14
  13x3x24
  4x4x17
  6x27x24
  2x18x3
  14x25x2
  30x14x17
  11x6x14
  4x10x18
  15x4x2
  27x7x10
  13x24x1
  7x12x6
  25x22x26
  19x2x18
  23x29x2
  2x15x4
  12x6x9
  16x14x29
  9x17x3
  21x9x12
  23x18x22
  10x8x4
  29x2x7
  19x27x15
  4x24x27
  25x20x14
  8x23x19
  1x24x19
  6x20x10
  15x8x5
  18x28x5
  17x23x22
  9x16x13
  30x24x4
  26x3x13
  12x22x18
  29x17x29
  26x4x16
  15x7x20
  9x15x30
  12x7x18
  28x19x18
  11x23x23
  24x20x1
  20x3x24
  1x26x1
  14x10x6
  5x27x24
  13x21x12
  20x20x5
  6x28x9
  11x26x11
  26x29x12
  21x4x11
  20x11x17
  22x27x20
  19x11x21
  2x11x11
  13x5x7
  12x10x25
  21x28x1
  15x30x17
  28x19x1
  4x19x12
  11x4x12
  4x10x30
  11x18x5
  22x20x12
  3x7x27
  20x26x4
  13x27x26
  23x14x13
  4x19x7
  26x27x16
  20x5x20
  18x5x8
  19x21x1
  22x8x1
  29x4x1
  24x10x15
  24x9x20
  10x3x8
  29x30x3
  2x8x24
  16x7x18
  2x11x23
  23x15x16
  21x12x6
  24x28x9
  6x1x13
  14x29x20
  27x24x13
  16x26x8
  5x6x17
  21x8x1
  28x19x21
  1x14x16
  18x2x9
  29x28x10
  22x26x27
  18x26x23
  22x24x2
  28x26x1
  27x29x12
  30x13x11
  1x25x5
  13x30x18
  3x13x22
  22x10x11
  2x7x7
  18x17x8
  9x22x26
  30x18x16
  10x2x3
  7x27x13
  3x20x16
  9x21x16
  1x18x15
  21x30x30
  4x25x23
  3x11x7
  5x6x12
  27x1x20
  13x15x24
  23x29x2
  13x5x24
  22x16x15
  28x14x3
  29x24x9
  2x20x4
  30x10x4
  23x7x20
  22x12x21
  3x19x11
  4x28x28
  5x4x7
  28x12x25
  2x16x26
  23x20x7
  5x21x29
  9x21x16
  9x6x10
  9x6x4
  24x14x29
  28x11x6
  10x22x1
  21x30x20
  13x17x8
  2x25x24
  19x21x3
  28x8x14
  6x29x28
  27x10x28
  30x11x12
  17x2x10
  14x19x17
  2x11x4
  26x1x2
  13x4x4
  23x20x18
  2x17x21
  28x7x15
  3x3x27
  24x17x30
  28x28x20
  21x5x29
  13x12x19
  24x29x29
  19x10x6
  19x12x14
  21x4x17
  27x16x1
  4x17x30
  23x23x18
  23x15x27
  26x2x11
  12x8x8
  15x23x26
  30x17x15
  17x17x15
  24x4x30
  9x9x10
  14x25x20
  25x11x19
  20x7x1
  9x21x3
  7x19x9
  10x6x19
  26x12x30
  21x9x20
  15x11x6
  30x21x9
  10x18x17
  22x9x8
  8x30x26
  28x12x27
  17x17x7
  11x13x8
  5x3x21
  24x1x29
  1x28x2
  18x28x10
  8x29x14
  26x26x27
  17x10x25
  22x30x3
  27x9x13
  21x21x4
  30x29x16
  22x7x20
  24x10x2
  16x29x17
  28x15x17
  19x19x22
  9x8x6
  26x23x24
  25x4x27
  16x12x2
  11x6x18
  19x14x8
  9x29x13
  23x30x19
  10x16x1
  4x21x28
  23x25x25
  19x9x16
  30x11x12
  24x3x9
  28x19x4
  18x12x9
  7x1x25
  28x7x1
  24x3x12
  30x24x22
  27x24x26
  9x30x30
  29x10x8
  4x6x18
  10x1x15
  10x4x26
  23x20x16
  6x3x14
  30x8x16
  25x14x20
  11x9x3
  15x23x25
  8x30x22
  22x19x18
  25x1x12
  27x25x7
  25x23x3
  13x20x8
  5x30x7
  18x19x27
  20x23x3
  1x17x21
  21x21x27
  13x1x24
  7x30x20
  21x9x18
  23x26x6
  22x9x29
  17x6x21
  28x28x29
  19x25x26
  9x27x21
  5x26x8
  11x19x1
  10x1x18
  29x4x8
  21x2x22
  14x12x8
  (defun day2/surface-area (w h l)
    "Calculate the surface area of a box."
    (+ (* 2 l w)
       (* 2 w h)
       (* 2 h l)))

  (defun day2/slack (w h l)
    "Find the area of the smallest side of a box.

  The smallest side is the side with the smallest area."
    (min (* l w)
         (* w h)
         (* h l)))

  (defun day2/wrapping-paper (w h l)
    "Find the area of wrapping paper needed to wrap a box."
    (+ (day2/surface-area w h l)
       (day2/slack w h l)))

  (ert-deftest day2/wrapping-paper ()
    (should (eq 58 (day2/wrapping-paper 2 3 4)))
    (should (eq 43 (day2/wrapping-paper 1 1 10))))

  (defun day2/parse-dimensions (dimension-string)
    "Parse a string representing the dimensions of a box separated
  by the character 'x' into a list of integers."
    (seq-map #'string-to-int
             (split-string dimension-string "x")))

  (defun day2/sum-list (input)
    (seq-reduce
     #'+
     (seq-map (lambda (dimension-string)
                (let ((dimensions (day2/parse-dimensions dimension-string)))
                  (eval (cons 'day2/wrapping-paper dimensions))))
              (split-string input))
     0))

  (ert-deftest day2/sum-list ()
    (let ((test-data (string-join '("2x3x4" "1x1x10") "\n")))
      (should (eq (+ 58 43)
                  (day2/sum-list test-data)))))

  (day2/sum-list input)
1606483

Part 2

The elves are also running low on ribbon. Ribbon is all the same width, so they only have to worry about the length they need to order, which they would again like to be exact.

The ribbon required to wrap a present is the shortest distance around its sides, or the smallest perimeter of any one face. Each present also requires a bow made out of ribbon as well; the feet of ribbon required for the perfect bow is equal to the cubic feet of volume of the present. Don't ask how they tie the bow, though; they'll never tell.

For example:

  • A present with dimensions 2x3x4 requires 2+2+3+3 = 10 feet of ribbon to wrap the present plus 2*3*4 = 24 feet of ribbon for the bow, for a total of 34 feet.
  • A present with dimensions 1x1x10 requires 1+1+1+1 = 4 feet of ribbon to wrap the present plus 1*1*10 = 10 feet of ribbon for the bow, for a total of 14 feet.

How many total feet of ribbon should they order?


  (defun day2/smallest-perimeter (w h l)
    (min (* 2 (+ l w))
         (* 2 (+ w h))
         (* 2 (+ h l))))

  (defun day2/volume (w h l)
    (* w h l))

  (defun day2/ribbon (w h l)
    (+ (day2/smallest-perimeter w h l)
       (day2/volume w h l)))

  (ert-deftest day2/ribbon ()
    (should (eq 34 (day2/ribbon 2 3 4)))
    (should (eq 14 (day2/ribbon 1 1 10))))

  (defun day2/sum-ribbon (input)
    (seq-reduce
     #'+
     (seq-map (lambda (dimension-string)
                (let ((dimensions (day2/parse-dimensions dimension-string)))
                  (eval (cons 'day2/ribbon dimensions))))
              (split-string input))
     0))

  (day2/sum-ribbon input)
3842356

Day 3: Perfectly Spherical Houses in a Vacuum

Santa is delivering presents to an infinite two-dimensional grid of houses.

He begins by delivering a present to the house at his starting location, and then an elf at the North Pole calls him via radio and tells him where to move next. Moves are always exactly one house to the north (^), south (v), east (>), or west (<). After each move, he delivers another present to the house at his new location.

However, the elf back at the north pole has had a little too much eggnog, and so his directions are a little off, and Santa ends up visiting some houses more than once. How many houses receive at least one present?

For example:

  • > delivers presents to 2 houses: one at the starting location, and one to the east.
  • ^>v< delivers presents to 4 houses in a square, including twice to the house at his starting/ending location.
  • ^v^v^v^v^v delivers a bunch of presents to some very lucky children at only 2 houses.

  >^^v^<>v<<<v<v^>>v^^^<v<>^^><^<<^vv>>>^<<^>><vv<<v^<^^><>>><>v<><>^^<^^^<><>>vv>vv>v<<^>v<>^>v<v^<>v>><>^v<<<<v^vv^><v>v^>>>vv>v^^^<^^<>>v<^^v<>^<vv^^<^><<>^>><^<>>><><vv><>v<<<><><>v><<>^^^^v>>^>^<v<<vv^^<v<^<^>^^v^^^^^v<><^v><<><^v^>v<<>^<>^^v^<>v<v^>v>^^<vv^v><^<>^v<><^><v^><><><<<<>^vv^>^vvvvv><><^<vv^v^v>v<<^<^^v^<>^<vv><v<v^v<<v<<^^>>^^^v^>v<><^vv<<^<>v<v><><v^^><v<>^^>^^>v^>^<<<<v><v<<>v><^v>^>><v^^<^>v<vvvv<>>>>>^v^^>v<v<^<vv>^>^vv^>vv^^v<<^<^^<>v>vv^v>><>>>v^>^>^^v<>^<v<<>^vv>v^<<v>v<<><v>^vvv<v<vvv^v<vv<v^^^>v><<^<>><v^^>^v^>>^v<^<><v<>>v^<>>v<>>v^^^><^>>vvvv>^v<^><<>>^<>^>vv><v<<>>^^>v^^^><^<<^^v>v<^<<>v>^^vvv^v^>v^<>^^<>v^v>v>v<v^>vv>^^v<>v>>^<>><>v>v^<<vvvv<vvv><v^<^>^v<>>^><v>><>^<v>v<v>vv^>>vvv<>v>v<v^>>^>>v<<>^<>^<>>>^v<<<^<^v>vv^>><<><v^>^v^^^v<>^^vv><>><>>^>v^<v<>v<>>^<<^v>^^^<>^v^><>v<<v>vv^>vv<<>>><<^v^<>v<vv>>>^^<>^><<^>vv>>^<<v^^vv<>>><v>v><^<v<<>>>^^<>>^<^v><>vv^^^v>vvv>^><<>^^>^<<v^<v<^v<<>vvv<^<<>^>^v<vv<^>vvv>v>vv^<v^><>>^vv<^^^vv><^vv<v^<><v^vvv><<^>^^><v<<vv^>v<vv<v>^<>^v<<>v<v^v^>^>^>v<<^vvv<<<v>^^>^<<<<>vv>>^<>^>>>v<v>^^<v^<v<>>>vv>^^v<<>>>^^v><<<v<v<^v<>^^><v<^v<<v^><><^<><v<^^v>>><v^^v<<v^><^<><<v^>><^<>v>v^<><^<v>^v^>^>^vv^>^^<<vv^>vv<^vvv<>>^^<^>v^>^>^<v^><v<v>>>v<<<><^v<<><^<vv^v^^^>v<^^<v^vvv<v<><v<vv<^vv<>vv<v^<>>vvvvv<<>^v^v>vv>>>vvv^^<^<^<><>v<v>><^v><^<<<>><<<v>^>v<>^>^v>>^<>v^<^>><<>^<v>^>^^^>^^<v>>>><>^v^v><<<<vv^<vv<>vv>v<>v^<v^>v><>>>v^<><^vvv>vv^<^<<^<^^v>^>>>v<^<^v^^<^<^>>><v>vv>^<<><>^>>v>^<<>><^<>v<>vv^^>^>vvv^v<<^<^^<vv<>^vvv<^^v^vv^>>v<^>^^<v^<>v<^<^vv>v<<vv>vv>^>vvv>>>^^>v<>^v>v^<^>>v>^^v>>>>v^<v>v<^>v<v<<>>^v<^^<v><^<>>^<<vv^>>v<<v>^v<>><^>vv<v<^>>^^<vvvvvvvvv>>>v<v<>v^<>>^vv<v^^v<<^vvv^<<^><>vv<><<>>v>vv^><>>^^v^>>v^v^><<<>>^^<^v<<^<>>>>^<^>v^><<^>v<^v<^>>^^<<<<><^<^v^v<>>^v<^<<vv^<><^^vv><v^v^v>^>>^>^vv^>^v<v^v<<vvv^><>>^v^^><>v>vv><^>>vv<vvv<<<<^<>vvv^v<v>^<v<^>^<^<v<><>v^^^^<<vv<^^vv<v>><<v^><>>><v^>^v><^>^><vv^<><^<v>><<^vv<>>v^<<v<>v><v<><><vv>^>>v^<^<v>^><>>><^><v^v<>>>^^<^>v<v>vvv<>^<<><v^^>^>>v<^v>^>v>>>vv>v>>v^^^<^<vvv^<>^>^<v^<v^v>v>^>vv>vvv<>v<^>v>^^>>^<vv^^v>v^^^^^v^vv><^<><>^>vv<^>>^vvvv^^^>^<vv>^v<<^><^^>^<>^^>^<<v<^>>>^><<^^>v^v>>^>vvvv>^^v><v>>vv><<<vv<^>v>^^^<v>v^vvv<^><<^>^<>^><<<<<v^<<vv^v>^<>v<v>^>^>><>v^v<^vv^^>vv<<v^v>vv^vvv<<<<>^v<v^^v^v>v<<v>^^<>^vv^^>^>^v^vv^>>v^vv^^<vv><<v^v^^v><vv<^vvv<vv^^<<v>v^v^^^^v<^<^>v>^>v>^vv^v^^<v<^vvvv<<<>^<^^^<^^<>^<><vv<^^<<^>>><v^vvvv>^<>>^^>v^^v^<<v^^^<<<><^<v^v^^v<v^<>v><<v<>^v>v<^><^>vv^^<vvv<^v>>v>^<><v^><^^^<v^>>vv<<<<<^<>^v^v>^vv^<>v>v<^>vv<<^vv>vv<v<><>>v>><v<^<^^>><<v^v<<^><v<^<vv<v<<vv^>^<<><^^>^<^>>^<vv>><v<<vvv<^^v^>^^<^v>^v<v<>v><v^v^<<^<><<v<<^v>v<<>>^>v>>v>>v<^<<^<^>>>v>^^^v><^>^^>>v<<>^v><v>vvv^vv<<<>vvv<<>^>>>v<v<v^<^<^>^<^>v^^v<^^<v<>v<>>^^>^v^>v<<<<^<>v^><<<v>>>><<v^<^vv>v>><>>^<<<^<^^>v<>>v<>vv<<^<<><<^>v^^^vv^>vvvv>>v>v^><<v<>vv^<<><<vvv>^>>>^<<<^<^<<v>^>v<>>v>>vv^^><<<<^^^v>><<^><v><v^^><v<<v^^v^^v>>v<><><<>^><v><^<vv>><^v<>v<vvv<>^>><v>>v<^><<v>^<>^v><^><^^<v>^><^^v^<<><>>^>v^<^v^vv<><^>vv^>v^vvv^<>>^><^<^<>^<<v^v<^v><>^v<v>>^>>^v^vv>><vv><v^^<<^v^<>^v<<>^><^>><v>>v<<<v^^vv<>^^v>>><><><<v^<<<v^<^^><v^>v^^vv<v^<>>vv^<^v<>^v>>v^v>v<^^vv><>^v<<>v^<>v^>>v>vvv<^><><^^>^vv^>>v^>^<^^<><>><<>^^^><^v^v><<<><<^v^vv>v>><^>>><v^>v<v><><v^v<>v^^>>v<<>v>v<v<v<^^<><>v^^<>>v<^v<v>v<><v<v>^<<>v>vv^^<>>^^^<>^^>^v>v>>>^v^v><v^^<><v>^^v^v<^<^^><<v<^<^<>^<>><<>^>>^>^^><v><>v<><>><<<>>>>vv>>>^>>^v<^>v^^^v<<vv>><<<^<<<>>>>>^>vv<^v^<>^<v^>^v><v>vvv<>>>^v^^^v<<<<>>^^<vv<^<^^>^<>v<^<<<>><>>v<^<>^<vvv<^<>><><<v>^^^>^^<<v<v^>^^v^>><<^vv><v>^v>>^<v>v>^^>^v>^vvv<>v^v^^<><vv>vv^>>><>v<^><v<v^<><<<>^v>^v<<<^>^>^>v^v<<><vvv<<v^^<><v>^>>><vv>><v>>v^<vv>>vv<<^v^v<<><^v<vv>>>vv<>>>>^vv>v^<>vv>v^v<v^><v<^^^^^>vv<><<vvv^<v><^<vv><^^^vv^<>^^^^<^><^<>v^<v^v<<^v<<^^<>>^<v^^>>>vv<vvv<>v<<>><^vvv^<<^^<<>>>^<>>>v^^><>><<>><v^v>>>>>><>>><v^<<vvv^>v<>>v^<>vv<><^^^^v^<<^<v^vv><<^^>v<^vvv^v>>v>^>>v>^^><<v^<>v<>vv<^v^vv><v><<vv^v>>v^>>v<^^^>^><<v<>^><>v>>>vvv<v<vv<^>>^v<v>^<^^^^^v><>v><>v^v^v<v^vv^v>vvvv<>vv<<<vv<v<<>^<^>^^v^<<>^<v><^><v<v<><<>v^<<^<><vv>v<<^v>>^v<><v>^>>^^><>v^<^<vvv^>^>^<<<<>vv>^v^v<^^^<vv>><>^^<<v<^<^^>>>v^v<<^^^<v<v<^<>^v<v><v^vv^^v^^v^^<vv<>^<><vv^<^v^<<^><<vvv>^^<^^^<^v>^>^vv><<<^v<v>vv>v<>v^v<v^>v^>>>v^v<>^v<<>^vv>v>v>v^<^>v^^<^>^^^^vv>^^><^>vv^>>^^v>><<<<^><>v<>^<v<vv^>^^><<^><v>v^>^^<^>>><>><v^v<v^<v<vv^v^<<^<vvv>>><vv<^^>>^>^><<v^<>>v>v^v^^><<>vv^v>v^<v><^<>^^<^>v>^<><<<v>^<^<^>^>^>^^v^<<^^v^^<^<>><^>v>>^^<>^^^<<<<v^>^v<^vv>^<<<v<><<v<>vv>>>v><>>><>>v<<<vv><>^v>v<^>><^><><v<>^v^>^v>^v<<><<^<>>v>^><>^>><>><^<v^><v^^<><v><^^>^v^^<>v^<v^<^v<v^^^^^v^<<^>^^^<^v><>^^<<<><<<<<^^>v^vvvv>v<>>vv<^>^v^>v<^vv^v<<><<v>v^v>^^><><^<v^>v><vv><>>><<>^vv<>v>>v<^v>>>v<v>v>v>^vv<<>^^vv<v<^v^<v<v>vv<>^<^<vv<v^<^v^^><<>^>><^v>vv^^v<<^^><<>v^^<><><v^^<v^v>^>^>^>v<^<v>^v^^>v<>vvv<^v<v^v><<v^><<^^><^<<v^v^>v<>^>v><><v>^<v<v>^<^^^>^v<<><<><>vv>v^<>v^><v^v<v><><<v>v<vv><<v>>v>^<<<>vv>>vvv>^^vv^v^^<^^<>v^^<>v>>^^>^>^>v>><^>><>>^<<>><^>v<<<<<<<^v^v<v^<v^^>^<><<v<^>v^>v^vv<<^^vv^>>>>^<>v<^v<>v<vv<^>>v^vv>vv><vv<<^>v>><vv>>>vv^<<<<vv^>v<<<<^^>^^v^><<^<v^>v^>^^<v<>vvv^>^<>vvv<v<^^>v^<<v>><>v<v<>^^<vvv>^>vv><><<<^^vv<v^<v<>v<>><<v><^vv^>^<^>^^^<<<v>vv^<^<<>^>^<vv>v><v<<^><^>^^<vv^v^^>>>>vv^><^^vv><>^<v^v>v<vv>v><<<v>v<v>^><v^^><v>v<^v^>>^^<v^>^^>vv>>vv^><^vv^vv<<^>vv>^v<v><vv><v<vvvvv>^^v^v><v>>>^vv<>v>^^^^<^>><>^v^^^>v<^^<<^^v<vv<>vvv<^>><><^>>^><^<>v<v<<><<v><v^v<>><^>v><<v^<v>v<^<vv^v^v^>vvv^^>v>^<vv^>v^v^<>v>^>>vv>><^^<v<<>^vv<><><<^v<v>v<<vv><>><^v<v>>v^>vvv^v^<<^><v<>^vv^>v^<v<^>>v<v><v><v>>^<<<v^<><<>v>^>^^<v<>>^<>^>^><<<^<<^<<^>^v>>><vvv>><<<<v>>>>>>>^<^v<^>v<>vv<><>v>>^>>^>vv^^><<^<v<v>>^^<<^>v<^>>vv>^<>v><^>v<vv>>>>>>^v<^<<<v^><vv<<>>vv<<><v<><<<v<^<v<>>v<^^^^v^^<^^^<^<vv><<^>><>v<<>v<v<>>>><>v^vv>^>^>>vv^v<v<<><^v>vv^><v<<>v^v<^>vv<<^^v><^>>^^vv<^<>>v^^>><v>^v>>>^>>v>v<>v<^vv><>^<<^>vv>>><><>v^><>v^>v>v><^v<><v<v>^v<<^vv^><^^>><^^^<<<^>v>^v>>><^>><^>>>^^^<^>vv<><<<v^>^<^^>>^^^v^v^v>v<v>>>><^>>>v>^vv<<^^^<^^vv>v<<><v<<^^>v>><<v^^><^>^<^>^v^>v><^<^vv>v>><>^<<vv<<v>v<vv<v>^>^>><^^<v>^v^v<><<>vvv<^<v>^><>^>vvv>>>^><<>><v^^<^<<^v>>^v<v<vv>vv^v^>v<<vvv<^^v^v>^<^>>^>v<^>^v<<><<<^>^<^^^>vv<^^^^vv<v<^^v<<<<v<^v^<><v<<^><<>vv>>><^<^<>>>^>^>>^<<<<<^^v>^>^<>vvv^^<^><^>^^v>^vv^><v^<^<<v^<vvv<<^v<><^><^>>>v>^v>^>^v<vv^v>><v><^><v^^>v^>^<><<><>v<v^>vvv^>^>>v<>^><^>^><vvv>^^v^v>v<>^v^><^>>v>v^><<<^>>^<>^<>>v><>>v^>^>^^<>>v^>^<vvvv<^vvvv^>>vv^<v^v>^vv<>v<>^<v<v>v>^^><^>vv^<^v^<<^<^<><vv<^v<^v><>>>^v^<<^><^>vv<v>v<^>vv^>v<<<>^<><v<^^^>v><^^<>^<^<v^vv^<<^>><<v^v<^vvv<<<>>vvvv^v^^^>v<>>><<>vvv<<^^^>v>v>>v<<v<v^v^>^^v>^><^<><<v^<v<v^^^><>v^^^<v>vv<>^>^^vv>^<<^v<^v><v>>>^>>><^<<>^v>>^>vv<<<v<>^<v><v^<^<>v>v^^v^>><<^v<<<<>v>v>v^^<^><>^^<<<v>vv<>>>^>>v<><v^>^<><vv>v>v^v<v^<^>>^>><<^^<^^v<vv<>><<<v<^<<^^^>vvv^<vvv<^>vv><>><<<^<v^v^^<<^vvv^^<^<><<>^<^<>>vvv<>^<>v^v<><>>v^v><<>>>vvv>v<>^>>^><^>vv<<>>v<<^><>v>>^^<v>^>^<<>><^<<vv<^<vv^vv><>>>><^<v>^>vv<v><>^<>vvvvv^vv<<v<>>>^<<><>^^vvv>>>vv<<^^><^v^^v<>^^>^><^>v^^^^v<^<<vv<vv<>vv^^>v^vv>v><>>vv>^<^<v^v^>>v^v^^v>^>vv^>v<vvvv<^v<^v>^v>^^v<<^>^^<<>^><^v>>>vv^>^^>vvvv>>v<^<v>^>>>v^<><^<^^<v>vv^^><v>v^<>^^^>>><^^v>v>^<<>^<v^>vvv^>^^^><v<^>>v<v>>^v><<><<>v<^<<>^><>^>vv>^<v>^^v<<^v^vvv^^>^vv^<^>^>^^v>v^>^<<><<^>v>>vv^vv><v>>^<<^<v^^<^<v^^vv^><^^<^^><v^^>v^^^<^<>^<>>^v<^vvv^^v^<><^>>>>>v><><<<>vv<^v>><<>vvv<><<vv<<<^>v^^>>^>^v>><><^^v<>><>>v^>^<vv><<<>><><<v>^^<>>v<><^<vv>vv<^v>^<<<<v<^<<^^>>^<><^>><<>^>v>^^^v>>^<^^v><v^v>^><<><>>^>>^<<v<>^v<>^>^<v>>vv>^vvv<<v<<^>^>^<<^^<>^^^^vvv<>^vv<vvvvv^^>^^<^>>><>v^<><^<<^>v^^v<>>^vv<>v^^<>>v^vvvvv<<v^<v^^>>><vvvvv>><^>vv>v^v^<v<^>^^><^>^^^^v<><^v<<>v^>v>>vv<<>^<v^^>vvv>^^<v^<>vv^><>><v^^v<>^>>^>v><>>^^v>^>^>>>^>v<^v>v>^<^^^^^>>v<v<>>v<<^>^<v<<>^^>><<^><>v<>^^^vv<>^^>><<^^>v>vv>vv>v^>^v>v^^<>>><<v><v<<>>v><>vvv^^v>^^>^vvvv^>^<>^vvvv><v><v<>>><>^<^vv<>^v<^v<>^vvv<<>><vvv^>>^><<vv^<v^>^<v<<^^>^^<^^v^>v<>v^v><>><v^^>>^vvv><^vv>v^<^<^v>>v^^>^vvv^<v^^v^^>v<^<>>^<>>>^^<><^^vv<>^vv^<>>>>^^<<^^<>vv^^><>^^<v<<v>^<v^^>^v<><><>vvv>^v^>>vv<<^v<<>><v>^><^>>>^<^<^^>vv^<<^<>>^^><><<v>^^<v>>v<<vvvv>^v^vv>><^^<<^>>v>v<^^^<^><^^vv>^vv<^<vv<>v><^<><v><^^^>>^<><^<v>>>>v^<v>>>>>v<><^^>v<^<^>><v<>^>vv>^^v^v^<<v<><<<^v^><<^<><<<<v<^>><<<>v>>vv><vv<><<^<^<><vv>^^^^<>v<<<<v>vv<>vv^^^>><>vv^><>>^vv<<><^^vv<>v^>>^<<>^<v^<^>v<
  (defun day3/make-coord (x y)
    (cons x y))

  (defun day3/coord-x (coord)
    (car coord))

  (defun day3/coord-y (coord)
    (cdr coord))

  (defun day3/add-coords (a b)
    (day3/make-coord
     (+ (day3/coord-x a)
        (day3/coord-x b))
     (+ (day3/coord-y a)
        (day3/coord-y b))))

  (defun day3/arrow-to-coord (arrow)
    (cond ((eq arrow ?>) (day3/make-coord 1 0))
          ((eq arrow ?<) (day3/make-coord -1 0))
          ((eq arrow ?^) (day3/make-coord 0 1))
          ((eq arrow ?v) (day3/make-coord 0 -1))
          (t (day3/make-coord 0 0))))

  (defun day3/make-map ()
    (make-hash-table :test #'equal))

  (defun day3/map-visit (map coord)
    (puthash coord
             (+ 1 (gethash coord map 0))
             map))

  (defun day3/deliver (directions)
    (let ((map (day3/make-map)))
      (day3/map-visit map (day3/make-coord 0 0))
      (cdr (seq-reduce
            (lambda (acc next)
              (let* ((loc (car acc))
                     (map (cdr acc))
                     (next-loc (day3/add-coords loc
                                                (day3/arrow-to-coord next))))
                (day3/map-visit map next-loc)
                (cons next-loc map)))
            directions
            (cons (day3/make-coord 0 0)
                  map)))))

  (defun day3/map-count-visited (map)
    (hash-table-count map))

  (ert-deftest day3/map-count-visited ()
    (should (eq 2 (day3/map-count-visited
                   (day3/deliver ">"))))
    (should (eq 4 (day3/map-count-visited
                   (day3/deliver "^>v<"))))
    (should (eq 2 (day3/map-count-visited
                   (day3/deliver "^v^v^v^v^v")))))

  (day3/map-count-visited
   (day3/deliver input))
2592

Part 2

The next year, to speed up the process, Santa creates a robot version of himself, Robo-Santa, to deliver presents with him.

Santa and Robo-Santa start at the same location (delivering two presents to the same starting house), then take turns moving based on instructions from the elf, who is eggnoggedly reading from the same script as the previous year.

This year, how many houses receive at least one present?

For example:

  • ^v delivers presents to 3 houses, because Santa goes north, and then Robo-Santa goes south.
  • ^>v< now delivers presents to 3 houses, and Santa and Robo-Santa end up back where they started.
  • ^v^v^v^v^v now delivers presents to 11 houses, with Santa going one direction and Robo-Santa going the other.

  (require 'dash)

  (defun day3/alternate (count sequence)
    (->> (-zip (seq-into sequence 'list)
               (number-sequence 1 (seq-length sequence)))
         (-group-by (lambda (x) (mod (cdr x) count)))
         (-map (lambda (x) (-map #'car (cdr x))))))

  (defun day3/map-visit-n (map coord times)
    (puthash coord
             (+ times (gethash coord map 0))
             map))

  (defun day3/map-visits (map coord)
    (gethash coord map 0))

  (defun day3/map-locations (map)
    (hash-table-keys map))

  (defun day3/map-merge (a &rest maps)
    (-map (lambda (map)
            (-map (lambda (coord)
                    (day3/map-visit-n a coord (day3/map-visits map coord)))
                  (day3/map-locations map)))
          maps)
    a)

  (defun day3/deliver-with-robosanta (directions)
    (let* ((alternated (day3/alternate 2 (string-to-list directions)))
           (santa-directions (car alternated))
           (robot-directions (cadr alternated)))
      (day3/map-merge
       (day3/deliver santa-directions)
       (day3/deliver robot-directions))))

  (ert-deftest day3/deliver-with-robosanta ()
    (should (eq 3 (day3/map-count-visited
                   (day3/deliver-with-robosanta "^v"))))
    (should (eq 3 (day3/map-count-visited
                   (day3/deliver-with-robosanta "^>v<"))))
    (should (eq 11 (day3/map-count-visited
                    (day3/deliver-with-robosanta "^v^v^v^v^v")))))

  (day3/map-count-visited
   (day3/deliver-with-robosanta input))
2360

Day 4: The Ideal Stocking Stuffer

Santa needs help mining some AdventCoins (very similar to bitcoins) to use as gifts for all the economically forward-thinking little girls and boys.

To do this, he needs to find MD5 hashes which, in hexadecimal, start with at least five zeroes. The input to the MD5 hash is some secret key (your puzzle input, given below) followed by a number in decimal. To mine AdventCoins, you must find Santa the lowest positive number (no leading zeroes: 1, 2, 3, …) that produces such a hash.

For example:

  • If your secret key is abcdef, the answer is 609043, because the MD5 hash of abcdef609043 starts with five zeroes (000001dbbfa...), and it is the lowest such number to do so.
  • If your secret key is pqrstuv, the lowest number it combines with to make an MD5 hash starting with five zeroes is 1048970; that is, the MD5 hash of pqrstuv1048970 looks like 000006136ef....

  ckczppom
  (defun day4/mine-hash (key n)
    (md5 (format "%s%d" key n)))

  (defun day4/adventcoin-hash-p (hash)
    (string-equal
     "00000"
     (substring hash 0 5)))

  (defun day4/first-adventcoin (secret)
    (loop for x from 0
          while (not (day4/adventcoin-hash-p (day4/mine-hash secret x)))
          count x))

  (ert-deftest day4/first-adventcoin ()
    (should (eq 609043 (day4/first-adventcoin "abcdef")))
    (should (eq 1048970 (day4/first-adventcoin "pqrstuv"))))

  (day4/first-adventcoin (string-trim input))
117946

Part 2

Now find one that starts with six zeroes.


  (defun day4/adventcoin-hash-6-p (n hash)
    (string-equal
     "000000"
     (substring hash 0 6)))

  (defun day4/first-adventcoin-n (n secret)
    (loop for x from 0
          while (not (day4/adventcoin-hash-6-p n (day4/mine-hash secret x)))
          count x))

  (day4/first-adventcoin-n 6 (string-trim input))
3938038

Day 5: Doesn't He Have Intern-Elves For This?

Santa needs help figuring out which strings in his text file are naughty or nice.

A nice string is one with all of the following properties:

  • It contains at least three vowels (aeiou only), like aei, xazegov, or aeiouaeiouaeiou.
  • It contains at least one letter that appears twice in a row, like xx, abcdde (dd), or aabbccdd (aa, bb, cc, or dd).
  • It does not contain the strings ab, cd, pq, or xy, even if they are part of one of the other requirements.

For example:

  • ugknbfddgicrmopn is nice because it has at least three vowels (u...i...o...), a double letter (...dd...), and none of the disallowed substrings.
  • aaa is nice because it has at least three vowels and a double letter, even though the letters used by different rules overlap.
  • jchzalrnumimnmhp is naughty because it has no double letter.
  • haegwjzuvuyypxyu is naughty because it contains the string xy.
  • =dvszwmarrgswjxmb- is naughty because it contains only one vowel.

How many strings are nice?


  sszojmmrrkwuftyv
  isaljhemltsdzlum
  fujcyucsrxgatisb
  qiqqlmcgnhzparyg
  oijbmduquhfactbc
  jqzuvtggpdqcekgk
  zwqadogmpjmmxijf
  uilzxjythsqhwndh
  gtssqejjknzkkpvw
  wrggegukhhatygfi
  vhtcgqzerxonhsye
  tedlwzdjfppbmtdx
  iuvrelxiapllaxbg
  feybgiimfthtplui
  qxmmcnirvkzfrjwd
  vfarmltinsriqxpu
  oanqfyqirkraesfq
  xilodxfuxphuiiii
  yukhnchvjkfwcbiq
  bdaibcbzeuxqplop
  ivegnnpbiyxqsion
  ybahkbzpditgwdgt
  dmebdomwabxgtctu
  ibtvimgfaeonknoh
  jsqraroxudetmfyw
  dqdbcwtpintfcvuz
  tiyphjunlxddenpj
  fgqwjgntxagidhah
  nwenhxmakxqkeehg
  zdoheaxqpcnlhnen
  tfetfqojqcdzlpbm
  qpnxkuldeiituggg
  xwttlbdwxohahwar
  hjkwzadmtrkegzye
  koksqrqcfwcaxeof
  wulwmrptktliyxeq
  gyufbedqhhyqgqzj
  txpunzodohikzlmj
  jloqfuejfkemcrvu
  amnflshcheuddqtc
  pdvcsduggcogbiia
  yrioavgfmeafjpcz
  uyhbtmbutozzqfvq
  mwhgfwsgyuwcdzik
  auqylgxhmullxpaa
  lgelzivplaeoivzh
  uyvcepielfcmswoa
  qhirixgwkkccuzlp
  zoonniyosmkeejfg
  iayfetpixkedyana
  ictqeyzyqswdskiy
  ejsgqteafvmorwxe
  lhaiqrlqqwfbrqdx
  ydjyboqwhfpqfydc
  dwhttezyanrnbybv
  edgzkqeqkyojowvr
  rmjfdwsqamjqehdq
  ozminkgnkwqctrxz
  bztjhxpjthchhfcd
  vrtioawyxkivrpiq
  dpbcsznkpkaaclyy
  vpoypksymdwttpvz
  hhdlruwclartkyap
  bqkrcbrksbzcggbo
  jerbbbnxlwfvlaiw
  dwkasufidwjrjfbf
  kkfxtjhbnmqbmfwf
  vmnfziwqxmioukmj
  rqxvcultipkecdtu
  fhmfdibhtjzkiqsd
  hdpjbuzzbyafqrpd
  emszboysjuvwwvts
  msyigmwcuybfiooq
  druyksfnbluvnwoh
  fvgstvynnfbvxhsx
  bmzalvducnqtuune
  lzwkzfzttsvpllei
  olmplpvjamynfyfd
  padcwfkhystsvyfb
  wjhbvxkwtbfqdilb
  hruaqjwphonnterf
  bufjobjtvxtzjpmj
  oiedrjvmlbtwyyuy
  sgiemafwfztwsyju
  nsoqqfudrtwszyqf
  vonbxquiiwxnazyl
  yvnmjxtptujwqudn
  rrnybqhvrcgwvrkq
  taktoxzgotzxntfu
  quffzywzpxyaepxa
  rfvjebfiddcfgmwv
  iaeozntougqwnzoh
  scdqyrhoqmljhoil
  bfmqticltmfhxwld
  brbuktbyqlyfpsdl
  oidnyhjkeqenjlhd
  kujsaiqojopvrygg
  vebzobmdbzvjnjtk
  uunoygzqjopwgmbg
  piljqxgicjzgifso
  ikgptwcjzywswqnw
  pujqsixoisvhdvwi
  trtuxbgigogfsbbk
  mplstsqclhhdyaqk
  gzcwflvmstogdpvo
  tfjywbkmimyyqcjd
  gijutvhruqcsiznq
  ibxkhjvzzxgavkha
  btnxeqvznkxjsgmq
  tjgofgauxaelmjoq
  sokshvyhlkxerjrv
  ltogbivktqmtezta
  uduwytzvqvfluyuf
  msuckpthtgzhdxan
  fqmcglidvhvpirzr
  gwztkqpcwnutvfga
  bsjfgsrntdhlpqbx
  xloczbqybxmiopwt
  orvevzyjliomkkgu
  mzjbhmfjjvaziget
  tlsdxuhwdmghdyjb
  atoecyjhwmznaewi
  pyxpyvvipbqibiox
  ajbfmpqqobfsmesj
  siknbzefjblnohgd
  eqfhgewbblwdfkmc
  opylbscrotckkrbk
  lbwxbofgjkzdxkle
  ceixfjstaptdomvm
  hnkrqxifjmmjktie
  aqykzeuzvvetoygd
  fouahjimfcisxima
  prkzhutbqsyrhjzx
  qqwliakathnsbzne
  sayhgqtlcqqidqhj
  ygduolbysehdudra
  zricvxhdzznuxuce
  ucvzakslykpgsixd
  udirhgcttmyspgsb
  yuwzppjzfsjhhdzi
  gtqergjiuwookwre
  xvxexbjyjkxovvwf
  mlpaqhnnkqxrmwmm
  ezuqbrjozwuqafhb
  mcarusdthcbsonoq
  weeguqeheeiigrue
  pngtfugozxofaqxv
  copphvbjcmfspenv
  jiyahihykjjkdaya
  gdqnmesvptuyrfwp
  vbdscfywqmfxbohh
  crtrfuxyjypzubrg
  seihvevtxywxhflp
  fvvpmgttnapklwou
  qmqaqsajmqwhetpk
  zetxvrgjmblxvakr
  kpvwblrizaabmnhz
  mwpvvzaaicntrkcp
  clqyjiegtdsswqfm
  ymrcnqgcpldgfwtm
  nzyqpdenetncgnwq
  cmkzevgacnmdkqro
  kzfdsnamjqbeirhi
  kpxrvgvvxapqlued
  rzskbnfobevzrtqu
  vjoahbfwtydugzap
  ykbbldkoijlvicbl
  mfdmroiztsgjlasb
  quoigfyxwtwprmdr
  ekxjqafwudgwfqjm
  obtvyjkiycxfcdpb
  lhoihfnbuqelthof
  eydwzitgxryktddt
  rxsihfybacnpoyny
  bsncccxlplqgygtw
  rvmlaudsifnzhcqh
  huxwsyjyebckcsnn
  gtuqzyihwhqvjtes
  zreeyomtngvztveq
  nwddzjingsarhkxb
  nuqxqtctpoldrlsh
  wkvnrwqgjooovhpf
  kwgueyiyffudtbyg
  tpkzapnjxefqnmew
  ludwccvkihagvxal
  lfdtzhfadvabghna
  njqmlsnrkcfhtvbb
  cajzbqleghhnlgap
  vmitdcozzvqvzatp
  eelzefwqwjiywbcz
  uyztcuptfqvymjpi
  aorhnrpkjqqtgnfo
  lfrxfdrduoeqmwwp
  vszpjvbctblplinh
  zexhadgpqfifcqrz
  ueirfnshekpemqua
  qfremlntihbwabtb
  nwznunammfexltjc
  zkyieokaaogjehwt
  vlrxgkpclzeslqkq
  xrqrwfsuacywczhs
  olghlnfjdiwgdbqc
  difnlxnedpqcsrdf
  dgpuhiisybjpidsj
  vlwmwrikmitmoxbt
  sazpcmcnviynoktm
  pratafauetiknhln
  ilgteekhzwlsfwcn
  ywvwhrwhkaubvkbl
  qlaxivzwxyhvrxcf
  hbtlwjdriizqvjfb
  nrmsononytuwslsa
  mpxqgdthpoipyhjc
  mcdiwmiqeidwcglk
  vfbaeavmjjemfrmo
  qzcbzmisnynzibrc
  shzmpgxhehhcejhb
  wirtjadsqzydtyxd
  qjlrnjfokkqvnpue
  dxawdvjntlbxtuqc
  wttfmnrievfestog
  eamjfvsjhvzzaobg
  pbvfcwzjgxahlrag
  omvmjkqqnobvnzkn
  lcwmeibxhhlxnkzv
  uiaeroqfbvlazegs
  twniyldyuonfyzqw
  wgjkmsbwgfotdabi
  hnomamxoxvrzvtew
  ycrcfavikkrxxfgw
  isieyodknagzhaxy
  mgzdqwikzullzyco
  mumezgtxjrrejtrs
  nwmwjcgrqiwgfqel
  wjgxmebfmyjnxyyp
  durpspyljdykvzxf
  zuslbrpooyetgafh
  kuzrhcjwbdouhyme
  wyxuvbciodscbvfm
  kbnpvuqwmxwfqtqe
  zddzercqogdpxmft
  sigrdchxtgavzzjh
  lznjolnorbuddgcs
  ycnqabxlcajagwbt
  bnaudeaexahdgxsj
  rlnykxvoctfwanms
  jngyetkoplrstfzt
  tdpxknwacksotdub
  yutqgssfoptvizgr
  lzmqnxeqjfnsxmsa
  iqpgfsfmukovsdgu
  qywreehbidowtjyz
  iozamtgusdctvnkw
  ielmujhtmynlwcfd
  hzxnhtbnmmejlkyf
  ftbslbzmiqkzebtd
  bcwdqgiiizmohack
  dqhfkzeddjzbdlxu
  mxopokqffisxosci
  vciatxhtuechbylk
  khtkhcvelidjdena
  blatarwzfqcapkdt
  elamngegnczctcck
  xeicefdbwrxhuxuf
  sawvdhjoeahlgcdr
  kmdcimzsfkdfpnir
  axjayzqlosrduajb
  mfhzreuzzumvoggr
  iqlbkbhrkptquldb
  xcvztvlshiefuhgb
  pkvwyqmyoazocrio
  ajsxkdnerbmhyxaj
  tudibgsbnpnizvsi
  cxuiydkgdccrqvkh
  cyztpjesdzmbcpot
  nnazphxpanegwitx
  uphymczbmjalmsct
  yyxiwnlrogyzwqmg
  gmqwnahjvvdyhnfa
  utolskxpuoheugyl
  mseszdhyzoyavepd
  ycqknvbuvcjfgmlc
  sknrxhxbfpvpeorn
  zqxqjetooqcodwml
  sesylkpvbndrdhsy
  fryuxvjnsvnjrxlw
  mfxusewqurscujnu
  mbitdjjtgzchvkfv
  ozwlyxtaalxofovd
  wdqcduaykxbunpie
  rlnhykxiraileysk
  wgoqfrygttlamobg
  kflxzgxvcblkpsbz
  tmkisflhativzhde
  owsdrfgkaamogjzd
  gaupjkvkzavhfnes
  wknkurddcknbdleg
  lltviwincmbtduap
  qwzvspgbcksyzzmb
  ydzzkumecryfjgnk
  jzvmwgjutxoysaam
  icrwpyhxllbardkr
  jdopyntshmvltrve
  afgkigxcuvmdbqou
  mfzzudntmvuyhjzt
  duxhgtwafcgrpihc
  tsnhrkvponudumeb
  sqtvnbeiigdzbjgv
  eczmkqwvnsrracuo
  mhehsgqwiczaiaxv
  kaudmfvifovrimpd
  lupikgivechdbwfr
  mwaaysrndiutuiqx
  aacuiiwgaannunmm
  tjqjbftaqitukwzp
  lrcqyskykbjpaekn
  lirrvofbcqpjzxmr
  jurorvzpplyelfml
  qonbllojmloykjqe
  sllkzqujfnbauuqp
  auexjwsvphvikali
  usuelbssqmbrkxyc
  wyuokkfjexikptvv
  wmfedauwjgbrgytl
  sfwvtlzzebxzmuvw
  rdhqxuechjsjcvaf
  kpavhqkukugocsxu
  ovnjtumxowbxduts
  zgerpjufauptxgat
  pevvnzjfwhjxdoxq
  pmmfwxajgfziszcs
  difmeqvaghuitjhs
  icpwjbzcmlcterwm
  ngqpvhajttxuegyh
  mosjlqswdngwqsmi
  frlvgpxrjolgodlu
  eazwgrpcxjgoszeg
  bbtsthgkjrpkiiyk
  tjonoglufuvsvabe
  xhkbcrofytmbzrtk
  kqftfzdmpbxjynps
  kmeqpocbnikdtfyv
  qjjymgqxhnjwxxhp
  dmgicrhgbngdtmjt
  zdxrhdhbdutlawnc
  afvoekuhdboxghvx
  hiipezngkqcnihty
  bbmqgheidenweeov
  suprgwxgxwfsgjnx
  adeagikyamgqphrj
  zzifqinoeqaorjxg
  adhgppljizpaxzld
  lvxyieypvvuqjiyc
  nljoakatwwwoovzn
  fcrkfxclcacshhmx
  ownnxqtdhqbgthch
  lmfylrcdmdkgpwnj
  hlwjfbvlswbzpbjr
  mkofhdtljdetcyvp
  synyxhifbetzarpo
  agnggugngadrcxoc
  uhttadmdmhidpyjw
  ohfwjfhunalbubpr
  pzkkkkwrlvxiuysn
  kmidbxmyzkjrwjhu
  egtitdydwjxmajnw
  civoeoiuwtwgbqqs
  dfptsguzfinqoslk
  tdfvkreormspprer
  zvnvbrmthatzztwi
  ffkyddccrrfikjde
  hrrmraevdnztiwff
  qaeygykcpbtjwjbr
  purwhitkmrtybslh
  qzziznlswjaussel
  dfcxkvdpqccdqqxj
  tuotforulrrytgyn
  gmtgfofgucjywkev
  wkyoxudvdkbgpwhd
  qbvktvfvipftztnn
  otckgmojziezmojb
  inxhvzbtgkjxflay
  qvxapbiatuudseno
  krpvqosbesnjntut
  oqeukkgjsfuqkjbb
  prcjnyymnqwqksiz
  vuortvjxgckresko
  orqlyobvkuwgathr
  qnpyxlnazyfuijox
  zwlblfkoklqmqzkw
  hmwurwtpwnrcsanl
  jzvxohuakopuzgpf
  sfcpnxrviphhvxmx
  qtwdeadudtqhbely
  dbmkmloasqphnlgj
  olylnjtkxgrubmtk
  nxsdbqjuvwrrdbpq
  wbabpirnpcsmpipw
  hjnkyiuxpqrlvims
  enzpntcjnxdpuqch
  vvvqhlstzcizyimn
  triozhqndbttglhv
  fukvgteitwaagpzx
  uhcvukfbmrvskpen
  tizcyupztftzxdmt
  vtkpnbpdzsaluczz
  wodfoyhoekidxttm
  otqocljrmwfqbxzu
  linfbsnfvixlwykn
  vxsluutrwskslnye
  zbshygtwugixjvsi
  zdcqwxvwytmzhvoo
  wrseozkkcyctrmei
  fblgtvogvkpqzxiy
  opueqnuyngegbtnf
  qxbovietpacqqxok
  zacrdrrkohfygddn
  gbnnvjqmkdupwzpq
  qgrgmsxeotozvcak
  hnppukzvzfmlokid
  dzbheurndscrrtcl
  wbgdkadtszebbrcw
  fdmzppzphhpzyuiz
  bukomunhrjrypohj
  ohodhelegxootqbj
  rsplgzarlrknqjyh
  punjjwpsxnhpzgvu
  djdfahypfjvpvibm
  mlgrqsmhaozatsvy
  xwktrgyuhqiquxgn
  wvfaoolwtkbrisvf
  plttjdmguxjwmeqr
  zlvvbwvlhauyjykw
  cigwkbyjhmepikej
  masmylenrusgtyxs
  hviqzufwyetyznze
  nzqfuhrooswxxhus
  pdbdetaqcrqzzwxf
  oehmvziiqwkzhzib
  icgpyrukiokmytoy
  ooixfvwtiafnwkce
  rvnmgqggpjopkihs
  wywualssrmaqigqk
  pdbvflnwfswsrirl
  jeaezptokkccpbuj
  mbdwjntysntsaaby
  ldlgcawkzcwuxzpz
  lwktbgrzswbsweht
  ecspepmzarzmgpjm
  qmfyvulkmkxjncai
  izftypvwngiukrns
  zgmnyjfeqffbooww
  nyrkhggnprhedows
  yykzzrjmlevgffah
  mavaemfxhlfejfki
  cmegmfjbkvpncqwf
  zxidlodrezztcrij
  fseasudpgvgnysjv
  fupcimjupywzpqzp
  iqhgokavirrcvyys
  wjmkcareucnmfhui
  nftflsqnkgjaexhq
  mgklahzlcbapntgw
  kfbmeavfxtppnrxn
  nuhyvhknlufdynvn
  nviogjxbluwrcoec
  tyozixxxaqiuvoys
  kgwlvmvgtsvxojpr
  moeektyhyonfdhrb
  kahvevmmfsmiiqex
  xcywnqzcdqtvhiwd
  fnievhiyltbvtvem
  jlmndqufirwgtdxd
  muypbfttoeelsnbs
  rypxzbnujitfwkou
  ubmmjbznskildeoj
  ofnmizdeicrmkjxp
  rekvectjbmdnfcib
  yohrojuvdexbctdh
  gwfnfdeibynzjmhz
  jfznhfcqdwlpjull
  scrinzycfhwkmmso
  mskutzossrwoqqsi
  rygoebkzgyzushhr
  jpjqiycflqkexemx
  arbufysjqmgaapnl
  dbjerflevtgweeoj
  snybnnjlmwjvhois
  fszuzplntraprmbj
  mkvaatolvuggikvg
  zpuzuqygoxesnuyc
  wnpxvmxvllxalulm
  eivuuafkvudeouwy
  rvzckdyixetfuehr
  qgmnicdoqhveahyx
  miawwngyymshjmpj
  pvckyoncpqeqkbmx
  llninfenrfjqxurv
  kzbjnlgsqjfuzqtp
  rveqcmxomvpjcwte
  bzotkawzbopkosnx
  ktqvpiribpypaymu
  wvlzkivbukhnvram
  uohntlcoguvjqqdo
  ajlsiksjrcnzepkt
  xsqatbldqcykwusd
  ihbivgzrwpmowkop
  vfayesfojmibkjpb
  uaqbnijtrhvqxjtb
  hhovshsfmvkvymba
  jerwmyxrfeyvxcgg
  hncafjwrlvdcupma
  qyvigggxfylbbrzt
  hiiixcyohmvnkpgk
  mmitpwopgxuftdfu
  iaxderqpceboixoa
  zodfmjhuzhnsqfcb
  sthtcbadrclrazsi
  bkkkkcwegvypbrio
  wmpcofuvzemunlhj
  gqwebiifvqoeynro
  juupusqdsvxcpsgv
  rbhdfhthxelolyse
  kjimpwnjfrqlqhhz
  rcuigrjzarzpjgfq
  htxcejfyzhydinks
  sxucpdxhvqjxxjwf
  omsznfcimbcwaxal
  gufmtdlhgrsvcosb
  bssshaqujtmluerz
  uukotwjkstgwijtr
  kbqkneobbrdogrxk
  ljqopjcjmelgrakz
  rwtfnvnzryujwkfb
  dedjjbrndqnilbeh
  nzinsxnpptzagwlb
  lwqanydfirhnhkxy
  hrjuzfumbvfccxno
  okismsadkbseumnp
  sfkmiaiwlktxqvwa
  hauwpjjwowbunbjj
  nowkofejwvutcnui
  bqzzppwoslaeixro
  urpfgufwbtzenkpj
  xgeszvuqwxeykhef
  yxoldvkyuikwqyeq
  onbbhxrnmohzskgg
  qcikuxakrqeugpoa
  lnudcqbtyzhlpers
  nxduvwfrgzaailgl
  xniuwvxufzxjjrwz
  ljwithcqmgvntjdj
  awkftfagrfzywkhs
  uedtpzxyubeveuek
  bhcqdwidbjkqqhzl
  iyneqjdmlhowwzxx
  kvshzltcrrururty
  zgfpiwajegwezupo
  tkrvyanujjwmyyri
  ercsefuihcmoaiep
  ienjrxpmetinvbos
  jnwfutjbgenlipzq
  bgohjmrptfuamzbz
  rtsyamajrhxbcncw
  tfjdssnmztvbnscs
  bgaychdlmchngqlp
  kfjljiobynhwfkjo
  owtdxzcpqleftbvn
  ltjtimxwstvzwzjj
  wbrvjjjajuombokf
  zblpbpuaqbkvsxye
  gwgdtbpnlhyqspdi
  abipqjihjqfofmkx
  nlqymnuvjpvvgova
  avngotmhodpoufzn
  qmdyivtzitnrjuae
  xfwjmqtqdljuerxi
  csuellnlcyqaaamq
  slqyrcurcyuoxquo
  dcjmxyzbzpohzprl
  uqfnmjwniyqgsowb
  rbmxpqoblyxdocqc
  ebjclrdbqjhladem
  ainnfhxnsgwqnmyo
  eyytjjwhvodtzquf
  iabjgmbbhilrcyyp
  pqfnehkivuelyccc
  xgjbyhfgmtseiimt
  jwxyqhdbjiqqqeyy
  gxsbrncqkmvaryln
  vhjisxjkinaejytk
  seexagcdmaedpcvh
  lvudfgrcpjxzdpvd
  fxtegyrqjzhmqean
  dnoiseraqcoossmc
  nwrhmwwbykvwmgep
  udmzskejvizmtlce
  hbzvqhvudfdlegaa
  cghmlfqejbxewskv
  bntcmjqfwomtbwsb
  qezhowyopjdyhzng
  todzsocdkgfxanbz
  zgjkssrjlwxuhwbk
  eibzljqsieriyrzr
  wamxvzqyycrxotjp
  epzvfkispwqynadu
  dwlpfhtrafrxlyie
  qhgzujhgdruowoug
  girstvkahaemmxvh
  baitcrqmxhazyhbl
  xyanqcchbhkajdmc
  gfvjmmcgfhvgnfdq
  tdfdbslwncbnkzyz
  jojuselkpmnnbcbb
  hatdslkgxtqpmavj
  dvelfeddvgjcyxkj
  gnsofhkfepgwltse
  mdngnobasfpewlno
  qssnbcyjgmkyuoga
  glvcmmjytmprqwvn
  gwrixumjbcdffsdl
  lozravlzvfqtsuiq
  sicaflbqdxbmdlch
  inwfjkyyqbwpmqlq
  cuvszfotxywuzhzi
  igfxyoaacoarlvay
  ucjfhgdmnjvgvuni
  rvvkzjsytqgiposh
  jduinhjjntrmqroz
  yparkxbgsfnueyll
  lyeqqeisxzfsqzuj
  woncskbibjnumydm
  lltucklragtjmxtl
  ubiyvmyhlesfxotj
  uecjseeicldqrqww
  xxlxkbcthufnjbnm
  lhqijovvhlffpxga
  fzdgqpzijitlogjz
  efzzjqvwphomxdpd
  jvgzvuyzobeazssc
  hejfycgxywfjgbfw
  yhjjmvkqfbnbliks
  sffvfyywtlntsdsz
  dwmxqudvxqdenrur
  asnukgppdemxrzaz
  nwqfnumblwvdpphx
  kqsmkkspqvxzuket
  cpnraovljzqiquaz
  qrzgrdlyyzbyykhg
  opoahcbiydyhsmqe
  hjknnfdauidjeydr
  hczdjjlygoezadow
  rtflowzqycimllfv
  sfsrgrerzlnychhq
  bpahuvlblcolpjmj
  albgnjkgmcrlaicl
  pijyqdhfxpaxzdex
  eeymiddvcwkpbpux
  rqwkqoabywgggnln
  vckbollyhgbgmgwh
  ylzlgvnuvpynybkm
  hpmbxtpfosbsjixt
  ocebeihnhvkhjfqz
  tvctyxoujdgwayze
  efvhwxtuhapqxjen
  rusksgefyidldmpo
  nkmtjvddfmhirmzz
  whvtsuadwofzmvrt
  iiwjqvsdxudhdzzk
  gucirgxaxgcassyo
  rmhfasfzexeykwmr
  hynlxcvsbgosjbis
  huregszrcaocueen
  pifezpoolrnbdqtv
  unatnixzvdbqeyox
  xtawlpduxgacchfe
  bdvdbflqfphndduf
  xtdsnjnmzccfptyt
  nkhsdkhqtzqbphhg
  aqcubmfkczlaxiyb
  moziflxpsfubucmv
  srdgnnjtfehiimqx
  pwfalehdfyykrohf
  sysxssmvewyfjrve
  brsemdzosgqvvlxe
  bimbjoshuvflkiat
  hkgjasmljkpkwwku
  sbnmwjvodygobpqc
  bbbqycejueruihhd
  corawswvlvneipyc
  gcyhknmwsczcxedh
  kppakbffdhntmcqp
  ynulzwkfaemkcefp
  pyroowjekeurlbii
  iwksighrswdcnmxf
  glokrdmugreygnsg
  xkmvvumnfzckryop
  aesviofpufygschi
  csloawlirnegsssq
  fkqdqqmlzuxbkzbc
  uzlhzcfenxdfjdzp
  poaaidrktteusvyf
  zrlyfzmjzfvivcfr
  qwjulskbniitgqtx
  gjeszjksbfsuejki
  vczdejdbfixbduaq
  knjdrjthitjxluth
  jweydeginrnicirl
  bottrfgccqhyycsl
  eiquffofoadmbuhk
  lbqfutmzoksscswf
  xfmdvnvfcnzjprba
  uvugkjbkhlaoxmyx
  wadlgtpczgvcaqqv
  inzrszbtossflsxk
  dbzbtashaartczrj
  qbjiqpccefcfkvod
  hluujmokjywotvzy
  thwlliksfztcmwzh
  arahybspdaqdexrq
  nuojrmsgyipdvwyx
  hnajdwjwmzattvst
  sulcgaxezkprjbgu
  rjowuugwdpkjtypw
  oeugzwuhnrgiaqga
  wvxnyymwftfoswij
  pqxklzkjpcqscvde
  tuymjzknntekglqj
  odteewktugcwlhln
  exsptotlfecmgehc
  eeswfcijtvzgrqel
  vjhrkiwmunuiwqau
  zhlixepkeijoemne
  pavfsmwesuvebzdd
  jzovbklnngfdmyws
  nbajyohtzfeoiixz
  ciozmhrsjzrwxvhz
  gwucrxieqbaqfjuv
  uayrxrltnohexawc
  flmrbhwsfbcquffm
  gjyabmngkitawlxc
  rwwtggvaygfbovhg
  xquiegaisynictjq
  oudzwuhexrwwdbyy
  lengxmguyrwhrebb
  uklxpglldbgqsjls
  dbmvlfeyguydfsxq
  zspdwdqcrmtmdtsc
  mqfnzwbfqlauvrgc
  amcrkzptgacywvhv
  ndxmskrwrqysrndf
  mwjyhsufeqhwisju
  srlrukoaenyevykt
  tnpjtpwawrxbikct
  geczalxmgxejulcv
  tvkcbqdhmuwcxqci
  tiovluvwezwwgaox
  zrjhtbgajkjqzmfo
  vcrywduwsklepirs
  lofequdigsszuioy
  wxsdzomkjqymlzat
  iabaczqtrfbmypuy
  ibdlmudbajikcncr
  rqcvkzsbwmavdwnv
  ypxoyjelhllhbeog
  fdnszbkezyjbttbg
  uxnhrldastpdjkdz
  xfrjbehtxnlyzcka
  omjyfhbibqwgcpbv
  eguucnoxaoprszmp
  xfpypldgcmcllyzz
  aypnmgqjxjqceelv
  mgzharymejlafvgf
  tzowgwsubbaigdok
  ilsehjqpcjwmylxc
  pfmouwntfhfnmrwk
  csgokybgdqwnduwp
  eaxwvxvvwbrovypz
  nmluqvobbbmdiwwb
  lnkminvfjjzqbmio
  mjiiqzycqdhfietz
  towlrzriicyraevq
  obiloewdvbrsfwjo
  lmeooaajlthsfltw
  ichygipzpykkesrw
  gfysloxmqdsfskvt
  saqzntehjldvwtsx
  pqddoemaufpfcaew
  mjrxvbvwcreaybwe
  ngfbrwfqnxqosoai
  nesyewxreiqvhald
  kqhqdlquywotcyfy
  liliptyoqujensfi
  nsahsaxvaepzneqq
  zaickulfjajhctye
  gxjzahtgbgbabtht
  koxbuopaqhlsyhrp
  jhzejdjidqqtjnwe
  dekrkdvprfqpcqki
  linwlombdqtdeyop
  dvckqqbnigdcmwmx
  yaxygbjpzkvnnebv
  rlzkdkgaagmcpxah
  cfzuyxivtknirqvt
  obivkajhsjnrxxhn
  lmjhayymgpseuynn
  bbjyewkwadaipyju
  lmzyhwomfypoftuu
  gtzhqlgltvatxack
  jfflcfaqqkrrltgq
  txoummmnzfrlrmcg
  ohemsbfuqqpucups
  imsfvowcbieotlok
  tcnsnccdszxfcyde
  qkcdtkwuaquajazz
  arcfnhmdjezdbqku
  srnocgyqrlcvlhkb
  mppbzvfmcdirbyfw
  xiuarktilpldwgwd
  ypufwmhrvzqmexpc
  itpdnsfkwgrdujmj
  cmpxnodtsswkyxkr
  wayyxtjklfrmvbfp
  mfaxphcnjczhbbwy
  sjxhgwdnqcofbdra
  pnxmujuylqccjvjm
  ivamtjbvairwjqwl
  deijtmzgpfxrclss
  bzkqcaqagsynlaer
  tycefobvxcvwaulz
  ctbhnywezxkdsswf
  urrxxebxrthtjvib
  fpfelcigwqwdjucv
  ngfcyyqpqulwcphb
  rltkzsiipkpzlgpw
  qfdsymzwhqqdkykc
  balrhhxipoqzmihj
  rnwalxgigswxomga
  ghqnxeogckshphgr
  lyyaentdizaumnla
  exriodwfzosbeoib
  speswfggibijfejk
  yxmxgfhvmshqszrq
  hcqhngvahzgawjga
  qmhlsrfpesmeksur
  eviafjejygakodla
  kvcfeiqhynqadbzv
  fusvyhowslfzqttg
  girqmvwmcvntrwau
  yuavizroykfkdekz
  jmcwohvmzvowrhxf
  kzimlcpavapynfue
  wjudcdtrewfabppq
  yqpteuxqgbmqfgxh
  xdgiszbuhdognniu
  jsguxfwhpftlcjoh
  whakkvspssgjzxre
  ggvnvjurlyhhijgm
  krvbhjybnpemeptr
  pqedgfojyjybfbzr
  jzhcrsgmnkwwtpdo
  yyscxoxwofslncmp
  gzjhnxytmyntzths
  iteigbnqbtpvqumi
  zjevfzusnjukqpfw
  xippcyhkfuounxqk
  mcnhrcfonfdgpkyh
  pinkcyuhjkexbmzj
  lotxrswlxbxlxufs
  fmqajrtoabpckbnu
  wfkwsgmcffdgaqxg
  qfrsiwnohoyfbidr
  czfqbsbmiuyusaqs
  ieknnjeecucghpoo
  cevdgqnugupvmsge
  gjkajcyjnxdrtuvr
  udzhrargnujxiclq
  zqqrhhmjwermjssg
  ggdivtmgoqajydzz
  wnpfsgtxowkjiivl
  afbhqawjbotxnqpd
  xjpkifkhfjeqifdn
  oyfggzsstfhvticp
  kercaetahymeawxy
  khphblhcgmbupmzt
  iggoqtqpvaebtiol
  ofknifysuasshoya
  qxuewroccsbogrbv
  apsbnbkiopopytgu
  zyahfroovfjlythh
  bxhjwfgeuxlviydq
  uvbhdtvaypasaswa
  qamcjzrmesqgqdiz
  hjnjyzrxntiycyel
  wkcrwqwniczwdxgq
  hibxlvkqakusswkx
  mzjyuenepwdgrkty
  tvywsoqslfsulses
  jqwcwuuisrclircv
  xanwaoebfrzhurct
  ykriratovsvxxasf
  qyebvtqqxbjuuwuo
  telrvlwvriylnder
  acksrrptgnhkeiaa
  yemwfjhiqlzsvdxf
  banrornfkcymmkcc
  ytbhxvaeiigjpcgm
  crepyazgxquposkn
  xlqwdrytzwnxzwzv
  xtrbfbwopxscftps
  kwbytzukgseeyjla
  qtfdvavvjogybxjg
  ytbmvmrcxwfkgvzw
  nbscbdskdeocnfzr
  sqquwjbdxsxhcseg
  ewqxhigqcgszfsuw
  cvkyfcyfmubzwsee
  dcoawetekigxgygd
  ohgqnqhfimyuqhvi
  otisopzzpvnhctte
  bauieohjejamzien
  ewnnopzkujbvhwce
  aeyqlskpaehagdiv
  pncudvivwnnqspxy
  ytugesilgveokxcg
  zoidxeelqdjesxpr
  ducjccsuaygfchzj
  smhgllqqqcjfubfc
  nlbyyywergronmir
  prdawpbjhrzsbsvj
  nmgzhnjhlpcplmui
  eflaogtjghdjmxxz
  qolvpngucbkprrdc
  ixywxcienveltgho
  mwnpqtocagenkxut
  iskrfbwxonkguywx
  ouhtbvcaczqzmpua
  srewprgddfgmdbao
  dyufrltacelchlvu
  czmzcbrkecixuwzz
  dtbeojcztzauofuk
  prrgoehpqhngfgmw
  baolzvfrrevxsyke
  zqadgxshwiarkzwh
  vsackherluvurqqj
  surbpxdulvcvgjbd
  wqxytarcxzgxhvtx
  vbcubqvejcfsgrac
  zqnjfeapshjowzja
  hekvbhtainkvbynx
  knnugxoktxpvoxnh
  knoaalcefpgtvlwm
  qoakaunowmsuvkus
  ypkvlzcduzlezqcb
  ujhcagawtyepyogh
  wsilcrxncnffaxjf
  gbbycjuscquaycrk
  aduojapeaqwivnly
  ceafyxrakviagcjy
  nntajnghicgnrlst
  vdodpeherjmmvbje
  wyyhrnegblwvdobn
  xlfurpghkpbzhhif
  xyppnjiljvirmqjo
  kglzqahipnddanpi
  omjateouxikwxowr
  ocifnoopfglmndcx
  emudcukfbadyijev
  ooktviixetfddfmh
  wtvrhloyjewdeycg
  cgjncqykgutfjhvb
  nkwvpswppeffmwad
  hqbcmfhzkxmnrivg
  mdskbvzguxvieilr
  anjcvqpavhdloaqh
  erksespdevjylenq
  fadxwbmisazyegup
  iyuiffjmcaahowhj
  ygkdezmynmltodbv
  fytneukxqkjattvh
  woerxfadbfrvdcnz
  iwsljvkyfastccoa
  movylhjranlorofe
  drdmicdaiwukemep
  knfgtsmuhfcvvshg
  ibstpbevqmdlhajn
  tstwsswswrxlzrqs
  estyydmzothggudf
  jezogwvymvikszwa
  izmqcwdyggibliet
  nzpxbegurwnwrnca
  kzkojelnvkwfublh
  xqcssgozuxfqtiwi
  tcdoigumjrgvczfv
  ikcjyubjmylkwlwq
  kqfivwystpqzvhan
  bzukgvyoqewniivj
  iduapzclhhyfladn
  fbpyzxdfmkrtfaeg
  yzsmlbnftftgwadz
  (defun day5/vowels (string)
    (seq-filter
     (apply-partially 'seq-contains "aeiou")
     string))

  (defun day5/has-doubles? (string)
    (string-match-p "\\([a-z]\\)\\1" string))

  (defun day5/naughty? (string)
       (-any
        (lambda (naughty-pattern)
          (s-contains? naughty-pattern string))
        '("ab" "cd" "pq" "xy")))

  (defun day5/nice? (string)
    (and (<= 3 (length (day5/vowels string)))
         (day5/has-doubles? string)
         (not (day5/naughty? string))))

  (ert-deftest day5/nice? ()
    (should (day5/nice? "ugknbfddgicrmopn"))
    (should (day5/nice? "aaa"))
    (should-not (day5/nice? "jchzalrnumimnmhp"))
    (should-not (day5/nice? "haegwjzuvuyypxyu"))
    (should-not (day5/nice? "dvszwmarrgswjxmb")))

  (length
   (-filter #'day5/nice?
            (split-string input)))
255