#!/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)))