Advent of Code 2020 solutions in Racket, I guess
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.4 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. #lang racket
  2. (require "lib/common.rkt")
  3. (struct password (min max char content) #:transparent)
  4. (define (parse-line line)
  5. (match line
  6. [(pregexp #px"^([0-9]+)\\-([0-9]+) (.): (.*?)$" (list _ min max char pwd))
  7. (password (string->number min)
  8. (string->number max)
  9. (string-ref char 0)
  10. pwd)]
  11. [_ (error "oh no")]))
  12. (define (password-valid?/a pwd)
  13. (define occurrences
  14. (count (curry char=? (password-char pwd))
  15. (string->list (password-content pwd))))
  16. (<= (password-min pwd) occurrences (password-max pwd)))
  17. (define (password-valid?/b pwd)
  18. (define (in-position? n)
  19. (char=? (string-ref (password-content pwd) (sub1 n))
  20. (password-char pwd)))
  21. (xor (in-position? (password-min pwd))
  22. (in-position? (password-max pwd))))
  23. (define (solution lst fn)
  24. (count fn (map parse-line lst)))
  25. (module+ main
  26. (call-with-input-file "data/day2.txt"
  27. (lambda (prt)
  28. (define lines (port->lines prt))
  29. (answer 2 1 (solution lines password-valid?/a))
  30. (answer 2 2 (solution lines password-valid?/b)))))
  31. (module+ test
  32. (require rackunit)
  33. (define example1 (password 1 3 #\a "abcde"))
  34. (define example2 (password 1 3 #\b "cdefg"))
  35. (define example3 (password 2 9 #\c "ccccccccc"))
  36. (check-equal? (parse-line "1-3 a: abcde") example1
  37. "1-3 a: abcde, parse")
  38. (check-equal? (parse-line "1-3 b: cdefg") example2
  39. "1-3 b: cdefg, parse")
  40. (check-equal? (parse-line "2-9 c: ccccccccc") example3
  41. "2-9 c: ccccccccc, parse")
  42. (check-pred password-valid?/a example1
  43. "1-3 a: abcde, part 1 validity")
  44. (check-false (password-valid?/a example2)
  45. "1-3 b: cdefg, part 1 validity")
  46. (check-pred password-valid?/a example3
  47. "2-9 c: ccccccccc, part 1, validity")
  48. (check-pred password-valid?/b example1
  49. "1-3 a: abcde, part 2 validity")
  50. (check-false (password-valid?/b example2)
  51. "1-3 b: cdefg, part 2 validity")
  52. (check-false (password-valid?/b example3)
  53. "2-9 c: ccccccccc, part 2 validity")
  54. (call-with-input-file "data/day2.txt"
  55. (lambda (prt)
  56. (define lines (port->lines prt))
  57. (check-equal? (solution lines password-valid?/a) 572
  58. "final answer part 1")
  59. (check-equal? (solution lines password-valid?/b) 306
  60. "final answer part 2"))))