start day3

master-blaster
Matthew Butterick 8 years ago
parent 117a1a4401
commit ea9eb79e3f

@ -0,0 +1,47 @@
#lang racket
(require rackunit)
(provide read-syntax)
(define (str->visits str)
(define start '(0 0))
(define moves (map (λ(move) (case move
[("^") '(0 1)]
[("v") '(0 -1)]
[("<") '(-1 0)]
[(">") '(1 0)]))
(regexp-match* #rx"." str)))
(reverse (for/fold ([visit-acc (list start)])
([move (in-list moves)])
(cons (map + move (car visit-acc)) visit-acc))))
(define (str->unique-visits str)
(define visits (str->visits str))
(length (remove-duplicates visits)))
(define (str->robosanta str)
(define-values (reversed-santa-path reversed-robo-path)
(for/fold ([santa-acc empty][robo-acc empty])
([c (in-string str)][pos (in-naturals)])
(if (even? pos)
(values (cons c santa-acc) robo-acc)
(values santa-acc (cons c robo-acc)))))
(define santa-str (string-append* (map ~a (reverse reversed-santa-path))))
(define robo-str (string-append* (map ~a (reverse reversed-robo-path))))
(length (remove-duplicates (append (str->visits santa-str) (str->visits robo-str)))))
(check-equal? (str->unique-visits ">") 2)
(check-equal? (str->unique-visits "^>v<") 4)
(check-equal? (str->robosanta "^v") 3)
(check-equal? (str->robosanta "^>v<") 3)
(check-equal? (str->robosanta "^v^v^v^v^v") 11)
(define (read-syntax source-path-string in-port)
(with-syntax ([source-str (string-trim (port->string in-port))]
[str->unique-visits str->unique-visits]
[str->robosanta str->robosanta])
#'(module _ racket
(str->unique-visits source-str)
(str->robosanta source-str))))

File diff suppressed because one or more lines are too long

@ -0,0 +1,47 @@
#lang scribble/lp2
@(require scribble/manual aoc-racket/helper)
@aoc-title[3]
Our @link-rp["day3/input.txt"]{input} is a string made of the characters @litchar{^v<>} that represent north, south, west, and east. Taken together, the string represents a path through an indefinitely large grid.
In essence, this a two-dimensional version of the elevator problem in @secref["day-1"].
@chunk[<day3>
<setup>
<test>]
@section{How many grid cells are visited?}
In the elevator problem, we modeled the parentheses that represented up and down as @racket[1] and @racket[-1]. We'll proceed the same way here, but we'll assign Cartesian coordinates to each possible move — @racket['(0 1)] for north, @racket['(-1 0)] for west, and so on.
For dual-valued data, whether to use @seclink["pairs" #:doc '(lib "scribblings/guide/guide.scrbl")]{pairs or lists} is largely a stylistic choice. How do you plan to process the data? In this case, the way we create the path is by adding the x and y coordinates of the current cell and the new move. So it ends up being convenient to model these cells as lists rather than pairs, so we can add them with a simple @racket[(map + move cell)].
Once the whole cell path is computed, the answer is found by removing duplicate cells and counting how many remain.
@chunk[<setup>
(require racket rackunit)
(define (string->cells str)
(define start '(0 0))
(define moves (for/list ([s (in-list (regexp-match* #rx"." str))])
(case s
[("^") '(0 1)]
[("v") '(0 -1)]
[("<") '(-1 0)]
[(">") '(1 0)])))
(reverse (for/fold ([cells-so-far (list start)])
([move (in-list moves)])
(define last-cell (car cells-so-far))
(define next-cell (map + move last-cell))
(cons next-cell cells-so-far))))
(define (q1 str)
(length (remove-duplicates (string->cells str))))]
@section{How many grid cells are visited if ?}
@chunk[<test>
(module+ test
(define input-str (file->string "input.txt"))
(check-equal? (q1 input-str) 2565)
#;(check-equal? (q2 input-str) 2639))]

@ -6,7 +6,7 @@
(define (aoc-title which)
(define which-str (number->string which))
@title[#:style manual-doc-style]{@link[@string-append["http://adventofcode.com/day/" @which-str]]{Day @which-str}})
@title[#:style manual-doc-style #:tag (format "day-~a" which-str)]{@link[@string-append["http://adventofcode.com/day/" @which-str]]{Day @which-str}})
(define-syntax (link-rp stx)
(syntax-case stx ()

@ -10,3 +10,5 @@
@local-table-of-contents[]
@include-section[(submod "day1/main.scrbl" doc)]
@include-section[(submod "day2/main.scrbl" doc)]
@include-section[(submod "day3/main.scrbl" doc)]