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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/typed/day03.rkt

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))