Created
December 8, 2024 15:50
-
-
Save qookei/ac10274a25e8295b9f36664be1117d26 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(use-modules (srfi srfi-1) (srfi srfi-26) (ice-9 pretty-print) (ice-9 textual-ports)) | |
(define (%read-input) | |
(let ([line (get-line (current-input-port))]) | |
(if (eof-object? line) | |
'() | |
(cons (string->list line) (%read-input))))) | |
(define (read-input) | |
(list->array 2 (%read-input))) | |
(define (find-unique-antennas input) | |
(let ([antenna-set (make-hash-table)]) | |
(array-for-each | |
(λ (tile) | |
(if (not (eqv? tile #\.)) | |
(hash-set! antenna-set tile #t))) | |
input) | |
(hash-map->list (λ (k v) k) antenna-set))) | |
(define (find-antenna-positions input antenna) | |
(let ([unrolled (array-contents input)] | |
[width (cadr (array-dimensions input))]) | |
(let next ([i 0] | |
[acc '()]) | |
(if (array-in-bounds? unrolled i) | |
(next (1+ i) | |
(if (eqv? (array-ref unrolled i) antenna) | |
(cons (cons (quotient i width) | |
(remainder i width)) | |
acc) | |
acc)) | |
acc)))) | |
(define (all-antenna-positions input antennas) | |
(map (cut find-antenna-positions input <>) antennas)) | |
(define (vec2+ a b) | |
(cons (+ (car a) (car b)) | |
(+ (cdr a) (cdr b)))) | |
(define (vec2- a b) | |
(cons (- (car a) (car b)) | |
(- (cdr a) (cdr b)))) | |
(define (vec2* a scalar) | |
(cons (* (car a) scalar) | |
(* (cdr a) scalar))) | |
(define (cartesian-product a b) | |
(concatenate! | |
(map | |
(λ (av) | |
(map (λ (bv) (list av bv)) b)) | |
a))) | |
(define (set-antinodes! input antenna-positions start-i end-i) | |
(let ([all-pairs (cartesian-product antenna-positions antenna-positions)]) | |
(for-each | |
(λ (pair) | |
(if (not (equal? (car pair) (cadr pair))) | |
(let ([dist (vec2- (cadr pair) (car pair))]) | |
(let next ([i start-i]) | |
(let ([antinode (vec2+ (car pair) (vec2* dist i))]) | |
(if (and (<= i end-i) | |
(array-in-bounds? input (car antinode) (cdr antinode))) | |
(begin | |
(array-set! input #\# (car antinode) (cdr antinode)) | |
(next (1+ i))) | |
#f)))))) | |
all-pairs))) | |
(define (count-antinodes input) | |
(let ([count 0]) | |
(array-for-each | |
(λ (tile) | |
(if (eqv? tile #\#) | |
(set! count (1+ count)))) | |
input) | |
count)) | |
(let* ([input (read-input)] | |
[antennas (find-unique-antennas input)] | |
[antenna-positions (all-antenna-positions input antennas)]) | |
(for-each (cut set-antinodes! input <> 2 2) antenna-positions) | |
(pretty-print (count-antinodes input)) | |
(for-each (cut set-antinodes! input <> 1 9999) antenna-positions) | |
(pretty-print (count-antinodes input))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment