summaryrefslogtreecommitdiff
path: root/report-repair/rr.scm
blob: d96fa20b2fcea41913f3ee017648cd270de1ddf2 (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
(define-module (rr)
  #:use-module (combinations)
  #:use-module (srfi srfi-1)
  #: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))