If you have a lisp installation, emacs, org-mode, and org-babel support for lisp installed you can run this by:
- Starting slime (
M-x slime
) - Typing
C-c C-c
in the block initialize. - In the repl type
(in-package :aoc-2020-05)
- Typing
C-c C-c
in the block answers
(unless (find-package :cl-ppcre)
(ql:quickload "cl-ppcre"))
(unless (find-package :iterate)
(ql:quickload "iterate"))
(unless (find-package :parseq)
(ql:quickload "parseq"))
(unless (find-package :fiveam)
(ql:quickload "fiveam"))
(unless (find-package :series)
(ql:quickload "series"))
(unless (find-package :cl-permutation)
(ql:quickload "cl-permutation"))
(unless (find-package :bordeaux-threads)
(ql:quickload "bordeaux-threads"))
<<packages>>
(defpackage :aoc-2020-05
(:use :common-lisp
:iterate
:parseq
:fiveam)
(:export :problem-a
:problem-b))
(in-package :aoc-2020-05)
(defun read-input (file)
(iter (for line in-file file using #'read-line)
(collect line)))
(defparameter *input*
(read-input "input/05.txt"))
(defun bsp-to-number (s &optional (zero #\F) (one #\B))
(parse-integer (substitute #\0 zero (substitute #\1 one s)) :radix 2))
(defun to-row-number (row)
(bsp-to-number row))
(defun to-seat-number (seat)
(bsp-to-number seat #\L #\R))
(defun to-number (seat)
(let ((row (subseq seat 0 7))
(seat (subseq seat 7)))
(+ (* 8 (to-row-number row)) (to-seat-number seat))))
(defun maximum-seat (passes)
(iter (for p in passes)
(maximizing (to-number p))))
(defun problem-a () (format t "Problem 05 A: ~a~%" (maximum-seat *input*)))
Now that we have a way to identify seats, find a gap of 3, the middle one is our seat.
(defun find-my-seat (passes)
(let ((seats (sort (iter (for p in passes) (collect (to-number p))) #'<)))
(iter (for i in seats)
(for j in (cdr seats))
(until (= 2 (- j i)))
(finally (return (1+ i))))))
(defun problem-b () (format t "Problem 05 B: ~a~%" (find-my-seat *input*)))
<<read-input>>
<<input>>
<<initialize>>
<<structs>>
<<functions>>
<<input>>
<<problem-a>>
<<problem-b>>
(problem-a)
(problem-b)
Problem 05 A: 913 Problem 05 B: 717
(def-suite aoc.2020.05)
(in-suite aoc.2020.05)
(run! 'aoc.2020.05)
Simple runner.
with AOC2020.Day05;
procedure Day05 is
begin
AOC2020.Day05.Run;
end Day05;
Specification for solution.
package AOC2020.Day05 is
procedure Run;
end AOC2020.Day05;
Actual implementation body.
with Text_IO; use Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_Io;
with Ada.Containers.Vectors;
package body AOC2020.Day05 is
package Integer_Vectors is new Ada.Containers.Vectors
(Element_Type => Integer, Index_Type => Natural);
package Integer_Vectors_Sorting is new Integer_Vectors.Generic_Sorting;
use Integer_Vectors; use Integer_Vectors_Sorting;
-- Used as an example of matching regular expressions
function BSP_To_Number (BSP : String) return Integer is
Result : Integer := 0;
begin
for C of BSP loop
case C is
when 'F' | 'L' =>
Result := Result * 2;
when 'B' | 'R' =>
Result := Result * 2 + 1;
when others =>
null;
end case;
end loop;
return Result;
end BSP_To_Number;
procedure Gather_Input(Passes : out Vector) is
Fin : File_Type;
Line : String(1..11);
Length : Natural;
begin
Open (Fin, In_File, "../input/05.txt");
loop
exit when End_Of_File(Fin);
Get_Line(Fin, Line, Length);
Passes.Append(BSP_To_Number(Line));
end loop;
Close(Fin);
null;
end Gather_Input;
procedure Run is
Passes : Vector;
Max : Integer := Integer'First;
My_Seat : Integer;
begin
Gather_Input(Passes);
Sort(Passes);
Max := Last_Element(Passes);
for C in Passes.Iterate loop
exit when Next(C) = No_Element;
if Passes(Next(C)) - Passes(C) = 2
then
My_Seat := Passes(C) + 1;
end if;
end loop;
Put_Line("Advent of Code 2020 - Day 05:"); New_Line;
Put_Line("The result for part 1 is: " & Max'Image);
Put_Line("The result for Part 2 is: " & My_Seat'Image);
end Run;
end AOC2020.Day05;
In order to run this you have to “tangle” the code first using C-c
C-v C-t
.
cd ada
gnatmake day05
./day05