(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))