Skip to content

Instantly share code, notes, and snippets.

@qookei
Created December 8, 2024 15:50
Show Gist options
  • Save qookei/ac10274a25e8295b9f36664be1117d26 to your computer and use it in GitHub Desktop.
Save qookei/ac10274a25e8295b9f36664be1117d26 to your computer and use it in GitHub Desktop.
(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