;;;; 2015.02.01-first-attempt.lisp ;;;; Advent of Code 2015 ;;;; Day 2: I Was Told There Would Be No Math ;;;; Attempt 1: First attempt in Common Lisp ;; --------------------------------------------------------------------- ;;; Package Definition ;; --------------------------------------------------------------------- (ql:quickload :cl-ppcre) (ql:quickload :alexandria) (defpackage :2015-02-01-first-attempt (:use #:common-lisp #:cl-ppcre #:alexandria)) (in-package :2015-02-01-first-attempt) ;; --------------------------------------------------------------------- ;;; Definitions ;; --------------------------------------------------------------------- (defconstant +PUZZLE-INPUT-FILE+ "~/proj/Learn/aoc/src/2015.02._PUZZLE-INPUT.txt" "File to be used as input to the program.") (defconstant +PUZZLE-INPUT-STRING+ (uiop:read-file-string +PUZZLE-INPUT-FILE+) "Single-string version of the text in `+PUZZLE-INPUT-FILE+'.") (defconstant +PUZZLE-INPUT-STRING-LIST+ (loop for line in (ppcre:split #\Newline +PUZZLE-INPUT-STRING+) collect (ppcre:all-matches-as-strings "-?\\d+" line)) "List of sublists containing string versions of the dimensions of presents.") (defconstant +PUZZLE-INPUT-LIST+ (loop for sublist in +PUZZLE-INPUT-STRING-LIST+ collect (sort (mapcar #'parse-integer sublist) #'>)) "A list of presents and their numerical dimensions. Represented as a list of sublists, with each sublist containing the 3 dimensions of a particular present.") ;; --------------------------------------------------------------------- ;;; Part 1 ;; ------- ;; The elves are running low on wrapping paper, and so they need to ;; submit an order for more. They have a list of the dimensions ;; (length l, width w, and height h) of each present, and only want to ;; order exactly as much as they need. ;; ;; Fortunately, every present is a box (a perfect right rectangular ;; prism), which makes calculating the required wrapping paper for each ;; gift a little easier: find the surface area of the box, which is ;; 2*l*w + 2*w*h + 2*h*l. The elves also need a little extra paper for ;; each present: the area of the smallest side. ;; ;; For example: ;; ;; A present with dimensions 2x3x4 requires 2*6 + 2*12 + 2*8 = 52 ;; square feet of wrapping paper plus 6 square feet of slack, for a ;; total of 58 square feet. ;; ;; A present with dimensions 1x1x10 requires 2*1 + 2*10 + 2*10 = 42 ;; square feet of wrapping paper plus 1 square foot of slack, for a ;; total of 43 square feet. ;; ;; All numbers in the elves' list are in feet. How many total square ;; feet of wrapping paper should they order? ;; --------------------------------------------------------------------- (defun wrapping-paper-base (DIMENSIONS) "Calculate the base amount of wrapping paper needed for a present with `DIMENSIONS'. `DIMENSIONS' is assumed to be a list of 3 elements." (apply #'+ (list (* 2 (first DIMENSIONS) (second DIMENSIONS)) (* 2 (first DIMENSIONS) (third DIMENSIONS)) (* 2 (second DIMENSIONS) (third DIMENSIONS))))) (assert (= 52 (wrapping-paper-base '(4 3 2)))) (assert (= 42 (wrapping-paper-base '(10 1 1)))) (defun wrapping-paper-extra (DIMENSIONS) "Calculate the extra amount of wrapping paper needed for a present with `DIMENSIONS'. `DIMENSIONS' is assumed to be a list of 3 elements sorted highest to lowest." (apply #'* (cdr DIMENSIONS))) (defun wrapping-paper-area (DIMENSIONS) "Calculate the total amount of paper needed for a present with `DIMENSIONS'. `DIMENSIONS' is assumed to be a list of 3 elements." (+ (wrapping-paper-base DIMENSIONS) (wrapping-paper-extra DIMENSIONS))) (assert (= 58 (wrapping-paper-area '(4 3 2)))) (assert (= 43 (wrapping-paper-area '(10 1 1)))) (defun wrapping-paper-total (PRESENTS) "Calculate the total amount of wrapping paper needed for the entire list of `PRESENTS'. `PRESENTS' is assumed to be a list of sublists of 3 elements each." (apply #'+ (mapcar #'wrapping-paper-area PRESENTS))) ;; Test correct answer (assert (= 1586300 (wrapping-paper-total +PUZZLE-INPUT-LIST+))) ;; --------------------------------------------------------------------- ;;; Part 2 ;; ------- ;; The elves are also running low on ribbon. Ribbon is all the same ;; width, so they only have to worry about the length they need to ;; order, which they would again like to be exact. ;; ;; The ribbon required to wrap a present is the shortest distance around ;; its sides, or the smallest perimeter of any one face. Each present ;; also requires a bow made out of ribbon as well; the feet of ribbon ;; required for the perfect bow is equal to the cubic feet of volume of ;; the present. Don't ask how they tie the bow, though; they'll never ;; tell. ;; ;; For example: ;; ;; A present with dimensions 2x3x4 requires 2+2+3+3 = 10 feet of ;; ribbon to wrap the present plus 2*3*4 = 24 feet of ribbon for the ;; bow, for a total of 34 feet. ;; ;; A present with dimensions 1x1x10 requires 1+1+1+1 = 4 feet of ;; ribbon to wrap the present plus 1*1*10 = 10 feet of ribbon for ;; the bow, for a total of 14 feet. ;; ;; How many total feet of ribbon should they order? ;; ---------------------------------------------------------------------