puzzle-01.scm 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. (import
  2. (except (rnrs base) let-values map error)
  3. (only (guile) lambda* λ command-line string-null?)
  4. (srfi srfi-1)
  5. (fileio))
  6. (define concat-lines
  7. (lambda* (lines #:key (separator-test string-null?))
  8. (let next-line ([remaining-lines lines] [combined-line ""])
  9. (cond
  10. [(null? remaining-lines)
  11. (list (string-trim-both combined-line))]
  12. [else
  13. (let ([cur-line (first remaining-lines)])
  14. (cond
  15. ;; The passport-separator finishes an entry in
  16. ;; the lines. We cons the single passport data
  17. ;; onto the recursion and start collecting data
  18. ;; for the next single passport.
  19. [(separator-test cur-line)
  20. (cons (string-trim-both combined-line)
  21. (next-line (cdr remaining-lines) ""))]
  22. ;; If more data for a single passport follows, we
  23. ;; append it onto the single passport data and
  24. ;; look at the next line.
  25. [else
  26. (next-line (cdr remaining-lines)
  27. (string-append combined-line cur-line))]))]))))
  28. (define unique-chars
  29. (λ (str)
  30. (define look-at-next-char
  31. (λ (remaining-chars previous-char unique-chars)
  32. (cond
  33. [(null? remaining-chars)
  34. unique-chars]
  35. [(char=? previous-char (first remaining-chars))
  36. (look-at-next-char (cdr remaining-chars)
  37. previous-char
  38. unique-chars)]
  39. [else
  40. (look-at-next-char (cdr remaining-chars)
  41. (first remaining-chars)
  42. (cons (first remaining-chars) unique-chars))])))
  43. (let ([sorted-chars (sort (string->list str) char<?)])
  44. (look-at-next-char (cdr sorted-chars)
  45. (first sorted-chars)
  46. (list (first sorted-chars))))))
  47. (define main
  48. (λ (cmd-line-args)
  49. (let* ([lines (concat-lines (get-lines-from-file (second cmd-line-args)))])
  50. (apply + (map length (map unique-chars lines))))))
  51. (simple-format (current-output-port)
  52. "~a\n"
  53. (main (command-line)))