Skip to content

Latest commit

 

History

History
211 lines (203 loc) · 5.83 KB

2020.05.org

File metadata and controls

211 lines (203 loc) · 5.83 KB

Day 05

Executing this code

If you have a lisp installation, emacs, org-mode, and org-babel support for lisp installed you can run this by:

  1. Starting slime (M-x slime)
  2. Typing C-c C-c in the block initialize.
  3. In the repl type (in-package :aoc-2020-05)
  4. Typing C-c C-c in the block answers

Initial stuffs

Packages to load

(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"))

Create package for this day

<<packages>>
(defpackage :aoc-2020-05
  (:use :common-lisp
        :iterate
        :parseq
        :fiveam)
  (:export :problem-a
           :problem-b))
(in-package :aoc-2020-05)

Input

(defun read-input (file)
  (iter (for line in-file file using #'read-line)
        (collect line)))
(defparameter *input*
  (read-input "input/05.txt"))

Part 1

(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*)))

Part 2

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*)))

Putting it all together

<<read-input>>
<<input>>
<<initialize>>
<<structs>>
<<functions>>
<<input>>
<<problem-a>>
<<problem-b>>
(problem-a)
(problem-b)

Answer

Problem 05 A: 913
Problem 05 B: 717

Test Cases

(def-suite aoc.2020.05)
(in-suite aoc.2020.05)

(run! 'aoc.2020.05)

Test Results

Thoughts

Ada

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