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-25)
- 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-25
(:use :common-lisp
:iterate
:parseq
:fiveam)
(:export :problem-a
:problem-b))
(in-package :aoc-2020-25)
(defun read-input (file)
(iter (for line in-file file using #'read-line)
(collect (parse-integer line))))
(defparameter *input*
(read-input "input/25.txt"))
Breaking the cryptographic security of a hotel room door.
(defparameter *magic* 20201227)
(defun find-loop-size (n)
(loop for i from 0
with subject-number = 7
for value = 1 then (mod (* value subject-number) *magic*)
until (= value n)
finally (return i)))
(defun find-encryption-key (subject-number loop-size)
(loop repeat loop-size
for value = subject-number then (mod (* value subject-number) *magic*)
finally (return value)))
(defun problem-a () (format t "Problem 25 A: ~a~%" (find-encryption-key (first *input*) (find-loop-size (second *input*)))))
(defun problem-b () (format t "Problem 25 B: ~a~%" "free star!"))
<<read-input>>
<<input>>
<<initialize>>
<<structs>>
<<functions>>
<<input>>
<<problem-a>>
<<problem-b>>
(problem-a)
(problem-b)
Problem 25 A: 6408263 Problem 25 B: free star!
(def-suite aoc.2020.25)
(in-suite aoc.2020.25)
(test loop-size
(is (= 8 (find-loop-size 5764801)))
(is (= 11 (find-loop-size 17807724))))
(test encryption-key
(is (= 14897079 (find-encryption-key 17807724 8)))
(is (= 14897079 (find-encryption-key 5764801 11))))
(run! 'aoc.2020.25)
Running test suite AOC.2020.25 Running test LOOP-SIZE .. Running test ENCRYPTION-KEY .. Did 4 checks. Pass: 4 (100%) Skip: 0 ( 0%) Fail: 0 ( 0%)
Simple runner.
with AOC2020.Day25;
procedure Day25 is
begin
AOC2020.Day25.Run;
end Day25;
Specification for solution.
package AOC2020.Day25 is
procedure Run;
end AOC2020.Day25;
with GNAT.Regpat; use GNAT.Regpat;
with Text_IO; use Text_IO;
Actual implementation body.
<<ada-packages>>
package body AOC2020.Day25 is
<<types-and-generics>>
-- Used as an example of matching regular expressions
procedure Parse_Line (Line : Unbounded_String; P : out Password) is
Pattern : constant String := "(\d+)-(\d+) ([a-z]): ([a-z]+)";
Re : constant Pattern_Matcher := Compile(Pattern);
Matches : Match_Array (0..4);
Pass : Unbounded_String;
P0, P1 : Positive;
C : Character;
begin
Match(Re, To_String(Line), Matches);
P0 := Integer'Value(Slice(Line, Matches(1).First, Matches(1).Last));
P1 := Integer'Value(Slice(Line, Matches(2).First, Matches(2).Last));
C := Element(Line, Matches(3).First);
Pass := To_Unbounded_String(Slice(Line, Matches(4).First, Matches(4).Last));
P := (Min_Or_Pos => P0,
Max_Or_Pos => P1,
C => C,
P => Pass);
end Parse_Line;
procedure Run is
begin
Put_Line("Advent of Code 2020 - Day 25");
Put_Line("The result for Part 1 is " & Integer'Image(0));
Put_Line("The result for Part 2 is " & Integer'Image(0));
end Run;
end AOC2020.Day25;
In order to run this you have to “tangle” the code first using C-c
C-v C-t
.
cd ada
gnatmake day25
./day25