blob: 11c4bcd0f497e424a26d709c2a5cd8a35d6f7021 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
(define-module (rr)
#:use-module (combinations)
#:use-module (srfi srfi-1)
#:use-module (ice-9 format)
#:use-module (ice-9 exceptions)
#:export (rr
get-2020-terms
includes-all?
generate-sets
make-complete-set))
(define (rr str len)
(apply * (get-2020-terms (map string->number
(string-split
(string-trim-both str char-set:whitespace)
char-set:whitespace))
len)))
(define (get-2020-terms lst len)
"Given a list of numbers, returns a list
of length LEN whose contents add up to 2020.
Throws input-exception if none are found."
(let loop ((sets (generate-sets lst len)))
(cond
((null? sets) (raise-exception
(make-exception-with-message
(format #f "Could not find ~s arguments that add to 2020 in inputs!" len))))
((includes-all? (car sets) lst) (car sets))
(#t (loop (cdr sets))))))
(define (includes-all? lst1 lst2)
"Returns #t if all elements in LST1
are present in LST2, #f otherwise."
(equal? lst1
(lset-intersection eqv? lst1 lst2)))
(define (generate-sets lst len)
(map make-complete-set (combinations lst (1- len))))
(define (make-complete-set lst)
"Given a LST of numbers, i.e.
'(979 366)
returns a list of one greater length
such that all numbers add up to 2020."
(append (list (- 2020 (apply + lst))) lst))
|