1
0
Fork 0
adventofcode/src/16.rkt

54 lines
1.5 KiB
Racket

#lang racket
(require "../lib.rkt")
(define (string->numbers str)
(map (λ (c) (- (char->integer c) (char->integer #\0)))
(string->list str)))
(define input-string (car (problem-input 16)))
(define input
(string->numbers input-string))
(define (base n)
(let* ([bs (apply append (map ( make-list n) '(0 1 0 -1)))])
(rac (cdr bs) (car bs))))
(define (prod-sum l1 l2)
(let* ([len (min (length l1) (length l2))]
[l1 (take l1 len)]
[l2 (take l2 len)])
(sum (map * l1 l2))))
(define (fft ns)
(let* ([base-reps (λ (n) (ceiling (/ (length ns) (* 4 n))))]
[base-n (λ (n) (repeat (base-reps n) (base n)))])
(map (λ (n) (remainder (abs (prod-sum ns (base-n n))) 10))
(range 1 (add1 (length ns))))))
(define (part1)
(let loop ([signal input]
[count 0])
(if (= 100 count)
(take signal 8)
(loop (fft signal) (add1 count)))))
(define (fft-half ns)
(second
(foldr (λ (v acc)
(match-let ([(list sum lst) acc])
(let ([sum (% (+ v sum) 10)])
(list sum (cons (abs sum) lst)))))
(list 0 '(0)) ns)))
(define (part2)
(let* ([offset (digits->number (take input 7))]
[input-long (repeat 10000 input)]
[half-length (/ (* 10000 (length input)) 2)]
[input-half (drop input-long half-length)])
(let loop ([count 0]
[signal input-half])
(if (= count 100)
(take (drop signal (- offset half-length)) 8)
(loop (add1 count) (fft-half signal))))))