(defpackage #:rucksacks
(:use :cl))
(in-package #:rucksacks)
(defvar *data* ())
(defun chars (s) (loop for c across s collect c))
(defun strtok (s delim) (loop
for start = 0 then (1+ split)
for split = (position delim s :start start)
when (and (null split) (not (= start (length s))))
collect (subseq s start)
while split
when (> split start) collect (subseq s start split)
))
(with-open-file (s "./list.txt")
(setf *data*
(loop for line = (read-line s nil)
while line collect (strtok line #\,))))
(setf *data* (mapcar #'(lambda (pair)
(loop for range in pair collect
(mapcar #'parse-integer (strtok range #\-))))
*data*))
(defun normalize (x y)
;Normalize to
; x1 x2 x1 x2 x1 x2 x1 x2
; v v v v v v v v
; |-------------| or |-------------| and |-------------| or |-------------|
; ^ ^ ^ ^ ^ ^ ^ ^
; y1 y2 y1 y2 y1 y2 y1 y2
;
; u1 u2 u1 u2
; v v v v
; into |-------------| and |-------------|
; ^ ^ ^ ^
; v1 v1 v2
(let ((x1 (first x)) (x2 (second x)) (y1 (first y)) (y2 (second y)))
(if (or (> y1 x1) (and (eql x1 y1) (< y2 x2)))
(list x y)
(list y x))))
(defun cover? (x y)
(let ((norm (normalize x y)))
(let ((u (first norm)) (v (second norm)))
(let ((u1 (first u)) (u2 (second u)) (v1 (first v)) (v2 (second v)))
(and (>= v1 u1) (<= v2 u2))))))
(defun overlap? (x y)
(let ((norm (normalize x y)))
(let ((u (first norm)) (v (second norm)))
(let ((u1 (first u)) (u2 (second u)) (v1 (first v)) (v2 (second v)))
(not (> v1 u2))))))
(defun part-one ()
(length (loop for pair in *data*
when (cover? (first pair) (second pair)) collect t)))
(defun part-two ()
(length (loop for pair in *data*
when (overlap? (first pair) (second pair)) collect t)))
(format t "Part One: ~d, Part Two: ~d~%" (part-one) (part-two))
;(print (part-two))