Skip to content

Instantly share code, notes, and snippets.

@qookei
Last active December 15, 2023 17:35
Show Gist options
  • Save qookei/db816975257d4e02f6ced13e77bdc67c to your computer and use it in GitHub Desktop.
Save qookei/db816975257d4e02f6ced13e77bdc67c to your computer and use it in GitHub Desktop.
(use-modules (ice-9 textual-ports) (srfi srfi-1) (srfi srfi-26)
(ice-9 format) (ice-9 match) (ice-9 pretty-print)
(srfi srfi-8) (ice-9 arrays))
(define (%map-input-char c)
(match c
[#\. 0]
[#\O 1]
[#\# -1]))
(define (%read-input)
(let ([line (get-line (current-input-port))])
(if (eof-object? line)
'()
(cons (map %map-input-char (string->list line))
(%read-input)))))
(define (read-input)
(list->array 2 (%read-input)))
(define (break-on lst v)
(receive (before after)
(break (cut = v <>) lst)
(cond
[(null? after) (list before)]
[else (cons before
(cons (list (car after))
(break-on (cdr after) v)))])))
(define (%get-column-north input x)
(let ([y-range (second (array-shape input))])
(make-shared-array
input
(λ (i) (list i x))
y-range)))
(define (%get-column-south input x)
(let* ([y-range (second (array-shape input))]
[y-max (second y-range)])
(make-shared-array
input
(λ (i) (list (- y-max i) x))
y-range)))
(define (%get-row-west input y)
(let* ([x-range (first (array-shape input))]
[x-max (second x-range)])
(make-shared-array
input
(λ (i) (list y (- x-max i)))
x-range)))
(define (%get-row-east input y)
(let ([x-range (first (array-shape input))])
(make-shared-array
input
(λ (i) (list y i))
x-range)))
(define (%shift-rocks line)
(array-copy!
(list->array
1 (apply append
(map (λ (lst)
(if (equal? lst '(-1))
lst
(sort lst >)))
(break-on (array->list line) -1))))
line))
(define (%north-load input)
(let ([height (cadr (array-dimensions input))])
(fold
(λ (x prev)
(+ prev
(fold
(λ (v i prev)
(+ prev
(if (> v 0) i 0)))
0
(array->list (%get-column-north input x))
(iota height height -1))))
0 (iota height))))
(define (part1 input)
(for-each
(λ (x) (%shift-rocks (%get-column-north input x)))
(iota (second (array-dimensions input))))
(%north-load input))
(define (%one-cycle input)
(for-each
(λ (x) (%shift-rocks (%get-column-north input x)))
(iota (second (array-dimensions input))))
(for-each
(λ (y) (%shift-rocks (%get-row-east input y)))
(iota (first (array-dimensions input))))
(for-each
(λ (x) (%shift-rocks (%get-column-south input x)))
(iota (second (array-dimensions input))))
(for-each
(λ (y) (%shift-rocks (%get-row-west input y)))
(iota (first (array-dimensions input)))))
(define (%part2 input)
(let next ([i 0])
(let ([load (%north-load input)])
(if (= i 1000)
(list load)
(begin
(%one-cycle input)
(cons load (next (1+ i))))))))
(let ([input (read-input)])
(format #t "Part 1: ~a~%" (part1 (array-copy input)))
(format #t "Part 2:
Put the following numbers into a spreadsheet into column A.
Put numbers 1-1001 in column B.
Then set:
D3 to =MIN(A400:A1001)
D4 to =VLOOKUP(D3, A400:B1001,2,0)
D5 to =VLOOKUP(D3, A449:B1001,2,FALSE()) -- adjust 449 based on value in D4
D6 to =D5-D4
D7 to =D5+MOD(1000000000-D5,D6) -- may need +1? works without for sample
input, doesn't for my input
Then look at column A row (value of D7) for the answer.
~{~a~%~}" (%part2 (array-copy input))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment