summaryrefslogtreecommitdiff
path: root/report-repair/rr.scm
diff options
context:
space:
mode:
Diffstat (limited to 'report-repair/rr.scm')
-rw-r--r--report-repair/rr.scm100
1 files changed, 42 insertions, 58 deletions
diff --git a/report-repair/rr.scm b/report-repair/rr.scm
index b327d3c..6adee86 100644
--- a/report-repair/rr.scm
+++ b/report-repair/rr.scm
@@ -2,64 +2,48 @@
-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
- multiply-pair
- return-equivalent-pair
- equivalent-pair?
- return-friendship-pair
- report->pairs))
-
-
-(define (rr str)
- (multiply-pair
- (return-equivalent-pair
- (report->pairs str))))
-
-(define (multiply-pair pair)
- (* (car pair)
- (cdr pair)))
-
-(define (return-equivalent-pair pairs)
- "Given PAIRS friendship pairs, returns the
-ones that are found to be friends. Throws
-friendship-exception if no friends are found.
-
-We do NOT care if there are multiple pairs.
-Return the first one."
- (let loop ((pair (car pairs)) (pairs (cdr pairs)))
- (if (null? pairs)
- (raise-exception
- (make-exception-with-message
- "Concerning lack of friendship!"))
- (if (equivalent-pair? pair pairs)
- pair
- (loop (car pairs) (cdr pairs))))))
-
-(define (equivalent-pair? pair pairs)
- "Given friendship pair PAIR and a list
-of other PAIRS, determines if PAIR is
-contained in PAIRS, irrespective of order"
- (let ((r-pair (cons (cdr pair)
- (car pair))))
- (any (lambda (pair)
- (equal? r-pair pair))
- pairs)))
-
-(define (report->pairs str)
- "Given a report, convert it to a
-list of friendship pairs."
- (let ((lst (string-split
- (string-trim-both str char-set:whitespace)
- char-set:whitespace)))
- (map (lambda (str)
- (return-friendship-pair
- (string->number str)))
- lst)))
-
-(define (return-friendship-pair num)
- "Given NUM, returns a cons pair with
-CAR as the original number and CDR as
-the companion number."
- (cons num (- 2020 num)))
+ 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))