Skip to content

Instantly share code, notes, and snippets.

@sotolf2
Created December 30, 2019 15:03
Show Gist options
  • Save sotolf2/3f66a99e319a1ace1602cf556e477e4b to your computer and use it in GitHub Desktop.
Save sotolf2/3f66a99e319a1ace1602cf556e477e4b to your computer and use it in GitHub Desktop.
#lang typed/racket
(require threading)
(: get-input (-> (Listof String)))
(define (get-input)
(file->lines "day6.txt"))
(struct pt ([x : Integer] [y : Integer]) #:transparent)
(struct ins ([cmd : Symbol] [from : pt] [to : pt]) #:transparent)
(define-type Grid (Immutable-HashTable pt Integer))
(: list->pair (All (A) (-> (Listof A) (Pairof A A))))
(define (list->pair lst)
(cons (first lst) (second lst)))
(: parse-pt (-> String pt))
(define (parse-pt str)
(define xy : (Listof (U Complex False))
(~>> str
(string-split _ ",")
(map string->number)))
(define x : Integer
(assert (first xy) exact-integer?))
(define y : Integer
(assert (second xy) exact-integer?))
(pt x y))
(: parse-pts (-> String (Pairof pt pt)))
(define (parse-pts str)
(~>> str
(regexp-match* #px"(\\d{1,3}),(\\d{1,3})")
(map parse-pt)
(list->pair)))
(: parse-cmd (-> String Symbol))
(define (parse-cmd str)
(cond
[(string-prefix? str "turn on") 'turn-on]
[(string-prefix? str "turn off") 'turn-off]
[(string-prefix? str "toggle") 'toggle]
[else 'error]))
(: parse-line (-> String ins))
(define (parse-line str)
(define cmd : Symbol (parse-cmd str))
(define pts : (Pairof pt pt)
(parse-pts str))
(define from : pt (car pts))
(define to : pt (cdr pts))
(ins cmd from to))
(: parse-lines (-> (Listof String) (Listof ins)))
(define (parse-lines strs)
(map parse-line strs))
(: points-between (-> pt pt (Listof pt)))
(define (points-between a b)
(for*/list : (Listof pt)
([x : Integer (in-range (pt-x a) (+ 1 (pt-x b)))]
[y : Integer (in-range (pt-y a) (+ 1 (pt-y b)))])
(pt x y)))
(: follow (-> (Listof ins) Grid))
(define (follow in)
(: turn-on (-> pt pt Grid Grid))
(define (turn-on from to grid)
(: turn-on-rec (-> (Listof pt) Grid Grid))
(define (turn-on-rec pts grid)
(if (empty? pts)
grid
(turn-on-rec (cdr pts) (hash-set grid (car pts) 1))))
(turn-on-rec (points-between from to) grid))
(: turn-off (-> pt pt Grid Grid))
(define (turn-off from to grid)
(: turn-off-rec (-> (Listof pt) Grid Grid))
(define (turn-off-rec pts grid)
(if (empty? pts)
grid
(turn-off-rec (cdr pts) (hash-set grid (car pts) 0))))
(turn-off-rec (points-between from to) grid))
(: toggle-lamp (-> Integer Integer))
(define (toggle-lamp n)
(if (= 1 n)
0
1))
(: toggle (-> pt pt Grid Grid))
(define (toggle from to grid)
(: toggle-rec (-> (Listof pt) Grid Grid))
(define (toggle-rec pts grid)
(if (empty? pts)
grid
(if (hash-has-key? grid (car pts))
(toggle-rec (cdr pts) (hash-update grid (car pts) toggle-lamp))
(toggle-rec (cdr pts) (hash-set grid (car pts) 1)))))
(toggle-rec (points-between from to) grid))
(: follow-rec (-> (Listof ins) Grid Grid))
(define (follow-rec in grid)
(if (empty? in)
grid
(let ([cmd : Symbol (ins-cmd (car in))]
[a : pt (ins-from (car in))]
[b : pt (ins-to (car in))])
(cond
[(symbol=? cmd 'turn-on) (follow-rec (cdr in) (turn-on a b grid))]
[(symbol=? cmd 'turn-off) (follow-rec (cdr in) (turn-off a b grid))]
[(symbol=? cmd 'toggle) (follow-rec (cdr in) (toggle a b grid))]
[else (follow-rec (cdr in) grid)]))))
(follow-rec in #hash()))
(: part1 (-> Index))
(define (part1)
(~>>
(get-input)
(map parse-line)
(follow)
(hash-values)
(filter (lambda (n) (assert n exact-integer?) (= n 1)))
(length)))
(: follow2 (-> (Listof ins) Grid))
(define (follow2 in)
(: inc (-> Integer Integer))
(define (inc n)
(+ 1 n))
(: turn-on (-> pt pt Grid Grid))
(define (turn-on from to grid)
(: turn-on-rec (-> (Listof pt) Grid Grid))
(define (turn-on-rec pts grid)
(if (empty? pts)
grid
(if (hash-has-key? grid (car pts))
(turn-on-rec (cdr pts) (hash-update grid (car pts) inc))
(turn-on-rec (cdr pts) (hash-set grid (car pts) 1)))))
(turn-on-rec (points-between from to) grid))
(: minus-or-zero (-> Integer Integer))
(define (minus-or-zero n)
(if (zero? n)
0
(- n 1)))
(: turn-off (-> pt pt Grid Grid))
(define (turn-off from to grid)
(: turn-off-rec (-> (Listof pt) Grid Grid))
(define (turn-off-rec pts grid)
(if (empty? pts)
grid
(if (hash-has-key? grid (car pts))
(turn-off-rec (cdr pts) (hash-update grid (car pts) minus-or-zero))
(turn-off-rec (cdr pts) (hash-set grid (car pts) 0)))))
(turn-off-rec (points-between from to) grid))
(: toggle-lamp (-> Integer Integer))
(define (toggle-lamp n)
(+ 2 n))
(: toggle (-> pt pt Grid Grid))
(define (toggle from to grid)
(: toggle-rec (-> (Listof pt) Grid Grid))
(define (toggle-rec pts grid)
(if (empty? pts)
grid
(if (hash-has-key? grid (car pts))
(toggle-rec (cdr pts) (hash-update grid (car pts) toggle-lamp))
(toggle-rec (cdr pts) (hash-set grid (car pts) 2)))))
(toggle-rec (points-between from to) grid))
(: follow-rec (-> (Listof ins) Grid Grid))
(define (follow-rec in grid)
(if (empty? in)
grid
(let ([cmd : Symbol (ins-cmd (car in))]
[a : pt (ins-from (car in))]
[b : pt (ins-to (car in))])
(cond
[(symbol=? cmd 'turn-on) (follow-rec (cdr in) (turn-on a b grid))]
[(symbol=? cmd 'turn-off) (follow-rec (cdr in) (turn-off a b grid))]
[(symbol=? cmd 'toggle) (follow-rec (cdr in) (toggle a b grid))]
[else (follow-rec (cdr in) grid)]))))
(follow-rec in #hash()))
(: part2 (-> Integer))
(define (part2)
(~>>
(get-input)
(map parse-line)
(follow2)
(hash-values)
(foldl (lambda (n acc)
(assert n exact-integer?)
(assert acc exact-integer?)
(+ n acc)) 0)))
(module+ test
(require typed/rackunit)
(require typed/rackunit/text-ui)
(define part-1
(test-suite
"Part 1"
(check-equal? (parse-line "turn off 210,146 through 221,482")
(ins 'turn-off (pt 210 146) (pt 221 482))
"parse turn off")
(check-equal? (parse-line "turn on 766,112 through 792,868")
(ins 'turn-on (pt 766 112) (pt 792 868))
"parse turn on")
(check-equal? (parse-line "toggle 491,615 through 998,836")
(ins 'toggle (pt 491 615) (pt 998 836))
"parse toggle")))
(define part-2
(test-suite
"Part 2"
(check-equal? 1 1 "basic")))
(run-tests part-1)
(run-tests part-2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment