From adf41e9eaf8d5889750275c28b879ab3e2a62955 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Fri, 1 Jan 2016 22:38:02 -0800 Subject: [PATCH] day10 --- aoc-racket.scrbl | 3 ++- day10-input.txt | 1 + day10.scrbl | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ day7.scrbl | 2 +- 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 day10-input.txt create mode 100644 day10.scrbl diff --git a/aoc-racket.scrbl b/aoc-racket.scrbl index 3e52d63..eab9f33 100644 --- a/aoc-racket.scrbl +++ b/aoc-racket.scrbl @@ -17,4 +17,5 @@ @include-section[(submod "day6.scrbl" doc)] @include-section[(submod "day7.scrbl" doc)] @include-section[(submod "day8.scrbl" doc)] -@include-section[(submod "day9.scrbl" doc)] \ No newline at end of file +@include-section[(submod "day9.scrbl" doc)] +@include-section[(submod "day10.scrbl" doc)] \ No newline at end of file diff --git a/day10-input.txt b/day10-input.txt new file mode 100644 index 0000000..bf144d5 --- /dev/null +++ b/day10-input.txt @@ -0,0 +1 @@ +1321131112 \ No newline at end of file diff --git a/day10.scrbl b/day10.scrbl new file mode 100644 index 0000000..902fad4 --- /dev/null +++ b/day10.scrbl @@ -0,0 +1,63 @@ +#lang scribble/lp2 +@(require scribble/manual aoc-racket/helper) + +@aoc-title[10] + +@link["http://adventofcode.com/day/10"]{The puzzle}. Our @link-rp["day10-input.txt"]{input} is a short numeric key. + +@chunk[ + + + + ] + +@section{What's the length of the sequence after 40 iterations?} + +The puzzle asks us to compute the @italic{look and say} sequence invented by mathematician John Conway. Each iteration of the sequence is the description of the last step if you said it in numbers. So @racket[1] becomes ``one 1'', written @racket[11]; @racket[11] becomes ``two ones'', or @racket[21], then @racket[1211], @racket[111221], and so on. + +As in @secref{Day_1}, this puzzle relies on cumulative state, so we'll loop using @racket[for/fold]. To generate the new string for each pass of the loop, we'll use @racket[regexp-match*] to find every contiguous run of digits. Each digit run will be converted into a list with the number of digits and then digit. Then all these lists of numbers are concatenated into a new string, and the process repeats. + +The second part of the puzzle is just going to change the number of iterations. So we'll make one function that we can use for both parts. + +@chunk[ + (require racket rackunit) + + (define (look-and-say iterations input-key) + (for/fold ([start input-key]) + ([i (in-range iterations)]) + (define digit-runs (regexp-match* #px"(\\d)\\1*" start)) + (string-append* + (map ~a + (append-map (λ(digit-run) + (list (string-length digit-run) + (substring digit-run 0 1))) + digit-runs))))) + + ] + +@chunk[ + + (define (q1 input-key) + (string-length (look-and-say 40 input-key)))] + + + +@section{After 50 iterations?} + +We just run the same @racket[look-and-say] function 50 times rather than 40. + +@chunk[ + + (define (q2 input-key) + (string-length (look-and-say 50 input-key))) ] + + +@section{Testing Day 10} + +@chunk[ + (module+ test + (define input-key (file->string "day10-input.txt")) + (check-equal? (q1 input-key) 492982) + (check-equal? (q2 input-key) 6989950))] + + diff --git a/day7.scrbl b/day7.scrbl index 061ab4d..702b359 100644 --- a/day7.scrbl +++ b/day7.scrbl @@ -38,7 +38,7 @@ becomes (@racket[wire-value-cache] is just a performance enhancement, so that wire values don't have to be computed multiple times.) -One gotcha when using syntax transformers is that newly defined identifiers can mask others. For instance, one of the wires in our input is named @tt{if}. When our syntax transformer defines the @tt{if} function, it will override the usual meaning of @racket[if]. There are plenty of elegant ways to prevent these name collisions. (The most important of which is called @italic{syntax hygiene}, and permeates the design of Racket's syntax-transformation system.) But because this is a puzzle, we'll take the cheap way out: we won't use @racket[if] elsewhere in our code, and instead use @racket[cond]. +One gotcha when using syntax transformers is that identifiers introduced by a transformer can silently override others (in the same way that identifiers defined inside a @racket[let] will override those with the same name outside the @racket[let]). For instance, one of the wires in our input is named @tt{if}. When our syntax transformer defines the @tt{if} function, it will override the usual meaning of @racket[if]. There are plenty of elegant ways to prevent these name collisions. (The most important of which is called @italic{syntax hygiene}, and permeates the design of Racket's syntax-transformation system.) But because this is a puzzle, we'll take the cheap way out: we won't use @racket[if] elsewhere in our code, and instead use @racket[cond]. @chunk[ (require racket rackunit