Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
107
2020/day20/day20.rkt
Normal file
107
2020/day20/day20.rkt
Normal file
|
@ -0,0 +1,107 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (read-input filename)
|
||||
(define tiles-str (string-split (file->string filename) "\n\n"))
|
||||
(for/hash ([str tiles-str])
|
||||
(parse-tile str)))
|
||||
|
||||
(define (parse-tile str)
|
||||
(define tile-id
|
||||
(string->number (cadr (string-split (car (string-split str ":\n"))))))
|
||||
(define tile (string-split (cadr (string-split str ":\n"))))
|
||||
(values tile-id
|
||||
(for/set ([s (in-list tile)]
|
||||
[i (in-range 10)]
|
||||
#:when #t
|
||||
[x (in-string s)]
|
||||
[j (in-range 10)]
|
||||
#:when (eq? x #\#))
|
||||
(list i j))))
|
||||
|
||||
(define (get-tile-edges tile)
|
||||
(define edges-lists
|
||||
(list (for/list ([k (in-range 10)])
|
||||
(if (set-member? tile (list 0 k)) #\1 #\0))
|
||||
(for/list ([k (in-range 10)])
|
||||
(if (set-member? tile (list k 0)) #\1 #\0))
|
||||
(for/list ([k (in-range 10)])
|
||||
(if (set-member? tile (list 9 k)) #\1 #\0))
|
||||
(for/list ([k (in-range 10)])
|
||||
(if (set-member? tile (list k 9)) #\1 #\0))))
|
||||
(define reversed-edges-lists (map reverse edges-lists))
|
||||
(map (λ (lst) (string->number (list->string lst) 2)) (append edges-lists reversed-edges-lists)))
|
||||
|
||||
(define (get-neighbours tiles)
|
||||
(define neighbours (make-hash))
|
||||
(for* ([(tile1-idx tile1) (in-hash tiles)]
|
||||
[(tile2-idx tile2) (in-hash tiles)]
|
||||
#:unless (= tile1-idx tile2-idx)
|
||||
#:when (not (set-empty? (set-intersect (get-tile-edges tile1) (get-tile-edges tile2)))))
|
||||
(hash-update! neighbours tile1-idx (λ (ns) (set-add ns tile2-idx)) (set))
|
||||
(hash-update! neighbours tile2-idx (λ (ns) (set-add ns tile1-idx)) (set)))
|
||||
neighbours)
|
||||
|
||||
(define (part1 filename)
|
||||
(define tiles (read-input filename))
|
||||
(define neighbours (get-neighbours tiles))
|
||||
(for/product ([(tile-idx tile) (in-hash tiles)]
|
||||
#:when (= 2 (set-count (hash-ref neighbours tile-idx))))
|
||||
tile-idx))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 "test") 20899048083289))
|
||||
|
||||
(module+ main
|
||||
(displayln (part1 "input")))
|
||||
|
||||
(define (display-tile tile)
|
||||
(for* ([j (in-range 10)]
|
||||
[i (in-range 10)])
|
||||
(when (= i 0)
|
||||
(printf "\n"))
|
||||
(if (set-member? tile (list i j))
|
||||
(printf "#")
|
||||
(printf "."))))
|
||||
|
||||
(define (rotate tile)
|
||||
(for/set ([x (in-set tile)])
|
||||
(list (- 9 (cadr x)) (car x))))
|
||||
|
||||
(define (flipx tile)
|
||||
(for/set ([x (in-set tile)])
|
||||
(list (- 9 (car x)) (cadr x))))
|
||||
|
||||
(define (flipy tile)
|
||||
(for/set ([x (in-set tile)])
|
||||
(list (car x) (- 9 (cadr x)))))
|
||||
|
||||
(define (all-transformations tiles)
|
||||
(define r1 (set-map (hash-values tiles) rotate))
|
||||
(define r2 (set-map r1 rotate))
|
||||
(define r3 (set-map r2 rotate))
|
||||
(define s (set-union (hash-values tiles) r1 r2 r3))
|
||||
(list->set (set-union s
|
||||
(set-map s flipx)
|
||||
(set-map s flipy))))
|
||||
|
||||
(define (edge tile side)
|
||||
(define side-fn (match side
|
||||
[1 (λ (k) (make-rectangular 0 k))]
|
||||
[-1 (λ (k) (make-rectangular 9 k))]
|
||||
[0+1i (λ (k) (make-rectangular k 0))]
|
||||
[0-1i (λ (k) (make-rectangular k 9))]))
|
||||
(string->number
|
||||
(list->string (for/list ([k (in-range 10)])
|
||||
(if (set-member? tile (side-fn k)) #\1 #\0))) 2))
|
||||
|
||||
(define (find-corner tiles)
|
||||
(define neighbours (get-neighbours tiles))
|
||||
(define corner (for/first ([(tile-idx tile) (in-hash tiles)]
|
||||
#:when (= 2 (set-count (hash-ref neighbours tile-idx))))
|
||||
tile))
|
||||
corner)
|
||||
|
||||
;; Too boring, cheated
|
Loading…
Add table
Add a link
Reference in a new issue