part-02-improved.scm 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. (import
  2. (except (rnrs base) let-values map)
  3. (only (guile)
  4. lambda* λ
  5. string-split)
  6. (fileio)
  7. (srfi srfi-1))
  8. (define-syntax ->
  9. (syntax-rules ()
  10. ;; first expression is left unchanged
  11. [(-> expr) expr]
  12. ;; take from the back, wrap other calls
  13. [(-> expr* ... (op args* ...))
  14. (op args* ... (-> expr* ...))]
  15. ;; make parens unnecessary in trivial case of no further arguments
  16. [(-> expr* ... op)
  17. (op (-> expr* ...))]))
  18. (define-syntax define-mapped
  19. (syntax-rules ()
  20. [(_ name body-expr)
  21. (define name
  22. (λ (arg)
  23. (map (λ (one)
  24. (body-expr one))
  25. arg)))]))
  26. (define make-range
  27. (λ (a b)
  28. (cons a b)))
  29. (define string-range->range
  30. (λ (str-range)
  31. (let ([parts (string-split str-range #\-)])
  32. (make-range (string->number (car parts))
  33. (string->number (car (cdr parts)))))))
  34. (define range-start
  35. (λ (range)
  36. (car range)))
  37. (define range-end
  38. (λ (range)
  39. (cdr range)))
  40. (define in-range?
  41. (λ (num range)
  42. (and (>= num (range-start range))
  43. (<= num (range-end range)))))
  44. (define ranges-overlap?
  45. (λ (range1 range2)
  46. (or (in-range? (range-start range1) range2)
  47. (in-range? (range-end range1) range2)
  48. (in-range? (range-start range2) range1)
  49. (in-range? (range-end range2) range1))))
  50. (define-mapped split
  51. (λ (line) (string-split line #\,)))
  52. (define-mapped ranges
  53. (λ (range-strs)
  54. (cons (string-range->range (car range-strs))
  55. (string-range->range (cadr range-strs)))))
  56. (define-mapped matches
  57. (λ (range-pair)
  58. (let ([range1 (car range-pair)]
  59. [range2 (cdr range-pair)])
  60. (ranges-overlap? range1 range2))))
  61. (define count
  62. (λ (flags)
  63. (fold (λ (flag acc)
  64. (+ acc (if flag 1 0)))
  65. 0
  66. flags)))
  67. (-> (get-lines-from-file "input")
  68. split
  69. ranges
  70. matches
  71. count)