123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- (import
- (except (rnrs base) let-values map error)
- (only (guile) lambda* λ command-line string-null? string-count)
- ;; list procs
- (srfi srfi-1)
- ;; hash tables
- (srfi srfi-69)
- (fileio))
- (define concat-lines
- (lambda* (lines #:key (separator-test string-null?) (inserted-separator ":"))
- (let next-line ([remaining-lines lines] [combined-line ""])
- (cond
- [(null? remaining-lines)
- (list (string-trim-both combined-line))]
- [else
- (let ([cur-line (first remaining-lines)])
- (cond
- ;; The passport-separator finishes an entry in
- ;; the lines. We cons the single passport data
- ;; onto the recursion and start collecting data
- ;; for the next single passport.
- [(separator-test cur-line)
- (cons (string-trim-both combined-line)
- (next-line (cdr remaining-lines) ""))]
- ;; If more data for a single passport follows, we
- ;; append it onto the single passport data and
- ;; look at the next line.
- [else
- (next-line (cdr remaining-lines)
- (string-append combined-line
- (if (string-null? combined-line)
- ""
- inserted-separator)
- cur-line))]))]))))
- (define unique-chars
- (λ (str)
- (delete-duplicates (string->list str) char=?)))
- (define process-passenger-group
- (λ (group-answers-string)
- (define group-answers (string-split group-answers-string #\:))
- (define unique-group-chars
- (filter (λ (char) (not (char=? char #\:)))
- (unique-chars group-answers-string)))
- (define num-group-passengers (length group-answers))
- ;; (simple-format (current-output-port) "unique chars of group: ~a\n" unique-group-chars)
- (fold (λ (group-chars-availability acc)
- (if (cdr group-chars-availability) (+ acc 1) acc))
- 0
- (map (λ (char)
- ;; (simple-format (current-output-port) "looking for ~a times char ~a in ~a\n" num-group-passengers char group-answers-string)
- (cons char
- ;; Is the number of occurences equal to the number of
- ;; passengers in the group? NOTE: This does not work, if
- ;; the input is not clean and any character appears
- ;; multiple times for one passenger.
- (= (string-count group-answers-string char) num-group-passengers)))
- unique-group-chars))))
- (define main
- (λ (cmd-line-args)
- (let* ([lines (concat-lines (get-lines-from-file (second cmd-line-args)))])
- ;; (simple-format (current-output-port) "lines: ~a\n" lines)
- (apply + (map process-passenger-group lines)))))
- (simple-format (current-output-port)
- "~a\n"
- (main (command-line)))
|