You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.9 KiB
Racket
77 lines
2.9 KiB
Racket
#lang typed/racket
|
|
(require typed/rackunit)
|
|
(provide (all-defined-out))
|
|
|
|
(define-type Move (List Integer Integer))
|
|
(define-type Cell (List Integer Integer))
|
|
|
|
(: string->cells (-> String (Listof Cell)))
|
|
(define (string->cells str)
|
|
(define start '(0 0))
|
|
(match-define (list east north west south) '((1 0) (0 1) (-1 0) (0 -1)))
|
|
(define moves (for/list : (Listof Move)
|
|
([c (in-string str)])
|
|
(case c
|
|
[(#\>) east]
|
|
[(#\^) north]
|
|
[(#\<) west]
|
|
[(#\v) south]
|
|
[else (error 'TR)])))
|
|
(for/fold : (Listof Cell)
|
|
([cells-so-far : (Listof Cell) (list start)])
|
|
([next-move (in-list moves)])
|
|
(define current-cell (car cells-so-far))
|
|
(define next-cell (map + current-cell next-move))
|
|
(cons (cast next-cell Cell) cells-so-far)))
|
|
|
|
(: q1 (-> String Integer))
|
|
(define (q1 str)
|
|
(length (remove-duplicates (string->cells str))))
|
|
|
|
(: string->complex-cells (-> String (Listof Complex)))
|
|
(define (string->complex-cells str)
|
|
(define start 0)
|
|
(define east 1)
|
|
(define moves (for/list : (Listof Complex)
|
|
([c (in-string str)])
|
|
(* east (expt +i (case c
|
|
[(#\>) 0]
|
|
[(#\^) 1]
|
|
[(#\<) 2]
|
|
[(#\v) 3]
|
|
[else (error 'TR)])))))
|
|
(for/fold : (Listof Complex)
|
|
([cells-so-far : (Listof Complex) (list start)])
|
|
([next-move (in-list moves)])
|
|
(define current-cell (car cells-so-far))
|
|
(define next-cell (+ current-cell next-move))
|
|
(cons next-cell cells-so-far)))
|
|
|
|
(: q1-complex (-> String Natural))
|
|
(define (q1-complex str)
|
|
(length (remove-duplicates (string->complex-cells str))))
|
|
|
|
(: split-odds-and-evens (-> String (Values String String)))
|
|
(define (split-odds-and-evens str)
|
|
(define-values (odd-chars even-chars)
|
|
(for/fold : (Values (Listof Char) (Listof Char))
|
|
([odds-so-far : (Listof Char) empty][evens-so-far : (Listof Char) empty])
|
|
([c (in-string str)][i (in-naturals)])
|
|
(if (even? i)
|
|
(values odds-so-far (cons c evens-so-far))
|
|
(values (cons c odds-so-far) evens-so-far))))
|
|
(values (string-append* (map string (reverse odd-chars)))
|
|
(string-append* (map string (reverse even-chars)))))
|
|
|
|
(: q2 (-> String Integer))
|
|
(define (q2 str)
|
|
(define-values (odd-str even-str) (split-odds-and-evens str))
|
|
(length (remove-duplicates
|
|
(append (string->cells odd-str) (string->cells even-str)))))
|
|
|
|
(module+ test
|
|
(define input-str (file->string "../day03-input.txt"))
|
|
(check-equal? (q1 input-str) 2565)
|
|
(check-equal? (q1-complex input-str) 2565)
|
|
(check-equal? (q2 input-str) 2639))
|