day 18
This commit is contained in:
147
18-snailfish/code.scm
Normal file
147
18-snailfish/code.scm
Normal file
@@ -0,0 +1,147 @@
|
||||
(import (srfi :13)) ; string extensions
|
||||
|
||||
; returns a new string where all occurrences of `find` have been replaced by `replace`
|
||||
(define (string-substitute str find replace)
|
||||
(let [(len-find (string-length find))]
|
||||
(let loop [(str str)]
|
||||
(let [(index (string-contains str find))]
|
||||
(if index
|
||||
(loop (string-replace str replace index (+ index len-find)))
|
||||
str)))))
|
||||
|
||||
; turns a snailfish number into a regular scheme list
|
||||
(define (snailfish-number->list str)
|
||||
; this feels like cheating x)
|
||||
(get-datum
|
||||
(open-string-input-port
|
||||
(string-substitute str "," " "))))
|
||||
|
||||
; loads all the snailfish numbers from the given text port, one by line
|
||||
(define (load-numbers port)
|
||||
(let loop [(numbers '())]
|
||||
(if (eof-object? (peek-char port))
|
||||
(reverse numbers)
|
||||
(loop (cons (snailfish-number->list (get-line port)) numbers)))))
|
||||
|
||||
; updates literal from snailfish number at given index
|
||||
(define (update-literal! number index updater)
|
||||
(let [(i 0)]
|
||||
(let rec [(p number)]
|
||||
(if (null? p)
|
||||
i
|
||||
(if (number? (car p))
|
||||
(if (= i index)
|
||||
(begin
|
||||
(set-car! p (updater (car p)))
|
||||
(set! i #f)) ; kill recursion
|
||||
(begin
|
||||
(set! i (+ i 1))
|
||||
(rec (cdr p))))
|
||||
(begin
|
||||
(rec (car p))
|
||||
(when i
|
||||
(rec (cdr p)))))))))
|
||||
|
||||
; change literal at given index to be given value
|
||||
(define (set-literal! number index value)
|
||||
(update-literal! number index (lambda (v) value)))
|
||||
|
||||
; increment literal at given index by given value
|
||||
(define (add-literal! number index value)
|
||||
(update-literal! number index (lambda (v) (+ v value))))
|
||||
|
||||
; change the car of the cdr of l
|
||||
(define (set-cadr! l v)
|
||||
(set-car! (cdr l) v))
|
||||
|
||||
; explode snailfish number if possible
|
||||
; returns #t if any number has exploded
|
||||
(define (explode! input)
|
||||
(let [(index 0)]
|
||||
(let look [(parent '()) (set-parent! #f) (depth 0) (pair input)]
|
||||
(if (not (number? pair))
|
||||
(if (>= depth 4)
|
||||
; explode
|
||||
(let [(left (car pair))
|
||||
(right (cadr pair))]
|
||||
(add-literal! input (- index 1) left)
|
||||
(add-literal! input (+ index 2) right)
|
||||
(set-parent! parent 0)
|
||||
(set! index #f)) ; kill recursion
|
||||
(begin
|
||||
(look pair set-car! (+ depth 1) (car pair))
|
||||
(when index
|
||||
(look pair set-cadr! (+ depth 1) (cadr pair)))))
|
||||
; pair is actually a number
|
||||
(set! index (+ index 1))))
|
||||
(not index)))
|
||||
|
||||
; split snailfish number if possible
|
||||
; returns #t if any number has been split
|
||||
(define (split! input)
|
||||
(let [(index 0)]
|
||||
(let look [(pair input)]
|
||||
(if (number? pair)
|
||||
(if (>= pair 10)
|
||||
(begin
|
||||
; split
|
||||
(set-literal! input index (list (div pair 2) (- pair (div pair 2))))
|
||||
(set! index #f) ; kill recursion
|
||||
(reduce! input))
|
||||
(set! index (+ index 1)))
|
||||
(begin
|
||||
(look (car pair))
|
||||
(when index ; check recursion hasn't been killed
|
||||
(look (cadr pair))))))
|
||||
(not index)))
|
||||
|
||||
; reduce snailfish number according to the rules of the problem
|
||||
(define (reduce! input)
|
||||
(if (explode! input)
|
||||
(reduce! input)
|
||||
(if (split! input)
|
||||
(reduce! input)
|
||||
input)))
|
||||
|
||||
; adds two snailfish numbers
|
||||
; input will be corrupted!
|
||||
(define (add! a b)
|
||||
(reduce! (list a b)))
|
||||
|
||||
; compute magnitude of snailfish number
|
||||
(define (magnitude n)
|
||||
(if (number? n)
|
||||
n
|
||||
(+ (* 3 (magnitude (car n)))
|
||||
(* 2 (magnitude (cadr n))))))
|
||||
|
||||
; deep copy given list
|
||||
(define (duplicate lst)
|
||||
(if (pair? lst)
|
||||
(cons (duplicate (car lst)) (duplicate (cdr lst)))
|
||||
lst))
|
||||
|
||||
; finds the largest magnitude obtained by summing any two numbers from the given list
|
||||
(define (largest-magnitude numbers)
|
||||
(let [(largest 0)]
|
||||
(for-each
|
||||
(lambda (n1)
|
||||
(for-each
|
||||
(lambda (n2)
|
||||
(let* [(sum (add! (duplicate n1) (duplicate n2)))
|
||||
(mag (magnitude sum))]
|
||||
(when (> mag largest)
|
||||
(set! largest mag))))
|
||||
(remove n1 numbers)))
|
||||
numbers)
|
||||
largest))
|
||||
|
||||
(call-with-input-file
|
||||
"input"
|
||||
(lambda (file)
|
||||
(let [(numbers (load-numbers file))]
|
||||
(let [(numbers (duplicate numbers))]
|
||||
(printf "part 1:~% Magnitude of final sum: ~a~%"
|
||||
(magnitude (fold-left add! (car numbers) (cdr numbers)))))
|
||||
(printf "part 2:~% Largest magnitude: ~a~%"
|
||||
(largest-magnitude numbers)))))
|
||||
100
18-snailfish/input
Normal file
100
18-snailfish/input
Normal file
@@ -0,0 +1,100 @@
|
||||
[[[[9,5],[9,4]],[[6,5],[7,0]]],4]
|
||||
[[[5,2],[[7,2],1]],[[[7,5],[0,8]],[[6,9],[7,3]]]]
|
||||
[[[9,7],[0,1]],9]
|
||||
[1,[[7,3],[[3,7],[3,2]]]]
|
||||
[[9,[[0,8],7]],[[3,1],[[6,6],[9,0]]]]
|
||||
[4,[[4,4],[[7,7],1]]]
|
||||
[[[[6,2],[5,1]],[[3,3],9]],[7,[[5,7],[5,0]]]]
|
||||
[[[[4,8],[4,9]],[1,[9,3]]],[1,[1,[6,1]]]]
|
||||
[[[[4,7],[3,4]],[8,3]],[[3,7],[0,[1,8]]]]
|
||||
[[[6,[4,8]],[4,5]],[4,[1,3]]]
|
||||
[[[0,7],0],[[6,[1,8]],[9,[7,9]]]]
|
||||
[[[[4,8],[3,9]],[4,5]],[1,1]]
|
||||
[[[4,2],[0,[6,7]]],[[[1,8],2],[8,8]]]
|
||||
[[[[1,1],7],5],[[6,[5,6]],[6,[7,5]]]]
|
||||
[[[[3,2],5],[[5,3],1]],[[[0,4],[9,6]],9]]
|
||||
[[6,[7,6]],9]
|
||||
[[[[4,0],[0,1]],7],1]
|
||||
[[[[1,3],4],6],[[1,[4,2]],[1,4]]]
|
||||
[[[[6,9],[4,1]],[[6,3],[0,8]]],[[4,0],[[3,2],[2,9]]]]
|
||||
[[[3,6],[[2,0],[3,2]]],[2,5]]
|
||||
[[[[4,3],5],5],[[4,[4,0]],6]]
|
||||
[[[[4,0],3],[[3,5],8]],[[8,[4,4]],[[9,9],[4,1]]]]
|
||||
[[[2,7],6],1]
|
||||
[[[[5,3],[8,4]],[0,0]],4]
|
||||
[[[0,[8,1]],0],3]
|
||||
[[[6,5],[8,2]],[[[6,9],[6,1]],[9,9]]]
|
||||
[0,[[4,9],6]]
|
||||
[[9,[[9,9],4]],[[[4,7],1],2]]
|
||||
[[8,0],[[[0,7],6],[[6,4],2]]]
|
||||
[[1,[[2,4],8]],1]
|
||||
[[[[1,3],4],[[1,3],0]],[[[1,2],3],2]]
|
||||
[[[[2,1],2],[5,[2,8]]],[2,[[6,0],2]]]
|
||||
[[[8,[1,0]],[[6,7],[9,6]]],[[2,[9,7]],5]]
|
||||
[[[3,[2,0]],[[3,2],[0,0]]],[[[4,6],[9,4]],[[7,8],[5,1]]]]
|
||||
[[3,[[9,9],[7,2]]],[[1,3],[2,[3,2]]]]
|
||||
[4,[4,[[9,5],6]]]
|
||||
[[[[5,7],7],[[3,4],0]],[[9,[8,2]],[2,3]]]
|
||||
[[[[2,1],[5,7]],4],[[[6,3],8],[[1,6],[5,1]]]]
|
||||
[[[4,4],[[0,9],[7,8]]],[[2,[2,5]],5]]
|
||||
[1,[5,[[3,7],[8,2]]]]
|
||||
[[[[9,5],[8,6]],[5,5]],[[[9,2],8],[[9,3],[3,8]]]]
|
||||
[0,[[9,5],[[3,7],7]]]
|
||||
[[[8,[0,4]],[[2,9],6]],[[6,[8,0]],4]]
|
||||
[[0,[3,5]],[[5,[0,1]],[[3,6],7]]]
|
||||
[[2,[7,1]],[[[5,0],[7,7]],[[2,3],9]]]
|
||||
[[5,[9,[3,9]]],[[8,[3,7]],[[7,6],[3,0]]]]
|
||||
[[[4,[2,5]],5],[3,1]]
|
||||
[[[[4,3],1],[[5,7],6]],[0,[3,1]]]
|
||||
[[8,9],[[[0,7],5],[6,[5,7]]]]
|
||||
[[6,8],[[5,8],[[8,2],[6,0]]]]
|
||||
[[1,[5,6]],5]
|
||||
[[[6,1],[9,[1,2]]],1]
|
||||
[[5,[7,[4,8]]],[[4,[2,9]],5]]
|
||||
[[[2,2],[[7,1],3]],[[[9,7],[4,6]],[1,[0,1]]]]
|
||||
[[3,[6,[4,5]]],2]
|
||||
[[[0,2],[[8,1],[0,6]]],[[7,[9,6]],0]]
|
||||
[[[[1,0],[5,1]],[[0,6],5]],[[[1,8],8],[[0,2],5]]]
|
||||
[[6,[[3,6],6]],[[[9,7],[6,4]],[[9,5],1]]]
|
||||
[[[0,[5,6]],[9,0]],[[2,9],9]]
|
||||
[1,[[4,[9,3]],0]]
|
||||
[[1,0],[[1,9],[4,8]]]
|
||||
[[[9,3],[7,0]],[[[5,1],[3,8]],9]]
|
||||
[[[3,9],[[5,9],2]],[[7,2],1]]
|
||||
[[1,[[3,0],[7,6]]],[7,[8,1]]]
|
||||
[0,[6,[[7,1],[1,1]]]]
|
||||
[[4,[[5,0],[2,1]]],[[[8,8],[8,1]],7]]
|
||||
[[[[9,3],[4,3]],4],[7,5]]
|
||||
[[9,[[7,4],[8,3]]],[[[1,9],7],[[1,6],[3,1]]]]
|
||||
[[6,9],[5,[0,[5,1]]]]
|
||||
[[[8,7],3],[[4,8],[0,7]]]
|
||||
[[[[3,1],2],[[1,6],[4,3]]],[0,6]]
|
||||
[[5,[[5,4],3]],[[8,8],9]]
|
||||
[[5,[3,[4,5]]],[[2,[6,0]],[6,1]]]
|
||||
[[[[9,5],3],6],[[8,[1,9]],[[5,2],5]]]
|
||||
[[[7,5],[[3,6],4]],[6,[[5,1],[0,1]]]]
|
||||
[[1,[[4,8],[1,3]]],7]
|
||||
[[4,[[4,0],5]],[[[6,2],7],[[4,8],[4,9]]]]
|
||||
[[[[2,3],[0,9]],[7,2]],[4,5]]
|
||||
[[[[7,7],[8,0]],[7,7]],[[[6,6],[3,2]],[4,[4,3]]]]
|
||||
[[[[8,7],6],[[5,5],0]],[[6,[7,3]],[[4,1],[1,7]]]]
|
||||
[[[2,[2,2]],[[5,2],1]],[[9,[9,2]],6]]
|
||||
[[[[1,7],6],[[8,8],5]],[6,[1,[1,7]]]]
|
||||
[[[[8,6],[3,2]],[[5,2],[2,0]]],[[[8,7],2],[[5,5],2]]]
|
||||
[[[8,[9,0]],[[9,5],[7,5]]],[[5,1],[[1,1],[4,6]]]]
|
||||
[5,[9,[[0,2],7]]]
|
||||
[8,[[0,[4,9]],[[7,4],9]]]
|
||||
[[[[2,9],5],[[0,6],[6,6]]],[[0,6],[[4,2],[9,9]]]]
|
||||
[7,[[[4,3],3],[[5,4],[6,0]]]]
|
||||
[[0,[8,[1,1]]],5]
|
||||
[[[1,8],[[4,6],[9,7]]],[[[6,6],[2,6]],[4,3]]]
|
||||
[[0,[[7,5],[9,9]]],[[9,7],[6,2]]]
|
||||
[[[9,[3,0]],[[1,4],0]],[[1,1],1]]
|
||||
[[[0,7],[[3,0],8]],[[6,[8,0]],[[4,5],[4,0]]]]
|
||||
[[[[2,9],[4,2]],[5,[9,3]]],[4,[2,[3,4]]]]
|
||||
[[[1,[7,3]],[[5,7],0]],[6,[[6,5],2]]]
|
||||
[4,5]
|
||||
[[7,9],[6,[[6,5],[1,0]]]]
|
||||
[[4,[[7,5],8]],[[4,0],[[6,6],[0,4]]]]
|
||||
[[[9,[7,7]],[[4,2],7]],4]
|
||||
[[0,[0,3]],5]
|
||||
10
18-snailfish/simple
Normal file
10
18-snailfish/simple
Normal file
@@ -0,0 +1,10 @@
|
||||
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
|
||||
[[[5,[2,8]],4],[5,[[9,9],0]]]
|
||||
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
|
||||
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
|
||||
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
|
||||
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
|
||||
[[[[5,4],[7,7]],8],[[8,3],8]]
|
||||
[[9,3],[[9,9],[6,[4,9]]]]
|
||||
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
|
||||
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
|
||||
Reference in New Issue
Block a user