72 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Common Lisp
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Common Lisp
		
	
	
	
	
	
;;; https://adventofcode.com/2022/day/4
 | 
						|
 | 
						|
;; so, just read two intervals.
 | 
						|
;; intervals , separated, two numbers - separated.
 | 
						|
;; so. ugh. have a parsing function. maybe ask how to better parse
 | 
						|
;; then to calculate "total inclusion" - can go both ways, so 4 checks
 | 
						|
 | 
						|
(setq test-line "2-4,6-8")
 | 
						|
(setq test-line "2-8,3-7")
 | 
						|
 | 
						|
(require 'cl-ppcre)
 | 
						|
;; (cl-ppcre:split "(\\ )" line :with-registers-p nil)
 | 
						|
(setq intervals (mapcar #'parse-integer (cl-ppcre:split "(,|-)" test-line)))
 | 
						|
 | 
						|
(defun line-to-nums (line)
 | 
						|
  (mapcar #'parse-integer (cl-ppcre:split "(,|-)" line)))
 | 
						|
 | 
						|
(defun first-includes-second (l1 r1 l2 r2)
 | 
						|
  (and (<= l1 l2) (>= r1 r2)))
 | 
						|
 | 
						|
(first-includes-second 2 8 3 7)
 | 
						|
(first-includes-second 3 8 3 7)
 | 
						|
(first-includes-second 4 8 3 7)
 | 
						|
 | 
						|
(defun first-or-last-includes-another (l1 r1 l2 r2)
 | 
						|
  (or (first-includes-second l1 r1 l2 r2)
 | 
						|
      (first-includes-second l2 r2 l1 r1)))
 | 
						|
 | 
						|
(with-open-file (in-file "day4-test-input.txt")
 | 
						|
  (let ((running-count 0))
 | 
						|
    (loop
 | 
						|
      for line = (read-line in-file nil nil)
 | 
						|
      while line
 | 
						|
      do (if (apply #'first-or-last-includes-another (line-to-nums line))
 | 
						|
             (incf running-count 1))
 | 
						|
      finally (return running-count))))
 | 
						|
 | 
						|
(defun count-full-interlaps (filename)
 | 
						|
  (with-open-file (in-file filename)
 | 
						|
  (let ((running-count 0))
 | 
						|
    (loop
 | 
						|
      for line = (read-line in-file nil nil)
 | 
						|
      while line
 | 
						|
      do (if (apply #'first-or-last-includes-another (line-to-nums line))
 | 
						|
             (incf running-count 1))
 | 
						|
      finally (return running-count)))))
 | 
						|
 | 
						|
(count-full-interlaps "day4-test-input.txt")
 | 
						|
(count-full-interlaps "day4-input.txt")
 | 
						|
 | 
						|
;; next part - count intervals that "overlap at all", even if by single point
 | 
						|
;; could count 'not overlapping' - should be very easy
 | 
						|
;; and count total, and deduct
 | 
						|
 | 
						|
(defun count-any-overlap (filename)
 | 
						|
  (with-open-file (in-file filename)
 | 
						|
  (let ((running-count-non-overlap 0)
 | 
						|
        (total-count 0))
 | 
						|
    (loop
 | 
						|
      for line = (read-line in-file nil nil)
 | 
						|
      while line
 | 
						|
      do (let ((nums (line-to-nums line)))
 | 
						|
           (if (or (< (second nums) (third nums))
 | 
						|
                   (< (fourth nums) (first nums)))
 | 
						|
               (incf running-count-non-overlap 1))
 | 
						|
           (incf total-count 1)
 | 
						|
           )
 | 
						|
      finally (return (- total-count running-count-non-overlap))))))
 | 
						|
 | 
						|
(count-any-overlap "day4-test-input.txt")
 | 
						|
(count-any-overlap "day4-input.txt")
 |