2.scm 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. (import (chicken io))
  2. (import (chicken string))
  3. (import srfi-69)
  4. (import srfi-1)
  5. (define (read-input)
  6. (with-input-from-file "input"
  7. (lambda ()
  8. (define part1
  9. (let loop ((ret '()))
  10. (let ((line (read-line)))
  11. (if (= 0 (string-length line))
  12. (reverse ret)
  13. (loop (cons line ret))))))
  14. (define part2
  15. (let loop ((ret '()))
  16. (let ((line (read-line)))
  17. (if (eof-object? line)
  18. (reverse ret)
  19. (loop (cons line ret))))))
  20. (values part1 part2))))
  21. (define-values (part1 part2) (read-input))
  22. (set! part1 (map (lambda (x) (string-split x "|")) part1))
  23. (set! part1 (map (lambda (x) (map string->number x)) part1))
  24. (define rules (make-hash-table))
  25. (map (lambda (x)
  26. (hash-table-set! rules x #t) '())
  27. part1)
  28. (define updates (map (lambda (x) (string-split x ",")) part2))
  29. (set! updates (map (lambda (x) (map string->number x)) updates))
  30. (define (check-rules x lst)
  31. (if (null? lst)
  32. #t
  33. (and (not (hash-table-ref/default rules (list (car lst) x) #f))
  34. (check-rules x (cdr lst)))))
  35. (define (find-failed x lst)
  36. (if (null? lst)
  37. #f
  38. (if (hash-table-ref/default rules (list (car lst) x) #f)
  39. lst
  40. (find-failed x (cdr lst)))))
  41. (define (check-update update)
  42. (if (null? update)
  43. #t
  44. (and (check-rules (car update) (cdr update))
  45. (check-update (cdr update)))))
  46. (define (correct-update! update)
  47. (if (null? update)
  48. '()
  49. (let ()
  50. (define failed (find-failed (car update) (cdr update)))
  51. (if failed
  52. (let ()
  53. (define tmp (car failed))
  54. (set-car! failed (car update))
  55. (set-car! update tmp))
  56. (correct-update! (cdr update))))))
  57. (define (median lst)
  58. (list-ref lst (quotient (length lst) 2)))
  59. (define incorrect (filter (lambda (x) (not (check-update x))) updates))
  60. (define (do-correction! lst)
  61. (if (check-update lst)
  62. '()
  63. (let ()
  64. (correct-update! lst)
  65. (do-correction! lst))))
  66. (map do-correction! incorrect)
  67. (display (apply + (map median incorrect)))