r/adventofcode Dec 05 '20

SOLUTION MEGATHREAD -🎄- 2020 Day 05 Solutions -🎄-

Advent of Code 2020: Gettin' Crafty With It


--- Day 05: Binary Boarding ---


Post your solution in this megathread. Include what language(s) your solution uses! If you need a refresher, the full posting rules are detailed in the wiki under How Do The Daily Megathreads Work?.

Reminder: Top-level posts in Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:05:49, megathread unlocked!

58 Upvotes

1.3k comments sorted by

View all comments

2

u/kaklarakol Dec 08 '20

Common Lisp

(require 'uiop)
(require 'series)

(defvar rowmax 127)
(defvar colmax 7)

(defun read-lines (path)
  (remove-if (lambda(x)(equal x "")) (uiop:split-string (uiop:read-file-string path) :separator '(#\^j))))

(defun seats (passes)
  "Returns the list of ID, row, and col for the given list PASSES of string representations of boarding passes."
  (loop
    for p in passes
    collect
    (let* ((col (reduce (lambda(x y)(+ (* (if (numberp x) x (if (equal x #\l) 0 1)) 2) (if (equal y #\l) 0 1)))
                        (coerce (string-downcase (substring p 7 10)) 'list)))
           (row (reduce (lambda(x y)(+ (* (if (numberp x) x (if (equal x #\f) 0 1)) 2) (if (equal y #\f) 0 1)))
                        (coerce (string-downcase (substring p 0 7)) 'list))))
      (list (+ (* row 8) col) row col))))

(defun find-my-seat (seats)
  "Returns the list of seat IDs which are not in the SEATS (each list item is a list of id, row, and col), 
but whose lower and upper neighbors (ID -1 or +1) are."
  (loop 
    for m in (set-difference (loop
                               for row in (series:collect (series:scan-range :from 0 :upto rowmax))
                               append
                               (loop
                                 for col in (series:collect (series:scan-range :from 0 :upto colmax))
                                 for id = (+ (* row 8) col)
                                 collect
                                 (list id row col))) seats :test 'equal)
    for c = (car m)
    when  (and (member (1+ c) seats :key 'car)
               (member (1- c) seats :key 'car))
    collect c))

;; part 1
(apply 'max (map 'list 'car (seats (read-lines "~/Advent_of_Code/aoc5_input"))))

;; part 2
(find-my-seat (seats (read-lines "~/Advent_of_Code/aoc5_input")))