summaryrefslogtreecommitdiff
path: root/report-repair/rr.scm
blob: b327d3c245922d0498d34c31672c1320ff3741a5 (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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/run/current-system/profile/bin/guile \
-e main -s
!#
(define-module (rr)
  #:use-module (srfi srfi-1)
  #: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)))