44 lines
1.8 KiB
Plaintext
44 lines
1.8 KiB
Plaintext
(defun main []
|
|
// Day 1
|
|
// TODO implement unless
|
|
(let [p (pairWithSum 2020 [1721 979 366 299 675 1456])]
|
|
(when !(and (has p 1721) (has p 299))
|
|
(throw "pairWithSum is broken")))
|
|
(let [[a b] (pairWithSum 2020 (readInts "src/year2020/inputs/day1-1.txt"))]
|
|
(when !(= 545379 (* a b))
|
|
(throw "pairWithSum is broken")))
|
|
(let [t (trioWithSum 2020 [1721 979 366 299 675 1456])]
|
|
(when !(and (has t 675) (has t 366) (has t 979))
|
|
(throw "trioWithSum is broken")))
|
|
(let [[a b c] (trioWithSum 2020 (readInts "src/year2020/inputs/day1-1.txt"))]
|
|
(when !(= 257778836 (* a b c))
|
|
(throw "trioWithSum is broken"))))
|
|
|
|
(defun readLines [file]
|
|
(.filter
|
|
(.map
|
|
// TODO implement escape sequences in kiss string literals
|
|
(.split (File.getContent file) #|"\n"|#)
|
|
StringTools.trim)
|
|
(lambda [l] (< 0 l.length))))
|
|
|
|
(defun readInts [file] (let [lines (readLines file)] (lines.map Std.parseInt)))
|
|
|
|
(defun :kiss.List<Int> pairWithSum [sum :kiss.List<Int> numbers]
|
|
// Put the numbers in a map for random access. This gives an O(n) solution
|
|
(deflocal :Map<Int,Int> numbersMap (new Map))
|
|
(doFor number numbers
|
|
(dict-set numbersMap number (- sum number))
|
|
(let [requiredForPair (dict-get numbersMap number)]
|
|
(when (numbersMap.exists requiredForPair)
|
|
(return [number requiredForPair]))))
|
|
null)
|
|
|
|
(defun :kiss.List<Int> trioWithSum [sum :kiss.List<Int> numbers]
|
|
(deflocal &mut trio null)
|
|
(doFor number numbers
|
|
(let [requiredForTrio (- sum number)
|
|
pairThatSatisfies (pairWithSum requiredForTrio numbers)]
|
|
(when pairThatSatisfies
|
|
(return [number (nth pairThatSatisfies 0) (nth pairThatSatisfies 1)]))))
|
|
null) |