ea683b1ce8
Change-Id: Id149ff13d1e903a578cdcdc3a8d0045cfefaecfa Reviewed-on: https://cl.tvl.fyi/c/depot/+/2224 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
54 lines
1.5 KiB
EmacsLisp
54 lines
1.5 KiB
EmacsLisp
;; Advent of Code 2020 - Day 2
|
|
|
|
(require 'cl-lib)
|
|
(require 'f)
|
|
(require 'ht)
|
|
(require 's)
|
|
(require 'seq)
|
|
|
|
(defvar day2/input
|
|
;; This one was too large to inline.
|
|
(s-lines (f-read "/tmp/aoc/day2.txt")))
|
|
|
|
(defun day2/count-letters (password)
|
|
(let ((table (ht-create)))
|
|
(cl-loop for char across password
|
|
for current = (ht-get table char)
|
|
do (ht-set table char
|
|
(if current (+ 1 current) 1)))
|
|
table))
|
|
|
|
(defun day2/parse (input)
|
|
(let* ((split (s-split " " input))
|
|
(range (s-split "-" (car split))))
|
|
(list (string-to-number (car range))
|
|
(string-to-number (cadr range))
|
|
(string-to-char (cadr split))
|
|
(caddr split))))
|
|
|
|
(defun day2/count-with-validation (func)
|
|
(length (-filter
|
|
(lambda (password)
|
|
(and (not (seq-empty-p password))
|
|
(apply func (day2/parse password))))
|
|
day2/input)))
|
|
|
|
;; Puzzle 1
|
|
|
|
(defun day2/validate-oldjob (min max char password)
|
|
(let ((count (ht-get (day2/count-letters password) char)))
|
|
(when count
|
|
(and (>= count min)
|
|
(<= count max)))))
|
|
|
|
(message "Solution to day2/1: %s"
|
|
(day2/count-with-validation #'day2/validate-oldjob))
|
|
|
|
;; Puzzle 2
|
|
|
|
(defun day2/validate-toboggan (pos1 pos2 char password)
|
|
(xor (= char (aref password (- pos1 1)))
|
|
(= char (aref password (- pos2 1)))))
|
|
|
|
(message "Solution to day2/2: %s"
|
|
(day2/count-with-validation #'day2/validate-toboggan))
|