(defpackage #:rucksacks
  (:use :cl))

(in-package #:rucksacks)

(defvar *rucksacks* ())

(defun chars (s) (loop for c across s collect c))

(with-open-file (s "./list.txt")
  (setf *rucksacks*
	(loop for line = (read-line s nil)
	while line collect (chars line))))

(defmacro find-common-elems (first &rest others)
  `(loop for e in ,first when (and ,@(loop for o in others collect `(member e ,o))) collect e))

(defun char-to-priority (c)
  (let ((x (char-code c)))
    (cond ((and (>= x (char-code #\a)) (<= x (char-code #\z))) (+ 1 (- x (char-code #\a))))
	  ((and (>= x (char-code #\A)) (<= x (char-code #\Z))) (+ 27 (- x (char-code #\A))))
	  (t 0))))


;----------------------------------Part one------------------------------------
(defun split-bag (bag)
  (let ((half (floor (length bag) 2)))
    (let ((s1 (subseq bag 0 half)) (s2 (subseq bag half)))
      (list s1 s2))))
(defun get-duplicate-priority-by-bag (rucksacks)
(let ((duplicates (mapcar #'(lambda (x) (find-common-elems (car x) (car (cdr x)))) rucksacks)))
  (let ((tmp (loop for e in duplicates collect (mapcar #'char-to-priority e))))
    (reduce #'+ (loop for e in tmp collect (reduce #'+ (remove-duplicates e)))))))

(defun part-one ()
  (get-duplicate-priority-by-bag (mapcar #'split-bag *rucksacks*)))

;----------------------------------Part two------------------------------------
(defun get-groups (bags)
  (if bags
    (if (> (length bags) 3)
      (let ((group (subseq bags 0 3)) (others (subseq bags 3)))
	(cons group (get-groups others)))
      (list bags))
    nil))


(defun get-badge (group)
  (let ((b1 (car group)) (group (cdr group)))
    (let ((b2 (car group)) (group (cdr group)))
      (let ((b3 (car group))) 
	(remove-duplicates (find-common-elems b1 b2 b3))))))


(defun part-two ()
  (let ((groups (get-groups *rucksacks*)))
    (reduce #'+
	    (mapcar #'char-to-priority
		    (mapcar #'car ;Should only be a single item, so grab the first one we found
			    (mapcar #'get-badge groups))))))

(format t "Part One: ~d~%Part Two: ~d~%" (part-one) (part-two))