Advertisement
Guest User

Untitled

a guest
Dec 13th, 2019
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.99 KB | None | 0 0
  1. (defpackage aoc-3
  2. (:use :cl)
  3. (:export read-format))
  4.  
  5. (in-package :aoc-3)
  6.  
  7. (defstruct claim
  8. (id 0 :type integer)
  9. (x 0 :type integer)
  10. (y 0 :type integer)
  11. (w 0 :type integer)
  12. (h 0 :type integer))
  13.  
  14. (defun sort-by-slot (lst slot-name &optional (pred #'<))
  15. (sort lst (lambda (a b)
  16. (funcall pred
  17. (slot-value a slot-name)
  18. (slot-value b slot-name)))))
  19.  
  20. (defmethod axis-overlap ((a claim) b axis dim)
  21. (destructuring-bind (a b)
  22. (sort-by-slot (sort-by-slot (list a b) dim) axis)
  23. (cons (slot-value b axis)
  24. (max 0 (min (- (+ (slot-value a axis)
  25. (slot-value a dim))
  26. (slot-value b axis))
  27. (slot-value a dim)
  28. (slot-value b dim))))))
  29.  
  30. (defmethod overlap ((a claim) b)
  31. (* (cdr (axis-overlap a b 'x 'w))
  32. (cdr (axis-overlap a b 'y 'h))))
  33.  
  34. (defmethod overlap-coords ((a claim) b)
  35. (loop
  36. with (x-start . width) = (axis-overlap a b 'x 'w)
  37. with (y-start . height) = (axis-overlap a b 'y' h)
  38. for x from x-start below (+ x-start width)
  39. nconc (loop for y from y-start below (+ y-start height)
  40. collect (cons x y))))
  41.  
  42. (defun read-expect (in expected)
  43. (loop for c across expected
  44. for next = (peek-char nil in nil 'eof)
  45. do (assert (eq c next))
  46. do (read-char in))
  47. expected)
  48.  
  49. (defun read-int (in)
  50. (let* ((first (peek-char nil in nil 'eof))
  51. (chars (append
  52. (when (eq first #\-)
  53. (list (read-char in)))
  54. (loop
  55. for next = (peek-char nil in nil 'eof)
  56. while (and (not (eq next 'eof))
  57. (digit-char-p next))
  58. collect (read-char in)))))
  59. (when chars
  60. (parse-integer (coerce chars 'string)))))
  61.  
  62. (defun skip-whitespace (in)
  63. (loop for next = (peek-char nil in nil 'eof)
  64. while (find next '(#\space #\newline))
  65. counting (read-char in)))
  66.  
  67. (defun read-format (in spec)
  68. (loop for fmt in spec
  69. for val = (etypecase fmt
  70. (keyword fmt)
  71. (symbol (ecase fmt
  72. ((integer int) (read-int in))
  73. (whitespace (skip-whitespace in))))
  74. (string (read-expect in fmt) nil))
  75. when val collect val))
  76.  
  77. (defun claims ()
  78. (with-open-file (in "input3")
  79. (loop
  80. with fmt = '("#"
  81. :id int
  82. " @ "
  83. :x int "," :y int
  84. ": "
  85. :w int "x" :h int)
  86. do (skip-whitespace in)
  87. while (listen in)
  88. collect (apply #'make-claim
  89. (read-format in fmt)))))
  90.  
  91. (defun pairs (lst)
  92. (loop for a on lst
  93. nconc (loop for b in a
  94. collect (cons (car a) b))))
  95.  
  96. (defun solve-challenge ()
  97. (loop with touched = (make-hash-table :test #'equalp)
  98. for (a . b) in (pairs (claims))
  99. unless (eq a b)
  100. do (loop for xy in (overlap-coords a b)
  101. do (setf (gethash xy touched) t))
  102. finally (return (hash-table-count touched))))
  103.  
  104. (defun solve-challenge-2 ()
  105. (loop
  106. with claims = (claims)
  107. with ids = (mapcar #'claim-id claims)
  108. for (a . b) in (pairs claims)
  109. when (and (not (eq a b))
  110. (> (overlap a b) 0))
  111. do (setq ids (delete (claim-id a) (delete (claim-id b) ids :count 1) :count 1))
  112. finally (return ids)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement