summaryrefslogtreecommitdiff
path: root/report-repair/rr.scm
blob: 6adee86d4b561f69be6d85e219504bdb5b78b8cf (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
47
48
49
#!/run/current-system/profile/bin/guile \
-e main -s
!#
(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))