puzzle-02.scm 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. (import
  2. (except (rnrs base) let-values map error)
  3. (only (guile) lambda* λ command-line string-null? string-count)
  4. ;; list procs
  5. (srfi srfi-1)
  6. ;; hash tables
  7. (srfi srfi-69)
  8. (fileio))
  9. (define concat-lines
  10. (lambda* (lines #:key (separator-test string-null?) (inserted-separator ":"))
  11. (let next-line ([remaining-lines lines] [combined-line ""])
  12. (cond
  13. [(null? remaining-lines)
  14. (list (string-trim-both combined-line))]
  15. [else
  16. (let ([cur-line (first remaining-lines)])
  17. (cond
  18. ;; The passport-separator finishes an entry in
  19. ;; the lines. We cons the single passport data
  20. ;; onto the recursion and start collecting data
  21. ;; for the next single passport.
  22. [(separator-test cur-line)
  23. (cons (string-trim-both combined-line)
  24. (next-line (cdr remaining-lines) ""))]
  25. ;; If more data for a single passport follows, we
  26. ;; append it onto the single passport data and
  27. ;; look at the next line.
  28. [else
  29. (next-line (cdr remaining-lines)
  30. (string-append combined-line
  31. (if (string-null? combined-line)
  32. ""
  33. inserted-separator)
  34. cur-line))]))]))))
  35. (define unique-chars
  36. (λ (str)
  37. (delete-duplicates (string->list str) char=?)))
  38. (define process-passenger-group
  39. (λ (group-answers-string)
  40. (define group-answers (string-split group-answers-string #\:))
  41. (define unique-group-chars
  42. (filter (λ (char) (not (char=? char #\:)))
  43. (unique-chars group-answers-string)))
  44. (define num-group-passengers (length group-answers))
  45. ;; (simple-format (current-output-port) "unique chars of group: ~a\n" unique-group-chars)
  46. (fold (λ (group-chars-availability acc)
  47. (if (cdr group-chars-availability) (+ acc 1) acc))
  48. 0
  49. (map (λ (char)
  50. ;; (simple-format (current-output-port) "looking for ~a times char ~a in ~a\n" num-group-passengers char group-answers-string)
  51. (cons char
  52. ;; Is the number of occurences equal to the number of
  53. ;; passengers in the group? NOTE: This does not work, if
  54. ;; the input is not clean and any character appears
  55. ;; multiple times for one passenger.
  56. (= (string-count group-answers-string char) num-group-passengers)))
  57. unique-group-chars))))
  58. (define main
  59. (λ (cmd-line-args)
  60. (let* ([lines (concat-lines (get-lines-from-file (second cmd-line-args)))])
  61. ;; (simple-format (current-output-port) "lines: ~a\n" lines)
  62. (apply + (map process-passenger-group lines)))))
  63. (simple-format (current-output-port)
  64. "~a\n"
  65. (main (command-line)))