[
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: https://www.paypal.com/donate/?item_name=Donation+to+the+author+of+HAC&cmd=_donations&business=esgm%40bluewin.ch\n"
  },
  {
    "path": ".gitignore",
    "content": "/obj/\n/bin/\n/hac\n/hac_mini\n/hac_multi"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2013 .. 2025 Gautier de Montmollin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "build.cmd",
    "content": "@echo off\n\ngprbuild %1 -P hac           -XHAC_OS=Win64\ngprbuild %1 -P demo/hac_demo -XHAC_OS=Win64\n\nif %errorlevel% == 9009 goto error\n\necho Press Return\npause\ngoto :eof\n\n:error\n\necho.\necho The GNAT Ada compiler was not found in the PATH!\necho.\necho Check https://www.adacore.com/download for GNAT\necho or https://alire.ada.dev/ for ALIRE.\necho The HAC project is available as an ALIRE crate.\necho.\necho Press Return\npause\n"
  },
  {
    "path": "debug.pra",
    "content": "pragma Initialize_Scalars;\r\n-- pragma Normalize_Scalars; -- For all units!\r\n\r\n"
  },
  {
    "path": "demo/data_exchange/exchange_common.ads",
    "content": "-------------------------------------------\n--  HAC  <->  Native data exchange demo  --\n-------------------------------------------\n--  Package used by both HAC and         --\n--  Native sides                         --\n-------------------------------------------\n\npackage Exchange_Common is\n\n  type Animal is (ant, bat, cat, dog);\n\n  subtype Beast is Animal;\n  subtype Insect is Animal range ant .. ant;\n  subtype Mammal is Animal range bat .. dog;\n\nend Exchange_Common;\n"
  },
  {
    "path": "demo/data_exchange/exchange_hac_side.adb",
    "content": "-----------------------------------------\r\n--  HAC <-> Native data exchange demo  --\r\n-----------------------------------------\r\n--  HAC side                           --\r\n-----------------------------------------\r\n\r\n--  This file is meant to be compiled by the HAC compiler which is\r\n--  embedded in Exchange_Native_Side (exchange_native_side.adb).\r\n\r\nwith HAT;\r\n\r\nwith Exchange_Common;\r\n\r\nprocedure Exchange_HAC_Side is\r\n\r\n  use HAT;\r\n\r\n  procedure Demo_Parameterless is\r\n    procedure Parameterless_Callback with Import => True;\r\n  begin\r\n    Put_Line (\"   HAC: I call a parameterless callback.\");\r\n    Parameterless_Callback;\r\n    Put_Line (\"   HAC: done calling.\");\r\n    New_Line;\r\n  end Demo_Parameterless;\r\n\r\n  procedure Demo_Data_to_Native is\r\n    procedure Hello_Callback (message : in VString) with Import => True;\r\n    procedure Ints_Callback (i, j, k : in Integer) with Import => True;\r\n    procedure Floats_Callback (f, g, h : in Real) with Import => True;\r\n  begin\r\n    Put_Line (\"   HAC: I send some stuff through callbacks.\");\r\n    Hello_Callback (+\"I'm HAC and I say hello!\");\r\n    Ints_Callback (123, 456, 789);\r\n    Floats_Callback (123.0, 456.0, 789.0);\r\n    New_Line;\r\n  end Demo_Data_to_Native;\r\n\r\n  procedure Demo_Data_Bidirectional is\r\n    procedure Hello_Callback_in_out (message : in out VString) with Import => True;\r\n    procedure Ints_Callback_in_out (i : in out Integer) with Import => True;\r\n    procedure Floats_Callback_in_out (f : in out Real) with Import => True;\r\n    m : VString := +\"I'm HAC\";\r\n    i : Integer := 12;\r\n    f : Real := 11.0;\r\n  begin\r\n    m := +\"I'm HAC\";\r\n    Put_Line (\"   HAC: message before call: [\" & m & ']');\r\n    Hello_Callback_in_out (m);\r\n    Put_Line (\"   HAC: message after call: [\" & m & ']');\r\n    Put_Line (+\"   HAC: integer before call: [\" & i & ']');\r\n    Ints_Callback_in_out (i);\r\n    Put_Line (+\"   HAC: integer after call: [\" & i & ']');\r\n    Put_Line (+\"   HAC: float before call: [\" & f & ']');\r\n    Floats_Callback_in_out (f);\r\n    Put_Line (+\"   HAC: float after call: [\" & f & ']');\r\n    New_Line;\r\n  end Demo_Data_Bidirectional;\r\n\r\n  procedure Demo_Composite is\r\n    type Matrix is array (1 .. 2, 1 .. 2) of HAT.Real;\r\n    type Some_Record is record\r\n      i : Integer;\r\n      v : VString;\r\n      e : Exchange_Common.Animal;\r\n    end record;\r\n    procedure Composite_Callback (a, b : in Matrix; r : in out Some_Record; c : out Matrix)\r\n    with Import => True;\r\n    m, n, o : Matrix;\r\n    s : Some_Record;\r\n  begin\r\n    --  HAC 0.2: no aggregates, we have to write the matrix' contents cell by cell.\r\n    m (1, 1) := 1.1;\r\n    m (1, 2) := 1.2;\r\n    m (2, 1) := 1.3;\r\n    m (2, 2) := 1.4;\r\n    n (1, 1) := -2.1;\r\n    n (1, 2) :=  2.2;\r\n    n (2, 1) := -2.3;\r\n    n (2, 2) :=  2.4;\r\n    s.i := 13;\r\n    s.v := +\"I'm a HAC record field\";\r\n    s.e := Exchange_Common.bat;\r\n    Put_Line (+\"   HAC: integer before call: [\" & s.i & ']');\r\n    Put_Line (+\"        message before call: [\" & s.v & ']');\r\n    Put_Line (+\"           enum before call: [\" & s.e'Image & ']');\r\n    Composite_Callback (m, n, s, o);\r\n    Put_Line (+\"   HAC: integer after call: [\" & s.i & ']');\r\n    Put_Line (+\"        message after call: [\" & s.v & ']');\r\n    Put_Line (+\"           enum after call: [\" & s.e'Image & ']');\r\n    Put_Line (+\"        matrix product:\");\r\n    for i in o'Range (1) loop\r\n      Put (\"          \");\r\n      for j in o'Range (2) loop\r\n        Put (o (i, j), 2, 2, 0);\r\n      end loop;\r\n      New_Line;\r\n    end loop;\r\n  end Demo_Composite;\r\nbegin\r\n  Put_Line (\"   Exchange_HAC_Side is started.\");\r\n  New_Line;\r\n  --\r\n  Demo_Parameterless;\r\n  Demo_Data_to_Native;\r\n  Demo_Data_Bidirectional;\r\n  Demo_Composite;\r\n  --\r\n  Set_VM_Variable (\"Demo_Variable\", Get_VM_Variable (\"Demo_Variable\") & \"HAC... \");\r\nend Exchange_HAC_Side;\r\n"
  },
  {
    "path": "demo/data_exchange/exchange_native_side.adb",
    "content": "-------------------------------------------\r\n--  HAC  <->  Native data exchange demo  --\r\n-------------------------------------------\r\n--  Native side                          --\r\n-------------------------------------------\r\n\r\n--  Native & master side of the demo.\r\n--  HAC is embedded in this application.\r\n--  Compile this program with a \"full Ada\" compiler like GNAT.\r\n\r\nwith Ada.Directories,\r\n     Ada.Text_IO;\r\n\r\nwith HAC_Sys.Builder,\r\n     HAC_Sys.PCode.Interpreter;\r\n\r\nwith Exchange_Native_Side_Pkg;\r\n\r\nprocedure Exchange_Native_Side is\r\n  use Ada.Text_IO;\r\n  use HAC_Sys.PCode.Interpreter;\r\n\r\n  BD : HAC_Sys.Builder.Build_Data;\r\n\r\n  procedure Build is\r\n    hac_program_name : constant String := \"exchange_hac_side.adb\";\r\n  begin\r\n    Put_Line (\"Native: building a HAC program: \" & hac_program_name);\r\n    New_Line;\r\n    BD.Build_Main_from_File (hac_program_name);\r\n  end Build;\r\n\r\n  procedure Run is\r\n    post_mortem : Post_Mortem_Data;\r\n  begin\r\n    Interpret_on_Current_IO (BD, 1, \"\", post_mortem);\r\n    if Is_Exception_Raised (post_mortem.Unhandled) then\r\n      Put_Line (Current_Error, \"HAC VM: raised \" & Image (post_mortem.Unhandled));\r\n      Put_Line (Current_Error, Message (post_mortem.Unhandled));\r\n    end if;\r\n  end Run;\r\n\r\nbegin\r\n  Put_Line (\"Exchange_Native_Side is started.\");\r\n  New_Line;\r\n  Exchange_Native_Side_Pkg.Register_All_Callbacks (BD);\r\n  Exchange_Native_Side_Pkg.Set_Global_VM_Variable (BD);\r\n  Ada.Directories.Set_Directory (\"data_exchange\");\r\n  Build;\r\n  if BD.Build_Successful then\r\n    for i in 1 .. 2 loop\r\n      Put_Line (\"Native: Run #\" & Integer'Image (i));\r\n      Run;\r\n      Put_Line\r\n        (\"Native: Run #\" & Integer'Image (i) &\r\n         \". Global string variable is: \" & Exchange_Native_Side_Pkg.Get_Global_VM_Variable (BD));\r\n      New_Line;\r\n    end loop;\r\n  end if;\r\nend Exchange_Native_Side;\r\n"
  },
  {
    "path": "demo/data_exchange/exchange_native_side_pkg.adb",
    "content": "-------------------------------------------\r\n--  HAC  <->  Native data exchange demo  --\r\n-------------------------------------------\r\n\r\n--  Callbacks on Native side.\r\n\r\nwith Exchange_Common;\r\n\r\nwith HAC_Sys.Interfacing;\r\n\r\nwith Ada.Numerics.Long_Real_Arrays,\r\n     Ada.Text_IO;\r\n\r\npackage body Exchange_Native_Side_Pkg is\r\n  use Ada.Text_IO;\r\n  use HAC_Sys.Interfacing;\r\n\r\n  procedure Parameterless_Callback (Dummy : in out HAC_Element_Array) is\r\n  begin\r\n    Put_Line (\"      Native: Parameterless_Callback is speaking!\");\r\n  end Parameterless_Callback;\r\n\r\n  procedure Hello_Callback (Data : in out HAC_Element_Array) is\r\n  begin\r\n    Put_Line (\"      Native: HAC is saying: [\" & To_Native (Data (1)) & ']');\r\n  end Hello_Callback;\r\n\r\n  procedure Ints_Callback (Data : in out HAC_Element_Array) is\r\n    i, j, k : Integer;\r\n  begin\r\n    i := To_Native (Data (1));\r\n    j := To_Native (Data (2));\r\n    k := To_Native (Data (3));\r\n    Put_Line\r\n      (\"      Native: HAC has sent me the numbers:\" &\r\n       Integer'Image (i) &\r\n       Integer'Image (j) &\r\n       Integer'Image (k));\r\n  end Ints_Callback;\r\n\r\n  procedure Floats_Callback (Data : in out HAC_Element_Array) is\r\n    f, g, h : Long_Float;\r\n  begin\r\n    f := To_Native (Data (1));\r\n    g := To_Native (Data (2));\r\n    h := To_Native (Data (3));\r\n    Put_Line\r\n      (\"      Native: HAC has sent me the numbers:\" &\r\n       Long_Float'Image (f) &\r\n       Long_Float'Image (g) &\r\n       Long_Float'Image (h));\r\n  end Floats_Callback;\r\n\r\n  procedure Hello_Callback_in_out (Data : in out HAC_Element_Array) is\r\n  begin\r\n    Put_Line (\"      Native: HAC is saying: [\" & To_Native (Data (1)) & ']');\r\n    Data (1) := To_HAC (\"No, I'm Native, you loser!\");\r\n  end Hello_Callback_in_out;\r\n\r\n  procedure Ints_Callback_in_out (Data : in out HAC_Element_Array) is\r\n    i : Integer;\r\n  begin\r\n    i := To_Native (Data (1));\r\n    Put_Line\r\n      (\"      Native: HAC has sent me the number:\" &\r\n       Integer'Image (i) & \"; I will send it back squared.\");\r\n    Data (1) := To_HAC (i ** 2);\r\n  end Ints_Callback_in_out;\r\n\r\n  procedure Floats_Callback_in_out (Data : in out HAC_Element_Array) is\r\n    f : Long_Float;\r\n  begin\r\n    f := To_Native (Data (1));\r\n    Put_Line\r\n      (\"      Native: HAC has sent me the number:\" &\r\n       Long_Float'Image (f) & \"; I will send it back squared.\");\r\n    Data (1) := To_HAC (f ** 2);\r\n  end Floats_Callback_in_out;\r\n\r\n  procedure Composite_Callback (Data : in out HAC_Element_Array) is\r\n    m_pos : constant :=  1;  --  Index for matrix 1\r\n    n_pos : constant :=  5;  --  Index for matrix 2\r\n    r_pos : constant :=  9;  --  Index for record 1\r\n    o_pos : constant := 12;  --  Index for matrix 3\r\n    use Ada.Numerics.Long_Real_Arrays;\r\n    package LFIO is new Ada.Text_IO.Float_IO (Long_Float); use LFIO;\r\n    procedure Show (m : Real_Matrix) is\r\n    begin\r\n      for i in m'Range (1) loop\r\n        Put (\"          \");\r\n        for j in m'Range (2) loop\r\n          Put (m (i, j), 2, 2, 0);\r\n        end loop;\r\n        New_Line;\r\n      end loop;\r\n    end Show;\r\n    --\r\n    m, n, o : Real_Matrix (1 .. 2, 1 .. 2);\r\n    e : Exchange_Common.Animal;\r\n    --\r\n    function To_HAC is new To_HAC_Any_Enum (Exchange_Common.Animal);\r\n    function To_Native is new To_Native_Any_Enum (Exchange_Common.Animal);\r\n  begin\r\n    e := To_Native (Data (r_pos + 2));\r\n    Put_Line (\"      Native: Enum = \" & Exchange_Common.Animal'Image (e));\r\n    m := ((To_Native (Data (m_pos)),     To_Native (Data (m_pos + 1))),\r\n          (To_Native (Data (m_pos + 2)), To_Native (Data (m_pos + 3))));\r\n    Put_Line (\"      Native: Matrix m:\");\r\n    Show (m);\r\n    n := ((To_Native (Data (n_pos)),     To_Native (Data (n_pos + 1))),\r\n          (To_Native (Data (n_pos + 2)), To_Native (Data (n_pos + 3))));\r\n    Put_Line (\"      Native: Matrix n:\");\r\n    Show (n);\r\n\r\n    o := m * n;\r\n    Put_Line (\"      Native: Matrix o = m * n:\");\r\n    Show (o);\r\n\r\n    Data (o_pos .. o_pos + 3) :=\r\n      (To_HAC (o (1, 1)), To_HAC (o (1, 2)),\r\n       To_HAC (o (2, 1)), To_HAC (o (2, 2)));\r\n\r\n    Data (r_pos)     := To_HAC (Integer'(To_Native (Data (r_pos))) ** 2);\r\n    Data (r_pos + 1) := To_HAC (\"I'm a Native message now (niarg niarg niarg)!\");\r\n    e := Exchange_Common.cat;\r\n    Data (r_pos + 2) := To_HAC (e);\r\n    Put_Line (\"      Native: Enum = \" & Exchange_Common.Animal'Image (e));\r\n  end Composite_Callback;\r\n\r\n  procedure Register_All_Callbacks (BD : HAC_Sys.Builder.Build_Data) is\r\n  begin\r\n    Register (BD, Parameterless_Callback'Access, \"Parameterless_Callback\");\r\n    Register (BD, Hello_Callback'Access,         \"Hello_Callback\");\r\n    Register (BD, Ints_Callback'Access,          \"Ints_Callback\");\r\n    Register (BD, Floats_Callback'Access,        \"Floats_Callback\");\r\n    Register (BD, Hello_Callback_in_out'Access,  \"Hello_Callback_in_out\");\r\n    Register (BD, Ints_Callback_in_out'Access,   \"Ints_Callback_in_out\");\r\n    Register (BD, Floats_Callback_in_out'Access, \"Floats_Callback_in_out\");\r\n    Register (BD, Composite_Callback'Access,     \"Composite_Callback\");\r\n  end Register_All_Callbacks;\r\n\r\n  procedure Set_Global_VM_Variable (BD : in out HAC_Sys.Builder.Build_Data) is\r\n  begin\r\n    Set_VM_Variable (BD, \"Demo_Variable\", \"Native... \");\r\n  end Set_Global_VM_Variable;\r\n\r\n  function Get_Global_VM_Variable (BD : HAC_Sys.Builder.Build_Data) return String is\r\n  begin\r\n    return Get_VM_Variable (BD, \"Demo_Variable\");\r\n  end Get_Global_VM_Variable;\r\n\r\nend Exchange_Native_Side_Pkg;\r\n"
  },
  {
    "path": "demo/data_exchange/exchange_native_side_pkg.ads",
    "content": "-------------------------------------------\r\n--  HAC  <->  Native data exchange demo  --\r\n-------------------------------------------\r\n\r\n--  Registration of callbacks on Native side.\r\n\r\nwith HAC_Sys.Builder;\r\n\r\npackage Exchange_Native_Side_Pkg is\r\n\r\n  procedure Register_All_Callbacks (BD : HAC_Sys.Builder.Build_Data);\r\n\r\n  procedure Set_Global_VM_Variable (BD : in out HAC_Sys.Builder.Build_Data);\r\n\r\n  function Get_Global_VM_Variable (BD : HAC_Sys.Builder.Build_Data) return String;\r\n\r\nend Exchange_Native_Side_Pkg;\r\n"
  },
  {
    "path": "demo/data_exchange_simple/exchange_hac_side_simple.adb",
    "content": "-----------------------------------------\r\n--  HAC <-> Native data exchange demo  --\r\n-----------------------------------------\r\n--  HAC side (simple version)          --\r\n-----------------------------------------\r\n\r\n--  This file is meant to be compiled by the HAC compiler which is\r\n--  embedded in Exchange_Native_Side_Simple (exchange_native_side_simple.adb).\r\n\r\nwith HAT;\r\n\r\nprocedure Exchange_HAC_Side_Simple is\r\n\r\n  use HAT;\r\n\r\n  procedure In_Out_Callback (i : in out Integer) with Import => True;\r\n\r\n  x : Integer := 1234;\r\n\r\nbegin\r\n\r\n  HAT.Put_Line (\"   [HAC]: before callback, variable x has value:\" & x'Image);\r\n\r\n  In_Out_Callback (x);\r\n\r\n  HAT.Put_Line (\"   [HAC]: after callback, variable x has value:\" & x'Image);\r\n\r\nend Exchange_HAC_Side_Simple;\r\n"
  },
  {
    "path": "demo/data_exchange_simple/exchange_native_side_pkg_simple.adb",
    "content": "-------------------------------------------\r\n--  HAC  <->  Native data exchange demo  --\r\n-------------------------------------------\r\n\r\n--  Callbacks on Native side.\r\n\r\nwith HAC_Sys.Interfacing;\r\n\r\nwith Ada.Text_IO;\r\n\r\npackage body Exchange_Native_Side_Pkg_Simple is\r\n  use HAC_Sys.Interfacing;\r\n\r\n  procedure In_Out_Callback (Data : in out HAC_Element_Array) is\r\n    my_val : constant := 9876;\r\n  begin\r\n\r\n    Ada.Text_IO.Put_Line\r\n      (\"      [Native] (callback): HAC has given the following value:\" &\r\n       Integer'Image (To_Native (Data (1))));\r\n\r\n    Data (1) := To_HAC (my_val);\r\n\r\n    Ada.Text_IO.Put_Line\r\n      (\"      [Native] (callback): I just changed the value to...\" & my_val'Image);\r\n\r\n  end In_Out_Callback;\r\n\r\n  procedure Register_All_Callbacks (BD : HAC_Sys.Builder.Build_Data) is\r\n  begin\r\n    Register (BD, In_Out_Callback'Access, \"In_Out_Callback\");\r\n  end Register_All_Callbacks;\r\n\r\nend Exchange_Native_Side_Pkg_Simple;\r\n"
  },
  {
    "path": "demo/data_exchange_simple/exchange_native_side_pkg_simple.ads",
    "content": "------------------------------------------------------------\r\n--  HAC  <->  Native data exchange demo (simple version)  --\r\n------------------------------------------------------------\r\n\r\n--  Registration of callbacks on Native side.\r\n\r\nwith HAC_Sys.Builder;\r\n\r\npackage Exchange_Native_Side_Pkg_Simple is\r\n\r\n  procedure Register_All_Callbacks (BD : HAC_Sys.Builder.Build_Data);\r\n\r\nend Exchange_Native_Side_Pkg_Simple;\r\n"
  },
  {
    "path": "demo/data_exchange_simple/exchange_native_side_simple.adb",
    "content": "-------------------------------------------\r\n--  HAC  <->  Native data exchange demo  --\r\n-------------------------------------------\r\n--  Native side                          --\r\n-------------------------------------------\r\n\r\n--  Native & master side of the demo.\r\n--  HAC is embedded in this application.\r\n--  Compile this program with a \"full Ada\" compiler like GNAT.\r\n\r\nwith Ada.Directories,\r\n     Ada.Text_IO;\r\n\r\nwith HAC_Sys.Builder,\r\n     HAC_Sys.PCode.Interpreter;\r\n\r\nwith Exchange_Native_Side_Pkg_Simple;\r\n\r\nprocedure Exchange_Native_Side_Simple is\r\n  use Ada.Text_IO;\r\n  use HAC_Sys.PCode.Interpreter;\r\n  use Exchange_Native_Side_Pkg_Simple;\r\n\r\n  BD : HAC_Sys.Builder.Build_Data;\r\n\r\n  procedure Run_with_HAC is\r\n    post_mortem : Post_Mortem_Data;\r\n  begin\r\n\r\n    Interpret_on_Current_IO (BD, 1, \"\", post_mortem);\r\n\r\n    if Is_Exception_Raised (post_mortem.Unhandled) then\r\n      Put_Line (Current_Error, \"HAC VM: raised \" & Image (post_mortem.Unhandled));\r\n      Put_Line (Current_Error, Message (post_mortem.Unhandled));\r\n    end if;\r\n\r\n  end Run_with_HAC;\r\n\r\nbegin\r\n\r\n  Register_All_Callbacks (BD);\r\n  Ada.Directories.Set_Directory (\"data_exchange_simple\");\r\n\r\n  for i in Positive loop\r\n    New_Line (3);\r\n    Put_Line\r\n      (\"[Native]: Run #\" & i'Image &\r\n       \"   --------------------------------------------------------\");\r\n\r\n    BD.Build_Main_from_File (\"exchange_hac_side_simple.adb\");\r\n\r\n    if BD.Build_Successful then\r\n      Run_with_HAC;\r\n    end if;\r\n\r\n    Put_Line (\"[Native]: Delay\");\r\n    delay 3.0;\r\n\r\n  end loop;\r\n\r\nend Exchange_Native_Side_Simple;\r\n"
  },
  {
    "path": "demo/hac_demo.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the demos of the HAC project ( https://sf.net/projects/hacadacompiler/ ).\n--\n--  Build me with \"gprbuild -P hac_demo\", or open me with GNAT Studio.\n--  \n\nproject HAC_Demo is\n\n   type HAC_Build_Mode_Type is (\"Debug\", \"Fast\", \"Small\");\n\n   HAC_Build_Mode : HAC_Build_Mode_Type := external (\"HAC_Build_Mode\", \"Debug\");\n\n   for Main use \n     (\"exchange_native_side_simple.adb\",  --  Data exchange demo between HAC and \"full Ada\" - \"full Ada\" (native) side, simple version\n      \"exchange_native_side.adb\");        --  Data exchange demo between HAC and \"full Ada\" - \"full Ada\" (native) side\n      \n   case HAC_Build_Mode is\n      when \"Debug\" => for Object_Dir use \"../obj/debug\";\n      when \"Fast\"  => for Object_Dir use \"../obj/fast\";\n      when \"Small\" => for Object_Dir use \"../obj/small\";\n   end case;\n\n   for Source_Dirs use\n     (\"../src\", \"../src/compile\", \"../src/compile/emit\", \"../src/execute\", \"../src/manage\",\n      \".\", \"./data_exchange\", \"./data_exchange_simple\");\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";  --  Flips by default the \"-p\" switch\n\n   package Pretty_Printer is\n      for Default_Switches (\"ada\") use (\"-i2\");\n   end Pretty_Printer;\n\n   Common_Compiler_Options := (\n     \"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n     \"-gnatwcijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n     \"-gnatwCKMUV\",                    --  Warnings switches (turn off some irrelevant for the tests)\n     \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n     \"-gnatf\",  --  Full errors. Verbose details, all undefined references\n     \"-gnatq\",  --  Don't quit, try semantics, even if parse errors\n     \"-gnatQ\",  --  Don't quit, write ali/tree file even if compile errors\n     --\n     \"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n     \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n     \"-gnatyx\",       --  Style: check x:no extra parens\n     --  \"-gnatye\",       --  Style: check e:end/exit labels present\n     \"-gnatytc\"       --  Style: check t:token separation rules, c:comment format (two spaces)\n   );\n\n   Debug_Options := (\n     \"-gnata\",         --  Assertions enabled\n     \"-gnato\",         --  Enable overflow checking in STRICT mode\n     \"-gnatVa\",        --  Enable all validity checking options\n     \"-fstack-check\",\n     \"-fno-inline\",\n     --\n     \"-g\"              --  Generate debugging information\n   );\n\n   Fast_Options :=\n     (\"-O2\",\n      \"-gnatn\", \n      \"-fipa-cp-clone\",\n      \"-fgcse-after-reload\", \n      \"-funroll-loops\",\n      \"-fpeel-loops\", \n      \"-funswitch-loops\", \n      \"-ftracer\", \"-fweb\",\n      \"-ftree-vectorize\",\n      \"-frename-registers\",\n      \"-ffunction-sections\",\n      \"-g\");\n   \n   package Compiler is\n      case HAC_Build_Mode is\n         when \"Debug\" =>\n           for Default_Switches (\"ada\") use Common_Compiler_Options & Debug_Options;\n           for Local_Configuration_Pragmas use project'Project_Dir & \"../debug.pra\";\n         when \"Fast\"  => for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Options;\n         when \"Small\" => for Default_Switches (\"ada\") use Common_Compiler_Options & \"-Os\";\n      end case;\n   end Compiler;\n\n   Common_Binder_Options := ();\n\n   package Binder is\n      case HAC_Build_Mode is\n         when \"Small\" => for Default_Switches (\"ada\") use Common_Binder_Options;\n         --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n         when others  => for Default_Switches (\"ada\") use Common_Binder_Options & (\"-Es\");\n      end case;\n   end Binder;\n\n   Common_Linker_Options := ();\n\n   package Linker is\n      case HAC_Build_Mode is\n         when \"Debug\" => for Default_Switches (\"ada\") use Common_Linker_Options & (\"-g\");\n         when \"Fast\"  => for Default_Switches (\"ada\") use Common_Linker_Options & (\"-g\", \"-Wl,--gc-sections\");\n         when \"Small\" => for Default_Switches (\"ada\") use Common_Linker_Options & (      \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-g\", \"-j0\");\n   end Builder;\n\nend HAC_Demo;\n"
  },
  {
    "path": "doc/archeology/smallada_doc.txt",
    "content": "S M A L L A d a   1 9 9 1\nIBM PC-family version\n\nDepartment of Electrical Engineering and Computer Science\nThe George Washington University\nWashington, DC 20052 USA\n\nThis is a compiler/interpreter for a part of the Ada language, namely\nthe \"Pascal subset\" plus the Ada tasking support. It is not intended\never to be a full Ada compiler, rather a vehicle for teaching, learning,\nand experimenting with concurrent programming. The compiler is quite\nfast, producing P-code which is then interpreted by the interpreter.\n\nThe system will run on an IBM PC (or compatible) with the following\nminimum configuration: 640K of memory; one disk drive. A hard disk will\ngreatly improve the speed. The entire system runs in RAM with no disk\naccesses, so expect capacity to be limited. 250 statements or so can\nbe safely accommodated.\n\nSmallAda executables and demo programs are distributed as a self-\nextracting archive created by LHA. To install SmallAda, just create a \ndirectory on your hard disk called, say, smallada, move to that\ndirectory, and execute the self-extracting archive sm-archv directly\nfrom your diskette. If your diskette is in drive A:, just type\nA:\\SM-ARCHV.\n\nThe current version is not particularly robust, rather it is a preliminary\nstep toward effective window-oriented monitoring of task execution.\n\nThis package may be copied and used for educational purposes but not for\nprofit; please let us know by e-mail or regular mail how you like the idea \nof this package and what you are doing with it. The more users we know\nwe have, the better our case for getting funding to continue the work.\n\nproject supervised by\nProf. Michael B. Feldman\nDepartment of Electrical Engineering and Computer Science\nThe George Washington University\nWashington, DC 20052\n202-994-5253 (voice)\n202-994-5294 (fax)\nmfeldman@seas.gwu.edu\n\nauthors:\n1986 Charles Schoening             DOS version of CoPascal\n1987 Frederick C. Hathorn          conversion of CoPascal to Ada\n1988 Stuart Cramer and Jay Kurtz   refinement of tasking model\n1989 Arthur V. Lopes               window-oriented monitoring for IBM-PC\n1990 Manuel A. Perez               Macintosh version\n1990 Arthur V. Lopes               integrated environment for IBM-PC\n1991 Amr El-Kadi                   user-selectable task scheduling\n\nHOW TO RUN THE PC PROGRAM\n=========================\n\nTo run SMALLAda PC you will need the following files:\n\nSMALLADA.EXE    -- Small Ada integrated environment\nSMADA-IN.AVL    -- Small Ada interpreter pseudo code; it can be tunned\n                -- to suit any level of interpreter monitoring\n\nType SMALLADA RACE <enter>. You will be placed in the editor mode. To compile\nand run the race program follow these steps: press F10. A menu will appear\non the top of your screen. Press C, for compiler. Then a sub menu will be\ndisplayed. Press E (or <enter>. This will start the compilation process.\nIf the program is correctly compiled then it will run thereafter. If an\nerror is found an error message will be issued and after pressing any key\nthe editor will be activated. The cursor will be at the line where the\nerror was found.\n\nThe program will run much faster if you disable the window-oriented\nexecution monitoring by pressing <INS>, which toggles monitoring on and\noff. If monitoring is enabled, pressing <DEL> toggles step-by-step\nexecution on and off. With stepped execution on, pressing the space\nbar moves through each source line.\n\nYou can create and compile your own Ada programs, but we make no promises\nabout which parts of the language will be handled correctly. We assure you\nthat there is no support for packages, generics, exceptions, access types\nand dynamic data structures. Some of this may change in future versions,\nbut we make no commitment to support full Ada. And don't be surprised if\nthe compiler hangs here and there: error repair is in a rather primitive state.\nIf the compiler actually finds your errors, it will display the messsages in\na window.\n\n\nTHE SmallAda IBM-PC RUNTIME ENVIRONMENT\n=======================================\n\nThe runtime monitoring of tasking is really the whole point of this\nproject.\n\nEach task is given a window. If there are more than five tasks some tasks\nwill share a physical window.\n\nTo obtain help on the runtime environment press F1 while a program is running.\nIn summary, you can control the overall execution speed of the interpreter\n(to \"slow down the action\"), and exert some influence on the open windows.\nThere is no magic in all this runtime monitoring: it all takes machine cycles.\nIf you wish your program to run faster, remove all the monitoring windows\n(by pressing INS while they are open). You can also step through execution,\nsource line by source line, by pressing INS while windows are open. Then\npressing the space bar steps through one source line.\n\n\nTHE SmallAda EDITOR\n===================\n\nThe editor was adapted from the Turbo Pascal Editor Toobox Version 4.0.\nThe editor works much like the Wordstar editor. Next some of its basic\noptions are shown.\n\n\nFunction                        Keystrokes\n\nBASIC MOVEVMENT COMMANDS:\n\nCharacter left:                 left arrow or ^S (^ ==> Control)\nCharacter right                 right arrow or ^D\nWord left                       ^left arrow or ^A\nWord right                      ^right arrow or ^F\nLine up                         up arrow or ^E\nLine down                       down arrow or ^X\nScroll up                       ^W\nScroll down                     ^Z\nPage up                         PgUp or ^R\nPage down                       PGDn or ^C\nBeginning of Line               Home or ^Q S\nEnd of Line                     End or ^Q D\nTab                             Tab or ^I\nBackward tab                    Shift tab\n\nBASIC EDITING COMMANDS:\n\nNew line                        Enter or ^M\nInsert line                     ^N\nDelete current character        Del or ^G\nDelete character left           Backspace or ^H\nDelete word                     ^T\nDelete to end of line           ^Q Y\nActivate menus                  F10\nAbort command                   ^U\n\n\n\nTHE SmallAda TASKING MODEL\n===========================\n\nWe have tried to be reasonably faithful to Ada tasking. The scheduler is\ndesigned to show some of the important issues of concurrent programming,\ntherefore time-slicing is implemented, and the length of the slice is\nrandomly determined. Also, at each rescheduling point the next task to\nbe scheduled is selected randomly. This is to give a reasonable model of\nnondeterministic (unpredictable) behavior, and serves to highlight the\nneed for mutual exclusion. The dining philosophers examples on the\ndisk, taken together, show this point rather well.\n\nCurrent incompletenesses in the tasking model: only named tasks (i.e. no\ntask types), no dynamically created tasks. We also don't support nested\ntask declarations; all tasks must be declared in MAIN's declarative section.\n\nThe \"select\" statement is functional including the \"terminate\" alternative;\nchecking for termination is tricky in Ada and you might find that some\nselect structures with terminate alternatives deadlock or don't work at all.\nIn general, be gentle with the select statement; try to avoid tricky or\npathological code, which will surely choke the compiler or interpreter!\n\nYou will also discover quickly that though the \"delay\" statement is functional,\nthe elapsed time to expiration of the delay is considerably more than was\nrequested in the delay statement. As it happens, this is correct Ada, as the\nstandard says only that a task will be suspended for _at least_ the amount\nof time requested. This is to take account of the likelihood that contention\nwill make it impossible for a task to take immediate control when it wakes\nup from a nap. Indeed, we think that the sometimes too-long delays\nmay be due to the interference in the interpreter caused by all the references\nto the user interface for monitoring purposes. The relationship of the delay to \nreality depends upon your PC's speed as well. We are working on this problem\nbut do not yet see an obvious solution. So take the time given in a delay\nstatement with a grain of salt, please.\n\nIf you have tasks in finite (counting) loops, if they complete but there are \nother tasks with infinite loops that can never terminate, the system may \ndetect no activity and report a deadlock state. \n\nThe current version now supports user-selected task scheduling. Pressing\n<alt-F10> during execution opens a window giving scheduler options.\n\n\nTHE SmallAda SUPPORT PACKAGE (SMALL_SP.PKG)\n===========================================\n\nA large number of \"intrinsic\" library subroutines are included in a\npseudo-package called SMALL_SP.PKG. It is not necessary (or proper) to\ncompile this package; it is included in the environment. It is necessary\nto begin each program with a context clause\n\nWITH SMALL_SP; USE SMALL_SP;\n\nto give the effect of writing genuine Ada. A specification for this\npackage is included in the distribution; it includes I/O routines,\nmath functions, and the like. This is not really good Ada-like decomposition,\nand we will change it in subsequent versions of the system. Meanwhile, use\nthe package spec as a guide to all the intrinsic routines. Note especially\nthat the formatting parameters supplied to the I/O procedures are more\nPascal-like than Ada-like. This will change later to look more like\nstandard TEXT_IO.\n\n\nTHE DEMONSTRATION PROGRAMS\n==========================\n\nWe have supplied a set of what we hope will be interesting and instructive\nprograms illustrating both the sequential aspects of the Ada subset and\nthe tasking model.\n\nTEST1 through TEST6 can be thought of as \"validation\" programs testing \nspecific features of the language; reading them can serve a useful purpose \nin understanding our subset.\n\nATEST1 through ATEST4 demonstrate the differences in program behavior\nunder different scheduling policies. Each program contains a block\ncomment explaining its purpose in this demonstration.\n\nSHELLSORT is what its name implies: a standard implementation of Shell sort\nin which the state of the array is displayed on the screen as it is sorted;\nRACE is a tasking program which we have used with success in concurrent\nprogramming courses: three sort algorithms are activated as Ada tasks\nand run in parallel.\n\n4TASKSEM shows the use of the semaphore primitives \"exported\" by the SMALL_SP\npseudo-package. A semaphore SCREEN is declared and used to give mutual\nexclusion on the terminal screen.\n \nAttention: semaphores are NOT Ada primitives! SmallAda was originally \nconstructed as a modification to the CoPascal system of Ben-Ari\n(as described in \"Principles of Concurrent Programming\", Prentice Hall 1982),\nand the semaphore primitives are still there from the system's last\nincarnation. To show how to do it in \"real\" Ada, we include the program\n4TASKMON, in which a screen monitor task is declared.\n\nFinally, there are three versions of Dijkstra's legendary dining philosophers\nproblem. SmallAda has a capacity limitation of around ten tasks. We are\nlimited to four instead of the usual five philosophers, because four diners,\nfour chopsticks, and MAIN add up to 9 tasks. EATCHAOS is very instructive:\nit demonstrates why it's nice to have monitors for mutual exclusion: without\na monitor guarding the screen, the display becomes rather chaotic. EAT-SEM\nuses the SmallAda semaphore primitives; EAT-MON does the same thing but\nwith a \"genuine\" Ada monitor.\n\nFINALLY\n=======\n \nIn case you are curious, the system is coded in Turbo Pascal with the\nTurbo Toolbox libraries used for the editor and environment. \n\nPlease let us know about bugs; tell us what you're doing with\nthe sytem. Good luck; have fun!\n\n\nGood luck; have fun!\n\n\n\n\n\n\n\n"
  },
  {
    "path": "doc/hac.txt",
    "content": "HAC - HAC Ada Compiler\n======================\n\n  HAC is perhaps the first open-source (albeit very partial) Ada\n  compiler (and virtual machine interpreter) fully programmed in Ada itself.\n  Note: HAC was not written from scratch, but is based on a renovation of\n  SmallAda, a system developped around 1990 and abandoned since then.\n\nObjectives\n==========\n\n    - Fun!\n    - Have a simple, quick Ada compiler and execution tool.\n    - Be useful for small Ada sandboxed prototypes.\n    - Produce the smallest Hello-world executable!\n    - Have a tool for script-like jobs (avoid long\n        programming-compiling-binding-linking-running cycles).\n    - Stay Ada-compatible (HAC programs can be compiled\n        and run by other Ada compilers, through\n        the compatibility package HAT).\n\n  HAC will most probably never be a complete compiler.\n\nWarning & legal\n===============\n\n  There is NO WARRANTY in this software.\n  Read copyright notice and license in hac_sys.ads .\n  The license is the open-source license MIT.\n\nGetting started\n===============\n\n  Assuming you have the GNAT (*) compiler installed, do the\n  following from a command line interpreter (please replace\n  '\\' by '/' on Unix-like platforms):\n\n      gnatmake -P hac\n      cd exm\n      ..\\hac gallery.adb\n\n  If `gnatmake` doesn't work, try `gprbuild`.\n  Alternatively, on Windows and with mouse only, you can go\n  into the \"exm\" folder and double-click \"e.cmd\" .\n\n  The program \"gallery.adb\" will run a bunch of demos that\n  are located in the \"exm\" directory.\n  You can test HAC on any other example of course (the \"*.adb\"\n  files in the \"exm\" and \"test\" directories).\n  As a bonus, you can build some examples with GNAT to compare the output.\n  You can do it easily with the hac_exm.gpr project file.\n  Since hac_exm.gpr is a text file, you can see there the progress\n  (or the lack thereof) in the pieces of Ada code that are really\n  working with HAC. See the \"Limitations\" section below as well.\n  ___\n  (*) On Debian-based Linuxes like Ubuntu, GNAT is part of the standard\n  packages. For other systems, you can get GNAT from AdaCore's Web site:\n  https://www.adacore.com/community or from other sites providing GCC\n  (the GNU Compiler Collection) with Ada support.\n  Check http://www.getadanow.com/ for instance.\n\nDirectories\n===========\n\n   src        sources of HAC, plus the compatibility package HAT\n   doc        documentation\n   exm        examples\n   exm/aoc    Advent of Code solutions - also used for regression testing\n   exm/pdf    demos of Acrobat (tm) PDF documents produced by HAC\n   demo       demos of applications embedding HAC\n   test       testing (notably, the all_silent_tests.adb regression test suite)\n\nKey files in the main directory\n===============================\n\n   hac.gpr             project file for building HAC with GNAT\n   hac_objectada.prj   equivalent project file with ObjectAda64 for Windows\n   save.hac            backup program\n   save_modif.hac      backup program\n\nDocumentation\n=============\n\n   hac.txt                             this file\n   HAC Ada Compiler User Manual.pdf    an 80+ pages user manual; source here:\n                                         https://github.com/sowebio/hac-doc\n   hac_work.xls                        Excel workbook containing, notably,\n                                         a bug list and a \"to-do\" list and\n                                         a \"done\" (history) list\n\nSome design points\n==================\n\n  - HAC is a single-pass, recursive-descent Ada compiler which, in its\n      simplest form, emits machine code on the fly. It means that there\n      are no advanced optimizations available, such as common subexpression\n      elimination, that are provided by compilers like GNAT; but, the\n      compilation is very fast, which is very pleasant for some usages\n      like prototyping and programming-for-fun.\n\n  - Current targets are:\n      - p-code (a virtual machine specially adapted for HAC)\n      - \"Semantics\", a pseudo-target that is used for smart editors\n          (for example, LEA).\n      - AMD x64/Windows (currently, only an embryo that can do\n          \"Hello World\" only)\n\n  - HAC reads Ada sources from any stream. In addition to files, it is able\n      to read from a Zip archive (plan is to have sets with many sources\n      like libraries in Zip files, for instance), from an internet stream,\n      from an editor buffer (see the LEA project), from a source stored in\n      memory, etc.\n\n  - HAC Ada source file naming follows the GNAT convention: \"parent-child.ads\"\n      for specification and \"parent-child.adb\" for body. An exception for\n      HAC is the main program, where the extension can be anything. We\n      recommend using \".hac\" for programs that are meant to be principally\n      executed through HAC. That way you can associate the \".hac\" extension\n      with the \"hac[.exe]\" executable on your operating system or your\n      file explorer.\n\n  - One goal is to complement or challenge GNAT, for instance in terms of\n      compilation speed, or object code compactness, or useability on\n      certain targets or for certain purposes (like scripting jobs).\n\n  - HAC could theoretically be also used for tuning run-time performance;\n      this would require a completion of the code emission for other targets\n      than p-code (HAC's virtual machine), including, perhaps, an intermediary\n      target that builds a syntax tree.\n\nTo-do list\n==========\n\n  The to-do list is located in the spreadsheet \"To do\", within the\n  workbook \"doc/hac_work.xls\".\n\nLanguage subset\n===============\n\n  HAC supports a small subset of the Ada language. On the other hand,\n  Ada is very large, so even a small subset could already fit your needs.\n  There is a growing list of programs that are working (in the meaning:\n  the compilation succeeds and the execution gives a correct output).\n  They are located in the \"exm\" directory and subdirectories (except\n  the \"not_working\" one), as well as in the \"test\" subdirectory.\n\n  The available Ada language subset supported by HAC is so far, roughly,\n  the \"Pascal subset\", plus tasking, plus packages, less pointers.\n  From a different perspective, HAC supports Ada 83, less pointers,\n  less generics, less unconstrained types, plus a few items from\n  later Ada versions: 95, 2005, 2012 and 2022.\n  Since each Ada version is compatible with previous ones,\n  one can say simply that HAC is a subset of Ada 2022.\n  \n    - Recursion and nested subprograms are supported.\n    - You can define your own data types: enumerations, records, arrays\n        (and every combination of records and arrays).\n    - Only constrained types are supported (unconstrained types are\n        Ada-only types and not in the \"Pascal subset\" anyway).\n    - The \"String\" type (unconstrained) is implemented in a very limited\n        way. So far you can only define fixed-sized constants,\n        variables, types, record fields with it, like:\n          Digitz : constant String (1..10) := \"0123456789\";\n        ... output them with Put, Put_Line, do comparisons and\n        concatenations with expressions of the VString variable-length\n        string type.\n        For general string manipulation, the most practical way with\n        the current versions of HAC is to use the VString's.\n    - There are no pointers (access types) and nor heap allocation,\n        but you will be surprised how far you can go without pointers!\n    - Subprograms names cannot be overloaded, although some *predefined*\n        subprograms, including operators, of the Standard or the\n        HAT package, are overloaded many times, like\n        \"Put\", \"Get\", \"+\", \"&\", ...\n    - Programmable modularity (packages or subprograms that you\n        can \"with\") is implemented.\n        See exm/unit_a.adb for an example with subprograms as modules.\n        See exm/prc.adb for an example with packages as modules.\n        See exm/pkg_demo.adb for a larger example with packages.\n    - Generics are not yet implemented.\n    - Tasks are implemented, but not fully working yet (they used to\n        work on SmallAda). See in exm/tasking for what is working\n        and exm/not_working for what is not.\n    - Small parts of the standard Ada library are available indirectly\n        through the HAT, Interfaces and Standard built-in packages.\n        You can see the currently available HAT items in its\n        specification, src/hat.ads .\n\n  A systematic testing is done in the \"test\" directory, via\n  the all_silent_tests.adb test suite.\n\nThanks\n======\n\n  - The authors of SmallAda (list below) for making their work open-source.\n  - Stphane Rivire, for extensive testing, contributions, suggestions,\n        remarks, feedbacks and the User Manual.\n  - J-P. Rosen for the free AdaControl tool\n        ( https://www.adalog.fr/en/adacontrol.html ,\n          https://sourceforge.net/projects/adacontrol/ ) which was very\n        helpful detecting global variables stemming from SmallAda's code.\n  - Pierre van de Laar for running his Renaissance-Ada tool\n        ( https://github.com/TNO/Renaissance-Ada )\n        on HAC's sources.\n  - AdaCore for providing their excellent Ada compiler for free:\n        https://www.adacore.com/community (via the Alire crate system)\n        https://www.adacore.com/download (versions till 2021, standalone)\n\nHAC on the Web\n==============\n  Home page:     http://hacadacompiler.sf.net/\n  Project page:  http://sf.net/projects/hacadacompiler/\n  Mirror:        https://github.com/zertovitch/hac\n  Alire crate:   https://alire.ada.dev/crates/hac\n\nHistory of HAC\n==============\n\n    - Now:  HAC is being made more and more usable for real applications,\n              with Ada compatibility, modularity, a library with I/O,\n              system subprograms,...\n    - 2020: Presentation at FOSDEM's Ada Developer Room:\n              https://fosdem.org/2020/schedule/event/ada_hac/ .\n              Starting a bit more serious testing and code cleanup.\n    - 2013: January 24th: Day One of HAC: Hello World, Fibonacci\n              and other tests work!\n    - 2009: A bit further trying to make the translation of SmallAda sources\n              succeed (P2Ada was improved on the way, for WITH statements\n              and UCSD/Turbo/Delphi-style modularity)...\n    - 1999: Automatic translation of Mac Pascal SmallAda sources\n              to Ada, using P2Ada.\n    - 1989: SmallAda is derived from CoPascal; works only within two\n              very system-dependent environments (a Mac GUI, a DOS GUI);\n              two similar source sets in two Pascal dialects (Mac Pascal,\n              Turbo Pascal).\n    - 1986: CoPascal (Schoening).\n    - 1975: Pascal-S (Wirth)\n              Reference: PASCAL-S, a subset and its implementation\n              https://doi.org/10.3929/ethz-a-000147073\n\n  Authors of SmallAda (in Pascal):\n    1990 Manuel A. Perez               Macintosh version\n    1990 Arthur V. Lopes               integrated environment for IBM-PC\n    1989 Arthur V. Lopes               window-oriented monitoring for IBM-PC\n    1988 Stuart Cramer and Jay Kurtz   refinement of tasking model\n    1987 Frederick C. Hathorn          conversion of CoPascal\n\n  Author of CoPascal (derived from Niklaus Wirth's Pascal-S)\n    1986 Charles Schoening\n\n  You can find the SmallAda sources and examples in the \"archeology\" folder.\n  The Turbo Pascal sources files are smaller than the Mac Pascal ones,\n  probably because of the memory constraints of the 16-bit DOS system.\n  So the Turbo Pascal sources are especially cryptic and sparsely commented,\n  full with magic numbers and 1-letter variables, many of them global - ouch!\n"
  },
  {
    "path": "exm/ackermann.adb",
    "content": "--  https://en.wikipedia.org/wiki/Ackermann_function\n--  https://rosettacode.org/wiki/Ackermann_function#Ada\n\nwith HAT;\n\nprocedure Ackermann is\n\n  function A (M, N : Natural) return Positive is\n  begin\n    if M = 0 then\n      return N + 1;\n    elsif N = 0 then\n      return A (M - 1, 1);\n    else\n      return A (M - 1, A (M, N - 1));\n    end if;\n  end A;\n\n  use HAT;\n\nbegin\n  Put_Line (\"Ackermann function\");\n  --  With M >= 4, numbers and recursions become HUGE.\n  --  See table of values in the Wikipedia page!\n  for M in 0 .. 3 loop\n    for N in 0 .. 6 loop\n      Put (A (M, N), 6);\n    end loop;\n    New_Line;\n  end loop;\nend Ackermann;\n"
  },
  {
    "path": "exm/anti_primes.adb",
    "content": "--  https://rosettacode.org/wiki/Anti-primes#Ada\n--\n--  The anti-primes (or highly composite numbers, sequence A002182 in\n--  the OEIS) are the natural numbers with more factors than any\n--  smaller than itself.\n\nwith HAT; use HAT;\n\nprocedure Anti_Primes is\n\n  function Count_Divisors (n : Integer) return Integer is\n    count : Integer := 1;\n  begin\n    for i in 1 .. n / 2 loop\n      if n mod i = 0 then\n        count := count + 1;\n      end if;\n    end loop;\n    return count;\n  end Count_Divisors;\n\n  stop : constant := 15;\n\n  results, div_count : array (1 .. stop) of Integer;\n\n  procedure Search is\n    candidate    : Integer := 1;\n    divisors     : Integer;\n    max_divisors : Integer := 0;\n  begin\n    for i in 1 .. stop loop\n      loop\n        divisors := Count_Divisors (candidate);\n        if max_divisors < divisors then\n           results (i)   := candidate;\n           div_count (i) := divisors;\n           max_divisors  := divisors;\n           exit;\n        end if;\n        candidate := candidate + 1;\n      end loop;\n    end loop;\n  end Search;\n\nbegin\n  Put_Line (+\"The first \" & stop & \" anti-primes are:\");\n  Search;\n  --\n  for i in 1 .. stop loop\n    Put (results (i), 5);\n    Put (\" has\");\n    Put (div_count (i), 3);\n    Put_Line (\" divisors.\");\n  end loop;\nend Anti_Primes;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Advent of Code 2020 examples.\n--  Some work with both HAC and \"full Ada\" compilers,\n--  some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject AoC_2020 is\n\n   for Source_Dirs use (\n     \".\",\n     \"../../../src\"   --  GNAT's access to the HAT package.\n   );\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\",\n       \"Style_Checks\" \n      );\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   for Main use (\n     \"aoc_2020_25.adb\",\n     \"aoc_2020_24.adb\",\n     \"aoc_2020_23.adb\",\n     \"aoc_2020_23_simple_array.adb\",\n     \"aoc_2020_22.adb\",\n     \"aoc_2020_22_full_ada.adb\",\n     \"aoc_2020_21_full_ada.adb\",\n     \"aoc_2020_21_full_ada_preproc.adb\",\n     \"aoc_2020_20.adb\",\n     \"aoc_2020_19_full_ada.adb\",\n     \"aoc_2020_18_full_ada.adb\",\n     \"aoc_2020_17.adb\",\n     \"aoc_2020_16.adb\",\n     \"aoc_2020_15.adb\",\n     \"aoc_2020_15_full_ada.adb\",\n     \"aoc_2020_15_full_ada_hashed_maps.adb\",\n     \"aoc_2020_14_full_ada.adb\",\n     \"aoc_2020_13.adb\",\n     \"aoc_2020_12.adb\",\n     \"aoc_2020_11.adb\",\n     \"aoc_2020_11_full_ada.adb\",\n     \"aoc_2020_10.adb\",\n     \"aoc_2020_09.adb\",\n     \"aoc_2020_08.adb\",\n     \"aoc_2020_07.adb\",\n     \"aoc_2020_07_full_ada.adb\",\n     \"aoc_2020_07_full_ada_vectors_2x.adb\",\n     \"aoc_2020_06.adb\",\n     \"aoc_2020_06_full_ada.adb\",\n     \"aoc_2020_06_full_ada_using_hat.adb\",\n     \"aoc_2020_05.adb\",\n     \"aoc_2020_04.adb\",\n     \"aoc_2020_04_b_full_ada.adb\",\n     \"aoc_2020_03.adb\",\n     \"aoc_2020_02.adb\"\n   );\n   \n   case AoC_Build_Mode is\n      when \"Debug\" | \"Style_Checks\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n   end case;\n\n   Common_Options := (\n     \"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n     \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n     \"-gnatf\",  --  Full errors. Verbose details, all undefined references\n     \"-gnatq\",  --  Don't quit, try semantics, even if parse errors\n     \"-gnatQ\"   --  Don't quit, write ali/tree file even if compile errors\n   );\n\n   Fast_Options := (\n     \"-O3\",\n     \"-funroll-loops\", \"-fpeel-loops\", \"-funswitch-loops\",\n     \"-ftracer\", \"-fweb\", \"-frename-registers\",\n     \"-ftree-vectorize\", \"-fipa-cp-clone\", \"-fgcse-after-reload\"\n   );\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Options & Debug_Options ;\n         when \"Style_Checks\" => \n            for Default_Switches (\"ada\") use Common_Options & Debug_Options & \n             (\"-gnatyaknpr\",  --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n              \"-gnatybfhiu\",  --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n              \"-gnatyO\",      --  Style: check that overriding subprograms are explicitly marked as such.\n              \"-gnatyx\",      --  Style: check x:no extra parens\n              \"-gnatye\",      --  Style: check e:end/exit labels present\n              \"-gnaty2\",      --  Style: check indentation\n              \"-gnatytc\");    --  Style: check t:token separation rules, c:comment format (two spaces)\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Options & Fast_Options & (\"-gnatpn\", \"-ffunction-sections\");\n      end case;\n   end Compiler;\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" | \"Style_Checks\" =>\n            for Default_Switches (\"ada\") use (\"-g\");\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use (\"-g\", \"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend AoC_2020;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_02.adb",
    "content": "--  Solution to Advent of Code 2020, Day 2\n------------------------------------------\n--  Password Philosophy\n--\n--  https://adventofcode.com/2020/day/2\n--\n--  Part One\n------------\n--  Each line gives the password policy and then the password.\n--  The password policy indicates the lowest and highest number of times\n--  a given letter must appear for the password to be valid.\n--  For example, 1-3 a means that the password must contain 'a'\n--  at least 1 time and at most 3 times.\n--\n--  1-3 a: abcde     -> valid (1 time 'a')\n--  1-3 b: cdefg     -> invalid (0 times 'b')\n--  2-9 c: ccccccccc -> valid (9 times 'c')\n--\n--  Part Two\n------------\n--  Each policy actually describes two positions in the password, where 1\n--  means the first character, 2 means the second character, and so on.\n--  Exactly one of these two positions must contain the given letter.\n--\n--  1-3 a: abcde     is valid   : position 1 contains 'a' and position 3 does not.\n--  1-3 b: cdefg     is invalid : neither position 1 nor position 3 contains 'b'.\n--  2-9 c: ccccccccc is invalid : both position 2 and position 9 contain 'c'.\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_02 is\n  s : VString;\n  f : File_Type;\n  c, sep1, sep2, sep3, sep4 : Character;\n  i, n, valid, arg1, arg2 : Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, \"aoc_2020_02.txt\");\n    valid := 0;\n    while not End_Of_File (f) loop\n      Get (f, arg1);\n      Get (f, sep1);\n      Get (f, arg2);\n      Get (f, sep2);\n      Get (f, c);\n      Get (f, sep3);\n      Get (f, sep4);\n      Get_Line (f, s);\n      i := 1;\n      n := 0;\n      while i <= Length (s) loop\n        if part = 1 then\n          if c = Element (s, i) then n := n + 1; end if;\n        else\n          if c = Element (s, i) and (i = arg1 or i = arg2) then n := n + 1; end if;\n        end if;\n        i := i + 1;\n      end loop;\n      if (part = 1 and n >= arg1 and n <= arg2) or (part = 2 and n = 1) then\n        valid := valid + 1;\n      elsif verbose then\n        Put_Line (+\"Invalid: \" & arg1 & ',' & arg2 &\n                  ',' & c & \"  -->  \" & n & \"  |----|  \" & s);\n      end if;\n    end loop;\n    Close (f);\n    if compiler_test_mode then\n      if valid /= Integer_Value (Argument (part)) then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n    else\n      Put_Line (+\"Valid passwords (part \" & part & \"): \" & valid);\n    end if;\n  end loop;\n  --  Part 1: validated by AoC: 607\n  --  Part 2: validated by AoC: 321\nend AoC_2020_02;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_02.txt",
    "content": "1-4 m: mrfmmbjxr\n5-16 b: bbbbhbbbbpbxbbbcb\n7-8 x: qxrxmxccxxx\n9-11 k: kkkkkkktmkhk\n8-12 g: sgwvdxzhkvndv\n6-9 v: zvmvvmvvvd\n8-19 f: ffffsplmfflffhtfrfj\n5-16 p: pppppppppspppjpcp\n2-3 w: wwmw\n7-19 j: jjjjjjjjjjjjjjjjjjvj\n5-9 q: wqzqqqqqq\n14-15 g: gggggggggglggfgg\n4-6 p: tppzkppdt\n11-14 p: vppgpktpppppptpppqp\n5-9 f: bfflffrfgf\n7-9 p: ppppptbzn\n1-3 l: lllvn\n2-4 g: qvcdg\n1-3 m: wsmdv\n1-5 v: vvvvvvvv\n10-14 l: lckqlgjllltlwbl\n3-4 t: bsttftltjhbqbgtm\n15-17 j: jjzjjjjjhjjjjjjpzjj\n2-3 t: thtt\n6-17 f: ffwkwzjtjktvsfmfhvsf\n3-5 b: rqxbb\n4-7 m: nbcmcwmmxrxqvtjfmm\n1-2 v: gzvvvv\n1-3 w: hkwhv\n7-8 p: pppppppp\n3-4 h: hhnwh\n2-4 t: ttrtjtththkr\n3-4 w: wwww\n4-6 s: xsntgrftmpx\n4-7 s: ssskssmsbs\n10-15 m: bmmrbmmmmlmmmmmm\n12-13 w: wqpwdmwllnjwx\n5-14 n: nnnnlnnnnnnnnmnn\n5-6 k: kktkfczk\n5-7 r: nrdrtrvr\n4-6 c: ccqchcc\n2-9 l: fnldtfnbxjlvnlsnjhml\n1-13 d: dlchvkccnwrcc\n5-7 j: jjjjjjj\n3-5 z: zzzzz\n6-12 f: ffffflvmfhfx\n8-10 w: wwwwwwwwww\n3-4 r: rrbtr\n3-11 b: bbbrbbvphbxbqk\n16-17 n: nqhknnnnsnnnnnnnnnb\n18-20 k: kkkkkkkkkkkkkkkkkhtj\n3-15 r: ktvzqbmbrvczprfcw\n9-11 q: qnqqdqqqgrrqsqq\n3-5 p: pvppp\n7-11 m: mfcdmmxmmmp\n7-8 t: ttttktnt\n5-6 b: bbpbbbv\n14-16 z: zzzzzzzzzrzzblzw\n11-12 j: jkjjjkjjjjjjgj\n7-9 q: qqqqqqqqqq\n10-11 f: cfffffffffff\n4-6 c: nccccc\n7-8 r: gmdlqfpwmrr\n6-8 v: nvvpdnjx\n8-12 x: xxlxxbbxxxxx\n8-10 s: ssxssssssss\n5-12 z: zhzdfzgdzzhzlz\n11-12 k: qbkhvqjpqzfq\n2-11 w: wwmlttwjflwdjcpclww\n2-16 w: twkkmcrxmvjtwxlwsksf\n6-8 s: sssfxbskvs\n5-6 s: ssnsxsbs\n10-19 l: ndzmdxqlnllxsbbwvsl\n2-4 g: gggg\n5-10 x: zxxxsxxxxxxxsxx\n7-15 f: ffbrbdtzvdffktxfm\n7-8 m: xmkmmmmmtmm\n9-13 s: hksrdhzlsdmps\n15-17 b: bbbbbbbrbbbbbbbrbb\n3-5 x: xxxxxxx\n2-6 t: wtltztnct\n3-15 v: vvwvvvvvhvvvbwwvmdvr\n12-14 p: ppphsppppppbphp\n8-9 t: ttttvttttttt\n2-3 c: cchvj\n8-9 z: vzzzzzzgl\n11-12 q: qqmqqqqqqqsnqqqqqqq\n12-13 d: dddddddddddmd\n8-9 t: wttttttqt\n7-8 p: ppppvvcw\n4-5 g: gncgj\n12-13 s: sssssssssssmw\n7-9 f: pswpnjftf\n11-16 p: ppppnpkpkzppcpzbppp\n1-12 q: ksqrqpqnqmqxqb\n2-10 l: lllllllllll\n17-18 z: zzzzzzzzzzzxzzzzzz\n11-12 g: qggbjgggggssgggrk\n3-4 s: bpss\n6-8 v: vwvvvrvvv\n3-4 t: tglktt\n4-12 l: kvrnzqslwrdkfll\n12-16 b: fbbbbbnbbvbbbbbcbbb\n5-6 t: ttttzz\n5-8 w: sqwhwwxw\n8-9 z: zzzvztzrzzzz\n3-6 l: llvdlt\n7-8 r: mrcvnrrr\n10-11 k: kkkkkkkkkmc\n1-3 n: nnnmn\n4-16 c: dqlcbclcrxkkszvcv\n9-10 g: fxssmlmgbh\n5-6 p: nwpfpp\n3-7 w: cwhgrfshdwhwwll\n14-16 l: llllllllllllllpll\n3-4 f: ffff\n4-9 d: dcdddxzvmrd\n4-11 w: jwwnwwwwwvx\n3-4 t: ttvc\n4-17 r: rrsrrrrrrrrrbtrrrr\n8-9 x: wqxxxcfdx\n6-8 d: qgddwddtdddlc\n12-13 v: vvjvvvvvzvvtvv\n3-4 g: sghxg\n3-4 b: ckbbmprfbbmzgqtkbw\n5-6 x: xxxxxv\n10-13 f: zpfffbfchxfffffjff\n5-6 f: ffffwf\n12-19 l: mlllllplllldllnsllql\n4-5 v: vvvvp\n5-8 w: vjwvghggwww\n1-3 n: lnnn\n16-18 p: ppppppvpppppwppppppp\n15-18 z: zzzzzzzzzzzzzzjzzg\n4-6 b: bbmbbb\n5-7 z: wzlwzmzzzzzzzzzzzwz\n8-12 p: gppmpppvppkzpcnpb\n16-19 h: hhbhhhhhhhhhhhlnhhw\n2-3 n: nnnn\n3-10 m: mmntfkdjftmtmmbm\n3-5 j: jjjjw\n4-6 z: zjnzzzdzz\n1-7 s: zsvsssf\n6-7 v: vtvvvcg\n3-12 f: qsrtmnxkvlcmt\n5-11 q: mqgqqqqqrpch\n5-9 g: msxkggnggg\n3-8 v: vvvvhvjvdvxtr\n4-6 k: jcklxdhkwhsqhq\n6-7 x: vppxbhcjzxdqx\n2-3 n: ntrg\n7-8 g: gggwgjdhg\n1-3 d: dddd\n14-18 l: llllllllwlllxllllllz\n8-19 g: ggggghggkhgrtzcgrrk\n7-14 q: phzxvmbxxfsfwr\n8-14 r: hbjmdrhnpxnwgz\n15-17 d: dddddpddddldddtdgddd\n6-7 k: kkkkkgkkq\n2-12 w: wwzwwwwwwwwww\n5-8 q: qqqqqqqzqqwqqzqcq\n5-6 z: czzzrz\n14-15 b: bbbrzhbbbbnxbgbb\n12-13 d: dgddddddddtvddddvbz\n3-5 v: vvvvv\n13-16 q: qqqqqvzwqqqqqqqq\n2-3 n: jpznnwfpchs\n7-10 w: jwwpwkwwwpw\n6-7 b: bbcnbcjxbbb\n14-17 w: wqtwwwwwnwcwwbsww\n3-14 w: gwwwwwwwhwwnxwwwww\n4-9 w: mwllcfjfwwwjp\n9-12 n: nnnnnnnhnwjnn\n2-4 j: jjjjj\n3-6 t: mrmttccttqt\n16-17 p: ppmjpgptzgbppphfbp\n12-17 v: vvvvvvvvvvvvvfvvvv\n13-15 x: xxxxxxxxxxxxxxgx\n2-4 d: dddddddd\n2-5 t: ttmvt\n13-14 j: jjjjjjjjjjjjtj\n3-5 r: ggmrdf\n7-8 f: ffdfflszfsfffqff\n10-11 t: ttpttttttrgtt\n8-12 j: jjjjqdhzjhjdj\n19-20 z: zbzzzzzzzzzzzzzzzzrq\n7-11 b: bbbbbhbbbxbbb\n4-9 p: gzmkkbtpkzpgthklpq\n2-5 b: bbbbxgb\n4-13 k: kkkkkkzktckkkwkjkk\n10-12 q: vrxznfqqnqgq\n15-16 m: mmmmkmmmmmmmmmmmm\n15-18 h: hlhhvhchthhhhtphhh\n2-3 m: mftzmc\n6-11 s: ksssssssssszs\n5-6 q: qqqpqkq\n7-8 n: nnfnnnnpn\n6-8 c: chfcllrvxcnnjhtc\n6-8 k: kkkkkxlk\n2-4 s: tsspb\n9-12 q: qqqqqqqqqqqqqq\n17-20 h: hhhhhhhhhhhhhhhhhhhh\n6-13 r: rrrrrgrrrrrrn\n4-8 f: fffrfffz\n13-14 n: nbnnnngnnnnnnpz\n8-11 f: fvffsfqftcffff\n3-5 w: vwhxz\n8-10 x: nmxxknlptx\n3-4 p: pppt\n17-18 v: vvvvvvhkvvvvvnvvjlvv\n10-15 z: twnsdkmgpvzfmzg\n3-5 n: njnjnkghp\n10-12 q: qvqqqqqqqqqq\n6-7 r: rrrrrrrr\n3-4 t: qltt\n2-16 f: gffflcvtpfkfcjfrjvfs\n3-5 s: swssp\n11-13 l: lrpllllllvtslwllllld\n1-3 n: nnnn\n3-5 g: jjggnvg\n4-5 b: bvbbb\n13-15 l: llvllllllllllnll\n5-6 j: hjjjjfsj\n3-4 b: bkfbnb\n5-8 z: zdzzzzzzzrzzz\n3-4 r: rrrx\n2-12 c: mczhvchkmjdrjh\n12-16 x: sjxbcgdqtpfxflsxx\n2-4 c: tcxf\n4-5 w: kwjww\n1-2 r: rrrwzc\n4-7 d: ddddddkdd\n5-6 q: qqqqqp\n13-16 l: flljlllvnzlllllclldl\n3-6 j: jjjpjj\n3-4 g: gxgg\n10-11 n: nnnnnnnnnnn\n2-5 j: ztchj\n4-6 j: pjzzrmjvhcxn\n4-11 c: jchcccgccckc\n11-12 d: dddddddddddd\n6-7 n: nznnnnnntnnnnzpjfjnn\n8-9 k: kbkkkkkkk\n13-18 x: xbxxmxqxxxmxkxsxxxx\n7-16 r: rrrrrrzrrrrrrrjmrrr\n3-5 h: hhqhd\n1-2 b: bbmb\n2-3 n: rlnntn\n2-8 q: qnfqnqhx\n2-5 b: bjbbh\n5-11 t: twtjnpttqtvtttptt\n16-17 w: wtmwwhxtgwrrswwfblll\n8-16 g: ggggghshggdggggcpwg\n1-3 l: lsllzl\n11-13 n: nnnvncnnmvnqnnnnn\n6-7 s: ssqssss\n10-18 t: tttnmjxttjttttttdzt\n4-10 n: nkvncgtdpz\n16-18 p: cphtrgffcpphfspxppgp\n2-6 k: kkhgkskkm\n6-20 r: fhrwtrzwrddfrndnrlgr\n2-8 w: lkwnccgw\n6-10 x: lxxxxxxgxwxxxrxqxx\n4-9 q: tqtpgqjzdmqfq\n9-12 k: kkkkkqbkkckkkjkql\n5-9 r: rrrrrrrhcr\n17-20 h: hhshshhhhhhhshhhbhhq\n7-9 s: dngddfsss\n12-13 q: qqqqqqqqqqqcq\n2-6 v: vqtvvvv\n8-10 c: cccfcncccccc\n14-15 m: mmmmmmmmmmmmmmdm\n7-14 s: ssslssfdssflvvsj\n2-5 z: wcllj\n2-11 n: cvnrlftcjct\n8-16 k: krzkfbkkqkhnsjkjgkk\n2-7 q: mvhvqnzdjw\n5-8 l: lgbnlnclkllll\n4-12 l: llllmllrlgllrklnlrbt\n7-10 j: jjjjjjnjjcjsj\n1-2 k: dgwmgsn\n2-5 z: zjmxc\n6-7 c: ccccccccc\n14-17 k: bkkkkkkkkkkkndkkkk\n2-4 x: xxjxtxbq\n7-9 w: drjcfwzwwwfwwfzxww\n4-5 p: pppwc\n4-5 r: rrrvm\n1-8 r: qrrrmrrrrr\n16-18 l: llllllllldllltlklk\n1-11 p: pwcpppbppppppp\n5-19 w: wwwwwwwwwwwwwwwcwww\n17-18 k: kkkkkwkkkkkkkkkkkxk\n12-15 f: fsffffffflfqgfx\n6-13 d: zddpdvddrvrdxq\n1-10 f: ffffffrfkb\n13-14 x: xxxxxxxxxxxxxxx\n16-20 j: jjjjjjjdwjjfjjjjjjdj\n8-11 r: rrrrrrrrrrrr\n15-16 x: dxjxxxdxxxxxxxxxwxx\n3-9 m: mjhqdgkmzmsmtdmhfn\n2-7 k: kkkhwgtxlkmkqkk\n11-15 m: mmgmmmmnsjmmlmmm\n1-2 v: wvvk\n8-14 s: zssssssssssssts\n3-4 z: ztbzzr\n4-10 x: xxkmqxxxxx\n3-5 p: pkppppppppzpp\n3-15 q: qpqmkqfqqlqqdfqtkqq\n16-17 d: ddddddzbxcdddcddq\n4-5 s: nqssf\n4-5 s: sssbks\n4-5 s: tsjlhsbsmt\n1-5 z: zzzbztzf\n1-4 l: pvsgtvt\n3-6 b: bbbjbb\n2-4 d: wkdvd\n16-18 w: wwwwwwwrwwwwwwwzwkw\n15-17 t: tqttjttttttttvtttt\n5-9 q: qcqqqqdtqq\n8-11 s: sssssssfssssssssssss\n5-6 x: xxxvcpbxr\n13-15 d: ddwdtctnjdcdpch\n5-6 z: zzzwzzzq\n3-7 v: bsphcnvwvtvphdp\n3-4 q: vhcprqqgdmlfpwqqw\n11-18 b: bfbbbfbbbbvhwbbbzlb\n12-15 c: cccccccccccccqfcc\n4-10 j: jjjjjjjjjjjw\n8-14 s: ssssssspmssssssssms\n6-15 b: jxnbdvxbbbcbrsbxrs\n10-12 s: ssssjsssssfs\n8-12 f: ffffdfkqflfpf\n8-9 w: wwwwwwwwz\n7-10 z: fzzlzzbtmthzzzz\n2-3 k: kqzzb\n11-12 s: ssssssssssls\n16-17 r: rrrrhrrrrrrrrrrnr\n3-11 b: czpbpbzswgcddm\n4-8 z: cnzztzgzqz\n18-19 m: mjmmmmmmmmmmmmmmmpk\n10-13 q: gqqqqqqsxqqqqdtqkq\n10-11 x: nxmbxxxrgpmxxxfnxxxz\n2-5 x: xbxzrxd\n9-14 l: llllpljlllfllwv\n1-2 m: mmmmmm\n1-3 b: fblbbfbbbbbtbbgbbb\n3-4 g: gnnccg\n8-9 f: fffffffkffff\n5-6 r: rrrrhf\n7-8 l: lwlwllllllctl\n5-7 j: jrjjwgjvkkncnjbqc\n3-4 b: bbsbb\n4-13 c: jmcczvkbxccdf\n4-5 g: wgrgg\n7-8 d: dgddddzh\n3-8 h: hhbhhhhhhhh\n15-16 l: llldllllllldlllllll\n11-15 r: rrgrrrrrrrnrrgxr\n10-11 l: lllllllllll\n4-5 x: xfdbjsmbbcxdphvlfkxr\n9-12 m: rqmnmrmhcmmms\n3-8 b: tzsnnndnbwgbskbb\n4-10 v: vvkvvdrvwvc\n9-11 j: jjjdjjjjjsj\n6-11 b: hbbmbbbbbbjbtrbbbz\n13-16 v: vvpvvvbvcvvvvvvvv\n11-14 j: jjjjjjljjjtjjmj\n7-11 v: cvdglnvjxkvvgptxvp\n1-6 t: ttjqtttzt\n7-10 f: ffwpzfxjfgffzf\n4-7 d: dddgddp\n4-19 n: mjbdzqxhtfbnbfxrpgnh\n6-13 d: ddddddddddddd\n2-4 t: rhkd\n5-9 c: ccrcxzjdzccx\n3-4 j: fwjj\n15-19 q: qqqtxqqqqqqqqqqqqqqq\n1-11 c: gcccccmccctcc\n3-5 d: dxhhdr\n8-12 k: pkvrkkkvkkmbkcxjwktk\n9-11 p: ppnpppppxppp\n11-12 p: dppcsppppppqppp\n7-8 b: bbbbbbmbqp\n7-8 c: cbccccccc\n8-9 b: bbbbbbbcrbb\n2-6 z: gzlnpzpkhjwwqtswcrz\n5-6 d: dddsdkd\n1-5 w: dxwkgwwwwwwmwwwww\n4-7 q: qqqnwqlqrqdcqpq\n6-9 m: lmmmdmmvmmmm\n7-8 h: hhhghhxh\n2-3 j: jjjj\n1-4 r: rrrw\n4-7 m: mmjmmrm\n4-5 j: vljjrj\n19-20 j: jjjjjtjjjjjjjjjjjjgx\n2-6 h: xhltfh\n5-11 s: ssssjsssssss\n3-4 b: bbbb\n1-5 g: chgmtgnn\n6-7 j: jjjjjjz\n3-8 c: cccccrccccc\n3-17 s: sslstssssssssspsgs\n17-18 x: bxxxxxxxqxxxxxxxkwxx\n9-10 q: qfqqzqqqsddqqqqqqq\n6-10 k: kmkkkxvqkrk\n5-9 f: kffffffffcdfffffplf\n5-6 r: rrrrrz\n2-5 d: hdgzt\n7-10 k: zkrllwkkkjrkqfkkk\n9-11 b: bbrkbbbbcbqqb\n8-12 g: gfgkgggggggggggggg\n12-14 s: sssjsspstlvlsrsssss\n4-8 g: pqgzcgvgflgntlp\n13-14 j: jjjjjjjjjjjjjx\n4-6 k: kkkmqpk\n3-5 j: sjjbjlvjjvjr\n2-9 c: ckccjxzcrcctbfn\n10-12 n: hvnnnnxnntnlnn\n11-15 m: mmrmmmdmmmlmmmjqm\n6-8 p: qpzrrpcpbxg\n5-8 w: xwdzcgclxwsvfwtwbxnw\n3-8 q: qzqzhlzc\n2-3 v: hvvvvltft\n5-12 s: tgvsswttkwfssnsqjsxk\n5-17 b: bbbbbbbbbbbrbcbbbhb\n3-6 p: ppjpzw\n3-5 k: kkxvkswk\n4-8 v: vbvrvxvgrvvwwvvm\n3-12 v: njvvgvdcjvvtvvcnvg\n4-5 n: bnnnrn\n8-9 l: jlvxdlpll\n12-14 w: fkwwwwwwcwwjwmwc\n1-4 q: wmqrzpqhj\n4-7 t: tctsttlt\n13-14 h: hhhhhhhhhhhhhf\n2-3 j: jmjjjjj\n5-6 v: vvvvlv\n5-13 v: fnxvvvvvnvqvvvvvws\n16-17 l: gllllllllllgwqlll\n1-2 s: pnpfsqw\n6-13 g: ntzqggvbnwxrgskg\n5-12 k: krxmbxqbkhxlnvdxdkkq\n14-18 d: ddddddddjdddbdddddd\n4-7 z: zzzzxzzs\n15-18 d: dddddddddbddddpddh\n8-11 x: slxxxxxjkxxxrsdx\n4-6 n: nnnfzzn\n1-4 h: gslcmnhhfhvz\n1-4 d: tddqds\n2-3 c: fccp\n2-5 k: mkqrknj\n9-16 g: gpggdggwgwgwglggg\n2-5 h: hhjds\n4-5 b: zbnvld\n6-14 m: mfqmnmqtdmmzmm\n7-8 j: thvcsgjn\n1-5 x: xwjdxdqjtc\n4-17 r: fqbrqrnpslndrmjdhpjp\n4-5 c: ccccw\n5-6 v: vvvvdm\n5-12 n: nnqzjntfnnnd\n3-4 c: nccqlccq\n1-10 p: nrvvzpppqpn\n9-16 v: jvvrpvvvvvzvhhvvgz\n12-13 s: sjsslsssfxxkrssstkss\n1-3 t: vtwbh\n5-16 q: sxxfrqhqtvzbzqwg\n5-9 z: dnzlhzzzsdzz\n15-16 d: pdddddjddpkdddtdddd\n3-4 p: pplqppp\n7-9 s: scsslshsqssw\n2-3 v: vxvxv\n8-9 w: wqwwwwwgshww\n8-9 k: kkkkkkkkc\n9-10 v: vhfvvnvvtvvb\n1-12 z: zzzbzzzzzzzdzzzz\n6-7 b: bbbbbwhb\n12-13 z: zzzsvtlzzzzzz\n1-3 s: pssssssxw\n8-9 w: xwwwwwwdzw\n1-4 x: xxkxxx\n10-12 f: fffffffpffvffff\n18-19 w: wwspwwzwwqcrwwhwwww\n6-8 s: ssssstsks\n5-6 j: jjcjgm\n2-5 p: wprwpxbdkrfpmppqpd\n8-18 n: nnnnnnnnnnnnnnnnnn\n4-11 c: txncpqclrlc\n2-10 f: ffcffftfffxrxf\n1-4 t: ttttttt\n4-9 f: zdpjffffbfbl\n6-7 f: kfsffffffm\n1-4 b: bbdn\n6-12 k: kkhkkkkdqkbkjkkkl\n3-4 n: kmnn\n4-11 l: kllcllldllclll\n7-19 w: pfwdwdnkblwzgkfnfmh\n3-9 z: zzphzdnhqwlzzwzz\n15-16 h: hhhhhhhnhhhhhhhd\n1-4 l: vllll\n2-13 l: hdhvgdrlltlmjptzq\n1-3 p: njvpltppbkxpfpppp\n1-2 j: kkjv\n10-11 c: ccccccmcccjcc\n5-8 v: tqvmvtwvzfczvvvvw\n6-9 x: xxmxxxfxxxxx\n1-10 z: zgzzztmdtkzzpxztbgpp\n10-12 g: ggwzjgdsgbnggl\n5-6 j: jvxjvjj\n4-7 x: xnxxmgxxtjxxkj\n13-14 d: ddddmddddddddd\n12-15 c: cccccccccccnccc\n16-17 n: nnnnnnnntnnnnngnmn\n1-12 m: bzckgvmmbdcxtgtmb\n4-7 l: ljllllljl\n5-11 w: wzvzwwrkmtwh\n11-13 l: lmtpwxlllhlgllwvqnp\n6-10 f: fvgkffqvcfffdbfff\n3-5 j: kbfjjj\n1-2 h: hhztdpbttnc\n8-10 b: bbbbjbbqkbbbd\n1-13 c: hccvcxtcclpckzd\n6-10 w: wwwwwtwwzrwwf\n2-3 j: fjnnj\n2-4 j: njtjjjxrjv\n4-5 w: fwwzw\n7-9 k: qbnkghdbqlz\n2-9 s: dsdftlzsszlf\n4-5 v: vvvvd\n1-2 w: fbfwwb\n4-7 t: tttttmt\n3-10 h: hhhhnhhhskhh\n3-8 w: qwswwswfl\n1-3 p: pmpgpp\n2-7 n: nmmgnssmtn\n2-3 j: djvjgjp\n6-13 x: jxxbxxgnxvbxx\n6-10 v: vrvvvvvvdz\n2-3 b: bbbbjrkwnc\n1-2 h: fshnf\n1-5 n: htsknrzqnntknfnjx\n5-9 d: kkgtwrdjmxkzc\n12-13 x: xxxxxxxxxxxxx\n2-10 m: wmmmmmdpmmmmh\n2-12 n: xttqcmfkvnlkzskjhmzn\n6-9 m: mmmmmxmkp\n10-16 m: gmmdqmjmflmmmmmcmmm\n13-14 p: pprprppppspxfgnptppp\n1-16 b: gcnbbnbbmsjxnbppcb\n10-11 d: dkdddddfjmpvdddd\n1-9 f: zlfwstnzp\n14-15 n: nnnnnndnnnnnrnnvcndn\n2-6 l: lvvldlzdzgdf\n6-10 z: zzzzztzzzhzz\n13-14 n: nnnnnnnnnnnngln\n8-9 z: zjqztzztqzzbxzz\n2-3 v: dwcv\n4-6 m: kmmmkmm\n5-9 g: wtgfgdmxkx\n3-5 b: vbzbf\n10-11 w: wwwwwwwvwwz\n2-8 s: sztstsnssq\n2-6 l: lldzcslxdwghmn\n1-2 n: vmznndnnnbrhknjwzkzx\n3-4 k: kknp\n1-5 h: hhhhhhh\n12-13 z: zzzzzlszzzzzxz\n1-12 m: mtbspfpdgpznrsmvgq\n11-13 q: qqqqkqnqhqrqrq\n14-18 d: dtdrdddddddddxfddddd\n1-6 q: bqqqqqgqqqq\n1-7 c: dlmvcsztzpx\n4-6 g: gmgggg\n5-6 s: ssswsssgdghv\n8-9 k: kkkkkkkgn\n1-17 s: ssssssssssksssssss\n4-5 b: qqtlsh\n5-6 g: gggggg\n2-11 r: drkpvrrlrtrvrjhpd\n3-7 k: fkkhmddh\n6-7 h: hhhwhnfph\n3-4 p: ptppmwpnps\n3-6 w: hwcshlrm\n7-8 d: dtddqddzn\n1-6 s: sslsbssbsg\n12-15 n: tbnnjknnkwnnnnsnnnz\n8-9 z: zzzzzzzzz\n2-5 w: kjnwn\n4-7 m: mmmtdjmmmmtl\n4-7 h: dqfhzrqhfhntzhkhhdvb\n3-5 g: zvflgg\n5-12 s: lvsvqnvssgcx\n11-19 p: pcppvppplpwppppjlps\n5-19 p: gkpmfxlmppczdnhbqcw\n5-17 b: mdzljsdvxdmbbbbddvrw\n1-5 s: shpdss\n2-5 t: btggtltvw\n1-6 b: sbbbbbb\n3-6 w: wwpsfkwnrrr\n13-18 f: ffffwfffsfffwffffn\n4-5 m: mpmmmxmmggvnb\n5-6 z: pwsqhcztlf\n8-11 d: ddddddddddlf\n1-2 t: xttt\n6-8 m: mmmpmvmmm\n16-17 h: hhhhhhhhhhhhhhhrw\n1-5 g: gpgpgg\n3-7 p: gplrpzp\n11-18 t: ftqnxttzttxtgttntrtt\n10-11 z: zzzzzzdzzlgzzz\n3-10 z: lzfzzzzszbzzztj\n2-10 l: khdbddnxltnk\n4-8 b: tbbcjsnbrbhfb\n3-6 x: xgsxmn\n9-13 t: ttttttttmtttt\n7-11 l: fllllllzllmdshrll\n18-19 g: hffqfwssgqpcnmddkcw\n3-4 m: mmhvmc\n1-3 w: vwnw\n5-6 r: rrrrrb\n2-4 j: rjqj\n5-7 b: kgblcbbdrb\n3-5 g: jgggggg\n1-11 v: vvrvvhxvrvvnrvvv\n3-14 w: ncwphcwvjwhdpwqkg\n6-7 x: xxxfqmkvxx\n13-14 v: vvvvvvvvvvvvkt\n2-12 x: xzcvvxhhwwxxc\n6-14 m: mdtnmjmhmnmmmmm\n15-16 z: zzzzzzzzzznzzzzzzz\n4-6 s: mcssdssjshscvcl\n11-12 b: bnbbbmbjsbxbbbbbj\n7-13 c: cccfhccczccwcccsc\n3-4 m: cgtmmm\n5-10 l: hxhbggrllmtgn\n6-8 d: sdfdddlv\n4-9 x: xxxxxvxxcx\n11-12 c: rcmqkzjccccrdccmc\n1-3 g: jgng\n4-5 l: lvlll\n9-16 n: rnnnqjnvqnnnlnnwdnnn\n4-10 x: crdxgxrfjhr\n1-5 f: tgdffffffqf\n15-16 q: qqqqqqqqvqbfqknqqqqq\n9-11 s: sssnffssksq\n3-4 v: vqvvv\n5-19 z: jthjzpgmwjbftzvmnpzk\n3-10 w: mpxhrrnqdvncwssqwlxz\n14-15 b: bzbbbbbsbbbbbbbbbbb\n3-5 j: jpjvjjrjtmjj\n3-6 w: wwmwwzw\n1-6 c: ccccvzcccm\n10-11 m: mmvwgmjmmmrqjmmmglm\n2-3 f: fffw\n6-12 m: bmbzmmrshmmz\n5-6 n: nnnnnn\n4-5 k: kmsgkwvkk\n6-8 t: tttttbttt\n4-5 j: vtmvsqjl\n5-6 q: qshzdqqk\n1-3 w: dwgw\n8-9 q: qbqqqqqwq\n5-10 m: lmmmkgmmwb\n6-9 n: nnnlnnnnn\n4-5 t: tntct\n6-8 g: hgngghgw\n6-9 t: gttwtgvpgtlt\n6-7 l: lllllll\n4-5 j: jhjkjjm\n13-15 h: hhhhhhhhhhhhxnh\n1-4 m: mmmmm\n4-6 q: cqrtqsdqqzrknf\n9-13 f: fffffffffzfvff\n2-16 p: prxdxjpkppgpxsjwpppp\n3-4 r: rrzh\n1-2 g: cglblsnkg\n1-3 f: xqnfwjmmwqffd\n13-14 q: qqqqqqqqqqqqvjqq\n18-19 g: dggggggggggggggggvgg\n5-6 s: dsssssss\n4-6 z: szdzzb\n9-12 t: xtltpgftttmtt\n10-16 m: mqmmmmmmmcmmmmqx\n3-7 c: cpccngcvccm\n2-16 s: jsdfsjsjtswhkvmsskj\n2-3 c: kccc\n4-16 k: qhndnqmrvjcczfkpds\n4-6 n: nnnrkxl\n9-10 s: ssssssssds\n2-3 z: hfzcz\n2-3 s: sssz\n8-10 b: qbbbjbbbbw\n7-16 k: gcvskkjkkkkwkzkz\n7-9 n: nnnnnnhnnnn\n1-10 q: qjxqmqxcgg\n9-11 l: jdhjbbcnlzll\n7-14 l: llrlxlllllltlnl\n3-6 f: wfdqfbrf\n3-8 t: ttzttmtvttzpl\n10-12 v: vfvvvvvvvsvv\n5-6 v: vvvvvm\n11-13 t: ttttxtttttptttctttt\n3-4 k: kkdm\n4-6 n: nnnlnt\n13-15 m: mmmmmbmmmbmmmmmm\n5-6 l: klllnl\n2-3 f: flzff\n3-4 r: frrs\n1-5 d: cqwkvsdqdvb\n9-15 l: jvtfqczlnlwdpclxwp\n12-14 t: ttttttlqtpttnt\n11-12 m: mmmmmmmmmmmm\n4-5 j: jjjkbjjjjj\n9-12 w: wwwwwwwwkwxkwcb\n6-12 q: tcqrqqqqxjqqqqmqhq\n5-6 m: mmmsmmmm\n2-5 t: mttbttprttddtv\n10-13 t: tttttttttttztt\n10-11 f: kmqfxttfkfd\n5-7 v: vrlzpvjtvv\n6-7 l: nlllllj\n1-5 q: szdbqqkqqtkmssq\n3-4 q: kcmlwqzczwms\n13-16 b: bsbbbbbbbbrbsbbpzbb\n9-11 d: dddsdbddkdkdd\n2-15 j: xkjnntffvvxfnntcv\n4-6 v: hvvvcvqvrwv\n9-12 j: qjjjjdjgqhrjjfjrdj\n8-10 v: vvvvvvvnvnvv\n4-9 t: ttttthttt\n8-16 g: ggggklggcggggxgg\n1-3 z: wpqz\n4-5 g: wgdnmxccgj\n8-11 r: rrrrrrrxrrmd\n1-9 f: ffffsfgdbsqfffzf\n7-8 q: qzqqqqrrq\n12-13 n: nnnnnnnnnnnnnn\n8-12 j: jpjjjmjjjjjzj\n1-4 j: nvjw\n7-13 z: zzzzsnzxzznzrzgzzzz\n14-16 z: zzzzzzzzzzzzzzzm\n1-4 x: xxxxnxh\n8-15 k: gnrkktkpcmklkksnkk\n2-4 h: klph\n11-16 c: ccckzdccgckpcccsc\n15-16 l: dlllllllllllllll\n2-3 s: dsxss\n1-4 v: jvvv\n2-8 t: ktkdtxkt\n1-3 t: ftftttttt\n4-5 k: kkkbkk\n4-6 g: llqcggg\n4-14 r: fmdvrrwlstlbjr\n2-16 p: rpdfhpbqfwxlxhhc\n6-8 j: jjjjjjjjj\n1-7 f: fnnffblbqffkrff\n1-3 k: rfqwlnnkzdq\n15-16 s: ssssswssssssskssss\n11-13 z: zzzzngfzzzzzz\n5-7 h: hhbhhcnhfghhhv\n2-7 j: zjrmjgmjdkp\n5-8 z: bzzzpzzrzzzz\n12-16 j: jtjnjjjjgjjjjjjsj\n5-9 s: ssssssssms\n2-3 s: ssss\n13-14 d: ddddddddddddkt\n12-13 r: wfdtrknrhvrrc\n6-8 p: vpxphxngzhnkppppfp\n2-3 j: jtjx\n3-6 k: tkkvjkb\n2-6 t: tvftftvbfx\n5-7 z: zzzqzzz\n14-15 h: whdhxhhhhhhhfxzhhh\n3-4 g: ngjgg\n9-10 z: zzzzztzztq\n2-7 f: fffffqfszchff\n4-6 f: lfqjnzccffjslsdf\n5-6 z: lpzzzzsz\n11-13 t: tttttwtttttttttttt\n2-6 z: zzzzzz\n9-10 m: mmmmmmmmjm\n5-6 w: xwggfcwvwlx\n1-4 j: jjjjjljjjjjjj\n8-10 t: ttttttwttt\n5-12 x: zxxxxxxpxxxn\n3-4 v: vvlrv\n3-6 h: hhhwhlxhlrhl\n2-5 p: cptsjktp\n4-11 j: bmjjjjjjnwwdk\n15-17 p: ppppppppppfpppvpp\n7-11 m: wnnmmwmtmmxmm\n9-19 k: kkkkkjkkhwkcvkkkmknw\n11-15 s: sspssbshssscssssss\n1-8 s: sssssmssssssssssss\n4-8 x: xxxxdxxx\n9-10 n: nnnrnlnnnnnnnnnnnnnn\n10-11 d: ddddddddddn\n5-9 z: tzzzqzbmzzzqzjkzlr\n9-20 f: fffffnfffffffsfnffff\n5-6 g: gvggggg\n13-14 x: xxxxxxxxxxxxxxx\n6-7 v: vvvzvvvv\n5-10 l: kbcvlfvlszndtlldjlh\n4-9 s: vkcsdvszthkwmmmxs\n3-4 b: jbmb\n2-4 w: nmwm\n5-10 z: tztzzfzgdzzszq\n2-8 k: kzkkkkzwf\n16-17 d: vxvzdgzwssqdcgbdb\n4-5 b: bbbbb\n7-9 w: wwfwwwjwln\n5-12 k: ljkkkqfvqtkkxsd\n5-7 q: qqqqhqqq\n8-9 n: vnnnnnnpstnn\n5-10 m: mmgzmmmmmm\n3-14 q: qgbvqjxqnqqqqqqq\n2-4 c: cccc\n3-7 b: szbbkbdbmbbzbqs\n1-5 m: mhmmc\n3-6 n: nnlvnnvnq\n2-3 c: mccc\n11-12 m: ddmmmmxmmmmwfmmm\n8-10 n: nnnnnrnnnn\n1-12 g: sgbggglnggddgggsngrx\n7-9 p: phppppppp\n4-5 q: qxqqqq\n3-7 v: vwsvvrvxvvvvvvwvvdlv\n8-18 j: jmjcjjltjmjwjzrllgcj\n2-14 r: rdrrrrrrrrrrrp\n2-4 r: cxcbkmr\n6-9 r: vtlnnvbcndqhrxkkjp\n2-3 s: hxssnsswzc\n10-16 r: csrsrxrrrrrrfrfdrr\n7-9 w: wwbwmvrwdxww\n12-14 p: pppbpppppppgpt\n2-7 n: nnnnnnnn\n3-12 f: mhjxfxgbbvffpclfffg\n10-14 l: lllskllljllllll\n11-16 l: lwlklllglzllllllll\n13-14 h: hhhhhhhhhhhhhdhhhh\n1-2 t: tttb\n1-6 z: zzzrrzzbf\n1-6 v: jrvzvvrs\n3-6 g: jggbnl\n17-18 x: xxxxxxxxxxxxxxxxrx\n8-17 f: xnmffffbwfdcfrdfw\n3-9 k: jmkdvkdnk\n7-9 m: mmmmmmdml\n9-11 c: cdmshccckqmcccccckp\n16-17 g: gggggngggggggggggdg\n7-8 n: nnknnnnnnn\n3-13 n: fjhgrspsnkmnf\n14-17 z: zzzzzzzzzzzzzqzzzzzt\n13-14 r: rrrtrrfsvrzngw\n7-8 k: kvkvkpvc\n1-2 b: bbpbb\n1-7 n: tchnrtbtldnmnnvvnn\n3-4 s: sssssjv\n1-9 l: cllllztmlllrzfl\n9-10 x: qjxxxxxxdhxxxxxh\n6-7 p: ppppfppv\n3-8 q: mkqzqqbqzjrqbq\n6-8 x: xxxxxxxx\n1-7 f: ffffffff\n5-16 b: jbbbbbqcbbbbbbfb\n9-11 c: ccccccccccq\n1-2 x: fqkx\n4-12 z: znzzzzzzzzzzzzz\n3-4 l: lglll\n9-11 m: mmmmmmmmmms\n14-17 x: xrxpxgkxxzdrxxxxckxv\n3-5 t: gxjbbfcpmkbkxbtwbt\n5-6 j: jmjjjj\n14-15 g: ggggggggggggggx\n6-7 l: lllllbl\n2-14 q: qqtsqkqvqqqpxzqqcqq\n2-4 w: fwhw\n4-5 m: mzmtkm\n2-4 g: ghghgp\n5-6 r: rrrrnl\n1-4 h: chghhw\n7-12 r: rrrzglvrrrrsrr\n1-7 x: xxcxdwxjmx\n5-12 r: rrgrrffwtrrnrrqrrjnr\n2-5 r: srdqrlxrkrrdkr\n3-4 t: ttdg\n11-12 s: bfjrkqqgdtlwrskmfrp\n3-5 n: nnrnfzsnm\n10-15 z: zzzzhzzqqczxwzqztv\n2-7 f: ffgdfgff\n7-10 d: ddtbdddddjtdqfdddfq\n2-9 k: gkrkkkkkkkkhkqkx\n13-14 n: nngnlnnnhnnnnnnnn\n6-9 r: qrxrxzrff\n7-9 m: mmmmmtmqqmml\n11-12 p: pppppppppppp\n10-13 j: jjjjjjjjjznvbjj\n1-2 c: ccvc\n7-8 m: mmmmtdmckkpmcbkjmm\n5-8 j: sjptjjbjjjjj\n6-8 d: jchdwrhd\n5-6 z: lqzzzzkrzzvzwbbzktp\n6-8 l: ztbltlll\n2-3 z: zkrxzp\n7-18 g: phgpgggqgzgnmwlpkwd\n8-9 f: hffffffqf\n17-19 p: pppppphpppppppppzpp\n2-3 z: zzzfg\n1-2 v: bfvj\n4-8 b: bcbbbbbb\n15-16 s: ppsnsssssssnssss\n2-3 m: mnsm\n2-4 h: hwfshh\n9-15 h: hhwhhhhxhhhhhhh\n17-18 n: nnnnnnnnnnnnnnnnnn\n7-11 n: nnnnnqpnlbgqnqnshn\n15-16 j: cdjmbcwdppvvjqvv\n6-11 p: ppplppppxpt\n4-5 r: rrrrrr\n10-11 w: wwwwwwwwwww\n3-7 p: pzppzspppmkxbldwpnwf\n2-12 w: zwdljlzwgxfwvtdm\n2-10 f: mzfjqfspgfrfhst\n14-15 m: mzmmmvhwmdmmdpz\n1-12 r: vrxrrtrxgvrd\n4-5 n: nnnnnnpn\n6-12 x: xkbwfsxxxxxkxxxxk\n4-6 n: mncnxn\n9-10 f: ffffpfqftbf\n3-5 b: bzwbk\n4-7 c: ncdcccc\n11-12 t: dgdkrjgsgtlf\n8-11 z: rqzdjqznrpkzmblbt\n1-3 z: zfzx\n2-4 z: kzgzkp\n6-10 v: jvvvvvvvvs\n2-9 v: vrvvvvvvvc\n5-6 q: qqqqqqc\n6-10 p: ppdknlgpqkp\n10-13 z: zzzzzzzzzzzzvz\n19-20 g: dtckblrmggknmxwnrjgg\n4-18 p: ppcjpqfpcxtphlppmhcx\n6-7 n: nnsnnknthn\n10-11 f: fffffffffff\n2-4 f: ffccltsfgk\n6-11 d: dsqddtddddjcnssrcd\n7-13 x: xxxxxqlxxxxfw\n12-13 r: rrrdrrrrrmrrrr\n15-17 p: pqppppppppppvppppppp\n7-8 j: jjjjjrdp\n4-6 v: vvvvvt\n1-4 t: tltftjtjhz\n9-15 j: jjjjjjhjjjjjjjkjj\n6-7 c: ccccccccz\n8-9 x: xxjxxxxxsx\n4-5 h: hhrhh\n2-3 g: cgnm\n8-10 l: llqlgllzlvrllg\n12-13 c: cvnbccpzzxcccfh\n3-8 z: zbzrwzzzwrzbqnr\n6-7 n: nnnnnnn\n8-11 j: tjqjrjggjxxjggjj\n7-12 l: bsvxdhljlcsj\n3-6 j: jjfjjjjb\n2-3 z: dzztwhmzqdx\n9-12 v: vvvvvvmvzvvcv\n13-14 v: vvvzvvvvvvvvvk\n6-7 g: fgggghgng\n13-14 h: wcghlwdbjhpdphkcv\n1-2 t: nncsg\n6-7 w: kwjwwxlwz\n4-5 z: zzztvz\n3-4 n: nvbvngnw\n15-17 z: zzzzzzzzzzzzzzzzzzp\n8-10 r: rrrstrgxrhrr\n8-10 g: cggggggvgcg\n1-4 m: mmvbz\n3-14 j: bdbhbjnjnrldhwlbrkrj\n1-4 r: rrkrnnd\n2-3 f: fvwc\n4-13 c: ccccvcgwbhwrcqf\n3-9 c: jcghltcfkjchxmccccbs\n3-5 h: hhhshm\n5-9 h: hhhsjhhhhgthfgldw\n4-12 h: mcwvwwphwwbc\n6-11 g: gqgggvggggh\n9-15 x: xxxxxxxxxxxxxxsx\n16-18 t: rmqqtbtvttsdtjvbttl\n9-20 f: cllnvlfkfrwzpqxwqgnn\n9-18 v: vvvvvvvvzvvvvvvzvxvv\n4-5 f: fzffbfvfff\n1-5 p: pppppp\n1-7 z: zjvchwzqjrtxzgz\n4-9 v: vvvvvvvvvv\n5-8 w: cwwwzwwb\n7-8 r: rrrrxrrr\n8-9 f: sgdcqfhfcfsflb\n3-7 g: gdgtnfggq\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_03.adb",
    "content": "--  Solution to Advent of Code 2020, Day 3\n------------------------------------------\n--  Toboggan Trajectory\n--\n--  Count trees (#) at integer locations, on a straight line\n--  going through a map.\n--  The line has a given rational slope.\n--\n--  https://adventofcode.com/2020/day/3\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2020_03 is\n  use HAT, Interfaces;\n\n  i_max : constant := 323;  --  1-based\n  j_max : constant := 30;   --  0-based\n  --\n  --  n : VString := +\"example_03.txt\";\n  --  i_max : constant := 11;\n  --  j_max : constant := 10;\n  --\n  map : array (1 .. i_max, 0 .. j_max) of Character;\n  --\n  --  Count trees on a trajectory with a rational slope (y / x).\n  --\n  function Trees (y, x : Positive) return Natural is\n    ii : Positive := 1;\n    jj, t : Natural := 0;\n  begin\n    for i in 1 .. i_max loop\n      if map (ii, jj) = '#' then\n        t := t + 1;\n      end if;\n      jj := (jj + x) mod (j_max + 1);  --  Map is periodic horizontally.\n      ii :=  ii + y;\n      exit when ii > i_max;\n    end loop;\n    return t;\n  end Trees;\n  --\n  test_mode : constant Boolean := Argument_Count >= 2;\n  f : File_Type;\n  prod : Integer_64;\nbegin\n  Open (f, \"aoc_2020_03.txt\");\n  for i in 1 .. i_max loop\n    for j in 0 .. j_max loop\n      Get (f, map (i, j));\n    end loop;\n  end loop;\n  Close (f);\n  --\n  prod := Integer_64 (Trees (1, 1)) *\n          Integer_64 (Trees (1, 3)) *\n          Integer_64 (Trees (1, 5)) *\n          Integer_64 (Trees (1, 7)) *\n          Integer_64 (Trees (2, 1));\n  if test_mode then\n    if    Trees (1, 3) /= Integer_Value (Argument (1))\n       or prod /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\" a) Trees met with slope 1/3: \" & Trees (1, 3));\n    Put_Line (+\" b) Product of total met trees with different slopes:\" & Integer_64'Image (prod));\n    --  Part 1: validated by AoC: 218\n    --  Part 2: validated by AoC: 3847183340\n  end if;\nend AoC_2020_03;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_03.txt",
    "content": "....#...##......##..#..#.#...#.\n..######...#......#....#..#.##.\n..#.#...##......#.#..#..#....#.\n..#.....#..#.#........#.#..#..#\n#......##..###...#.#..#.....#..\n#.......##...###...#....#......\n.....##...#......##.#.#..#.##..\n.........#......#.....#......#.\n..#.#..#....#....#......##.#.##\n.#...#..#.............#.#..#.#.\n....#..#.#.##.#....#..#..#....#\n...#..#.....#.......#...#..#..#\n.....#.....#.......#..#...#....\n.##.......#...#..#........#...#\n...#.......#.#.#...#.#.#......#\n#....#..#.....#......##....#..#\n###.#......#.#.#.#..#....#....#\n......##......#.#...#...#..#...\n.....#......#.#.#......#.#.....\n...##...#..#........#..#.##....\n..##.#.#..#...###..........#.#.\n.#..#..#.....#.........#.###.#.\n....##.....#...#...##..#.##...#\n....#.##....#.....##......#....\n........#.#.........#.#.......#\n#....##.#....#..#...#..........\n#..###......#....##..........##\n....##.#.....#..#.##......#....\n#..#......#......#.............\n...##.....##.......#.......#...\n#...#.#.....#..........#...###.\n#.....#..#.#.###...#......###..\n...##.#......#........#..#.....\n......#.....###.#...##........#\n.#......##......##....#....#...\n..#.#..#.....##....#....#..#...\n..#.#.....#.##.#.....#.....#...\n....#.......#...#.........##...\n.#....#..#.......##.......#....\n..#..##.....#...##.##.#.#......\n.##.#....#............#.......#\n.......#...#..#.#.##.....##..##\n..###....#..#.##........##.#...\n....#.#..#.....#..#.#.....#....\n..#..#.#..............#..#.....\n.......#.#.#.........#......#..\n...##..#.#...#......##.#.......\n#....#.#.........#...#....#..##\n.#..#.#...#.......#.#.#....#.##\n.#..###.#..#.#.....#..#........\n#.#..##.###.....##.........#..#\n#...##...#..##..#..#..........#\n.#...#..#......................\n...##..###...........#.#...##..\n..........#.#....#.#...........\n..#....#....#..#....#.#.#......\n.#..#.....###......#...#...#...\n#.##..#..#.........#..#....#...\n........#......#...#.........#.\n..#.....#.#..##...#.#.#...##...\n..#...........#.##..#.#..#.##..\n..............##...#.#......#..\n#.#..#....#...##.###........#..\n.#...#..#........#........##..#\n.....##..#...#.....#.#.........\n.#...#...#....###...#.#.#..##..\n....#.........#....###..##....#\n.#....#...####...##....####.#..\n..#..#.......#..#......#.#.#...\n....#....#.......##..#.#.......\n..#....#...........##.#.##.....\n#..#..#...##.##....#.#.#.###.##\n...#...#....#.#...##...#....###\n......##........#.........#.#..\n....#####..#..##.......#.#....#\n....##..#...###....#..#.....#..\n..#........#..#.#.....#....#...\n..#....#......#..#...#......#..\n...#.....##...#.#..##.....#..#.\n...#..#.......####.##...#......\n.....#..#..#.##..##....#..#.#..\n..#..#..##.#.#.##..#..#...#....\n...#..........#.........#....##\n.##.....###...............#.##.\n...##...........#.#.#......#..#\n.#...#.#.##....#....#..#.......\n.#...###.#....#..#..#..#......#\n#..#........###...........#..#.\n..#...#......#.#.#......####.#.\n...#.#....##.#.....#.....##....\n...###..#.#.#...#.....#.###..#.\n.#.#..#...##......#..........#.\n##.....#.......#.#..###...#.#..\n##.###....#.....#.....###.#....\n#...#..##....#.#...#...#......#\n.....##.#........#.###.........\n.#..#..#.#......##.#...#.#.....\n#..#.#........##...........##.#\n#...###..#..####..#.#..........\n..#...#....#...##.#....#....##.\n......#.#........#.....#..#....\n#.........#...#.....#...#..##..\n#....#.........#...#.##..###.#.\n#...###...#.##.#.#.............\n#.#....#....#......#....#.#...#\n##...#.##......#..#.#....#.....\n....#...#.##....#..............\n.........##..........#..##..#..\n......##....#.#......#.........\n..#.#..............#......#..##\n...........##.......#.#.#......\n##...#........##.......#.#.....\n....#...#...#....#.#......##...\n...#..#.#.#.........#..#.#....#\n.##.#...#.#.........#.....##.#.\n#.#.....#.#.....#..............\n..#.#..#....#..........#..##...\n...#..#....................#..#\n...........#...........#...#..#\n............#...#............##\n..#....##......##...........#..\n..#..#..#....#....##......##.##\n##..........#..##.##.#...#.....\n............#..#........###.#..\n###...##.#.#....#....#.#....#..\n...#......##...#.......####....\n.......#..#..#.#.....#.........\n........##.......##.....#......\n#.#...#.###....#..#...##.......\n...#.#....#..#####.#..##.#.....\n..#.#..##.......###...#.....#..\n..#.......#..#...#...#..#.##...\n......#..#.......#.....#....#..\n.......#........#.#.......##..#\n.#.#.....#.......#.......##..#.\n..#.#....#.#.#####.....#...#...\n#..#............###.......#..#.\n........##.........#..#...###..\n.#............##...#.....#.....\n.#..##..#....#....#.......#....\n....##..........##.............\n.##..........#..#..#....#...#..\n...#..#..#............####.....\n.............#..#.##..#.#.##...\n.....#........#....#.#.......#.\n###.#..#.#...#....##...........\n....#......#...#....##.......#.\n.......#.#...#.#...#........##.\n..........#........#..#.##.....\n##..#.#.....##.#...............\n.....#....#................#...\n...##....#........##.#....#....\n.....##...###....#.#..#.......#\n.....#.#.........##....###.....\n.#.....##......#..##..##...##.#\n.#..............#.....#.#......\n.##......#..#..#......##.......\n.......#..................#....\n...#.#...##......####.........#\n#....#####.#.#..#..#..#...#...#\n##.#...#.......#....#...#...###\n...#........#.....#...#.##.....\n..##....#.......#....#.......##\n#......#..##...#..##.#.....#.#.\n..###........#.#..#........#.#.\n...#.###..........#.....#.#.#..\n#.###.....#...#...#..##..###...\n#....#.#.....#.#........#......\n........#.......##.......#.....\n...........#...#......##.......\n............#...#....#..#.....#\n#.#.#.#....#.....#.#..........#\n#.##...#...#..#....##.#.......#\n...#..#......#..#...##..##..#..\n#....#......#.#.....##.#..#....\n#....#..##.#......#.#.....#..##\n.#..##....##....#.#...#...#....\n#.#.###....#.#............#...#\n.#.#....#..#..........#....#.#.\n......#..#.#...............##..\n..#......###.#..........#.###..\n....#.##.#..#...##..#.#...#....\n..............#...##.......#.##\n.#...........#....#....#.##....\n#..#....#.....#...#.....##...#.\n.........#...#.##.......#...#.#\n.....#......#.........#.#..#...\n##..........#.#..##...#.#.#....\n##..##.#..#..#.....#.##....#...\n........##....#.#.#....#......#\n.#.##...#.###....#.........#..#\n..........#....###..#.........#\n#.#..#.#...#.......#..##.......\n..#....#...###..............##.\n#..###.....####...#..#..#...#..\n......#..#...###........###....\n..#.....#...#.......#....###..#\n.#.........#.#.#....#.#.......#\n#.#.###.#.#...........#........\n......#..#.........#........#..\n...........##.#........#.#...#.\n.....#.#......##.......#.....##\n...##...#............#..#.....#\n.....#..##....##...##.#..#.#...\n...#...#........#.#......##....\n........#..##..#..#......##.#..\n.#.#.....#.....#...........#.##\n.#...#.#............#......#...\n.....#...#........#....#..#.#..\n...##....#..#...#..............\n#....##.#.#............#.......\n#..#..#.....##..#........##.#.#\n##..#.#....#....##.......###..#\n.#.#.#.....###.....#.#......###\n.....#..#...###...#....#.#...#.\n.##.....................##....#\n.#.....#.........#....#.....##.\n#...#....#.#...###.......#.#..#\n...#.................#.#....#.#\n.##...#.#......................\n.##.#........#...##............\n.#....#.....#.........#.##..##.\n#......#...##..#.........##.##.\n......#......#...####..#.##....\n.###....#..##......#.##......#.\n..#...#....#..#.......#.#......\n#....#...#.................#.#.\n....#.#.#..#...#..#.......#.#.#\n#.#...##.......#.....##.#......\n#.........#.....##..##..#......\n....#..##..#.....#..#..#.#..#..\n......#.#..#.#.#....#.#.......#\n.##......#..#....##...##..#....\n..#..#......#...##..#.##.....#.\n..#..#.......#.#....#.....#...#\n....#.#.....###...#.......#.#..\n..#....##.....##.#........##...\n#...............##....#.....##.\n.#.........#....#...##.###.##.#\n.#.##..#.............#.#.#..#..\n.#.....#.................##....\n..####.........#.#......#.#..#.\n#.......#..........#.#........#\n.#.#...##.....#.#.......#....#.\n..#.##.#.......###....#....#...\n.#....##.............##.#.#.#..\n#.#.....#.#.#.#..#......##..#..\n.............#..........#.#.#..\n...#.#.............#.#...##....\n.......#..#.#.......#..#.#....#\n.............#.........###..#..\n.#.#..#....#.....#..#.....#...#\n#.....#....##..##.#..#........#\n..##..###.....##....#.#..#.....\n..#...##....#...#.#..........#.\n...##..##.#.....#....#.........\n..#...#........##.#..#........#\n#.............#.###......#.##..\n.#...#........#...........#...#\n..##.......#.#..##.##......#...\n...#.#...##....##..#...........\n.#......##........#....##....#.\n.........#..#....#...#..##.##..\n....#..#.#...#.......#.#.##....\n...#.#......#.#..#..#.#....#..#\n.......#........#.........###..\n#.#..#.#.........##............\n##..##..#.##..###...#.#...#....\n.#....#.#..#...#....#.##.....#.\n.#.#.#.#........##...#..#.#.##.\n.#..#.#..#...........#..#......\n..#.##.#...#....#.........#...#\n.....##...#.#...#...#....#.....\n..#..........#.#.#.......##.#..\n#.#............#..#.....#..#...\n..#...........##.#.##.#....#..#\n#..####.....#............#.....\n.##......#####.#..#.....#....#.\n...##..#.#......#.#..#..#...##.\n#....................#.##...#.#\n...#............#.............#\n....#.##..........#.....#......\n....##..##....#.#..............\n...........#....##.#.....#.....\n....#.....#....#....#......#...\n#...##........#...#........#.#.\n........#.....##..#.##.#..#.#.#\n....##......##....#.....##....#\n...#.#........##.......#...##..\n#......##..#.#.#....##......#..\n..#.......#.......##..#.##.....\n.#...#...#.#.............##....\n......#.#.#.........##...#..#.#\n.....#..####....#.##..........#\n...#...#.#....#.....#..#.....##\n.........#.......#......###....\n........##..##..#.#.#...###...#\n.#..##.#....#...##.....#.#.#...\n........##...#...##..#.........\n.........#.......#.##..#...####\n#......#.....#..............#.#\n##..##.#.##.....##...........#.\n#.............#.........#......\n...####.#.##..#.#.#.##.#......#\n..#.....##....#...#............\n#..............#......#...###..\n..#..#.#...#.##.........##.....\n..#...##..#........#..#.##..##.\n......###...#..#....#..#.###...\n...##.##.###.....##.#.......#..\n#....#..###..#.......#.#.#..#..\n..##.............##..##...###.#\n.#.#..#.........#..........#...\n.........#.#.....##...#..#...##\n....#..#....#####..#...#..#....\n...#.....#.....#...#.#..#.#....\n.#..#.............#.......##.#.\n...##.......#.#.....##......#..\n...........##..#.##..###...#.#.\n...........#...........#...#..#\n..#....#.##.#..#..#...........#\n..#.....##...#......#...#......\n...###.###.....##..........#..#\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_04.adb",
    "content": "--  Solution to Advent of Code 2020, Day 4\n------------------------------------------\n--  Passport Processing\n--\n--  https://adventofcode.com/2020/day/4\n--\n-------------------------------------------------------------------------\n--\n--  HAC 0.084 \"nice to have\"'s detected in this exercise:\n--    *   exception handling to catch invalid values\n--    *   Index with From parameter\n--    *   'Image attribute for enumerated types\n--\n--  Solved in HAC 0.098:\n--    *   \"and then\", \"or else\"\n--\nwith HAT;  --  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n\nprocedure AoC_2020_04 is\n  use HAT;\n  --\n  function Val_Num (s : VString; hexa : Boolean) return Integer is\n    c : Character;\n  begin\n    if Length (s) = 0 then\n      return -1;\n    end if;\n    for i in 1 .. Length (s) loop\n      c := Element (s, i);\n      if not (c in '0' .. '9' or else (hexa and then c in 'a' .. 'f'))\n      then\n        return -1;\n      end if;\n    end loop;\n    if hexa then\n      return Integer_Value (+\"16#\" & s & '#');\n    else\n      return Integer_Value (s);\n    end if;\n  end Val_Num;\n  --\n  function Val (s : VString) return Integer is\n  begin\n    return Val_Num (s, False);\n  end Val;\n  function Val_Hexa (s : VString) return Integer is\n  begin\n    return Val_Num (s, True);\n  end Val_Hexa;\n  --\n  cats, total, cat_idx, tok_begin, tok_end, nb : Integer;\n  s, tok, cat, un : VString;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  f : File_Type;\nbegin\n  for criteria in 1 .. 2 loop\n    Open (f, \"aoc_2020_04.txt\");\n    cats := 0;\n    total := 0;\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      if s = \"\" then\n        cats := 0;\n      end if;\n      if criteria = 1 then\n        if Index (s, \"ecl:\") > 0 then cats := cats + 1; end if;\n        if Index (s, \"pid:\") > 0 then cats := cats + 1; end if;\n        if Index (s, \"eyr:\") > 0 then cats := cats + 1; end if;\n        if Index (s, \"hcl:\") > 0 then cats := cats + 1; end if;\n        if Index (s, \"byr:\") > 0 then cats := cats + 1; end if;\n        if Index (s, \"iyr:\") > 0 then cats := cats + 1; end if;\n        if Index (s, \"hgt:\") > 0 then cats := cats + 1; end if;\n      else\n        cat_idx := 0;\n        loop\n          s := Slice (s, cat_idx + 1, Length (s));\n          cat_idx := Index (s, \":\");\n          exit when cat_idx <= 3;\n          tok_begin := cat_idx + 1;\n          tok_end := tok_begin - 1 + Index (Slice (s, tok_begin, Length (s)), \" \");\n          if tok_end >= tok_begin then\n            tok_end := tok_end - 1;\n          else\n            tok_end := Length (s);\n          end if;\n          tok := Slice (s, tok_begin, tok_end);\n          cat := Slice (s, cat_idx - 3, cat_idx - 1);\n          if cat = \"byr\" and then Val (tok) in 1920 .. 2002 then cats := cats + 1; end if;\n          if cat = \"iyr\" and then Val (tok) in 2010 .. 2020 then cats := cats + 1; end if;\n          if cat = \"eyr\" and then Val (tok) in 2020 .. 2030 then cats := cats + 1; end if;\n          if cat = \"hcl\" and then Element (s, tok_begin) = '#'\n                         and then Val_Hexa (Slice (s, tok_begin + 1, tok_end)) > 0\n          then\n            cats := cats + 1;\n          end if;\n          if cat = \"pid\" and then Length (tok) = 9 and then Val (tok) >= 0 then cats := cats + 1; end if;\n          if cat = \"ecl\" and then Index (+\"amb blu brn gry grn hzl oth\", tok) > 0\n                                --  ^ Idea: Maxim Reznik, replaces checking each value\n          then\n            cats := cats + 1;\n          end if;\n          if cat = \"hgt\" then\n            nb := Val (Slice (s, tok_begin, tok_end - 2));\n            un := Slice (s, tok_end - 1, tok_end);\n            if (un = \"cm\" and then nb in 150 .. 193) or else\n               (un = \"in\" and then nb in 59 .. 76)\n            then\n              cats := cats + 1;\n            end if;\n          end if;\n        end loop;\n      end if;\n      if cats = 7 then\n        total := total + 1;\n        --  Prevent incrementing total if there is garbage\n        --  or a \"cid:\" until next blank line:\n        cats := 0;\n      end if;\n    end loop;\n    Close (f);\n    if compiler_test_mode then\n      if total /= Integer_Value (Argument (criteria)) then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n    else\n      Put_Line (+\"Valid passports (criteria set #\" & criteria & \"): \" & total);\n      --  Part 1: validated by AoC: 228\n      --  Part 2: validated by AoC: 175\n    end if;\n  end loop;\nend AoC_2020_04;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_04.txt",
    "content": "pid:827837505 byr:1976\nhgt:187cm\niyr:2016\nhcl:#fffffd\neyr:2024\n\nhgt:189cm byr:1987 pid:572028668 iyr:2014 hcl:#623a2f\neyr:2028 ecl:amb\n\npid:#e9bf38 hcl:z iyr:2029 byr:2028 ecl:#18f71a hgt:174in eyr:2036\n\nhcl:#cfa07d byr:1982 pid:573165334 ecl:gry eyr:2022 iyr:2012 hgt:180cm\n\ncid:151 hcl:#c0946f\necl:brn hgt:66cm iyr:2013 pid:694421369\nbyr:1980 eyr:2029\n\necl:brn\npid:9337568136 eyr:2026\nhcl:#6b5442\nhgt:69cm iyr:2019 byr:2025\n\ncid:66 hcl:#efcc98 pid:791118269 iyr:2013\neyr:2020 ecl:grn hgt:183cm byr:1993\n\neyr:2022\nhgt:160cm iyr:2016 byr:1969 pid:767606888 ecl:gry hcl:#6b5442\n\nhgt:157cm eyr:2026 ecl:oth hcl:#efcc98 byr:1938 iyr:2014\n\nbyr:1931 iyr:2015\necl:gry\nhgt:76in\ncid:227 hcl:#09592c eyr:2024 pid:276365391\n\necl:gry hgt:170cm iyr:2014 cid:285 pid:870052514\nhcl:#866857 byr:1925 eyr:2025\n\neyr:2021\nbyr:1960 pid:569950896\niyr:2010 hgt:179cm hcl:#888785 cid:167\n\nhgt:154in cid:194\npid:8142023665 byr:2010 hcl:7d22ff ecl:utc iyr:2026 eyr:1976\n\necl:blu eyr:2030 hgt:192cm\npid:363860866 iyr:2019 hcl:#ceb3a1 byr:1963\n\nbyr:1947 hgt:167cm hcl:#7d3b0c ecl:amb\ncid:70 eyr:2022 iyr:2019 pid:756932371\n\nhgt:185cm pid:871945454\niyr:2020\nhcl:#866857 ecl:amb\nbyr:1989 cid:184 eyr:2030\n\nbyr:1935 pid:322117407\nhgt:153cm iyr:2011\ncid:244 eyr:2022 hcl:#efcc98 ecl:hzl\n\necl:blu hcl:#5e6c12\neyr:2029 iyr:2011 hgt:191cm byr:1992\n\nhcl:#7d3b0c eyr:2029\nhgt:163cm\npid:625292172 byr:1932 ecl:brn\niyr:2020\n\nhgt:158cm\neyr:2030 iyr:2016 byr:1969\ncid:173 pid:092921211 hcl:#602927 ecl:grn\n\nhcl:#733820\niyr:2016 eyr:2029\necl:hzl hgt:180cm pid:292904469 byr:1984\n\necl:amb pid:901224456 hgt:190cm\niyr:2013\nhcl:#733820\nbyr:1922\n\npid:262285164 iyr:2010\nbyr:2018 eyr:2026 hcl:#602927 hgt:179cm ecl:gmt cid:349\n\nbyr:1956 eyr:2027 pid:351551997 hgt:71in cid:277 hcl:#cfa07d iyr:2010 ecl:grn\n\neyr:2027 hcl:#602927 hgt:157cm ecl:gry\ncid:128 byr:1953\npid:231551549 iyr:2012\n\niyr:2011 pid:771266976\ncid:264 byr:1955 hcl:#b6652a\nhgt:189cm ecl:blu\neyr:2030\n\neyr:2026 pid:698455242\nbyr:1949 ecl:gry hgt:190cm\niyr:2013 hcl:#efcc98 cid:139\n\necl:blu hgt:181cm byr:1977 iyr:2011 eyr:2022\npid:454163967 hcl:#b6652a\n\npid:534506872 hgt:155cm iyr:2012\nbyr:1968\ncid:333 eyr:2024 hcl:#623a2f\necl:amb\n\nhgt:162cm\niyr:2020\nhcl:#733820 eyr:2027 byr:1995 ecl:gry pid:084994685\n\niyr:2016 byr:1990\necl:amb pid:185689022 eyr:2025\nhgt:184cm hcl:#866857\n\nbyr:2016 hcl:z iyr:2022 hgt:166in\neyr:2040\n\nbyr:1943 hgt:152cm hcl:#cfa07d ecl:hzl iyr:2016 cid:300 pid:376088014\n\niyr:2020 eyr:2026 hcl:#602927 ecl:gry byr:1962 pid:453907789 hgt:172cm\n\neyr:2023 hgt:185cm\nhcl:#623a2f pid:963767258 byr:1977\niyr:2019 ecl:oth\n\nhgt:159cm byr:1965 cid:349 ecl:blu pid:962908167\niyr:2013 eyr:2024\nhcl:#fffffd\n\neyr:2026\npid:912822238 hgt:66in byr:1985 iyr:2018 hcl:#c0946f ecl:hzl\n\nhgt:167cm hcl:#ceb3a1\nbyr:1990 eyr:2027 ecl:grn\niyr:2011 pid:642877667\n\nhcl:#7d3b0c byr:1921 pid:976412756 hgt:192cm\niyr:2013 ecl:gry\n\niyr:2030 pid:283599139\neyr:2039 cid:203\nhcl:f943cb\nhgt:111\n\nhgt:190cm\niyr:2027 ecl:blu hcl:z\nbyr:2004 eyr:2039\npid:734570034\n\nhcl:#6b5442 hgt:191cm\necl:oth byr:1989 pid:669414669 cid:196 iyr:2016 eyr:2023\n\necl:brn eyr:2028 byr:1965 pid:630674502 hcl:#602927 iyr:2020 hgt:61in\n\niyr:2016 eyr:2022 cid:225\nhcl:#733820 ecl:hzl hgt:166cm\nbyr:1934\npid:232742206\n\necl:amb hcl:#602927 eyr:2029\npid:897535300\nhgt:189cm byr:1952\niyr:2017\n\npid:853604345\nhgt:161cm cid:269\nhcl:#fffffd eyr:2030 iyr:2011 ecl:grn byr:1966\n\nhgt:151cm hcl:#18171d eyr:2026 ecl:grn iyr:2016 pid:176cm\nbyr:2000\n\nhcl:#341e13\neyr:2022\npid:536989527 cid:73 byr:1971\necl:hzl\n\npid:739005658 hcl:#b6652a\neyr:2026 hgt:154cm ecl:hzl\niyr:2019 byr:1935\n\npid:373465835 ecl:oth byr:1932 cid:333 hgt:165cm\nhcl:#b6652a eyr:2021 iyr:2014\n\nbyr:1967 pid:486658617 hcl:#18171d hgt:174cm\neyr:2021 iyr:2015 ecl:gry cid:53\n\neyr:2024\ncid:124 iyr:2017 hgt:152cm pid:095649305 hcl:#341e13\nbyr:1920 ecl:oth\n\nhcl:#623a2f\nbyr:1951 pid:993284548\ncid:106\nhgt:186cm\necl:amb iyr:2017 eyr:2029\n\ncid:308 pid:080673934\nhgt:193cm\nbyr:1967 hcl:#623a2f iyr:2016 ecl:hzl\neyr:2021\n\niyr:2010 eyr:2024 byr:1946 hgt:156cm\ncid:199\necl:blu hcl:#866857\n\necl:blu byr:1955 eyr:2022 cid:95 pid:139391569\niyr:2019 hgt:180cm\nhcl:#efcc98\n\necl:brn pid:579889368\neyr:2023 hgt:158cm byr:1935\niyr:2018 hcl:#cfa07d\n\nbyr:1920 pid:90919899 hcl:#18171d\nhgt:152cm\neyr:2029 ecl:oth iyr:2014\n\nbyr:1961 eyr:2024\necl:#d401e3 iyr:2011 hgt:172cm pid:919145070\ncid:100\nhcl:#efcc98\n\necl:gry\nhgt:168cm\nhcl:#888785 byr:1942 pid:731032830 iyr:2014\neyr:2028\n\nhcl:#6b5442 pid:265747619 hgt:191cm\ncid:217\neyr:2028\niyr:2019 ecl:amb\nbyr:1948\n\niyr:2011 ecl:brn\nhgt:183cm hcl:#fffffd cid:258 byr:1983\npid:835909246\n\nbyr:2030\niyr:2024 ecl:#f66808\nhcl:fd548d cid:183\npid:#fced33\nhgt:160in\n\necl:utc hgt:183in hcl:a92c31 pid:0394222041\niyr:2008\neyr:1976 byr:2020\n\npid:126195650 iyr:2019 hcl:#341e13\necl:blu\nhgt:150cm\neyr:2025\nbyr:1964\n\ncid:71 iyr:2016 hgt:157 ecl:grt\nhcl:#18171d pid:#1ab5ea eyr:2027\n\neyr:2026 hcl:#b5266f\nbyr:1971\ncid:269 hgt:192cm iyr:2012\npid:736578840 ecl:amb\n\npid:152109472 hcl:#ceb3a1 ecl:grn hgt:188cm eyr:2027\nbyr:1923\n\nhcl:#341e13 pid:535175953 hgt:63in eyr:2028 iyr:2015 byr:1999 ecl:gry\n\nhgt:183cm pid:611738968 byr:2001\neyr:2020 hcl:#a97842 iyr:2014\necl:gry\n\neyr:2038 ecl:gmt pid:113210210 iyr:2012 byr:2011\nhcl:z\nhgt:157cm\n\nhgt:157cm\npid:699449127\niyr:2014 ecl:gry byr:1980 hcl:#fffffd eyr:2029\n\niyr:2028 hcl:z pid:152cm\neyr:2039\necl:#4760fb hgt:177in\nbyr:2017\n\neyr:2026 hcl:#efcc98\niyr:2020 hgt:180cm ecl:hzl pid:747449965 byr:2016\n\nbyr:1974 iyr:2019\ncid:89 eyr:2023 pid:421418405\nhcl:#fffffd hgt:192cm\necl:gry\n\nhcl:26c2ef eyr:2029 cid:309 byr:1931 ecl:grn pid:#4eb099 iyr:2024\nhgt:174cm\n\necl:gry\nhgt:183cm\ncid:281\neyr:2022 pid:050492569\nbyr:1968 hcl:c88145\niyr:2015\n\neyr:2028\niyr:2014 pid:712984515 hgt:187cm cid:206 hcl:#866857 byr:1927\necl:brn\n\nbyr:1936 hgt:61in ecl:oth iyr:2012 pid:447813841\nhcl:#c0946f\ncid:126 eyr:2021\n\necl:gry pid:791970272\neyr:2020\nbyr:1932 hcl:#623a2f hgt:161cm\niyr:2015\n\nhcl:#c0946f\nbyr:1935 pid:721144576 eyr:2025 hgt:162cm\niyr:2017 ecl:oth\n\nbyr:1959\npid:551109135\necl:hzl hgt:68in\neyr:1977 hcl:#888785\niyr:1955 cid:100\n\nhgt:190in eyr:1993 pid:8358180772 iyr:1975\necl:oth\nbyr:2024\nhcl:3de172\n\neyr:2030 hgt:190cm hcl:#a40ef3 byr:1935 pid:484932501\necl:amb iyr:2016\n\niyr:2015\nbyr:1964\nhgt:176cm\npid:819552732 hcl:#c0946f ecl:amb cid:263\neyr:2024\n\nhgt:65cm cid:59 eyr:2027 pid:074880819 ecl:utc iyr:2023\nbyr:1954 hcl:#623a2f\n\nbyr:1954 hgt:167cm iyr:2020\neyr:2023 hcl:#602927\npid:280295309\necl:hzl cid:168\n\nhgt:168cm pid:311043701 iyr:2017 byr:1965\necl:hzl\neyr:2026 hcl:#fffffd\n\nhcl:#fffffd ecl:grn pid:672987232 iyr:2012 eyr:2022 hgt:66in\n\niyr:2012 ecl:#6f4f9f\nhgt:133 byr:1937\neyr:1953 pid:7177768428 hcl:#602927\n\niyr:2010\nbyr:1922 hcl:#c0946f\neyr:2029 ecl:gry\nhgt:165cm\npid:893045052\n\niyr:2013 eyr:2028 hcl:#866857 pid:137143403\necl:brn hgt:170cm byr:1940 cid:194\n\nhgt:161cm\neyr:2027 pid:3966920279 ecl:gry iyr:2015 byr:1997 hcl:#cfa07d\n\necl:amb\nhgt:157cm byr:1971\npid:562746894 cid:305 hcl:#0b0e1a eyr:2021 iyr:2016\n\nhcl:8b821d hgt:157cm pid:187cm cid:298 eyr:1926 iyr:2019\necl:amb\nbyr:2030\n\nhgt:155cm hcl:#341e13 byr:1924 pid:779847670\necl:hzl iyr:2015\neyr:2024\n\npid:768590475 hcl:#a97842 iyr:2014 cid:128 eyr:2029\necl:oth hgt:164cm byr:1990\n\niyr:2019 hgt:181cm cid:342\neyr:2020 ecl:gry byr:2001\nhcl:#623a2f\npid:473165431\n\nbyr:1928 eyr:2026 hcl:#42a9cb iyr:2010\necl:grn hgt:157cm pid:638074984\n\neyr:2028\nbyr:1951\npid:239781647 iyr:2020 hgt:156cm\necl:hzl cid:215 hcl:#efcc98\n\npid:636605355 ecl:hzl\niyr:2017 cid:323 eyr:2025\nbyr:1995\nhcl:#18171d hgt:187cm\n\nbyr:1933 hcl:#866857 hgt:152cm ecl:oth iyr:2014 pid:900790914 eyr:2030 cid:267\n\necl:brn byr:1999 eyr:2027 hcl:#623a2f iyr:2017\npid:853165955\nhgt:152cm\n\neyr:2030 pid:316704688 hcl:#c0946f ecl:brn iyr:2014 hgt:193cm\n\niyr:2012 byr:1928\nhgt:154cm pid:570535769 hcl:#623a2f eyr:2026 ecl:hzl\n\niyr:2016 cid:252 eyr:2030 hcl:#888785\nhgt:177cm ecl:grn byr:2002 pid:568715162\n\npid:570999226 iyr:2012 hgt:150cm\nbyr:2024\necl:brn hcl:z eyr:2029\n\npid:174002299 iyr:2019 hcl:#cfa07d ecl:brn byr:1927\ncid:77 hgt:159cm eyr:2027\n\necl:#d16191 eyr:2022 pid:166cm hgt:165cm hcl:#18171d iyr:2015\n\npid:112585759\nhcl:#341e13 eyr:2025 byr:1962 hgt:164cm ecl:hzl iyr:2018\n\npid:478415905 eyr:2025 cid:315\necl:amb hgt:91\niyr:2014 hcl:#cc9d80\nbyr:1985\n\npid:561885837 hcl:#7d3b0c\nhgt:169cm\nbyr:1921 iyr:2014 cid:178\neyr:2022 ecl:gry\n\necl:#c87497 hcl:5321a2 eyr:2020 hgt:74in\npid:#7a62c6 iyr:1976\n\neyr:2037\npid:858202391 hgt:162cm\necl:grn byr:2003\ncid:278\niyr:2010 hcl:cbf662\n\necl:blu iyr:2012 hgt:183cm hcl:#623a2f pid:848200472 byr:1997 eyr:2027\n\nbyr:1942\nhgt:164cm\npid:464257339\niyr:2016\nhcl:#7d3b0c ecl:gry\n\niyr:2012 hcl:#ceb3a1\nhgt:193cm ecl:amb\npid:667987561 eyr:2024 byr:1960\n\nhgt:187cm\npid:222340640\niyr:2018 eyr:2022\necl:oth\nbyr:1957\nhcl:#336667 cid:83\n\neyr:2025 iyr:2015 hcl:#733820\necl:brn\npid:131195653\n\nhgt:185cm eyr:2026\necl:amb byr:1998 pid:938587659 hcl:#733820\niyr:2016\n\necl:oth pid:300949722\neyr:2028 iyr:2016\nbyr:1933\nhgt:179cm\nhcl:#cfa07d\n\nbyr:1974 iyr:2019\necl:hzl hcl:#c0946f eyr:2024 pid:484547079\ncid:112\nhgt:185cm\n\neyr:2022 iyr:2018 hcl:#fffffd pid:118568279\nhgt:153cm ecl:gry byr:1941 cid:341\n\niyr:2018\neyr:2027 hcl:#888785\nbyr:1970 hgt:165cm pid:773715893\necl:amb\n\nhcl:#623a2f hgt:156cm byr:1938 iyr:2012 pid:745046822\necl:amb\neyr:2030\n\niyr:2012\npid:097961857\neyr:2023 hgt:66in hcl:#fffffd byr:1962 ecl:utc\n\nbyr:1943 hgt:150cm\niyr:2012\npid:740693353 eyr:2023\nhcl:#18171d cid:101 ecl:blu\n\niyr:2018 pid:183728523 byr:1924 hgt:154cm eyr:2030\ncid:167 ecl:blu hcl:#ceb3a1\n\nhgt:69cm\neyr:2025 hcl:z ecl:brn byr:1982 pid:250782159\niyr:2011\n\nbyr:1998 iyr:2018 hcl:#341e13 eyr:2022 hgt:157cm pid:497100444 cid:266 ecl:gry\n\neyr:2027 iyr:2011 hcl:#6b5442 hgt:156cm pid:494073085\nbyr:1998\necl:hzl\n\nbyr:1947 hcl:#b6652a\niyr:2011 pid:228986686 eyr:2030 hgt:175cm cid:70 ecl:brn\n\neyr:2026 hgt:159cm\nbyr:1946 pid:534291476\niyr:2018 ecl:gry cid:225\nhcl:#18171d\n\npid:439665905\ncid:311 ecl:amb iyr:2018\neyr:2030\nhgt:186cm byr:1950\nhcl:#cfa07d\n\npid:250175056 hcl:#efcc98\nbyr:1981 cid:262 hgt:154cm ecl:gry iyr:2020 eyr:2027\n\npid:461335515 iyr:2014 hcl:#f1cf00 hgt:180cm ecl:amb eyr:2027\nbyr:1956\n\niyr:2014 eyr:2030 cid:194\npid:234623720 hcl:#733820\nhgt:164cm byr:1929\necl:blu\n\nbyr:1992\neyr:2024 hcl:#ef8161 cid:216\necl:brn hgt:177cm iyr:2018\npid:101726770\n\nhcl:#341e13 hgt:178cm iyr:2016 eyr:2029 byr:1945 pid:045325957 ecl:grn cid:99\n\necl:gry\niyr:2012\ncid:52 hgt:168cm byr:1943\nhcl:#cfa07d\npid:899608935 eyr:2030\n\ncid:241\nbyr:1934 hgt:161cm eyr:2027 iyr:2011 hcl:#c0946f ecl:amb pid:346857644\n\niyr:2019 hgt:178cm\nhcl:#c0946f byr:1957\neyr:2026\necl:brn pid:222885240\n\necl:blu\neyr:2021 cid:312 hcl:#733820 hgt:186cm iyr:2012 byr:1969\npid:821704316\n\nhcl:#6b5442 cid:159\nhgt:180cm\niyr:2018\neyr:2028\necl:hzl byr:1966\npid:#e0238e\n\npid:622400994 eyr:2022 hcl:#5b6635 iyr:2012 byr:1980\nhgt:190cm ecl:oth\n\nbyr:1976 ecl:gry eyr:2020 iyr:2020 hgt:171cm pid:219878671 hcl:#6b5442\n\nhgt:163cm byr:1968\npid:003521394 ecl:oth\niyr:2010\ncid:61 hcl:#888785\n\ncid:115 pid:810722029 hgt:166cm byr:1955\necl:blu eyr:2030 iyr:2018\n\nhgt:176cm\neyr:2025\npid:617393532 hcl:#733820 byr:1975 iyr:2018 ecl:grn\n\nhcl:#733820 byr:1979 pid:838168666\nhgt:190cm ecl:oth cid:330\neyr:2029 iyr:2018\n\neyr:1940 hgt:67cm iyr:2009 ecl:gry pid:#e76a62 byr:2020 hcl:z\n\nhgt:190cm ecl:brn pid:396113351\nbyr:1956 iyr:2010\nhcl:#6b5442 eyr:2024\ncid:256\n\nhcl:#efcc98\nhgt:178cm byr:1984 iyr:2013 pid:752620212 eyr:2021 ecl:gry\n\niyr:2014 hcl:#a97842\nhgt:166cm ecl:blu eyr:2024\nbyr:1935\npid:836748873\n\ncid:236 ecl:amb hgt:168cm iyr:2010 hcl:#602927 byr:1950 eyr:2026 pid:404810674\n\neyr:2030 ecl:grn\nbyr:1975 pid:064596263 hgt:193cm\niyr:2019 cid:71 hcl:#a97842\n\niyr:2014\npid:298386733 hcl:#c0946f\nhgt:180cm ecl:hzl cid:115 byr:1940 eyr:2023\n\niyr:1960 hgt:139 ecl:#9db7b8 byr:1980 pid:#ef597b cid:54 eyr:2028 hcl:fdcda3\n\niyr:2015 byr:1954 ecl:blu hgt:62in hcl:#ceb3a1 pid:253593755 eyr:2028\n\neyr:2025 ecl:blu pid:216388098 iyr:2017 byr:1968 hgt:151cm hcl:#602927\n\neyr:2022 hcl:#a97842\npid:606979543 iyr:2013 ecl:grn cid:63\nhgt:186cm byr:1992\n\necl:gry\nhgt:168cm hcl:#18171d iyr:2017 pid:670898814 byr:1983\neyr:2022\n\nhgt:155cm ecl:grn iyr:2012 pid:837979074 eyr:2024 hcl:#888785 byr:1972\n\niyr:2015 pid:970743533 hcl:#866857 eyr:2027\nbyr:1921 ecl:brn\n\neyr:2022\nhgt:160cm\nbyr:1964 hcl:#efcc98 iyr:2019 ecl:oth pid:141923637\n\nbyr:2029 pid:3313111652 ecl:brn eyr:2034\niyr:2013 hgt:193cm hcl:z\n\npid:853890227 eyr:2029\nhcl:#efcc98 iyr:2021 byr:2003 ecl:#037c39 hgt:160cm\n\niyr:1927\nbyr:1992\neyr:2030\nhcl:#efcc98\necl:amb hgt:152cm pid:436765906\n\niyr:2014\nhcl:#c0946f pid:207052381\neyr:2024 ecl:hzl\nhgt:177cm\nbyr:1923\n\necl:blu\niyr:2014\neyr:2025 hgt:165cm\nhcl:#733820 pid:343011857 byr:1967\n\necl:xry\neyr:2028\niyr:2011 hgt:166in hcl:#c0946f\npid:805297331\ncid:167 byr:1926\n\nbyr:1947\npid:468012954 eyr:2026 ecl:oth iyr:2018 hgt:170cm hcl:#b6652a\n\nhcl:#6b5442 ecl:brn\nhgt:180cm cid:233\npid:029789713\nbyr:1920 iyr:2010 eyr:2024\n\niyr:2010 eyr:2027\nhgt:156cm\nhcl:#c0946f\nbyr:1960 pid:312723130 ecl:hzl\n\neyr:2023 byr:1959 iyr:2010 hgt:186cm pid:066768932 ecl:grn hcl:#602927 cid:310\n\neyr:2030 pid:460535178 hgt:171cm ecl:gry iyr:2020 byr:1934 hcl:#888785\n\nhgt:64cm eyr:2021 byr:1995 cid:336\necl:gmt pid:926714223 iyr:2017 hcl:#18171d\n\neyr:2022 iyr:2010\necl:grn pid:285994301 cid:215\nhgt:186cm byr:1978\n\nhgt:63in hcl:#866857\npid:386128445 iyr:2020 byr:1971 eyr:2021 ecl:gry\n\nhgt:183cm hcl:#733820 iyr:2015\necl:blu pid:216205626 eyr:2022 byr:1941\n\ncid:150 ecl:amb pid:872515243 byr:1926\neyr:1996\nhcl:#dedc39 hgt:67in iyr:2020\n\nbyr:1927 ecl:brn cid:153 iyr:2011\npid:165190810 hcl:#fffffd\neyr:2028 hgt:64in\n\npid:502603734\nbyr:1966 iyr:2015 hgt:176cm cid:205 ecl:brn hcl:#fffffd eyr:2021\n\nhcl:#18171d hgt:158cm byr:1943 iyr:2019\npid:058840094\neyr:2023\n\nbyr:1962 hcl:#b6652a ecl:grn\ncid:297\niyr:2010 pid:990422650\nhgt:154cm eyr:2020\n\neyr:1934 iyr:2011\necl:gry\nhcl:z byr:2004 hgt:63cm pid:6173356201\n\npid:329432364 eyr:2029\necl:grn hcl:#18171d iyr:2013\nhgt:158cm byr:1960\n\nhcl:#efcc98 iyr:2016 hgt:186cm cid:215\npid:852781253 eyr:2027 ecl:blu byr:1937\n\nhcl:#623a2f ecl:gry iyr:2020 byr:1972 hgt:182cm pid:073426952 eyr:2027\n\nhcl:#3317b9 byr:1950 pid:304511418 hgt:177cm cid:124 eyr:2020 ecl:hzl iyr:2014\n\neyr:2029\npid:034754507 byr:1936\ncid:265 ecl:#b50997 hgt:183cm\nhcl:#623a2f iyr:1924\n\neyr:2024 byr:1927 cid:243 ecl:gry hcl:#6b5442 pid:714355627 hgt:160cm\niyr:2016\n\nhgt:152cm\necl:gry hcl:#a97842\neyr:2029 byr:1952\npid:555308923 iyr:2010\n\nbyr:2008\npid:19681314 hgt:180in iyr:2030 ecl:gry cid:272\neyr:2023\nhcl:#b6652a\n\ncid:234\niyr:2014 byr:1940 ecl:hzl pid:042231105 hcl:#3bf69c hgt:172cm eyr:2029\n\nhcl:#efcc98 pid:831567586 hgt:190cm iyr:2017\nbyr:1966 eyr:2024 ecl:blu\n\nhcl:#341e13 ecl:blu\neyr:2022 cid:161 pid:197839646 iyr:2014\n\nhcl:#cfa07d\nbyr:1957\niyr:2019 hgt:181cm\npid:543775141 ecl:oth eyr:2021\n\nhcl:z\npid:#596c41 eyr:2035\nbyr:2008 iyr:1975\necl:#c66ee6\nhgt:150in\n\necl:grn\nhcl:#7d3b0c iyr:2016\npid:804255369 eyr:2028 byr:1983 hgt:69in cid:82\n\neyr:2022\niyr:2013 hgt:191cm ecl:gry\nhcl:#a97842 pid:186827268 byr:1969\n\npid:871672398 eyr:2026 byr:1946 ecl:oth\niyr:2015\nhcl:#866857 hgt:185cm\n\nbyr:1973\nhgt:150cm\npid:905076707\niyr:2017\nhcl:#2edf01 ecl:oth cid:221 eyr:2026\n\neyr:2024 ecl:grn pid:955444191 hcl:z iyr:2015 byr:2008 hgt:151cm\n\nbyr:1958 hcl:#fffffd pid:218986541 cid:203 ecl:brn hgt:154cm\niyr:2014\neyr:2026\n\nhcl:#623a2f byr:1964 ecl:oth iyr:2010 pid:525843363 hgt:164cm eyr:2025\n\necl:blu iyr:2013 hgt:193cm byr:1990 pid:612387132 hcl:#18171d cid:280 eyr:2028\n\necl:oth eyr:2022\npid:110447037 hgt:187cm byr:1967 hcl:#efcc98\n\nbyr:1930\neyr:2026 hgt:159cm\niyr:2011\necl:hzl hcl:#6b5442 pid:923471212\n\ncid:350\neyr:2029 pid:823592758 iyr:2018\necl:grn byr:1972 hgt:167cm hcl:#18171d\n\ncid:76 eyr:2027 hcl:#6b5442 pid:099579798 byr:1930\niyr:2020\necl:gry hgt:153cm\n\nbyr:1957 ecl:brn\nhcl:z iyr:2016 pid:352677969 hgt:189cm\neyr:2029\n\ncid:143 eyr:2035 pid:602952079\necl:#9b73f0 hcl:#602927\niyr:2022 byr:1975\nhgt:174cm\n\nbyr:1971 pid:741305897 hgt:192cm\necl:amb hcl:#888785 eyr:2028 iyr:2011\n\necl:oth iyr:2016\nbyr:1942 hgt:189cm hcl:#888785 eyr:2024 pid:054290182\n\nhcl:#a97842\nbyr:1945\necl:amb pid:370849304\neyr:2028\niyr:2016 hgt:168cm\n\nhgt:154cm iyr:2015 eyr:2030 byr:1952 ecl:hzl hcl:#341e13 pid:996518075\n\nbyr:1941 ecl:amb iyr:2014\nhcl:#fffffd pid:560990286 eyr:2022 hgt:173cm\n\necl:blu byr:1974\nhgt:150cm hcl:#ceb3a1 eyr:2020 iyr:2013\npid:827415351\n\nhcl:#623a2f eyr:2027 iyr:2011 pid:913199234 ecl:oth\nbyr:1990 hgt:178cm\n\necl:blu byr:1989 hcl:#b6652a\neyr:2026 pid:724881482 hgt:185cm iyr:2014\n\ncid:115 pid:255002731 eyr:2025 ecl:amb\nbyr:1934 iyr:2020 hcl:#7d3b0c\n\nhgt:150cm byr:1969 ecl:blu iyr:2023\nhcl:#866857 pid:754288625 eyr:2029\n\niyr:2011 hcl:#7d3b0c ecl:hzl\nbyr:1930\nhgt:188cm\neyr:2023\npid:256556076 cid:136\n\niyr:2025 byr:1978\necl:#fe30a9 hcl:#efcc98 eyr:2029\npid:392032459 hgt:178cm\n\neyr:2027 iyr:2017 hgt:160in\nbyr:1990 pid:131099122 hcl:#623a2f ecl:amb\n\necl:grn\nbyr:1978\neyr:2029 hcl:#18171d\nhgt:165cm pid:172369888\ncid:93\niyr:2011\n\necl:hzl\nhcl:#733820 iyr:2010 eyr:2029 pid:127253449\nhgt:156cm\nbyr:1963\n\nhcl:#6c8530\niyr:2020\nbyr:1929 eyr:2021 hgt:177cm ecl:oth pid:347925482\n\neyr:2037 iyr:2026\npid:163cm\nhgt:174in byr:2007 hcl:c1305f cid:134\necl:#0cf85c\n\niyr:2011 pid:033811215\nhcl:#a97842 byr:2002 eyr:2021 hgt:186cm\necl:brn\n\nhcl:#a97842\niyr:2020 eyr:2029 byr:1972 pid:535511110 hgt:160cm ecl:oth\n\necl:grn cid:89 hgt:193cm pid:73793987 iyr:2021 eyr:2027 byr:1939 hcl:z\n\nhcl:#623a2f\nhgt:182cm cid:154\npid:873863966 iyr:2018 byr:1999 ecl:brn eyr:2031\n\niyr:2014 eyr:2029\ncid:71 hcl:#fffffd byr:1924 hgt:63in\necl:gry pid:897972798\n\nhgt:76cm\nhcl:z eyr:1955\niyr:2012 byr:2001 pid:9425090 ecl:hzl\n\neyr:2021\npid:501861442\necl:grn hcl:#d71ae9\nbyr:1977\nhgt:167cm iyr:2015\n\niyr:2014\nhgt:170cm ecl:gry byr:1928 cid:314 hcl:#602927 eyr:2029\npid:836710987\n\neyr:2027 hcl:#efcc98 ecl:amb iyr:2016 byr:1995 pid:603705616 hgt:179cm\n\neyr:2030 hcl:#602927 cid:105 byr:1943 ecl:hzl\npid:381601507\nhgt:188cm iyr:2020\n\niyr:2011\nbyr:1993 hcl:#c0946f pid:292649640 hgt:139 ecl:hzl cid:268\neyr:1999\n\ncid:339 byr:1928\necl:brn eyr:2022 hcl:#733820 hgt:191cm pid:282733347 iyr:2019\n\nhgt:176cm\nbyr:1935 ecl:brn cid:252 eyr:2023 pid:105060622 iyr:2020 hcl:#18171d\n\necl:hzl eyr:2029\nhgt:193cm pid:770254253\nhcl:#efcc98 iyr:2020 byr:1926\n\npid:977785261 eyr:2022 iyr:2015 byr:1978\nhcl:#733820 hgt:172cm\necl:brn\n\nbyr:2021\nhgt:160in\necl:gmt\neyr:2032 cid:345 pid:179cm\nhcl:8f5c13 iyr:2029\n\niyr:2018 hgt:182cm ecl:gry\npid:897076789 eyr:2023 hcl:#866857\nbyr:1980\n\nhgt:88 eyr:2039 cid:99 byr:2007 hcl:a1bb42 ecl:#a2f6bb\npid:2264966188\niyr:2022\n\niyr:2012 cid:59 ecl:gry eyr:2021\nbyr:1931\nhgt:172cm hcl:#7d3b0c pid:862416147\n\nbyr:1962 eyr:2025\necl:grn\nhcl:#866857 hgt:180cm iyr:2014 pid:313647071\n\neyr:2030 hgt:157cm byr:1985\niyr:2020\nhcl:#7d3b0c pid:911544768\necl:grn\n\nhgt:175cm\nbyr:1938\niyr:2020 ecl:amb hcl:#602927 eyr:2026 pid:144411560\n\niyr:2019 ecl:amb hcl:#888785 eyr:2025 hgt:187cm\npid:942054361 byr:1939\n\ncid:168 pid:722146139 byr:1952 ecl:grn\niyr:2014 hgt:97\nhcl:z\neyr:2023\n\neyr:2024 pid:567528498 ecl:gry iyr:2012 byr:1990\nhcl:#733820 hgt:193cm\ncid:293\n\nhcl:#bc352c pid:321838059 byr:1930 hgt:178cm cid:213 eyr:2023 ecl:amb\niyr:2017\n\nhgt:173cm byr:1925 pid:070222017 iyr:2013 hcl:#ceb3a1 ecl:gry eyr:2024\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_04_b_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 04, Part Two\n-----------------------------------------------------\n--  Passport Processing\n--\n--  Full Ada version.\n--\n--  https://adventofcode.com/2020/day/04\n--\nwith Ada.Characters.Handling, Ada.Strings.Fixed, Ada.Text_IO;\nwith Interfaces;\n\nprocedure AoC_2020_04_b_Full_Ada is\n  use Ada.Characters.Handling, Ada.Strings.Fixed, Ada.Text_IO, Interfaces;\n  --\n  function Val (s : String) return Integer_64 is\n  begin\n    return Integer_64'Value (s);\n  exception\n    when others => return -1;\n  end Val;\n  --\n  type Cat is (byr, iyr, eyr, hgt, hcl, ecl, pid);\n  ok : Boolean;\n  f : File_Type;\n  cats, cat_idx, total : Integer := 0;\n  tok_begin, tok_end : Integer;\nbegin\n  Open (f, In_File, \"aoc_2020_04.txt\");\n  while not End_Of_File (f) loop\n    declare\n      s : constant String := Get_Line (f);\n    begin\n      if s = \"\" then\n        cats := 0;\n      end if;\n      for c in Cat loop\n        cat_idx := Index (s, To_Lower (Cat'Image (c)) & ':');\n        if cat_idx > 0 then\n          tok_begin := cat_idx + 4;\n          tok_end := Index (s, \" \", tok_begin);\n          if tok_end > 0 then\n            tok_end := tok_end - 1;\n          else\n            tok_end := s'Last;\n          end if;\n          declare\n            tok : String renames s (tok_begin .. tok_end);\n          begin\n            case c is\n              when byr => ok := Val (tok) in 1920 .. 2002;\n              when iyr => ok := Val (tok) in 2010 .. 2020;\n              when eyr => ok := Val (tok) in 2020 .. 2030;\n              when hcl => ok := Val (\"16\" & tok & '#') > 0;\n              when pid => ok := tok'Length = 9 and then Val (tok) > 0;\n              when ecl => ok := Index (\"amb blu brn gry grn hzl oth\", tok) > 0;\n                                --  ^ Idea: Maxim Reznik, replaces checking each value\n              when hgt =>\n                ok :=\n                    ((Val (s (tok_begin .. tok_end - 2)) in 150 .. 193\n                                 and then s (tok_end - 1 .. tok_end) = \"cm\")\n                      or else\n                     (Val (s (tok_begin .. tok_end - 2)) in 59 .. 76\n                                 and then s (tok_end - 1 .. tok_end) = \"in\")\n                    );\n            end case;\n          end;\n          if ok then cats := cats + 1; end if;\n        end if;\n      end loop;\n      if cats = 7 then\n        total := total + 1;\n        --  Prevent incrementing total if there is garbage\n        --  or a \"cid:\" until next blank line:\n        cats := 0;\n      end if;\n    end;\n  end loop;\n  Close (f);\n  Put_Line (\"Valid passports (criteria #2):\" & Integer'Image (total));\nend AoC_2020_04_b_Full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_05.adb",
    "content": "--  Solution to Advent of Code 2020, Day 5\n-------------------------------------------\n--  Binary Boarding\n--\n--  https://adventofcode.com/2020/day/5\n--\n--  Binary space partition in the plane for\n--  locating seats.\n--    F means \"front\", B means \"back\",\n--    L means \"left\", and R means \"right\".\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_05 is\n  f : File_Type;\n  x : Character;\n  max, id, r, c, b : Integer;\n  test_mode : constant Boolean := Argument_Count >= 1;\nbegin\n  max := 0;\n  Open (f, \"aoc_2020_05.txt\");\n  while not End_Of_File (f) loop\n    r := 0;\n    b := 64;\n    for i in 1 .. 7 loop\n      Get (f, x);\n      if x = 'B' then\n        r := r + b;\n      end if;\n      b := b / 2;\n    end loop;\n    c := 0;\n    b := 4;\n    for i in 1 .. 3 loop\n      Get (f, x);\n      if x = 'R' then\n        c := c + b;\n      end if;\n      b := b / 2;\n    end loop;\n    id := r * 8 + c;\n    if id > max then max := id; end if;\n    exit when End_Of_File (f);\n    Skip_Line (f);\n  end loop;\n  Close (f);\n  if test_mode then\n    if max /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Maximum seat Id in the plane = \" & max);\n  end if;\n  --  Part 1: validated by AoC: 835\n  --  Part 2: validated by AoC: 649\nend AoC_2020_05;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_05.txt",
    "content": "FFFFBFBLLR\nBFBFFBBLLR\nBBFFFFBLRR\nFBFBFFFRLL\nBFFBFFFRRR\nBFBFBFFRLR\nFFFBBBBLRL\nBFFFFBFLLL\nFFFFBBFLLR\nBBFFBFFRRR\nFBBFBBFLRL\nBFBFFBFLRR\nFBFFBFFLLL\nFFFBFFFRLR\nFFFBFBBLLR\nBBFFBFFLRL\nFFFFFBBRLR\nBFFBFBBLLR\nFFBBBBBLRR\nFBBFFBBLLR\nFFFFFBBLLR\nFBBFFFBRLR\nFFBFBBFRRR\nFBBFFFFLRL\nFFBFBBFLLR\nBFBBBBFRRL\nFFFFBBBLLR\nFFBFFFFRLL\nFFBBFFBLRL\nBBFFFBBRLR\nFBBFBBFRLL\nFBBBFBFRRR\nFBBBBBBRLR\nBFBBFBBRRL\nFBBBBFFRLR\nFBFBFBBLLL\nFBBFFFBLRL\nBFFBBBFRLL\nFFBFFBBLLL\nFFFFFFBRLL\nBFFBFBFRLR\nFBBFBBBRRL\nBFBFBFFLLR\nBFBFBFBRLL\nFBFBBBFLRL\nFBFFFBFRLR\nFBBBBBBRRL\nBFBBFFBLLL\nBFFFFFBLRR\nBFFBFFFLRL\nFBBBFFBLLL\nBFBFBFFLRR\nBFBFBFFRRL\nFBBBFFFLRR\nFFBBFFBRLL\nBFBFFFFLRR\nFFFFBBFRRL\nFFFFBBFLRL\nBFFBBFBRRR\nFBFBBFBRRR\nFFBFFBFLLR\nBFFFFBBLRL\nFBBFBFFLRR\nBFFBFBFLLL\nBFFBFBFRRR\nFBBBFFBRLL\nFBFFFBBRRL\nBBFFBFFRRL\nBBFFBBFLLR\nBBFFFBBRLL\nFFFBFFBLRL\nBBFFFFBRRR\nFBFBBFBRLR\nBFBBFBFLLR\nFFBFFFFRLR\nFBBFFFBRRR\nFFFBFFFLLL\nFFBBFFFRLL\nFBBBBFBLRR\nBFFFBFFRLR\nFFFBBFBRRL\nFBFFBBBLLL\nFBFFBBFLRR\nBFFBFFBRLR\nFBBBBFBRLR\nBFBBBBFRRR\nFBBFBBFLLR\nFBBBFBBLRR\nBFFFBFFLRR\nFFBBBBFLRR\nFBFBFFFRRR\nFBBFFBFLRL\nFBBFFFFLLL\nBFFFBBBRRL\nFFBBBFFLLL\nFFFBBBFLRL\nFBBFFBBLRL\nBFFFFFFRLL\nBFBBFBBRRR\nFBBBBBFLRL\nFFBFFFFLRR\nFBFFBBFRRR\nFFBBFBBRLL\nFBFFBFBLLR\nFFBBFFBLLL\nFBFFFBBLLL\nFBFBBFBLLR\nBFFBFBFLLR\nFBFBBFFLLR\nBFBFBFBRRL\nBFBFFBBRRL\nFFBFFBFLRL\nFBBFBFFLRL\nFBFFFBBRRR\nBFBFFFFRLR\nBBFBFFFLRR\nBFBBFFFLRL\nFFBFBFBLRR\nBFFFBBBLRL\nFBBFBFBLRR\nFBBFFBBRLR\nBFBBBFBRRL\nFBBBFBBRRL\nBFBFBBFLLL\nFFBBFBBLRL\nFBBBFBFLLL\nBFFBFFBLLR\nFFFBFBBRLR\nFBFBFBFLRR\nBBFFBBBRLL\nBFBBFBBLRR\nBFBFFBFRLL\nFBBBBBFRLL\nFBFFFFBRRR\nFFFBFFBLLL\nFFFBFFBLLR\nBFFFFBBRLL\nFBBFBBBLRR\nBFFFBBBLRR\nBFBBFBBRLL\nFBFBBFBLLL\nFFBBFBBRRR\nBBFFBFBRRL\nFBFFFFFLRR\nFFBBFBFRRL\nBFBFFBFRRR\nFFBFBBFRLR\nBFBBBFBLLL\nFBBFBFBRLL\nBFBFFBBRRR\nBFFBBFBLLL\nBBFFFBFRRR\nFFFBFFFRRL\nFFFBBFFRLL\nBFFFFBFRLR\nBFFBFBFRRL\nFBFFFFFLLR\nFFFFFFBRRR\nBBFFFFFLRR\nFBFBFFBRLL\nFFBFBFBLLL\nFBFFBFFRRL\nFBBBFFFRLL\nBFFFFBBRRL\nBFFFFBBRLR\nFFFFBFFRLL\nBBFFFFBLRL\nBBFFBFFLLL\nFBFFBBFLLL\nFFFBFBFLLL\nBFBFFFBLRL\nBFFFFFFRLR\nBFBBBBBLLR\nFBBBBFBRRR\nFFFFFBBLRR\nFBFFFBBRLR\nFBFFBBBRRR\nBFBFFBFLRL\nBBFFFFBRRL\nFFFBBBBLLR\nBFFFFFBLLL\nBFFBFFFLRR\nFBFFFFFLRL\nFFFBBFFLLR\nBFBBBFFLRR\nFFBBFFBRRR\nFFFFBFBRRL\nFBBFBBBLLL\nBFBFFBBLRL\nBFBFBBFRLL\nBFFBBBFRRR\nBFFFBBFRRL\nFFFFBBBLLL\nBFFFFFFLLR\nFFBBFFBLRR\nBFBFFBBLRR\nFBFBFBBLRR\nBFBFFFBLRR\nFBBBFBFLRR\nFFBBFFBRLR\nBFFBBBBRRR\nFFFFBBBLRR\nBBFFBBBLRL\nFBBBFBFRRL\nFFBFBBFLRL\nFFBBBFBRRR\nFFFBFBFRLL\nFBFFFFBLLL\nFBFFBBBLLR\nFFBFBBFLLL\nBFFBBFFRLL\nFFFFFBFRRL\nFBBFBBBLRL\nFBBBFFBLRR\nBFFFBBBRLL\nFBFFFFFRLR\nBFBBBFFLLR\nBBFFBBBRRR\nBFBFFFFRLL\nBBFFBBFLRR\nBBFFBFBLLR\nFBBFFFFRRL\nBFBBFBFRRL\nFBFFBBBLRR\nBFBBFFBRLL\nBBFFBBFRRL\nBBFFBFBRRR\nFFFBFBFLRL\nFBFFFFFRLL\nBFFFBBFLLL\nFBBFFBFLRR\nFBFBBBBRRR\nFBFFBBFRLR\nFBBBFFFRRR\nBFFFBBFRRR\nFFBFBFBRLL\nBFBFBFBLRR\nBBFFBBBLLL\nBFFBBBBRLL\nFBFBFBFLLR\nFBBBBBBLLR\nBFBFFBBRLL\nFBFBFFBLLR\nBFFBBFBLRR\nBFFBFFFLLL\nFBBFBBFRLR\nFFFBFBFLLR\nBFFBBFBLRL\nFFFFBBBRLR\nFFBFFFBRLR\nBBFFFFFRLL\nBFFBBBFLRR\nBBFFBBFRLR\nFBFFFFFRRR\nFBBFBFBRLR\nFFFBFFFRLL\nBFBBFFFRRR\nFFFFFBBRRL\nFBBFFFBRLL\nFBBBBBFRLR\nBFBBBBFLLL\nFBFFFFBRRL\nBBFFFFFRLR\nFFFBFBBRRR\nBFBBBFFRRR\nBFBFBFBLLL\nFFFFBFBLLL\nFBFBFFBLRR\nBFFFBFFLRL\nFFFFBFFLRR\nFBBFBBBRRR\nBFBFBBBLRR\nBFFBFBBRLR\nBFBFBBFLRR\nFFFBBFFRLR\nBFFBBBBRLR\nFBFBFFBLRL\nFFFBBBFRLL\nBFBFBBBRRR\nFFFBFBBRRL\nFFBFBBBRLL\nFBFBBBBLRL\nBFFBBFFRLR\nBFFFBFBLLR\nBFFBBBBLRR\nFFBFFBFLLL\nFFBFBBBLRR\nBFFFBBFLRR\nBBFFBBFLRL\nFBBFFFBLRR\nFFFBBBFLLL\nFBBFBBBLLR\nBFFFFBFLRL\nBFFBFBFLRR\nFBBFFFBLLL\nBFBFBBFRRR\nFFFBBFFLRL\nFBBFFBBRRL\nFBFBFFFRRL\nFBFFBFFLLR\nBFBBFBBRLR\nBFBFBFFRLL\nFFBFFBBLRR\nFBFFBBFRRL\nFBFBFFFRLR\nFBFBFBBRLL\nFFBBBFBLRL\nFBFFFBFRRL\nBFFBFFBRRL\nFFBBBBBRLL\nFFFBBBBLRR\nFFFFBFFRRR\nFBBBBFBRLL\nBBFFFBFLRR\nFBFBFFBRRR\nFFBBBFFRRR\nFBBFFBFRRR\nBFBFBFFRRR\nFFFBBFBRRR\nFBBFBFFLLL\nFFBBFFFLLL\nFFFBFFBLRR\nFFFBBBBRRR\nFBFFBFFRLL\nFBFBFFBLLL\nFFFBFFFRRR\nFBBBBFFLRL\nBFBBFFFRRL\nBFBBBFFLLL\nBFBBFFFLLR\nBFFFBFBRRR\nFFFFBBFRLR\nBFFFFFBRRR\nBFFBBBFLLL\nFBFFFBFRRR\nFBFFFFBLRL\nFFBFFFFLLL\nBFBFBBFLLR\nFBBBBFFLRR\nFFBBBFBRLL\nBBFFFFBRLL\nBFBBFBFLRR\nBBFFBFBLRR\nBBFFBBFRRR\nBFFFBBFLLR\nFFBBBFFRLL\nFFBFBFFLLR\nFFBFFFBRLL\nFFFBBFFLLL\nBFBBBFBRRR\nFFFBFFBRLR\nBBFFFBBRRR\nFFBFBBBRRL\nFFBFFBBRLL\nFFFBBBFLRR\nBFBBBBFLLR\nBFBFFFBLLL\nBBFFBBBLLR\nBFFBBFFLRR\nFBFFBFBLRR\nFFBFBFFLLL\nFFFBBBBLLL\nFFFFBBBLRL\nBBFFBFFLLR\nBFBFBBFRLR\nBFFFFBFRLL\nBFFFFBBRRR\nFBFFFBFLLR\nBFFFBBFRLR\nFBBFFBBRLL\nFBBBBBBRRR\nFFBFBFFLRR\nFFBFFFBLLR\nFFFFBBBRLL\nFFFBBBFRLR\nFBFBBBFRRL\nBFFFBFBRLR\nFFFFBBBRRR\nFFFBFFFLLR\nFBBFFBFRRL\nFBBBBBBRLL\nFBBBFFBLRL\nBFFBFFFRRL\nFBFBBBBLLR\nFBFBBFBLRL\nBFFFFFBLLR\nBFBBBFBRLR\nBFFBFFBRRR\nFBFFBFBRRR\nBBFFBBFLLL\nFBFBBBFLLL\nFFBBBBBLRL\nFBBFBBFLLL\nFBBBFFFRLR\nFBFBFFBRRL\nFBBFFBBLRR\nFBBBFBBLRL\nBFFBBBFRLR\nFFFFBBFRLL\nBFFFBFBLRR\nFBBBBBFRRL\nFBFBFFFLLR\nFFBBBFFLLR\nBFBBBBBRLR\nBFBBFBBLRL\nFBBBFBBRLL\nFBFFBBBRLR\nFBFFBBFRLL\nBFBFFFBRLL\nFBBBFBBLLL\nBBFFFBFLRL\nFBFFBFBRLR\nFBFBFBFRLL\nFFBBBFBRRL\nFFBFFFBRRL\nBFBFBFFLLL\nFFBFFBBRRL\nBFBBFBBLLR\nBFBBFFBRLR\nBFFFFFFLLL\nFBFBBBBRRL\nBFBBFFFLLL\nFFFFFBFLRR\nBBFFFBFLLR\nFFBFFFBLRR\nFFBBBBBRLR\nBFBFBBBLRL\nBFFFFFBRRL\nFFBBFFFLRR\nBBFFFFBLLR\nFBBBFFFLLR\nFBBFFBFLLR\nFBBFFBFRLL\nFBFFFBBRLL\nFFBFFFFRRR\nBBFFBFFLRR\nBFFBFBBLRR\nFFBBBFBLLL\nBFBBBBFLRL\nBBFFFBFLLL\nFBBFBBFRRR\nFFBBFFFLRL\nFBBFBBFLRR\nBFFBFFFRLR\nFFBBFBFRLL\nFBFBFBFLRL\nBFBFBBFRRL\nFFFFBFFRLR\nBFFFFFFRRL\nFFFFFBBRLL\nFBFBFFBRLR\nFBFBBFFRLR\nFFFFBBFRRR\nFBFBBBBRLL\nFFFBBBBRLR\nFBBFBFFLLR\nFFFBBBFRRL\nBFBFFFFLRL\nFFBBBFFRLR\nBFBFBFBLLR\nFFFFBFBLRL\nFBFBFFFLRL\nBFBBFBFRLL\nFBBBBFBLLR\nFBFBBBBRLR\nFFFBBFBLRL\nFBFFFBBLRL\nFBFFFFFRRL\nFFBBBBFLLR\nFFFBBFBRLL\nFBFBFBFRLR\nFFFBBFFRRR\nBBFFFBBLRL\nBFFBBBBLLL\nBBFBFFFLRL\nFBFFBBFLRL\nBFFFFFFLRR\nFFBBFFFRRL\nFFFFFBBRRR\nBFFFBFFRRR\nBBFFFFFRRR\nBBFFFBFRRL\nFBBBFBFLLR\nBFFBBBBLLR\nFFFFFFBRLR\nFBBBFBBRRR\nFFBFFFBRRR\nBFFBFFBLRL\nBFBFFBFRRL\nFBFBFBBRLR\nFFFBFBBLRL\nBFBBBFFRLR\nFBFFBFBRLL\nFFFFFBBLLL\nFFFFBFFRRL\nFFBBBBFRLL\nFBBBFFBRRR\nBBFFFFBLLL\nBFBBFFFRLL\nBFBFFFBRRL\nFBBFBBBRLL\nFFBBFBFRLR\nFFFBFBFRRR\nBFFBBFFLLL\nBFFBBBFRRL\nBFBFFFFRRL\nFBFBFBBLRL\nFBFBBFFRRR\nFBFBBBFRLR\nFFBFBBBLLL\nFFFBBBFLLR\nFFBFBFBRLR\nFBFBBFBRLL\nFBBFBFBRRL\nFBBBBBFRRR\nFBBBBFBRRL\nBFFFBFBRRL\nFFFFBFFLLL\nBFBBFBFLLL\nBBFFFBBLLL\nFBFBBBBLRR\nBFFBBBBRRL\nFBFFFFBRLR\nFBFFBBBRRL\nFFFBFFFLRR\nFBBFFFFLRR\nBFFBFFBLRR\nFFBFBFBRRR\nFBFBBFBLRR\nBFFFFBFLRR\nBFBBFFBLRL\nFFBBBBBLLR\nFBBBFBBLLR\nFFFBBFFLRR\nFFBFFFFLRL\nFFBBFBFLRR\nFBFBBBBLLL\nFBBFFFBRRL\nFFFBFBFLRR\nBFFFBFFLLR\nBFBFFBFLLL\nBFBFFFFRRR\nFFFFFFBLRR\nFBFFBFBLRL\nFBBFBFFRRR\nFBFFBBBLRL\nFBFFBFBLLL\nFFBFBFFRLR\nFFBFBBBRRR\nBFBBBFBLLR\nFFBBBFFLRR\nFBBBBBFLLR\nBFFBFBFLRL\nBFFBBBFLRL\nFFBFFFBLRL\nBBFBFFFLLL\nFBBBBBFLRR\nFFBFBFFRLL\nFFFFBFBRLR\nFBBFBBBRLR\nFFFBBBBRLL\nBFBFBBBRLR\nFFFFBBFLLL\nFBBFBFFRLL\nFFBFBFFRRR\nFBBFFBBRRR\nBFBBFFBRRL\nBFBBBFFRLL\nBFFFFFBRLR\nFBFFBFFRLR\nFFBFBFBRRL\nBBFFBBBRLR\nFFBFBFFLRL\nFFFBFBFRLR\nBBFBFFFLLR\nFBBFFBBLLL\nBFFFBFBLLL\nBFFBBFFLLR\nBFFBBFFRRL\nBFBBBBBRLL\nBFBBBBFRLR\nBFFFFFBLRL\nFBBFBBFRRL\nFBBFBFBLLL\nBFFBFBBRRR\nFFBBBFFLRL\nBBFFBFFRLR\nFBBFFFBLLR\nFBBFFFFRLR\nFBBBBFBLRL\nBFFFFBBLLL\nFFBFFBBLLR\nFBFBBFBRRL\nBFFFBBBRRR\nFBBFFFFLLR\nFBFBBFFLRL\nFFBBBBFLRL\nFFFFFBFLLR\nBFFFFFFLRL\nBFFFBFFRRL\nFBBFBFFRRL\nBBFFFFFLLL\nFFFFFBFRRR\nFBBBFFBLLR\nBFFBFFBRLL\nFBFFFBFRLL\nFFFBFBBLLL\nBFBFBBBLLR\nFBBBBFBLLL\nBFBFBFBLRL\nBFFBFFFRLL\nBFBBFBFLRL\nFBBFFFFRRR\nFFBBBBFRLR\nFFBBFBBRRL\nBFBFBFFLRL\nFBBBBFFLLR\nFBFBFBBRRR\nFFBFBFBLLR\nBFFBFFBLLL\nFFBFBBFLRR\nFFBFFBBLRL\nFFBBFFFLLR\nBBFFBFBLLL\nFBFBFBFRRL\nFFBFFBBRRR\nBFFFFFFRRR\nBFBFBBBRRL\nFFBFBBBLLR\nFFBFBBFRRL\nFFBBBFBRLR\nFBFFFBBLLR\nFFBBFBFRRR\nFBFFFFFLLL\nFFFFFFBRRL\nFFBBBBFRRL\nFBFFBBBRLL\nBFBBBBBLRL\nFFBBFBFLRL\nBBFFBFBRLL\nFFFBBFBLLR\nBBFFFFFRRL\nFFBFFBFRLR\nBFFBFBFRLL\nBFBBBBBLRR\nFFBFFBBRLR\nBFFFBFFLLL\nBFBBBFBRLL\nFBBFFBFRLR\nFFBFBBBLRL\nBBFFFBFRLR\nBFFFFBFRRL\nBBFFFFFLRL\nBFBFFBBLLL\nFFFFBFFLLR\nFBFFBFFLRL\nBFFFBBFLRL\nBFBBFFBLRR\nFFFFBFFLRL\nFFFFFBBLRL\nBFBBBBFLRR\nBFBBBBBRRL\nBFFFBFFRLL\nBFBFBBBRLL\nBFBFFBFRLR\nFFFFBFBRRR\nBFFBFBBLLL\nBFBBFBFRRR\nFBFBFBBRRL\nFFBFFBFRRL\nFBBFBFBLRL\nFFBFFFFLLR\nBFFFFBFRRR\nBFFFFFBRLL\nFFBBBFBLLR\nFFBFFBFLRR\nFFBFBFFRRL\nBFFBFBBRRL\nBBFFFFBRLR\nFBBBFFFLRL\nFBFBFFFLRR\nBFFFBBBLLL\nFFFFFBFLLL\nBFBBBFFRRL\nFBFBFFFLLL\nBFBFBBBLLL\nBFBBBBBLLL\nFFBBFFBLLR\nFBBFFFFRLL\nBFBFFFBRRR\nBFFBFFFLLR\nFBFBBBFLRR\nFBBBFFFLLL\nFBBBFFBRLR\nFBBBBBBLLL\nBFBFFFFLLL\nBFFBBFBRLR\nBBFFFBBLLR\nBFBBFFBRRR\nBFFBFBBRLL\nBFBBBFBLRR\nBFFFFBFLLR\nFBBBBFFRRR\nFBFFFFBLRR\nBFBBFBBLLL\nFBFBFBFRRR\nFFFBBBFRRR\nFFBBFFFRLR\nFBBBBBBLRL\nFFFBFFBRRR\nBFFFFBBLRR\nFBFBFBBLLR\nFFBBFBBLLR\nFBBBFFBRRL\nFBFFFFBLLR\nBFFBFBBLRL\nFFFBFBBLRR\nBFBFBBFLRL\nBFFBBFBLLR\nBFBFBFBRLR\nBFFFBBBLLR\nFFFFBBFLRR\nFBBFBFBRRR\nFBFFBBFLLR\nBBFFFBBRRL\nFBFBFBFLLL\nFFFBBBBRRL\nFBBBFBFRLR\nBFFBBBFLLR\nBFBBBFBLRL\nBFBBBFFLRL\nBFFBBFBRRL\nFFFBFBBRLL\nBFFBBBBLRL\nFFFBBFBRLR\nFFBFBFBLRL\nBFFFFBBLLR\nFFFFFBFRLR\nFFFFBFBRLL\nFBFFFBBLRR\nFBBBBFFRRL\nBFFBBFFRRR\nBFBBBBBRRR\nFFBFFBFRLL\nBBFFBFBLRL\nFFFFFBFLRL\nBFBBFFBLLR\nFBBBFBFLRL\nBFFFBBFRLL\nBFBFFBFLLR\nFFBFBBBRLR\nBFFBBFFLRL\nFFFBFBFRRL\nBFBBFFFRLR\nBFBFFFFLLR\nFFBFFFFRRL\nBBFFBBFRLL\nBBFFBBBLRR\nFFFBFFFLRL\nFBFBBFFRLL\nFBBBFBBRLR\nFBBFBFBLLR\nFFBFFFBLLL\nFBFFFBFLRL\nFBBBBBBLRR\nFFBBBBFRRR\nBFBFBFBRRR\nFBFFBFFLRR\nBFBBFFFLRR\nBBFFBFBRLR\nFFBBBBFLLL\nBBFFBBBRRL\nFFFBFFBRRL\nBFFFBBBRLR\nFFBBFBFLLR\nFBFFBFFRRR\nFFFFFBFRLL\nFBFBBFFRRL\nFFBBFBBLRR\nBBFFFFFLLR\nFFBBFFFRRR\nFFFBBFBLLL\nFBFBBBFLLR\nFFFFBBBRRL\nBFBFFBBRLR\nFBFBBBFRRR\nFFBBBFFRRL\nFFFBBFFRRL\nFBFBBFFLRR\nFBFFBFBRRL\nBBFFFBBLRR\nFFBBBBBRRL\nFBFBBBFRLL\nBFBFFFBRLR\nFBFBBFFLLL\nBFBBBBFRLL\nFBBBBFFLLL\nFBFFFFBRLL\nFFBBFBFLLL\nFBFFFBFLRR\nFFFBFFBRLL\nFFBBBFBLRR\nFFBBFFBRRL\nFFBBFBBLLL\nFFBBFBBRLR\nFFFFBFBLRR\nBFBBFBFRLR\nBFFFBFBRLL\nBBFFFBFRLL\nFFFBBFBLRR\nFBBFBFFRLR\nFBBBFFFRRL\nFFBBBBBRRR\nFBBBFBFRLL\nFBBBBFFRLL\nFFBFBBFRLL\nBFFBBFBRLL\nFFBFFBFRRR\nFFBBBBBLLL\nBFFFBFBLRL\nFBBBBBFLLL\nFBBFFBFLLL\nBBFFBFFRLL\nFBFFFBFLLL\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_06.adb",
    "content": "--  Solution to Advent of Code 2020, Day 6\n------------------------------------------\n--  Custom Customs\n--\n--  https://adventofcode.com/2020/day/6\n--\n-------------------------------------------------------------------------\n--\n--  HAC 0.084 \"nice to have\"'s detected in this exercise:\n--\n--    *     ` clear := (others => False); `\n--    *     ` rg := rg and r ` for arrays of Boolean (i.e., sets)\n--    *     ` aaa : constant Character := 'a';`\n--                       HAC should detect an expression as a\n--                       static (compile-time-known) value\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_06 is\n  total : Integer;\n  new_group : Boolean;\n  subtype Answer_Range is Character range 'a' .. 'z';\n  type Yes_Answer is array (Answer_Range) of Boolean;\n  r, rg : Yes_Answer;\n  --\n  procedure Collect_Group_Total is\n    g : Natural := 0;\n  begin\n    for c in Answer_Range loop if rg (c) then g := g + 1; end if; end loop;\n    total := total + g;\n    new_group := True;\n  end Collect_Group_Total;\n  --\n  f : File_Type;\n  s : VString;\n  test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, \"aoc_2020_06.txt\");\n    total := 0;\n    new_group := True;\n    while not End_Of_File (f) loop\n      --  Collect answers from every group on the plane.\n      Get_Line (f, s);\n      if s = \"\" then\n        --  Blank line: group separator.\n        Collect_Group_Total;\n      else\n        for c in Answer_Range loop\n          r (c) := Index (s, c) > 0;\n        end loop;\n        if new_group then\n          rg := r;\n          new_group := False;\n        elsif part = 1 then\n          --  Count the number of questions to which anyone answered \"yes\"\n          for c in Answer_Range loop rg (c) := rg (c) or r (c); end loop;\n        else\n          --  Count the number of questions to which *everyone* answered \"yes\"\n          for c in Answer_Range loop rg (c) := rg (c) and r (c); end loop;\n        end if;\n      end if;\n    end loop;\n    Collect_Group_Total;\n    if test_mode then\n      if total /= Integer_Value (Argument (part)) then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n    else\n      Put_Line (+\"Part \" & part & \".  Total customs answers: \" & total);\n      --  Part 1: officially validated by AoC: 6532\n      --  Part 2: officially validated by AoC: 3427\n    end if;\n    Close (f);\n  end loop;\nend AoC_2020_06;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_06.txt",
    "content": "qtmdwspah\nsqwdamhpt\nphwdaqsmt\nstmdqwhap\npqawdhtms\n\nbgsickuztovfwa\nyiozauvgfsbtkwc\nzygijavmtfkcuwobs\nfvsuwtiadzrncboklg\n\ndxgieku\ndihnxkgf\n\nmqybtd\nyqbtd\nbtydq\n\nrgpbcfxtzoewy\notbyrfgwxzpec\nyocrwtebzxgfp\n\nqcpngeodrszaky\nocaqrngsyuz\n\nxwenu\nnwsxuye\n\nxapwvhsktlmr\ntwpslarxhvkm\nvhlwmrapxkts\npmkxraswvlth\nksrxpvtmwahl\n\nxhcepbdsltvk\nkhcdptsixbg\nspbjtdchxk\ncbkxspqtdrh\n\nkaishmtdl\njcnprqigt\n\npjqtekodlmwcaginxfzrushbv\niuyzsfaxcvrotdmklgebpnjwqh\ndirxeqbswlonhzumgafvckptj\nzqpitfrjnmhvuxbcdlwkogase\nkhncmsfdzlgwpvriotxujbaeq\n\nmotb\ntwm\nmvt\nnomt\n\neuwhdnlaxbtjiqz\ndquxjznhtlwebia\natzdwxqiunhlebj\njnwlzxdiuaheqbt\n\njnktcwaovpbqzei\nqcrljzskbvo\n\ntangojspuvlwbryeicz\neujvkaporgwdilbyfscztn\n\npjrisxqwdoyze\ncvyzmjlqxsgpeirw\nxieqwcajzslryp\nxjpzerwqyamis\n\nrftxglbkpqnchvajs\ncnsvqgpurtjfeb\n\nm\nmcx\nwramgjy\nmv\n\nmeacfoiqpbzy\nzmvqpaibegoyfc\noiyzmaengcfbpq\nuiaqprbycmzfoe\n\nqjdnecvmsr\nsdmecpqn\n\ngt\ntg\n\nbndhmeupwszlqiycofkt\nfcrptkulhixjnazvmdg\n\nnrcytwdaozvbmhsjuk\nowarihdekqzslvnxmubyfpj\nsuzlnmxvkwjyodhbrag\n\nfz\nzf\nzefpk\nfz\nfz\n\nzfnqcdhvjwxa\nhxfazjcwd\nxzhtajkfwcd\n\nweusntyxblcdqpvgfzoam\noxiyslgabqvdhnwzm\n\njneuovbpgfxlsmkwd\nkjbwonlspfdumcegthv\nomvfbgejaiwnkdulsp\norfgdlbqjkvhumpewns\n\nmhb\nhb\ndhjxb\nboh\n\naf\ntzlbugdkq\nj\n\nqhgnav\nngvahqp\ngvnqha\n\nhoer\noufeq\nu\ngmy\ntd\n\nnaguhdzsmcxlye\npglwjsvxzduc\nuosgxqzldct\nxugcszld\nqcxsgtlzoud\n\nuoxacitdkeh\nkypudjgbsefi\n\nbjywqhgcps\nuaybelqkjpiwc\nyblwqpjec\njwvyrcpbqzt\nqjgywbocp\n\ncuvwxkmrnliodphaj\nrvuzcdxknphol\nhprvkucdonsxl\n\nqtgjunkhaovbw\nwkgvotljhbq\n\nblfvtr\nvrtfby\nmbtvjdfnr\nxbftpvrh\nsvbrhptf\n\nrijakd\nkadnijer\nkqdwjifar\njdrihkmaz\nejnirkfda\n\nysukmtloxgjhvnwp\nqjxlwnvpyzsgbutomd\n\ngxpdqomijnhkyws\nvyqgxmjpowhsnik\nmnxqhgykwiopjs\n\nfm\nu\nfc\nzd\nyplnbikosxj\n\nwelcjifhgnzupo\nizfpwljnodctheg\ndtlhgznwepcojif\nhzwvgpcifnjleo\nwgpqvtcnjofhlezi\n\nazhipsvbx\nxwbip\nixpb\nxbip\nbpxi\n\nyxhpltiuvzorefqnwm\nazwiylnohxmejqurftvp\nhvuzwfxmnqyeltpro\nkwxghtdyfreqmplvzuon\n\nn\nf\na\nf\n\nxfoaj\nofsqb\neqfo\n\ncanrzup\nznarcpu\npzcnrua\nczaupnr\npuchnzra\n\nhwxtaqvsci\nrhxylbskwcjmoid\nsvqexwhaic\nwhxisc\n\nxfamongdyrhjpizqbtswl\ntsnermfbvidyqcwhlxuzg\n\njz\nzj\nzj\n\nmohrs\nrom\nmro\norm\n\nrnwbshdkxv\nvkrjwsdthnxb\nkjwrxhsvnb\nrnbhvxowas\n\nlbdahrf\nralbfhd\nlhfadbr\nradhflb\n\nwztomybdgaqhu\nrmuohgyqbdz\ndgzqrumoayhb\nhgqdmyubjpeoz\nmgdquhzoyb\n\nxiy\nyix\nbixoy\nxyi\nxiy\n\nxvzqjwfkhctgeayu\nkdjmlrow\n\nvnlu\nulnvg\nwluvn\nlvun\n\nbtmcqewifuh\ngqvakfzrmyuicsjpdbo\n\nnpfy\nyznfx\nynf\n\nb\nb\nb\nb\nb\n\nzuhkqwfpm\nmqpzwkhf\npnwfqchkzm\nkfumpqzhw\nqzwhkmpfu\n\npcevtdhgylnmsxaqiuzkr\npxanvcgiquethzksmylrd\nvdszgiqyautrpxhcnmlek\n\nbhru\nubhr\nuhvopbr\ntrbizhud\n\nomnpx\nyp\ncpf\np\n\nfuhokrpewbyvlnjcdmqi\npcijvmskndtwohxylqeurf\ncdvfhebukmjrqnolwpiy\nqpwhymlcfjrndoeuivk\n\nxwehzfud\nwupfdexz\n\nxbdh\njxdhb\n\nhmkbuyl\nrtcefpsaui\n\njlfsy\noknuy\nkvpy\n\nhcgzs\nhegzs\nsapzhd\n\nvnhjbqk\nbkvqnhjd\nvhnkqjb\njhnkqvb\nbnhjkvq\n\nmyjnp\nwkyjamn\nkmyjna\n\nrupvd\npvrud\nrpdvu\n\nkvnlmhgizwdbjsxf\nnmfdkzgjxlbvsiwh\nzmsphibqwglkejfxrvn\n\nge\neg\ng\ng\nga\n\neivbk\nvikeb\nbkiyve\n\npuvf\nfvup\nuvfp\npvuf\nfvup\n\nrydhgfbmpktzvlewjusn\nwqgfnovcerskjad\nekrfsjgvowndcxq\n\nmuco\nouse\n\npxoihbg\nbogpxhi\n\naik\nk\nk\n\nqa\naq\naq\naq\n\nsnezvhbkwa\nnvzuaksbh\nzbvalskhn\nxposdbmhnavgzk\nthvfcbznkulas\n\njaxdfucymsghp\nhfxaqcwunsjgmkpyd\nglfdjpuzxacyhm\n\nsp\nps\n\ncesof\nvsu\ns\nsvu\nsv\n\ns\nt\nte\nt\n\nepnq\noeyqn\nnqe\nqen\nqne\n\ntaxpglnzkejswbo\nzekwtongjpbxas\ngasokxnzbejpwty\nwanzsfbgpxjeotk\nwzxaengjkbptfso\n\nimftvao\nvtmif\n\npbjelcf\nprnhgwqem\n\nxopmzg\nzfoxg\nxzgo\nozxg\n\ngmcybniqevotjda\nytiebavgdqojcnm\n\nmr\nm\n\nf\nn\n\nmnhpxfircz\ncihmvrxzyf\n\nygibvxud\nykubiqxgvd\nxydibeuv\nbuvqdyxi\nbudxiyv\n\nzjpqlmftionbgu\ntzbfgjiqoumapn\nnzcjuftibompqg\naztbmoiqnjfgup\n\nchpnjmvlw\nhlbrdvqemcnwp\npnkvcmlwh\nlmcyfwpvhn\nynlmcjvipawh\n\nkzhxeqfa\nfeaxqzkh\nhzxkaeqf\nzfqhexka\nfqxahkze\n\nblwqdpy\nyqdaniplwbe\njhxbrwdylngqs\nqwtdylukzvbm\n\nasobzdl\njahzxpdy\ndaksz\nzadufl\n\nahunxksgp\nsakhpun\nnukathps\nuzhnsapk\npmusknahz\n\nyzmogwp\ntbqcp\nbnpcr\nxhp\n\ndhyxojbvrqnml\nnkr\nrnc\nwngra\n\nkmdynhutpjlvxaroce\npbwohkjtmyfnzg\ntjoikmhypnsq\n\nzduqkfivgjo\noizvjfuqbd\nzvjuqrfigdo\nvudqiozjf\noidvqyzuftj\n\nusmo\nsm\nsm\nms\n\nnjf\nf\nglft\n\nauh\nhwiavfug\n\nxevqipr\ngwxdmlsuakcyf\n\niltoavmycurph\nluhcarivtomxy\nyihcratumoevxl\nlouhcvmiytra\nmiqzdtolhrcayuvwg\n\nxwtcmqso\n\nxdnimfbyr\nokimydfr\nuhgzfyjqat\n\nevjdtmcoxiklhpgwq\nqgnxbkftmhiy\nixqrakuhngytm\n\nhfzpe\nuefphkb\nafmwhqpek\nfvpoygjinlhexds\n\noly\nbyoal\nyol\nkoly\noyl\n\nk\nk\nk\nk\nk\n\nofhrz\nxhpruzq\nzrh\nhwgrbedykvsmzin\n\nginxcsjevrwyqz\negysvqncxzrij\nsyvgzcnreqijx\nzcvxgsjrqenyi\nqyfvzirnjcgxes\n\neyxfutwoqjbrvkgds\nxsfjoutrbeqwkvgyd\nvqwtjgdbrsfoyukxe\nvfurtykqgebjwosdx\neypubrkojqvdsgtfwx\n\nodwmeztifrjxn\nnrgmwlxc\nvgkxwrlnm\n\ntz\ntz\nrtz\n\ndaze\nezyad\n\nujqdozgh\ngoujdmqkzh\njghuqdzo\ngjozdqhu\n\nerdnakojyfzchvxg\nhfekdrnctgvzpyjaxom\n\nhwi\nwih\nhiw\nhiw\n\nkrqdscaoiwhnyz\nrwjaknoxyidzsqhpc\nrnyqdawcoskifghz\nwahrqznyvdcskiuo\n\nswlakrxjmtpv\ninaylxhdjwkmsvur\nqbxavfrlewkcsjm\n\nucxvtw\nue\nu\nlu\n\noztxeqjvgb\ntpdbjgoqe\n\nspyqunh\nuypnhqs\n\nfdw\nsafw\nwfjh\nwfomxi\nlwfsdn\n\ndaibtezjo\nqtxeaizjmdb\naoejitbkzd\netadizjb\n\njkeynazqvobiflrushcwtgdmxp\nwnrjequcdxlkmtfobihsvy\niksvuebxtjwmhfrdqyocln\n\ngkxq\npkw\nkw\n\nswy\nywsn\n\njzqurhixawto\ngaojpfrzciq\nizoxrtqawj\nasoihjqzutr\n\nwijlermdyzhstf\nzjlrwfsdhmtiey\nelymwztijfrdhs\n\nqatxy\ntyq\n\nnja\nyha\na\ngfsav\nkha\n\nuebolhvntdkfsxap\nfpnlskhdeuobva\noahteupksbvdlnf\noeulbvhdpfksna\nansgphkrfdlovebu\n\nvpe\nvedp\npev\npev\npev\n\nzacfpshmrequykt\ntuzarfpmknwc\npzuimacvfktr\n\ncjeqourh\neouqcljr\nrojueqc\n\nykoi\nkoyi\nkoyi\nkiyo\n\nfvkhuntrmpz\nckngmxirpuzvat\nrfuvksnozpath\nbntdrlyvkzupj\nrukwpvtzcn\n\nwczery\neczwrby\nwrzcey\n\nxjndayl\nhnlyaxdj\nlndayxj\nynjdlaxt\n\nj\nj\nj\ntj\n\nawhrfvjbzduistx\ngnyhcmteop\n\nym\ny\nsy\nmy\n\nzkai\najiz\naiz\naiz\nikaz\n\nirgsokuwy\nlnxtcqsiwmf\nbusyvhzidw\n\nqxhpynjewsfmkd\nhwpqenfkydm\n\naedbfmx\nfwexa\njgckhspy\n\nzpusakfeb\nizpev\nsdepzu\nznpwe\npqjgehtxzr\n\nvqmlkjznbeiofahucdtsgw\nutmvhgqedbocfwkszjlain\nyfbqzaspnlgotrdjxuhvkemiwc\nidglcasthofkuemnbjwqzv\n\nuqhdebp\nchdbquepl\nqedzphbu\nhupdqbe\nqbedhpu\n\nehnv\nt\n\naksmbzu\nwvlhktdqpjmsirz\nfznykbsem\nksgmz\nkzxsymc\n\nvnoetrhlgkcmqxdp\nnvdqtkolcrhxep\npxcedrnhoiltqvk\nelrxnhitcpqdokv\n\nymuxitzqsagrkofcvbj\ntauxskfigjymro\n\ncnfdjwbxkisp\ncpydkbjxwsifn\ncipnkbufswdjrx\nybkxihfwejnscdp\n\nyueaplwitfdvkoxnbjcmrqgz\njvlfmxoakzwiegpbdnrquct\nmanwikovgbpuhrcfesjlzxtqd\n\nlptzwxfn\nfpnxtlz\nnxtflegzpj\n\ndkpuyaefsijvlrhgqxmnt\nbshiwokugpflvtmzeqxnyja\n\nin\nn\nxzou\n\nng\ngn\n\nepqbvmi\nvqembi\nbvmeqizu\nmbeqiv\n\ncjapgriulbzeq\nugiqdzcvpobjlrek\nzqleircpubjg\ncirjuqbzgepl\n\nnhpsreikdjzo\nhkjsnodipzer\nznoidphekjrs\n\ndezf\nedfz\nefdz\nrdfze\n\nnzitsqrfp\nqiznrfspt\nrfqizspnt\nnsqizrptf\n\nxntrkogqfapj\nnioagqtmrfkjyp\n\nis\nsgdi\nqsity\n\npe\nep\nep\nep\n\nuhvpiwdgsfr\nuwlpcqrezykovni\n\naevu\nae\nea\nae\n\ndjzfhxmas\nmsdxhz\nzexhdsymt\ndxzshktm\ndzemshxg\n\nmsqiuvncoltxejg\ncqxfmsonlvute\n\nwmfblsrogvjinpc\nrplfngicojbkvwms\ncfbolhnjvrsimwgk\ngmisflrwnkcjbov\nvmwrcbosjngfuil\n\nkbxitoqvzajudfnsgmyc\nikfwcxzgvtjedmsyouqnab\naqknmufjiypcvxbgodstz\n\neshyzxbqncuomfpwgk\ngzcxqpmhljeoyuikbfrn\nbzhxveutpfyaqmkcong\n\nevqyuicpfhl\nyquckvlpiejf\n\nanf\nszydm\n\nqt\nqt\nqt\n\nmfyovqgpnlbcxidauzh\ncqniopdhfgxlauvzbmy\nidxofbaylmcznuvqhpg\nqbcpihzogydlfvmnwuxa\nqgvcumyizpnabxdfhol\n\nbtwjlohyfaq\nydlwprkj\n\nrhisamcj\ncsirha\nsrcaih\nicshar\n\nmejydkgtnfovuzix\nenuvirjogdmkyxztf\nxefomztvkungysdijc\njxdginfktapovyzueqhm\nfioktdsnemgjuzyxv\n\nhrztvexlkob\nlwekirhbxdzqtmo\n\netxv\narxtvue\nexvft\n\nfwdnqsomhtryxvcgzej\neczwytuhfsgmdqnxoj\nycdsqwznhftgjmkoxe\ntsjnexcafwmhygzbvqod\n\nxovcfts\ncfsopxvdt\nxoscfvt\nosfxtvc\n\nw\nrc\nt\nzs\nik\n\nlzm\nzpl\n\nromqvb\nmvo\n\nuy\ny\ny\ny\n\ngovwliuabszqp\ngoiabwfusvzlpnq\nqpiwgbvaosulz\napvguizblwsqo\n\ns\nm\ns\ns\n\nozpiljymxhswnfuevt\nemvbwshnylzxpjti\nnveblmzchtwjiypsx\n\nnldfsb\nsfblndt\nsdblfn\nbnflds\nndslbf\n\nieg\nidew\n\nwonxsab\nwbsaoxn\nnobaxws\nwasbnox\n\nalscukjbf\nlsbjakfc\n\njxcduqioabwpyhlzef\nialdxwfzycqjhbepuo\njfzypowishadclxbueq\n\nriydchjfnwqvtmbpsaloxe\ndsbwfintzelormhvxcaqpyj\nejomaiyqsxcthfvpdlwbnr\nlrycvtunboifgxawqemhpjd\nxvtiafqrdwnoymclepbhj\n\njsydqempfvntrhui\nmiyefthpuqsrvnj\nzsvyrmhbtuelpqinfja\nnuphytvreqmfsji\n\ncltvanwuh\ntulachoyvwn\ntuwclvanh\n\nbixkgozashw\nhakibzoswmx\n\npoxkblmhqjftwsdcn\nbhtykpvzjxuiengao\n\nj\nj\nj\n\ncqodguxrzles\nloxqcrgeszudw\nocsdqruxglze\nrugqoyxesdzlcf\nulzdorxgsqec\n\nyvz\nvyz\n\nmfq\nsztdnk\npy\n\nzawgmj\njawgz\ngwapjz\nsgzajw\n\nekoadscpwhg\njsuchbxmfyzlnwq\n\nwlkrqcjux\nxuqjclr\ngjrqlcxu\n\nafcosnhvprzblxtwd\nabszvxoglnctfhpwr\nbjhlvzfwceayksxtun\ntzvnxrhwlmsfacbd\n\nigreocyhquzjmvlx\nliowjethfkqszvmxdyu\n\nljeqkvwpdazgocf\ncqgdyvmjuwpeotainsr\n\nmhoylsckuzxbiaevq\nvyczxkjeoapsbifu\nkxbdosyzavujiec\n\nmwsfxbkjqazpiohgnyldc\nxqgnadblfkwpcomshiy\nwgvsalrhqbmieyxodpfnkc\n\neurqfmtkvjbosh\nvyqrhkotfblmseu\nbrtfqkvoheums\nrvtksmehoubqf\nuwftdoarkmvqgehbcps\n\nctyalrqdxskjuoh\ndlathrokujqxs\nhxsqukdoaltjr\nosrqkautljxdh\n\nzfdlxtr\nsburlzxd\nzlrdx\n\nocfb\ncbfo\n\nuykhxqrtmnc\nahigrcuptnxdqmk\n\ntckz\nktzc\n\nvzgtxhkums\nkvzmhtgus\nsgthkzumv\nvzxsgmkuht\nznqmuhvkswgt\n\njtdwk\nydkti\nkdt\ndkjt\n\nmwxehozbnqpad\nryjdeblzwxnpoucqahmtg\n\nliumaz\nizulam\nzauloim\nmiludzaqr\n\nrzkjguslxohwnfdivm\nofulwkhisgvjmnrxzd\ndikwvojugxzfrmnlsh\nsxjdzkcuworbnvgflmih\nvlmxrzikndhwjofgus\n\nfzqnodmx\na\nv\n\nlfoeh\nleovfh\nhofsle\n\ndjku\nkjud\ndukj\n\nqtiwbxfhlzjnokvpadruymgse\nonurjdisvgzwaqkybftlhpmex\nfnmqwuhtyjrkepbgildovxasz\nmarndljbkegqxtupviscywfhzo\nfdbqehtxkavjimzwporsugyln\n\naqkonbhvfdljigp\nphaqrlkbjdin\nphldcbkaumjvinq\niplbjxeykqhdazn\n\nzsl\nsz\nxsyzh\nzs\n\nxdhlq\nndlkxjyu\nxlde\nxdl\n\nblwmairvkofcuq\ntedokrvbqm\n\npw\np\n\niqrbnglofs\ngrwuylifvkbq\n\nyl\nyl\n\nxaizpuhlqo\nkiloxm\nilkox\n\npuaorhzmtvfg\nmutoegrhzafv\n\nlrzmpt\ndpqyihnsa\n\njfiodcs\nspi\nswni\nisn\n\nohdmyvlpbxjnqzfrswiuaeg\nceafhrujqtndivbxpwzsmg\n\nmvoxyd\ntvdoymx\nxdymov\n\npy\ny\n\nnutogsehiczykpmdvf\nngmueistpxkfodhvzrcy\nyuhczioegpvmnfktsd\n\nzp\nz\nzbc\nz\nz\n\ncreyt\nuisfmova\ner\n\ndltugzhniyjro\nlizndhrutojyg\njhgnzytuordli\nlhgotuznirjydc\n\nxtrckznswlueia\nivnwstaeulrkzjc\nkcwaleiuznqrts\nrkwiunqzatsecl\n\ny\npqnae\nofm\nfl\ny\n\nczoi\nsmvbnd\ntzi\n\ntzanvx\nazgnjx\ningjzyuae\nanrhzkq\n\neqhafrbmw\nrjscmwxz\nlrgnyfeukdvmiqwpt\n\ntarsmxwveqdhjbk\nxrajvebtdmwkh\ntaojykmefwbdzrxuvnp\nwbdtmjrevakx\nctilgkbmaredjwvx\n\nwp\np\np\n\nzprwtogmdu\norwdmtzuxpg\nomwputzdgr\numgrtpwozd\nwgzdrtpmou\n\nxtkjsm\nylqptfjmk\n\npzgyknr\nkyorpngz\npnzykgra\n\nrtsiypahgecuvj\nrsudtcgjiheyvp\nrpyehvtijcgsu\ncyprhvestgjui\nuvigershtyjpc\n\njlmhtfbsoq\ngbtohjsqm\nmbstojqh\nmhkecsqtabjox\n\nxrhinjamvo\nhproxvnma\nmzscorhnx\n\nutwprfqjyhsvzaomcb\nyesrijzcagmhbwoutvpnqk\nporcxwmyutzajbhqsv\nuvrcpyzsmhajowtqb\nycpwuzovatbsmjqhr\n\nfbkgycqutlmw\nwuybgqmlcfk\nxycgbkqmulwf\nbgcfwyuqklm\n\nvntsimju\nboegqz\n\nedotgsi\ndgoism\niogds\ngdstio\nsogdixz\n\nfdi\nifd\n\nrx\nv\nx\n\nqibkwyvmtxargjldc\nbykzitxevgrwsnqflcdjm\n\ndborhtpxjsflciveyq\nxbuijhdqafnsrvepozytcl\nqhlopsdtebcjyfrixv\nhlvdyqxtcroegfjbisp\normifqdhyvxjpclebst\n\nqtzumogwrclaiex\niburltzgexdocwapq\nixuwtoqlegnrzc\nxizeklwrugtqhoj\n\niynjbsahtvfeurqkgd\nrtnwjgeukyadicflq\ndeytfqknlpjuairgc\n\noy\nto\npo\n\nwyj\nq\n\nvatgy\nxegndfrv\nsmgv\nsgzbacv\n\nifmepunrdszgh\nmvgdesianluzpfrh\neypfughdnmszitr\nnepugsfimzrdh\nfzuiqesnjcdwoxmhkpbrg\n\ngoycuvjqnpix\nytwnigvcjq\n\nbsiczfhkne\ngwxp\nojdl\na\nuvgm\n\nkaxzjpmwutcqnv\nisadmolbtrfugxyhcj\n\nvxqhfryiakbn\ntxhqbavyknri\n\nptbqifxcwyjgordls\ndbpvkeauyc\n\nkovpawxf\novwxkpfa\nxbknwjpcoaftq\noxapvfkw\n\nybjvaftkzheqgiuposnmxc\nungfezmiskqvyjaphobxtc\nyjqimsvbktaonpeucfzhgrx\nnepvgsifuqytahxzmjkocb\nqmaexzipshcvjkfyonutgb\n\nu\nu\nu\nu\n\ntpgqyvjaedlkbhwr\nnytwkpqlvmgrbehxjad\n\nvsruxht\nrdmb\nrfb\n\nkhqyd\nycj\n\naidrbmzkxvt\nyzvbkiorxamdt\n\nmzwvhblrxtn\nvqalzwcbrxjmtnd\nwlvnrtxmzcbg\n\now\now\newuob\nwo\n\ngl\nmnacgl\nlg\ngul\nkdflg\n\noqvd\nqodvy\nqdvo\nqvoda\n\nrd\nfus\nthoi\n\nrtnz\ntqagrnlb\n\nwemlvjbhuqcfrtodkxzn\npjbtruvdmhowfznlxekq\neoyadnxbuktqshgwfmvzirlj\n\nkumotnwel\nlmezwoutkn\nnuemkwlot\nefnlduohmtkw\n\nmhaubleozw\nzwulbhmo\nmhbzouwl\nhmwulbzo\n\nhvjpdoiswzbenma\nojndsepwhiq\ndwsjnhiope\ntsohjdpwien\njoipwhesnd\n\nedbhi\nfisdhbe\n\nr\nv\nv\nv\n\nezlc\nczei\nazlcei\nczie\neynczs\n\nngfuhekmzxvopy\ntwogyeknxvmhbjzpuf\nzxpfnygeomukvh\n\nktxduimz\nvtgmurjiqk\nmtkbuia\n\nuykwh\nkuyhnw\n\ndzjqnwbrouh\nqfncpvszdeg\ncydmlqnz\ndzqtn\n\nxga\nhmxpdg\nfnxgeu\nnxeogu\n\nnsxrgu\nxngurs\n\njvmudzscnalhwktry\nlrvucmjkwztsyna\nwyruzcjxlbtemsknva\nyzwvklpcqustojrmnai\nzyjntswcuarkmvl\n\nzq\nqz\nqz\nqz\nzqt\n\ngbpnqrxu\ndqnxyvwhbtgi\ncsqmbfjeaokxlz\n\nrdtuqpxnbzj\nyzsnpu\nfcnrzpou\npenzu\nnvukhlmizwpag\n\ntdvfgahbiw\ngtbpsdo\n\nucdprxmznhbw\nrcumdzpwnx\ndxnpzrmcuw\ndrpxcmnzuw\nzxwcnpmrdu\n\ndhouqlfvsakg\nuaofqkdsvhgl\nuoalfhvqsgkd\nklgvfudqosah\nauhslqfkgvdo\n\nqkwfimrogubyhljda\nshuprevacxlndiqfjwy\n\ncrpsetajviwmqhl\nszqdpfvimaekgbj\n\ngeyqpl\ngzqlei\nqleg\n\nkcfipzjwyugsrtahboneqxdm\nuwkcmtdfopayenqbshxi\neudhcyfpwamoxvkqlistnb\n\nyfqbtnwuzsdl\nlszfnquwbtyd\nfsjznbdwytulq\nbfgldzqyutwsn\n\nn\nuv\n\nvjfzuhqgaypbmcd\nhqmbpsjyugrvfzatndc\novfazbdipqxeclykjgum\nvmbzptjwydaguncfrq\n\nk\nw\nk\nk\n\neipruzqndlys\nelrysidnzqu\n\npzlgeciqys\nwjvrdxmunfsb\n\nkdy\nkd\nkd\ndlk\nkd\n\nyretjs\ng\nkahzubo\nrjd\nr\n\nhlxpawm\nxmyeltpqw\ngmpxicbv\nburmxc\nozxmsfjdn\n\ndtskziwy\nqxzycupgs\n\niflherjytpxg\nthienjgrfxly\nheyftrgjlix\nigyfjurphtexl\ngtyxrjleihf\n\nnuswkhz\nxosqihvwfrez\nhgszyw\n\nukphojt\nhotkpzju\nhtupjbko\nmjpkouhd\n\nluhsi\nshliu\nlihqsu\n\niqr\nybndlhzrgwtmkf\nrxcuq\n\nj\nj\nj\nj\n\nrwqsbyoe\nfweujxcoliya\nmpowrey\n\nwvn\nwv\n\nfrbuexwg\nxmqgdwfeb\n\nrbyjsiqxtfcvlup\nvqpuyrifcsjxtlb\nyvtqirslxpjfbcu\nvsribxjcufylqpt\n\nikcvoguphqtyjdswzexa\nptjocgxiuhwavydsqzek\nipcuohvqdwyxsetkagjz\nvpgdhzqckoywxaijuest\n\nerhdoyugavcq\ndoqsvahugec\ncnhezgfavbuixdo\n\nlhgvknmequsctapxzbjdorf\nfodnxkrlqthcubmzvpjaeg\nfcvqmordxhklpybujgenatz\nnlmbxvpcokearhdzjtqufg\nuthcdpbvojlqewrknafgxzmi\n\nhwjpevzgrtmoqknydfs\njvzstyfdhgkoqpmw\n\nncw\ngwivun\nwnl\nnxw\nnajwbzdrke\n\nckyowhxblrt\nflabyrdwctk\nlbwripvjtykcs\n\npn\neonwtzp\nyxsirvqhcm\nfapu\nnjwb\n\nlsjdymwpz\nzmrhuajxvewysp\n\nlyisuvcbdqxotkmh\nbkmrldugxsycohqitv\nxlhcvtmyqibdosuk\nhscubvoelkyqdximt\n\nmb\nmjbf\nrbm\n\nzvqlg\ngnlvjbz\nzvdgl\ndslgvzt\nvczwgl\n\nbem\nyqpgj\ndxflhwokatuvnzs\nirqc\njqp\n\ngqolch\nhnozqgcl\n\ndnhwl\nhdo\nfduc\n\nlug\nlug\ngurkal\nlgu\nulg\n\nuahmzdyxbr\nhtkmwpcxbqy\ncbhyxmp\n\najv\nmjt\nj\nji\n\nbfpygmtxajnk\nkpnmfbxtgayj\npcynamktgbjxf\ntfympjvqxgnkab\n\nx\nx\nx\nmxf\nvqx\n\nwlzsgdhixr\nhgcoaiwpbluv\nwyhlig\niwfnlhqgs\njfgqihmxwlr\n\ncqrdbpoehiwfuzvgalxm\nularwipqxcfedozmbvg\nvurqezjkoysgpalbfimxwcdt\nmcvfzqplaxwrgoebiud\n\nmydhxfvgzcleojiq\nixcozgyvjdfl\nnjxuwiaovpycslrzgdf\n\ngfwtnr\nmojdinwkf\nrfnwqhcg\nwfn\n\nlwise\narl\ntrzbvl\nbal\n\ny\ny\ny\ny\n\nsayqdimthfrpjvgn\ncrdphnmayqbgf\n\nsfgtqwbzej\npnmlcyitj\n\nyvtng\ntyn\nnyutg\nytgenh\nonpty\n\nbleicngomsqhwfdy\nmrbnfygxpiwucoldqshke\ncqdeimynwhsfoblg\ngqesldbcijmwhonfy\nenblgcmfwdhyqois\n\nufmsgkbcxz\nxfsckzmub\numbkoxzhrsvcnf\nkzmcsbfxgu\n\ntuiwqd\nhbtdou\n\nt\nt\nt\nt\nt\n\nureltqfji\nohzkrul\n\noievpqgs\nsqdvopigle\neasvqpkgio\n\nupkr\nurpk\n\nwrbipknheldxjfm\nrhjexfldkwpb\nlhrpejxfwbdk\n\ndrybxszfetlnwjigk\nfngbltzjywsroixk\n\nhodteualp\ndtrpuile\n\ntqrbsjni\nsbcirnqt\nrsbaitqv\nqbsrit\ngbtsriq\n\novjmetdznlw\ndtjvlmonze\nzdjntemolvw\nmlouvjngzkdter\n\nckrnly\nrclkyn\ncyjlkrnh\ncrynkl\nylckrn\n\nzjk\nzkj\ndjkz\njzk\njzk\n\nxoj\nmjro\nkjuxro\nybsjeahf\n\nzhwvtialqegufxmrcj\nhwljxrecaqmztgifv\nvgibmzlxwrdeacfqhjt\n\nnxicerwtzolfgky\nhogmsvdplbweja\n\nw\nclq\ni\ngi\n\ncilrkspgjqmw\nxhvadtlyfjobnzue\n\nckytg\nnqtyg\ngyxbt\nkygtc\n\nfwcd\nwfc\noebwhmil\nfdwxr\n\nlomdtfsihk\nsfyitokldmh\ndimyotfkls\niovdstlmkfj\nsmulideqtfok\n\nfrazxb\nahfbxz\nbafzx\naftbxpz\n\nubdarimsqvgtlhfjze\neqfrvhsguzjamtidl\n\nhjidpgrc\nvrp\nzpxwsulqrona\ndrhpftvi\nkbrdhype\n\nxidcskygjwmbzr\nbsqexaypghjkv\n\ntgxmy\natxym\ntxym\n\nqjrbmxtluews\nulbrwtjsxqop\nfzbksturwmxlqj\ntbxvnsjqriuwcl\n\nedhvzwqxojuplbkyf\nwfphdjyczxvlkbqo\njhxbpkvyfzdloqw\nyhmlfwoqkjpvdxbz\nqfmxikhozbvwydplj\n\nseyq\nyogxm\n\njzbgatxhrplowqsyecvdn\nnzjvohtguxpydsrlcewab\n\napzf\nzanwg\npza\naz\n\nsapxfnyhbowujlcdveqiztkm\ntzskjxqcoebdunyfphi\n\ncaruks\nrhlwsv\n\ncnswqfaztmdh\nuxszromtanqdfb\n\ncjnmstxqvdik\nqmjdcksitxvn\ncjktvxqmdnis\ncjnrsqdkxptivm\n\noq\nqaion\nomq\nqo\n\nkzymeqtbasgn\ncuktvbsorim\nlpjxwhdf\n\nknflw\nezvkn\nyuhakrnc\n\nvidhwxfrmnsyuct\nrzumskdfeqx\n\np\np\n\nduicxvgnbeopfzlqyrks\nskdetoclpbmzqfghwixr\ngfozcdskprxeaiqbml\nplkhqcifedxbgosrz\n\nydtjolrxzefiaschwng\ntdoerngfhzwxjcylia\nzrawdytxhcojlgenfi\n\nghvjqlifws\nsfiqklwjehrgv\n\nq\nq\ns\na\ns\n\net\ntme\n\na\na\na\na\na\n\nqng\ng\nwg\n\nnvmlaui\naudrigo\natnjdu\nhybxcpszkwuq\nfnu\n\nzmngdceqikxyuapwv\nciwyqekgamdzvp\nikcpavfgbwmerqyz\n\nmcvyjezqxrpkiu\nwlfatnmghs\n\nawkqenuiorcd\nlkuowsracdtzqgei\njoxhucpqrmfyvikawe\n\ncdn\nndc\n\nfybj\nbjfy\nbyjucsf\nflybjx\n\nzfcphgxqno\nzhmxyncpqr\niqhwaclzupsne\n\noscpyvdebfhz\npbonsjyrelkfxvz\nwfpvyigbmaeztoqus\n\nypbfhaivmkx\nxpjfhikyoca\n\nwkzvxlebarsmcdpi\nxidcbpswmazekr\nzsxwidpmekacrb\npwczxsedakirbm\n\nvfupqwdshxygkmrzol\nwslmypfkogrxzqdvh\nqwlxsrfzpgdomvyhk\n\ncmkdiapszuyb\nbkpyduimascz\n\nvjpxmdzfwkuq\neycbgsnhltmapxo\n\nxmnklfpugdewtj\nokzerxjuihqcptdmysf\n\nyajvhbtowixds\ndvynabxjiwhs\nasydoixzbh\nihjdxbasyk\nlifxrbspedahyumcg\n\nsnragze\ngmszrnae\negrazsn\nensragz\n\nodi\nodi\nido\nodi\n\nmvogdzfker\nveongkrpzmdf\nvgekmrzdfo\nombjdfqykergvz\nhzsormkdgfve\n\nl\nl\nl\nly\n\nkgnpliuwmsebhjfrcyqxotvazd\nmzqryvgsftauxpcknehbiwojld\n\nvczkrabfmhpyjteui\nmerjtikybvaugz\naieydktjrmzvubg\nyeslqoibauvtkmrjz\n\nvi\nvip\neigv\nvix\niv\n\nmcuknbexfowszpvtyi\nztmfwonvcsapqxyieb\netowynxzcpirmbvsf\nwjfnyvopzetkmiusbcx\n\nywhqemsx\nbanksxwemy\nymsexw\nsmyewx\nszxeywm\n\nyvqtnsahzpwebgr\nzgtjnevyapwbhrs\njzynhrpvwgsbat\nobtynrfwslcahvzgpm\neytrpagzwsjvbkhn\n\nynwutpmvhj\nmvwjpuyt\nwupzyjvmt\n\nkwnyatozcmdqbpsvejfrxug\nvkzjaogfmqsxhnyctpu\ncozypjmtvlxquakgfnsi\n\nqrwtgecs\ndaley\nemh\n\nqmbjwe\nqebfwjm\nqewjm\nqjiwem\n\ndqc\ntad\nqdcs\n\nzrvjnfpe\nzpefunyvqc\nfzpvern\npnefvz\nenvpfz\n\nnduhkvstxqmbfyr\nufmhbtkqvxdnpy\nhdntqxuvmbkfy\n\not\no\nyv\nxp\n\nevkrifstpzgbahl\nvzkmdtchgseajyfub\nbgtnkxvheoaqifsz\n\nwxec\nwfuie\nawmj\nghsnkvwbqor\nmcexwf\n\nteosna\ntnkb\nptm\nt\n\nr\nna\nykx\n\njdl\nmzjtp\n\nxbpj\ntzrkxba\nxnbjmgosv\nmhxbw\n\nj\nj\nj\nj\n\nxn\nlrvt\nhtg\nmr\n\nhafkb\nfkab\nafbk\n\nzlyxomawvuib\nvxwzbaymolui\n\ntcdfzgx\nql\nluo\nuh\n\nixtbluahoeqgsv\neovsiglhuqanxtb\n\nntychjig\nchyijtgn\nhcnjtiyg\ntgjnhiyc\ntgjiychn\n\nkhomqatzscydwunfe\nygoazrdukh\nzokbrlyaudjh\n\nuojynifthzvcgqp\nphnvryfbtucl\n\nsbeizdtjopxu\nnouqbeykmszd\n\ncga\ngca\ncag\n\nhiogxbslyptfc\npilwxcthogysb\nholsibtcypfgx\n\noahyr\npkjro\n\nqgfkj\ngjzk\njgvk\n\nkw\nwk\nkw\nwk\n\nbxvmnks\nsfmbva\n\nfsocn\nygfopn\n\nwbarmxtfyjzenicvlhps\naefdirlyvzjpwtcmnh\nrqymwfzjpevchiaotnl\nlietnypmcrvhowfjaz\nztjcehympnavirlwf\n\ngqsnyhtafdcbki\nyncbhxiakgpqt\n\nmikyzoxflndetbp\nebqdwiopkhyfxnl\njbscverlgfyauo\n\nbkewpj\nn\nsolnxmfr\n\nybxa\nybxa\nxyba\nbyax\nabxy\n\nsgbo\nsg\n\nunvqlyhzdaxrcwg\ndxvhaugicrzqnlw\nmrplcqatdxzbuvgnwh\nvzaurnhdgqlxwc\nucdwavqhylxrngz\n\nfrhdaek\nfpuwosv\n\nqm\nm\nsmg\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_06_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 6\n------------------------------------------\n--  Custom Customs\n--\n--  https://adventofcode.com/2020/day/6\n--\n--  Full Ada version.\n--\nwith Ada.Strings.Fixed, Ada.Text_IO;\n\nprocedure AoC_2020_06_Full_Ada is\n  total : Integer;\n  new_group : Boolean;\n  subtype Answer_Range is Character range 'a' .. 'z';\n  type Yes_Answer is array (Answer_Range) of Boolean;\n  r, rg : Yes_Answer;\n  --\n  procedure Collect_Group_Total is\n    g : Natural := 0;\n  begin\n    for c in Answer_Range loop if rg (c) then g := g + 1; end if; end loop;\n    total := total + g;\n    new_group := True;\n  end Collect_Group_Total;\n  --\n  use Ada.Strings.Fixed, Ada.Text_IO;\n  f : File_Type;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, In_File, \"aoc_2020_06.txt\");\n    total := 0;\n    new_group := True;\n    while not End_Of_File (f) loop\n      declare\n        s : constant String := Get_Line (f);\n      begin\n        if s = \"\" then\n          Collect_Group_Total;\n        else\n          for c in Answer_Range loop\n            r (c) := Index (s, (1 => c)) > 0;\n          end loop;\n          if new_group then\n            rg := r;\n            new_group := False;\n          elsif part = 1 then\n            rg := rg or r;\n          else\n            rg := rg and r;\n          end if;\n        end if;\n      end;\n    end loop;\n    Collect_Group_Total;\n    Put_Line (\"Part\" & Integer'Image (part) & ' ' & Integer'Image (total));\n    Close (f);\n  end loop;\nend AoC_2020_06_Full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_06_full_ada_using_hat.adb",
    "content": "--  Solution to Advent of Code 2020, Day 6\n------------------------------------------\n--  Custom Customs\n--\n--  https://adventofcode.com/2020/day/6\n--\n--  Full Ada version, using the HAT package.\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_06_Full_Ada_using_HAT is\n  total : Integer;\n  new_group : Boolean;\n  subtype Answer_Range is Character range 'a' .. 'z';\n  type Yes_Answer is array (Answer_Range) of Boolean;\n  r, rg : Yes_Answer;\n  --\n  procedure Collect_Group_Total is\n    g : Natural := 0;\n  begin\n    for c in Answer_Range loop if rg (c) then g := g + 1; end if; end loop;\n    total := total + g;\n    new_group := True;\n  end Collect_Group_Total;\n  --\n  f : File_Type;\n  s : VString;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, \"aoc_2020_06.txt\");\n    total := 0;\n    new_group := True;\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      if s = \"\" then\n        Collect_Group_Total;\n      else\n        for c in Answer_Range loop\n          r (c) := Index (s, c) > 0;\n        end loop;\n        if new_group then\n          rg := r;\n          new_group := False;\n        elsif part = 1 then\n          rg := rg or r;\n        else\n          rg := rg and r;\n        end if;\n      end if;\n    end loop;\n    Collect_Group_Total;\n    Put_Line (+\"Part \" & part & \".  Total customs answers: \" & total);\n    --  Part 1: officially validated by AoC: 6532\n    --  Part 2: officially validated by AoC: 3427\n    Close (f);\n  end loop;\nend AoC_2020_06_Full_Ada_using_HAT;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_07.adb",
    "content": "--  Solution to Advent of Code 2020, Day 7\n------------------------------------------\n--  Handy Haversacks\n--\n--  https://adventofcode.com/2020/day/7\n--\n--  HAC 0.081 \"nice to have\"'s detected in this exercise:\n--    *     \"=\" for composite types ( ` rules (ri).contains (cti).col = c  `)\n--\n--  Solved in HAC 0.099:\n--    *     I/O with enums, at least 'Image and 'Value.\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_07 is\n\n  type Base_Colour is\n    (aqua, beige, black, blue, bronze, brown, chartreuse, coral, crimson, cyan, fuchsia, gold,\n     gray, green, indigo, lavender, lime, magenta, maroon, olive, orange, plum, purple, red,\n     salmon, silver, tan, teal, tomato, turquoise, violet, white, yellow);\n\n  type Colour_Qualifier is\n    (bright, clear, dark, dim, dotted, drab, dull, faded, light,\n     mirrored, muted, other, pale, plaid, posh, shiny, striped, vibrant, wavy);\n\n  --  Emulate full Ada's Enumeration_IO's Get (ouch!) ...\n\n  procedure Get_CQ (f : in out File_Type; cq : out Colour_Qualifier) is\n    c : Character;\n    s : VString;\n  begin\n    loop\n      Get (f, c);\n      exit when c < 'a' or c > 'z';\n      s := s & c;\n    end loop;\n    cq := Colour_Qualifier'Value (To_String (s));\n    --  We don't treat the invalid cases...\n  end Get_CQ;\n\n  procedure Get_BC (f : in out File_Type; bc : out Base_Colour) is\n    c : Character;\n    s : VString;\n  begin\n    loop\n      Get (f, c);\n      exit when c < 'a' or c > 'z';\n      s := s & c;\n    end loop;\n    bc := Base_Colour'Value (To_String (s));\n    --  We don't treat the invalid cases...\n  end Get_BC;\n\n  procedure Get_Nat (f : in out File_Type; n : out Natural) is\n    c : Character;\n  begin\n    n := 0;\n    Get (f, c);\n    while c = ' ' loop  --  Skip heading blanks.\n      Get (f, c);\n    end loop;\n    loop\n      exit when c < '0' or c > '9';\n      n := n * 10 + Ord (c) - Ord ('0');\n      Get (f, c);\n    end loop;\n    --  Result 0 when invalid...\n  end Get_Nat;\n\n  type Colour is record\n    cq : Colour_Qualifier;\n    bc : Base_Colour;\n  end record;\n\n  type Contained_Spec is record\n    col : Colour;\n    num : Natural;\n  end record;\n\n  subtype Contains_Range is Integer range 1 .. 4;\n\n  type Contains_List is array (Contains_Range) of Contained_Spec;\n\n  type Rule is record\n    container   : Colour;\n    num_contain : Natural;\n    contains    : Contains_List;\n    can_contain : Boolean;  --  Used for marking container bag rule without double-counting.\n  end record;\n\n  subtype Rules_Range is Integer range 1 .. 1000;\n\n  rules : array (Rules_Range) of Rule;  --  Cheap version of Vectors...\n  rules_count : Natural := 0;\n\n  details : constant Boolean := False;\n\n  procedure Put_Colour (c : Colour) is\n  begin\n    Put (Colour_Qualifier'Image (c.cq)); Put (\"~\"); Put (Base_Colour'Image (c.bc));\n  end Put_Colour;\n\n  function Equal (c1, c2 : Colour) return Boolean is\n  begin\n    return c1.cq = c2.cq and c1.bc = c2.bc;\n  end Equal;\n\n  function Containing_Bags (c : Colour) return Natural is\n    --\n    procedure Scan_Containing_Bags (c : Colour) is\n      is_top : Boolean := True;\n    begin\n      for ri in 1 .. rules_count loop\n        for cti in 1 .. rules (ri).num_contain loop\n          if Equal (rules (ri).contains (cti).col, c) then\n            --  Colour c is contained in bag described by rule #ri.\n            is_top := False;\n            rules (ri).can_contain := True;\n            if details then\n              Put (\"   container of \"); Put_Colour (c);\n              Put (\" is \"); Put_Colour (rules (ri).container); New_Line;\n            end if;\n            Scan_Containing_Bags (rules (ri).container);\n          end if;\n        end loop;\n      end loop;\n      if is_top and details then\n        Put (\"Top: \"); Put_Colour (c); New_Line;\n      end if;\n    end Scan_Containing_Bags;\n    --\n    can_contain_count : Natural := 0;\n  begin\n    for ri in 1 .. rules_count loop\n      rules (ri).can_contain := False;\n    end loop;\n    Scan_Containing_Bags (c);\n    for ri in 1 .. rules_count loop\n      if rules (ri).can_contain then\n        can_contain_count := can_contain_count + 1;\n      end if;\n    end loop;\n    return can_contain_count;\n  end Containing_Bags;\n\n  function Contained_Bags (c : Colour) return Natural is\n    contained : Natural := 0;\n  begin\n    for ri in 1 .. rules_count loop\n      if Equal (rules (ri).container, c) then\n        if details then\n          Put (\"Container \"); Put_Colour (c); New_Line;\n        end if;\n        for cti in 1 .. rules (ri).num_contain loop\n          contained := contained +\n            rules (ri).contains (cti).num * (1 + Contained_Bags (rules (ri).contains (cti).col));\n        end loop;\n        exit;\n      end if;\n    end loop;\n    return contained;\n  end Contained_Bags;\n\n  procedure Get_Rules is\n    f : File_Type;\n    sep : Character;\n    new_rule : Rule;\n    new_spec : Contained_Spec;\n  begin\n    Open (f, \"aoc_2020_07.txt\");\n    while not End_Of_File (f) loop\n      Get_CQ (f, new_rule.container.cq);\n      Get_BC (f, new_rule.container.bc);\n      if details then\n        Put_Colour (new_rule.container);\n      end if;\n      for i in 1 .. 13 loop Get (f, sep); end loop;  --  \" bags contain\"\n      if details then\n        Put (\" bags contain: \");\n      end if;\n      new_rule.num_contain := 0;\n      loop\n        Get_Nat (f, new_spec.num);\n        if new_spec.num = 0 then\n          Skip_Line (f);\n          exit;\n        end if;\n        Get_CQ (f, new_spec.col.cq);\n        Get_BC (f, new_spec.col.bc);\n        if details then\n          Put (new_spec.num, 2);\n          Put (\" \");\n          Put_Colour (new_spec.col);\n          Put (\"   \");\n        end if;\n        new_rule.num_contain := new_rule.num_contain + 1;\n        new_rule.contains (new_rule.num_contain) := new_spec;\n        loop\n          Get (f, sep);\n          exit when sep = ',' or sep = '.';\n        end loop;\n        exit when End_Of_Line (f);\n      end loop;\n      if details then\n        New_Line;\n      end if;\n      rules_count := rules_count + 1;\n      rules (rules_count) := new_rule;\n    end loop;\n    Close (f);\n  end Get_Rules;\n  --\n  shiny_gold : Colour;\n  test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  shiny_gold.cq := shiny;\n  shiny_gold.bc := gold;\n  Get_Rules;\n  if test_mode then\n    if (Containing_Bags (shiny_gold) /= Integer_Value (Argument (1))) or\n       (Contained_Bags (shiny_gold) /= Integer_Value (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Rules about bag contents: \" & rules_count);\n    Put_Line (+\"Part 1: all possible direct or indirect containers of shiny gold: \" &\n                Containing_Bags (shiny_gold));\n    Put_Line (+\"Part 2: all bags contained by shiny gold: \" &\n                Contained_Bags (shiny_gold));\n  end if;\n  --  Rules: 594\n  --  Part 1: all possible direct or indirect containers of shiny gold: 169\n  --  Part 2: all bags contained by shiny gold: 82372\nend AoC_2020_07;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_07.txt",
    "content": "wavy green bags contain 1 posh black bag, 1 faded green bag, 4 wavy red bags.\ndotted chartreuse bags contain 1 light beige bag.\ndark white bags contain 2 dotted white bags.\nclear aqua bags contain 4 posh orange bags, 4 pale blue bags.\nfaded green bags contain 2 plaid orange bags, 4 drab green bags, 4 pale aqua bags, 4 drab coral bags.\ndrab lavender bags contain 2 shiny white bags, 2 muted orange bags, 1 mirrored crimson bag, 1 dotted aqua bag.\ndull maroon bags contain 1 plaid plum bag, 5 plaid orange bags, 4 posh maroon bags.\npale lavender bags contain no other bags.\nplaid cyan bags contain 2 posh violet bags, 5 dim turquoise bags, 2 dark tomato bags.\ndull plum bags contain 5 muted red bags, 4 dotted salmon bags, 1 dull maroon bag.\nbright turquoise bags contain 2 dotted chartreuse bags, 3 dull tan bags, 4 light gray bags, 3 mirrored red bags.\nposh violet bags contain no other bags.\nfaded coral bags contain 1 wavy teal bag, 4 wavy cyan bags.\nstriped turquoise bags contain 3 bright gray bags, 4 bright bronze bags.\nmuted magenta bags contain 5 light teal bags.\ndull lavender bags contain 3 clear orange bags, 3 pale cyan bags, 4 vibrant orange bags, 1 dim chartreuse bag.\npale silver bags contain 3 faded olive bags.\ndull turquoise bags contain 4 light gray bags, 4 clear green bags, 2 dull aqua bags, 5 dim white bags.\ndim cyan bags contain 4 pale cyan bags, 2 dotted beige bags, 4 drab lime bags, 2 muted silver bags.\nwavy plum bags contain 2 drab bronze bags, 3 mirrored yellow bags, 3 vibrant beige bags.\ndrab lime bags contain 5 muted plum bags.\nstriped yellow bags contain 3 dark fuchsia bags, 1 clear lime bag, 5 faded turquoise bags.\nshiny cyan bags contain 4 clear maroon bags, 1 dim yellow bag, 5 drab red bags.\nbright maroon bags contain 2 shiny gray bags, 2 faded indigo bags, 5 muted tan bags.\nstriped crimson bags contain 5 posh brown bags.\npale green bags contain 1 pale red bag.\nshiny blue bags contain 2 clear red bags, 2 dark black bags, 3 dotted silver bags.\nmirrored lime bags contain 2 drab violet bags.\nmirrored maroon bags contain 4 faded salmon bags, 2 shiny blue bags, 1 pale coral bag.\nlight bronze bags contain 2 clear red bags, 3 posh lavender bags, 1 clear purple bag, 5 plaid lavender bags.\nbright salmon bags contain 2 faded cyan bags, 1 striped blue bag, 1 faded crimson bag.\nfaded red bags contain 4 dotted purple bags, 1 bright brown bag, 1 pale tan bag, 1 drab teal bag.\npale indigo bags contain 3 pale orange bags, 5 muted bronze bags, 2 pale tan bags, 3 posh fuchsia bags.\npale orange bags contain 2 dotted magenta bags, 5 clear plum bags, 3 dim olive bags, 1 mirrored yellow bag.\ndrab gold bags contain 4 dotted cyan bags, 4 muted plum bags, 1 vibrant white bag, 4 dull green bags.\nmirrored teal bags contain 5 posh turquoise bags, 4 striped purple bags, 5 mirrored blue bags.\ndark chartreuse bags contain 1 striped crimson bag, 3 dull purple bags.\nposh olive bags contain 2 clear brown bags, 1 faded lavender bag.\nmuted tan bags contain 1 striped red bag.\ndrab olive bags contain 2 dim plum bags, 4 mirrored violet bags.\nfaded lime bags contain 3 dark tomato bags.\ndim black bags contain 2 wavy purple bags, 5 mirrored fuchsia bags, 5 drab beige bags.\ndotted plum bags contain 2 shiny gold bags, 4 shiny beige bags, 1 clear red bag.\nstriped red bags contain 5 pale tan bags, 5 pale lavender bags.\ndrab green bags contain 1 faded silver bag, 3 vibrant plum bags, 2 wavy purple bags, 1 plaid blue bag.\ndull orange bags contain no other bags.\nposh tomato bags contain 5 dim gold bags, 2 drab coral bags, 4 drab maroon bags, 2 pale indigo bags.\nlight turquoise bags contain 2 shiny violet bags, 1 dull violet bag.\nmuted salmon bags contain 2 mirrored teal bags, 1 mirrored bronze bag.\nbright red bags contain 1 dotted orange bag, 2 faded gray bags, 2 dim white bags, 4 plaid tomato bags.\ndotted tan bags contain 3 clear red bags, 5 pale coral bags, 3 clear turquoise bags, 2 muted beige bags.\nmuted gold bags contain 2 drab turquoise bags.\npale magenta bags contain 3 dotted cyan bags, 4 mirrored lime bags, 2 shiny cyan bags.\npale brown bags contain 2 dull silver bags, 3 wavy tomato bags.\nshiny lime bags contain 1 mirrored gold bag, 5 dull magenta bags, 5 shiny fuchsia bags.\ndark bronze bags contain 2 light green bags.\nlight magenta bags contain 4 pale crimson bags, 3 drab plum bags.\ndark gray bags contain 5 light maroon bags.\nplaid orange bags contain 5 plaid gray bags, 1 dark tomato bag, 2 drab chartreuse bags, 4 clear red bags.\nposh purple bags contain 2 posh blue bags.\ndrab turquoise bags contain 3 clear brown bags, 2 mirrored red bags, 2 muted green bags.\ndark fuchsia bags contain 4 light orange bags.\ndim lime bags contain 1 dotted olive bag, 5 posh blue bags, 3 dim gold bags, 2 drab lime bags.\ndrab tan bags contain 4 clear violet bags.\nposh fuchsia bags contain 5 drab black bags, 4 plaid purple bags, 3 dim white bags.\nclear orange bags contain 5 muted tomato bags, 1 dotted white bag, 5 bright fuchsia bags.\nposh crimson bags contain 1 mirrored chartreuse bag, 4 pale gray bags.\nplaid tan bags contain 1 light orange bag.\nposh brown bags contain 1 clear lavender bag, 4 clear yellow bags.\nmirrored salmon bags contain 2 dotted plum bags, 5 plaid lavender bags, 4 drab olive bags, 5 shiny violet bags.\nstriped bronze bags contain 5 light blue bags.\ndotted black bags contain 4 plaid coral bags, 2 drab maroon bags, 4 dotted red bags.\nlight gray bags contain 3 posh magenta bags, 5 wavy coral bags, 2 vibrant red bags, 2 wavy olive bags.\npale turquoise bags contain 2 light olive bags, 1 dark silver bag, 5 plaid yellow bags.\nstriped fuchsia bags contain 3 wavy aqua bags.\nlight teal bags contain 5 dotted turquoise bags, 5 muted tomato bags, 1 dotted gray bag, 1 pale lavender bag.\nwavy beige bags contain 5 dim gray bags, 4 bright aqua bags.\nlight salmon bags contain 2 clear plum bags.\nshiny magenta bags contain 4 dim fuchsia bags.\nclear white bags contain 4 dim white bags.\nwavy gray bags contain 1 vibrant beige bag.\nplaid bronze bags contain 5 plaid plum bags, 3 drab olive bags, 2 drab green bags.\ndrab plum bags contain 5 drab chartreuse bags, 5 plaid purple bags, 2 drab teal bags, 1 drab coral bag.\ndotted salmon bags contain 4 dim fuchsia bags, 4 striped cyan bags, 3 dotted white bags, 4 mirrored violet bags.\nstriped magenta bags contain 1 faded teal bag, 1 drab red bag.\nposh magenta bags contain 4 faded green bags, 2 dull magenta bags.\nstriped lavender bags contain 1 striped black bag, 4 wavy turquoise bags, 5 dull purple bags, 4 posh violet bags.\nmirrored lavender bags contain 1 wavy turquoise bag.\ndim violet bags contain 3 muted green bags, 1 striped plum bag, 4 dull coral bags, 4 wavy chartreuse bags.\nshiny tomato bags contain 3 bright red bags, 5 wavy beige bags, 5 faded blue bags, 3 muted black bags.\nwavy indigo bags contain 2 dull brown bags.\ndark tomato bags contain 2 drab olive bags.\nvibrant red bags contain 1 plaid tomato bag, 1 muted tomato bag.\nvibrant brown bags contain 4 shiny violet bags, 2 mirrored violet bags, 2 dark salmon bags, 5 faded turquoise bags.\ndim lavender bags contain 4 dim plum bags, 5 drab maroon bags, 3 dark black bags.\ndull lime bags contain 5 bright turquoise bags, 3 vibrant chartreuse bags, 1 pale gray bag.\nmuted plum bags contain 4 plaid plum bags, 3 dim beige bags, 5 wavy magenta bags.\nwavy tan bags contain 3 wavy chartreuse bags, 5 clear orange bags, 2 light blue bags, 2 pale yellow bags.\ndim maroon bags contain 2 dull yellow bags, 4 shiny orange bags.\nclear violet bags contain 2 clear red bags, 1 plaid blue bag.\ndim orange bags contain 4 posh red bags, 3 posh plum bags.\nplaid crimson bags contain 5 posh brown bags, 4 vibrant indigo bags, 5 drab teal bags, 1 dotted gray bag.\nclear yellow bags contain 1 plaid gray bag.\ndotted fuchsia bags contain 2 plaid plum bags, 1 drab chartreuse bag.\ndim brown bags contain 1 faded silver bag, 1 faded brown bag, 2 striped cyan bags.\nstriped aqua bags contain 2 faded purple bags.\nstriped gold bags contain 3 dotted lime bags.\nbright yellow bags contain 2 drab bronze bags, 2 dotted gray bags.\nwavy blue bags contain 5 drab olive bags.\nwavy turquoise bags contain 3 dotted indigo bags, 2 vibrant plum bags.\ndotted purple bags contain 4 light blue bags, 4 wavy gray bags, 5 pale lavender bags.\nmirrored gold bags contain 5 wavy silver bags, 3 clear white bags.\ndull purple bags contain 3 dim fuchsia bags, 3 clear indigo bags, 4 dotted purple bags.\nbright gold bags contain 5 shiny silver bags, 5 dark olive bags, 2 muted yellow bags, 3 vibrant magenta bags.\nfaded gray bags contain 3 dotted magenta bags, 5 clear lavender bags, 2 faded tomato bags.\ndark olive bags contain 1 drab tan bag, 2 striped crimson bags.\nlight silver bags contain 3 dark teal bags, 4 posh crimson bags, 2 wavy olive bags, 2 dotted fuchsia bags.\nlight yellow bags contain 3 wavy silver bags.\ndotted teal bags contain 3 vibrant orange bags, 2 clear maroon bags.\ndrab coral bags contain 5 mirrored violet bags.\ndim salmon bags contain 4 faded silver bags, 2 plaid cyan bags.\ndotted coral bags contain 3 faded gray bags.\nvibrant bronze bags contain 4 faded tomato bags, 3 light brown bags, 5 posh lavender bags.\nlight blue bags contain 3 clear brown bags, 3 posh violet bags, 3 bright brown bags.\nplaid fuchsia bags contain 4 striped white bags, 1 mirrored cyan bag.\nplaid indigo bags contain 5 bright cyan bags.\ndull magenta bags contain 5 muted tomato bags, 4 plaid tomato bags, 1 faded silver bag.\nshiny orange bags contain 3 dark coral bags.\nwavy white bags contain 2 striped indigo bags, 1 faded orange bag, 2 dull fuchsia bags, 2 vibrant silver bags.\ndotted bronze bags contain 5 shiny fuchsia bags, 5 dotted aqua bags, 1 faded aqua bag.\nlight chartreuse bags contain 3 dull chartreuse bags.\ndull salmon bags contain 2 vibrant plum bags.\nclear bronze bags contain 1 shiny tomato bag.\nfaded lavender bags contain 5 pale lavender bags, 2 dull maroon bags, 3 drab beige bags.\ndark black bags contain 2 dim fuchsia bags, 3 plaid tomato bags, 3 dull orange bags.\ndull violet bags contain 1 striped red bag.\nmirrored indigo bags contain 3 mirrored violet bags, 4 faded plum bags, 1 pale tan bag, 2 dotted white bags.\nshiny crimson bags contain 2 dim purple bags, 2 dotted purple bags, 2 bright bronze bags.\nplaid aqua bags contain 1 plaid tan bag, 1 mirrored orange bag.\ndrab beige bags contain 1 dull yellow bag.\nclear purple bags contain 1 vibrant cyan bag, 2 dim brown bags, 1 dark lavender bag.\ndim olive bags contain 5 light blue bags, 1 dull gold bag, 5 faded red bags, 1 dotted purple bag.\nmirrored green bags contain 4 wavy beige bags.\ndotted silver bags contain 5 wavy fuchsia bags.\ndotted blue bags contain 5 pale blue bags.\npale crimson bags contain 1 dim tan bag.\nplaid gold bags contain 5 wavy magenta bags, 2 dotted gray bags.\ndim crimson bags contain 4 dark lavender bags.\npale tomato bags contain 3 muted red bags, 1 clear lavender bag, 1 clear orange bag, 3 pale red bags.\ndrab fuchsia bags contain 3 faded red bags, 1 muted silver bag, 2 drab aqua bags.\npale maroon bags contain 5 vibrant lime bags, 1 light crimson bag, 1 posh white bag.\nwavy lavender bags contain 3 muted red bags, 2 posh violet bags.\nvibrant salmon bags contain 1 dark beige bag.\ndark blue bags contain 5 dim brown bags, 3 dark red bags, 1 light fuchsia bag, 5 shiny gold bags.\ndark plum bags contain 1 muted aqua bag.\ndrab crimson bags contain 2 drab turquoise bags, 3 shiny violet bags.\nvibrant tomato bags contain 1 light tomato bag, 5 vibrant gold bags.\ndrab maroon bags contain 2 faded tomato bags, 5 clear olive bags, 3 plaid gray bags.\nclear green bags contain 5 striped lavender bags, 4 dim gray bags.\nplaid green bags contain 2 shiny blue bags, 1 drab fuchsia bag, 5 dotted black bags, 1 dim plum bag.\nmirrored yellow bags contain 2 mirrored violet bags, 5 clear brown bags.\ndull aqua bags contain 2 faded tomato bags.\nshiny olive bags contain 4 light teal bags, 2 bright white bags.\nplaid lime bags contain 3 drab red bags, 2 light crimson bags.\ndull green bags contain 5 drab green bags, 4 dotted red bags, 4 shiny olive bags, 4 plaid plum bags.\ndull beige bags contain 2 faded tan bags.\nlight indigo bags contain 3 dotted white bags.\nshiny silver bags contain 3 vibrant cyan bags, 1 dim teal bag, 1 striped beige bag, 5 wavy chartreuse bags.\nplaid yellow bags contain 3 light beige bags.\nstriped orange bags contain 1 dotted maroon bag, 5 bright red bags, 3 shiny red bags.\nposh indigo bags contain 2 dotted bronze bags.\ndrab orange bags contain 1 striped crimson bag, 3 dark yellow bags, 3 light turquoise bags, 3 light silver bags.\nmirrored chartreuse bags contain 2 dotted magenta bags.\nplaid silver bags contain 5 wavy aqua bags, 3 vibrant plum bags, 1 dark black bag.\nstriped indigo bags contain 2 dotted salmon bags, 1 vibrant beige bag, 1 wavy cyan bag, 5 striped salmon bags.\nmuted coral bags contain 5 vibrant brown bags, 4 light fuchsia bags.\nshiny brown bags contain 2 vibrant violet bags, 3 drab gray bags.\nshiny indigo bags contain 5 muted bronze bags.\nstriped cyan bags contain 3 dim fuchsia bags, 3 dark coral bags, 1 faded red bag, 5 plaid brown bags.\nshiny tan bags contain 5 plaid white bags.\nclear gold bags contain 3 plaid purple bags, 4 striped black bags, 5 dim turquoise bags, 1 plaid plum bag.\nvibrant violet bags contain 2 posh violet bags, 2 pale tomato bags.\nmuted olive bags contain 2 dark tomato bags.\nmirrored tomato bags contain 5 pale black bags.\nclear crimson bags contain 1 dim crimson bag, 5 striped blue bags.\ndrab blue bags contain 1 bright indigo bag.\ndrab teal bags contain 1 plaid brown bag.\nstriped brown bags contain 4 dotted orange bags, 4 wavy blue bags.\nposh lavender bags contain 4 bright indigo bags, 4 faded bronze bags.\nlight fuchsia bags contain 1 shiny crimson bag, 2 clear brown bags, 2 striped crimson bags.\ndotted violet bags contain 4 dull crimson bags.\nvibrant lavender bags contain 2 faded olive bags, 5 shiny tomato bags.\nwavy gold bags contain 5 dotted black bags, 2 drab beige bags, 3 dull gold bags.\nfaded brown bags contain 1 wavy gray bag, 3 plaid teal bags.\nbright purple bags contain 1 faded tomato bag.\nshiny plum bags contain 2 dim silver bags.\nposh beige bags contain 3 bright crimson bags.\nposh coral bags contain 4 light chartreuse bags, 5 drab bronze bags, 2 striped aqua bags.\nshiny black bags contain 2 posh black bags, 5 clear white bags.\nposh white bags contain 1 plaid violet bag.\nvibrant chartreuse bags contain 5 clear aqua bags, 4 dotted magenta bags.\nfaded olive bags contain 2 mirrored fuchsia bags, 5 plaid brown bags.\ndrab purple bags contain 1 dim olive bag, 5 drab lime bags.\ndull yellow bags contain 2 dark coral bags, 3 clear brown bags.\nvibrant turquoise bags contain 5 plaid orange bags.\nwavy tomato bags contain 3 faded olive bags, 3 bright white bags, 5 dull gray bags.\npale plum bags contain 4 pale coral bags, 4 bright cyan bags, 3 dim brown bags.\nfaded indigo bags contain 1 clear beige bag, 2 vibrant beige bags.\nshiny violet bags contain 4 shiny tomato bags, 2 striped lavender bags.\nmirrored purple bags contain 5 dotted red bags, 1 mirrored fuchsia bag, 2 mirrored yellow bags.\nfaded cyan bags contain 4 drab red bags, 5 wavy purple bags, 2 dim beige bags, 5 faded red bags.\nshiny salmon bags contain 5 muted tomato bags, 5 striped olive bags.\nclear maroon bags contain 1 dotted magenta bag.\nfaded black bags contain 5 wavy fuchsia bags, 2 dim olive bags, 1 dark lavender bag.\nposh green bags contain 3 mirrored coral bags, 2 drab aqua bags, 4 wavy orange bags.\nfaded crimson bags contain 1 mirrored cyan bag, 2 dim gray bags, 5 light blue bags, 5 posh maroon bags.\nstriped tomato bags contain 4 drab lime bags, 2 wavy teal bags, 4 plaid cyan bags, 2 muted fuchsia bags.\nlight olive bags contain 2 dotted red bags, 2 pale coral bags.\nfaded gold bags contain 4 shiny green bags, 1 clear beige bag, 2 wavy brown bags, 2 dull tomato bags.\npale bronze bags contain 1 dim lime bag.\ndotted gray bags contain 5 mirrored yellow bags.\ndark beige bags contain 4 clear turquoise bags, 3 vibrant plum bags, 5 drab maroon bags, 5 clear red bags.\ndrab magenta bags contain 1 drab maroon bag, 1 clear magenta bag.\nvibrant beige bags contain 3 bright fuchsia bags, 1 dull gold bag.\ndark teal bags contain 5 clear turquoise bags, 5 dark maroon bags, 4 dotted magenta bags, 3 shiny crimson bags.\nmirrored blue bags contain 5 dark black bags, 5 vibrant brown bags, 5 dark aqua bags.\nwavy cyan bags contain 4 clear aqua bags, 4 dark aqua bags.\ndark turquoise bags contain 1 striped gold bag.\ndrab silver bags contain 3 plaid bronze bags.\nfaded beige bags contain 5 wavy cyan bags, 3 dull white bags, 5 dim purple bags, 4 faded brown bags.\nfaded purple bags contain 3 light white bags, 4 faded brown bags, 4 posh maroon bags.\ndotted magenta bags contain 3 posh violet bags.\nmuted green bags contain 2 dim gray bags, 1 vibrant indigo bag, 4 dotted indigo bags.\nbright beige bags contain 1 wavy teal bag, 4 bright cyan bags, 1 clear green bag, 1 posh brown bag.\nbright violet bags contain 2 plaid indigo bags.\ndim purple bags contain 1 posh maroon bag, 2 drab beige bags, 5 clear brown bags.\nclear magenta bags contain 4 pale white bags, 5 dotted chartreuse bags, 2 bright turquoise bags, 4 mirrored red bags.\nfaded magenta bags contain 1 dull gray bag.\nmirrored white bags contain 4 dotted purple bags, 2 plaid purple bags, 2 pale tan bags.\nclear salmon bags contain 2 mirrored lavender bags.\nlight maroon bags contain 1 plaid tomato bag, 5 pale aqua bags.\nvibrant tan bags contain 3 bright coral bags, 4 striped turquoise bags, 3 wavy aqua bags, 2 shiny gold bags.\nshiny lavender bags contain 2 drab tomato bags, 1 drab plum bag.\ndark crimson bags contain 2 pale purple bags, 2 dotted white bags, 3 shiny orange bags, 1 dotted bronze bag.\nfaded aqua bags contain 3 wavy purple bags.\nstriped blue bags contain 3 plaid bronze bags, 1 clear yellow bag, 2 clear white bags, 3 wavy teal bags.\nmirrored silver bags contain 5 striped salmon bags, 4 drab blue bags, 1 vibrant green bag, 1 muted cyan bag.\ndrab white bags contain 2 wavy salmon bags.\ndull brown bags contain 5 pale plum bags, 3 plaid tomato bags.\nbright cyan bags contain 2 clear lavender bags.\nfaded chartreuse bags contain 4 wavy aqua bags, 5 plaid orange bags, 5 dotted indigo bags, 4 clear yellow bags.\ndotted tomato bags contain 4 muted purple bags, 4 dotted black bags.\ndim white bags contain 5 mirrored cyan bags, 2 dim fuchsia bags, 2 dark tomato bags, 1 dotted purple bag.\nposh orange bags contain 5 drab olive bags, 5 vibrant beige bags.\nlight coral bags contain 5 light purple bags, 2 wavy tomato bags.\nwavy lime bags contain 4 clear brown bags.\nmirrored magenta bags contain 2 faded silver bags, 2 dark coral bags.\nwavy coral bags contain 4 dull purple bags, 1 dark white bag, 4 posh orange bags.\nvibrant gray bags contain 5 dotted aqua bags, 2 dark salmon bags, 2 bright blue bags, 1 dotted white bag.\nmirrored olive bags contain 3 dark coral bags, 3 wavy gray bags.\nlight gold bags contain 2 striped lime bags, 2 dark orange bags.\nlight cyan bags contain 2 dim turquoise bags, 3 dotted tan bags, 4 shiny crimson bags.\nshiny gray bags contain 5 plaid cyan bags, 1 wavy purple bag.\nbright plum bags contain 3 muted tomato bags, 1 dim chartreuse bag, 3 dotted indigo bags, 4 shiny olive bags.\nvibrant blue bags contain 2 shiny orange bags.\nclear lavender bags contain 5 faded red bags, 2 wavy gray bags.\ndim yellow bags contain 2 drab aqua bags, 3 dim lavender bags, 1 bright plum bag.\nposh gray bags contain 3 light lavender bags.\ndull tan bags contain 1 dim gold bag, 2 bright bronze bags, 5 dim plum bags.\nplaid brown bags contain 3 dull orange bags, 3 dim plum bags.\nmuted purple bags contain 5 dark black bags, 1 vibrant lime bag.\nshiny coral bags contain 4 dim green bags, 4 dim maroon bags, 2 dim chartreuse bags.\npale gold bags contain 2 dim beige bags.\ndim beige bags contain 2 mirrored yellow bags, 5 clear brown bags.\ndull chartreuse bags contain 2 faded red bags, 5 posh maroon bags, 5 clear lavender bags.\nmuted bronze bags contain 5 dim plum bags.\nvibrant coral bags contain 1 faded black bag, 3 light green bags, 1 wavy chartreuse bag.\nclear turquoise bags contain 2 shiny beige bags, 5 mirrored fuchsia bags.\nwavy silver bags contain 5 dim tan bags.\nmuted red bags contain 4 dull gold bags, 1 plaid brown bag, 1 wavy gray bag.\nlight tan bags contain 4 dotted yellow bags, 1 dull maroon bag, 1 light beige bag.\nbright tomato bags contain 1 muted beige bag.\nstriped coral bags contain 3 bright coral bags.\ndotted lime bags contain 2 dull salmon bags.\nmirrored plum bags contain 1 bright fuchsia bag, 1 drab yellow bag, 2 dark plum bags, 2 posh purple bags.\nplaid blue bags contain 5 dull gold bags, 4 wavy gray bags, 5 mirrored violet bags.\nplaid salmon bags contain 4 dim salmon bags, 1 dotted lavender bag.\nclear chartreuse bags contain 5 muted teal bags, 4 clear gold bags, 2 plaid tomato bags.\nmuted blue bags contain 3 faded tomato bags, 5 striped chartreuse bags.\ndim tan bags contain 4 clear lavender bags, 2 clear violet bags, 1 wavy plum bag, 4 pale gold bags.\nbright chartreuse bags contain 2 posh silver bags, 1 vibrant plum bag.\nplaid white bags contain 1 striped red bag, 3 dim beige bags, 3 plaid bronze bags, 2 dim turquoise bags.\nbright coral bags contain 3 shiny gold bags, 2 striped chartreuse bags, 4 light salmon bags, 2 vibrant aqua bags.\nclear indigo bags contain 4 posh orange bags, 4 dull gold bags.\nbright aqua bags contain 1 shiny orange bag.\nfaded bronze bags contain 2 pale gray bags, 3 dull gold bags.\nshiny green bags contain 1 drab chartreuse bag, 4 light salmon bags, 4 striped gold bags.\ndrab black bags contain 4 dark black bags, 1 dotted turquoise bag, 3 wavy gray bags, 3 shiny fuchsia bags.\npale yellow bags contain 2 dim green bags, 3 vibrant aqua bags.\ndull indigo bags contain 2 striped aqua bags, 4 clear chartreuse bags, 4 dark orange bags, 3 posh magenta bags.\nmirrored cyan bags contain 2 dotted purple bags, 5 mirrored violet bags, 2 dotted white bags, 3 bright brown bags.\ndark yellow bags contain 4 faded tan bags, 3 dim turquoise bags, 5 muted fuchsia bags, 5 clear salmon bags.\nwavy yellow bags contain 2 dim bronze bags, 4 drab bronze bags.\nmuted white bags contain 1 dotted black bag, 5 bright plum bags, 1 striped cyan bag, 2 clear turquoise bags.\ndotted gold bags contain 3 shiny fuchsia bags, 5 muted tan bags, 2 clear fuchsia bags.\nlight aqua bags contain 5 faded brown bags, 3 pale blue bags, 2 mirrored green bags.\nplaid violet bags contain 3 bright yellow bags.\nbright silver bags contain 1 drab violet bag, 4 light teal bags.\nwavy red bags contain 3 dotted gray bags, 5 drab fuchsia bags, 1 posh blue bag.\nmirrored tan bags contain 5 light green bags, 2 plaid gray bags, 4 pale orange bags, 1 shiny violet bag.\nmuted tomato bags contain 1 wavy purple bag.\nfaded blue bags contain 3 shiny crimson bags, 1 clear indigo bag.\nshiny purple bags contain 5 clear blue bags, 1 vibrant red bag.\nposh aqua bags contain 4 striped olive bags, 3 pale maroon bags, 1 dim yellow bag, 1 clear red bag.\nstriped white bags contain 1 bright cyan bag, 3 dotted orange bags.\nstriped lime bags contain 1 striped brown bag, 3 dotted chartreuse bags, 3 wavy fuchsia bags, 4 faded magenta bags.\nstriped tan bags contain 1 pale gray bag, 1 light indigo bag, 2 dark coral bags.\nshiny red bags contain 4 dotted gray bags, 1 drab bronze bag, 4 shiny fuchsia bags.\nshiny beige bags contain 3 vibrant beige bags, 2 vibrant indigo bags, 3 plaid blue bags.\ndim fuchsia bags contain 5 pale tan bags.\nplaid tomato bags contain 4 clear red bags.\ndull blue bags contain 4 pale turquoise bags.\ndull red bags contain 5 posh brown bags, 2 dotted tomato bags, 2 striped gold bags.\npale red bags contain 3 plaid brown bags.\nstriped maroon bags contain 3 pale cyan bags, 1 dotted cyan bag, 1 dim tomato bag.\nlight lime bags contain 3 light cyan bags, 4 light olive bags, 4 bright salmon bags, 3 shiny orange bags.\ndrab brown bags contain 3 dim tomato bags, 2 dark gray bags.\nfaded yellow bags contain 3 dotted beige bags, 2 muted blue bags, 2 wavy fuchsia bags, 1 dark magenta bag.\nbright green bags contain 2 pale cyan bags, 5 plaid bronze bags, 5 wavy orange bags.\nwavy bronze bags contain 3 wavy red bags.\ndull gold bags contain no other bags.\nplaid olive bags contain 4 muted white bags, 4 plaid red bags, 5 wavy red bags, 3 posh indigo bags.\ndotted aqua bags contain 3 dim indigo bags, 3 drab coral bags.\npale purple bags contain 1 dotted magenta bag, 3 clear indigo bags, 1 dim turquoise bag, 3 pale blue bags.\nfaded teal bags contain 3 drab maroon bags, 3 clear tan bags, 1 pale gray bag, 4 bright tomato bags.\ndrab chartreuse bags contain 2 drab aqua bags, 4 clear indigo bags.\nlight lavender bags contain 4 faded bronze bags, 1 plaid chartreuse bag.\ndim tomato bags contain 2 dull orange bags, 5 shiny cyan bags, 2 muted purple bags, 2 dotted black bags.\nfaded maroon bags contain 2 faded white bags, 3 dim maroon bags.\npale cyan bags contain 2 plaid brown bags.\nmuted indigo bags contain 4 mirrored red bags, 1 dotted indigo bag, 4 mirrored maroon bags.\nwavy orange bags contain 3 plaid bronze bags.\ndull teal bags contain 5 drab red bags, 4 dim green bags, 3 dotted olive bags, 5 pale maroon bags.\ndull gray bags contain 5 dark tomato bags, 4 dull magenta bags, 4 dotted red bags, 5 faded brown bags.\nvibrant gold bags contain 3 striped beige bags, 5 clear bronze bags.\nposh bronze bags contain 3 pale turquoise bags, 4 posh blue bags.\nstriped plum bags contain 3 pale orange bags, 5 clear tomato bags, 1 light salmon bag.\nshiny chartreuse bags contain 4 dim yellow bags, 4 mirrored yellow bags, 2 clear orange bags, 2 bright red bags.\nvibrant yellow bags contain 4 clear yellow bags, 2 vibrant olive bags, 5 drab salmon bags, 5 light tomato bags.\ndark coral bags contain 1 pale tan bag, 3 dull orange bags, 4 clear brown bags.\ndotted cyan bags contain 5 faded aqua bags, 2 dotted lime bags, 1 dim gray bag.\nlight purple bags contain 5 dotted indigo bags, 2 pale violet bags.\nbright bronze bags contain 1 dim turquoise bag.\nwavy brown bags contain 5 dotted silver bags.\nplaid black bags contain 1 clear magenta bag, 2 faded plum bags.\nposh cyan bags contain 5 muted beige bags, 1 clear brown bag, 3 wavy beige bags.\ndotted green bags contain 4 faded lavender bags, 2 muted blue bags.\nvibrant orange bags contain 1 dark aqua bag.\ndark violet bags contain 1 striped fuchsia bag.\ndark green bags contain 2 dark white bags, 3 vibrant chartreuse bags, 3 mirrored maroon bags.\nshiny aqua bags contain 2 light salmon bags, 5 pale turquoise bags, 1 pale silver bag.\nmirrored gray bags contain 2 dim salmon bags, 4 striped chartreuse bags, 5 dull gray bags, 2 bright white bags.\nbright black bags contain 1 dark aqua bag, 5 dark red bags, 4 faded tomato bags.\ndark purple bags contain 3 striped brown bags.\nvibrant plum bags contain 5 dim fuchsia bags, 1 posh orange bag, 1 dotted purple bag, 1 light blue bag.\npale gray bags contain 1 plaid cyan bag, 2 dim white bags, 1 dotted magenta bag, 4 shiny gold bags.\nstriped green bags contain 2 pale crimson bags, 3 dotted lime bags, 5 posh turquoise bags.\nshiny bronze bags contain 5 dark olive bags, 2 vibrant magenta bags, 4 striped silver bags.\nmuted fuchsia bags contain 5 drab fuchsia bags.\nbright olive bags contain 4 pale blue bags, 5 shiny crimson bags.\nposh lime bags contain 1 dim plum bag, 3 dim magenta bags, 1 mirrored tomato bag, 2 light lavender bags.\nlight crimson bags contain 3 clear turquoise bags, 5 dim brown bags, 3 bright cyan bags, 4 plaid tomato bags.\ndull silver bags contain 5 wavy silver bags.\nclear coral bags contain 5 muted aqua bags.\npale salmon bags contain 3 dark gold bags, 5 wavy orange bags.\npale lime bags contain 3 dim cyan bags, 4 striped turquoise bags, 2 muted aqua bags.\nwavy fuchsia bags contain 2 drab beige bags, 1 faded olive bag, 1 dim beige bag, 3 pale orange bags.\nclear blue bags contain 1 pale black bag, 2 plaid fuchsia bags, 2 mirrored chartreuse bags, 2 bright brown bags.\nmuted teal bags contain 5 pale black bags.\nmuted orange bags contain 4 dim olive bags.\ndotted indigo bags contain 3 drab lime bags.\ndrab yellow bags contain 1 dim beige bag.\nmuted brown bags contain 2 striped red bags, 4 muted green bags, 3 drab chartreuse bags, 4 dark aqua bags.\nposh red bags contain 1 wavy beige bag, 1 wavy tomato bag, 1 faded bronze bag, 1 clear coral bag.\nposh gold bags contain 1 dim chartreuse bag, 1 clear lavender bag, 1 bright fuchsia bag, 3 bright magenta bags.\nposh salmon bags contain 5 plaid red bags, 1 dim purple bag, 1 bright yellow bag.\nwavy black bags contain 5 faded white bags, 3 faded chartreuse bags.\nmirrored crimson bags contain 2 plaid gray bags, 2 vibrant tomato bags, 1 dim bronze bag.\nlight white bags contain 4 dim turquoise bags.\npale violet bags contain 5 dim beige bags.\ndim magenta bags contain 4 striped teal bags.\nstriped teal bags contain 5 drab lime bags, 5 mirrored yellow bags.\ndotted brown bags contain 4 shiny gold bags, 3 wavy brown bags, 4 clear brown bags, 1 clear teal bag.\nbright orange bags contain 2 plaid violet bags, 3 posh aqua bags, 1 clear tan bag.\nshiny gold bags contain 3 dotted magenta bags, 2 shiny beige bags, 3 plaid brown bags, 5 clear indigo bags.\nclear olive bags contain 4 drab red bags.\nplaid purple bags contain 3 plaid gray bags, 3 dim olive bags, 4 dotted purple bags.\npale teal bags contain 4 wavy cyan bags, 4 posh bronze bags.\nmuted cyan bags contain 2 light blue bags, 3 shiny purple bags, 3 dotted white bags.\nplaid chartreuse bags contain 4 clear lime bags, 4 pale red bags.\nwavy crimson bags contain 1 pale gray bag, 3 striped tan bags, 5 muted purple bags.\nbright tan bags contain 1 posh purple bag, 1 light chartreuse bag, 3 dark white bags.\ndark lavender bags contain 1 dotted beige bag, 2 dark tomato bags.\nplaid coral bags contain 5 dotted red bags, 1 dim white bag.\nfaded plum bags contain no other bags.\ndark indigo bags contain 4 drab beige bags, 5 clear red bags, 5 pale red bags, 4 pale blue bags.\nstriped gray bags contain 5 drab teal bags, 4 muted red bags.\nlight red bags contain 2 light gray bags, 3 vibrant aqua bags, 1 dotted aqua bag.\nclear tan bags contain 5 dull gold bags, 3 dim gray bags, 3 dim white bags, 2 light green bags.\npale aqua bags contain 5 dotted purple bags, 1 drab lime bag, 2 clear orange bags.\nvibrant fuchsia bags contain 5 clear turquoise bags, 3 clear red bags, 5 faded green bags.\nclear lime bags contain 3 striped red bags, 1 dull maroon bag.\nmuted gray bags contain 4 muted yellow bags, 4 dotted silver bags, 4 clear orange bags, 5 faded turquoise bags.\ndull fuchsia bags contain 1 dark aqua bag.\nwavy purple bags contain 4 drab teal bags, 3 light blue bags, 3 mirrored violet bags.\nvibrant teal bags contain 2 striped white bags, 4 dull red bags, 3 plaid chartreuse bags, 5 dotted salmon bags.\ndotted lavender bags contain 4 dim purple bags, 4 clear orange bags, 4 vibrant beige bags.\nclear gray bags contain 4 dotted tan bags, 1 dull gold bag, 4 dull gray bags.\nwavy violet bags contain 3 bright blue bags, 3 shiny purple bags, 2 bright fuchsia bags.\ndull cyan bags contain 4 clear green bags.\ndim blue bags contain 1 light brown bag, 3 faded indigo bags.\nbright magenta bags contain 1 dim brown bag, 4 wavy purple bags, 3 dotted red bags.\ndark cyan bags contain 4 vibrant maroon bags, 2 wavy salmon bags.\nvibrant magenta bags contain 4 plaid orange bags, 1 faded red bag.\nbright gray bags contain 5 dotted magenta bags, 3 clear olive bags, 1 bright fuchsia bag, 2 muted silver bags.\nwavy maroon bags contain 5 mirrored violet bags, 4 clear orange bags, 5 drab olive bags.\ndotted maroon bags contain 5 pale purple bags, 5 faded silver bags, 5 dotted lime bags.\ndrab indigo bags contain 5 light chartreuse bags.\ndark brown bags contain 4 bright red bags.\nbright blue bags contain 2 shiny cyan bags.\nbright brown bags contain 5 dark coral bags, 5 dim fuchsia bags.\ndotted orange bags contain 5 bright fuchsia bags, 2 dull gold bags.\nmirrored red bags contain 4 dotted salmon bags, 3 dark red bags, 3 drab teal bags, 4 pale blue bags.\nplaid red bags contain 2 light maroon bags, 3 drab tomato bags.\ndrab violet bags contain 2 vibrant cyan bags.\nvibrant olive bags contain 1 clear maroon bag, 3 clear green bags, 5 drab aqua bags.\nplaid plum bags contain 3 vibrant plum bags.\ndim coral bags contain 2 dull aqua bags, 3 vibrant tan bags, 5 muted fuchsia bags, 1 plaid silver bag.\nvibrant green bags contain 4 pale gray bags, 4 posh fuchsia bags, 3 bright lime bags, 5 faded blue bags.\nmuted beige bags contain 5 drab fuchsia bags.\nvibrant maroon bags contain 1 faded aqua bag.\nmuted yellow bags contain 3 clear maroon bags, 2 striped crimson bags, 4 mirrored maroon bags, 3 vibrant olive bags.\nfaded salmon bags contain 4 faded olive bags, 1 muted purple bag, 3 dotted yellow bags, 3 dim silver bags.\npale beige bags contain 3 mirrored tan bags.\nplaid lavender bags contain 2 bright magenta bags, 4 bright indigo bags, 1 posh tomato bag.\ndrab aqua bags contain 4 wavy magenta bags, 3 mirrored olive bags, 1 muted tomato bag, 3 posh orange bags.\nbright indigo bags contain 3 pale violet bags, 3 dark lavender bags, 4 muted plum bags, 3 striped crimson bags.\nclear black bags contain 4 wavy aqua bags, 3 light yellow bags.\ndrab gray bags contain 1 muted aqua bag, 3 plaid fuchsia bags.\nstriped beige bags contain 1 vibrant blue bag, 5 dotted tomato bags.\nfaded orange bags contain 2 mirrored maroon bags.\ndark orange bags contain 1 muted maroon bag, 5 drab indigo bags.\nmirrored coral bags contain 3 faded aqua bags, 2 drab lime bags.\ndim red bags contain 5 muted fuchsia bags.\ndark aqua bags contain 3 shiny gold bags, 4 pale blue bags, 3 dull magenta bags.\ndim gold bags contain 1 plaid blue bag, 1 posh fuchsia bag.\nstriped black bags contain 2 shiny gold bags.\nshiny turquoise bags contain 4 pale purple bags, 5 faded blue bags.\ndim chartreuse bags contain 2 pale coral bags.\ndrab red bags contain 5 mirrored olive bags, 5 vibrant beige bags.\nposh chartreuse bags contain 3 pale violet bags, 3 muted beige bags.\nlight black bags contain 3 mirrored maroon bags, 5 dull tan bags, 5 posh crimson bags, 3 dark gray bags.\nvibrant aqua bags contain 2 plaid coral bags.\npale olive bags contain 5 wavy lavender bags, 2 posh olive bags, 4 dim black bags, 3 drab cyan bags.\nmirrored aqua bags contain 3 mirrored violet bags.\nmuted lime bags contain 4 mirrored cyan bags, 1 drab turquoise bag, 5 wavy fuchsia bags.\ndull coral bags contain 4 muted lime bags, 4 dim white bags.\nfaded tomato bags contain 3 pale violet bags, 4 faded brown bags.\nmirrored fuchsia bags contain 3 dotted purple bags, 4 pale lavender bags.\nplaid magenta bags contain 3 light plum bags, 3 striped orange bags.\nclear teal bags contain 4 plaid blue bags.\nfaded fuchsia bags contain 1 dull purple bag, 2 bright brown bags.\nmirrored brown bags contain 4 faded bronze bags, 5 faded beige bags.\nmuted silver bags contain 2 dull gold bags, 4 clear orange bags, 2 dotted purple bags, 5 dim olive bags.\ndull bronze bags contain 4 shiny cyan bags, 1 posh cyan bag.\ndark silver bags contain 1 shiny olive bag, 2 drab aqua bags, 2 striped fuchsia bags, 4 mirrored tan bags.\nbright white bags contain 4 dark aqua bags, 5 plaid tomato bags, 5 drab green bags, 4 muted red bags.\ndark gold bags contain 2 dim teal bags, 4 shiny fuchsia bags.\ndull olive bags contain 5 mirrored orange bags, 3 drab gray bags, 1 shiny turquoise bag, 5 dull cyan bags.\nwavy olive bags contain 1 wavy cyan bag.\ndotted white bags contain no other bags.\nplaid gray bags contain 3 dim beige bags, 2 dotted magenta bags, 5 vibrant indigo bags.\ndim bronze bags contain 5 dark aqua bags.\ndotted yellow bags contain 2 wavy blue bags.\nmuted lavender bags contain 2 faded aqua bags.\ndim teal bags contain 5 pale gold bags.\nposh teal bags contain 1 muted plum bag, 5 clear tomato bags, 1 clear white bag.\nfaded turquoise bags contain 1 wavy teal bag, 1 plaid red bag.\nvibrant lime bags contain 4 vibrant beige bags, 5 drab lime bags.\nclear plum bags contain 1 vibrant beige bag.\nmirrored black bags contain 5 wavy white bags.\nmirrored orange bags contain 1 wavy turquoise bag.\nvibrant purple bags contain 2 faded crimson bags, 2 dull red bags, 3 plaid blue bags.\nposh maroon bags contain 5 clear orange bags, 5 vibrant indigo bags, 2 drab lime bags, 5 posh orange bags.\nplaid maroon bags contain 2 pale silver bags, 5 dotted salmon bags, 1 dotted plum bag, 3 bright olive bags.\nposh blue bags contain 1 dark coral bag, 2 vibrant lime bags, 4 pale orange bags, 1 plaid blue bag.\nmuted black bags contain 2 dim gold bags.\nclear red bags contain 5 pale lavender bags, 1 bright brown bag, 5 muted red bags, 4 dull orange bags.\nplaid teal bags contain 1 dark coral bag, 3 dull orange bags.\nlight tomato bags contain 4 dotted white bags, 1 pale blue bag, 1 dull coral bag.\nmirrored turquoise bags contain 1 shiny green bag, 1 wavy plum bag, 1 dull orange bag.\npale coral bags contain 2 shiny fuchsia bags, 1 dull gold bag, 5 dim plum bags, 5 dark black bags.\nmuted aqua bags contain 5 posh maroon bags, 4 dim gray bags, 3 pale aqua bags, 1 light crimson bag.\nshiny yellow bags contain 2 faded plum bags.\nfaded tan bags contain 2 dark maroon bags.\nclear fuchsia bags contain 4 light white bags, 5 posh maroon bags.\nlight brown bags contain 4 dim olive bags, 5 drab chartreuse bags, 5 posh maroon bags, 3 pale violet bags.\nmuted maroon bags contain 2 wavy silver bags.\nwavy aqua bags contain 4 pale purple bags.\nmirrored beige bags contain 4 posh brown bags.\ndrab salmon bags contain 3 striped red bags, 1 dull gray bag, 3 posh white bags.\ndotted crimson bags contain 2 light teal bags, 4 bright black bags, 3 drab teal bags.\nmuted violet bags contain 3 bright coral bags.\ndim green bags contain 1 drab violet bag, 5 dotted beige bags.\nstriped salmon bags contain 4 dull chartreuse bags, 2 dark indigo bags.\ndull black bags contain 3 dotted silver bags.\nshiny maroon bags contain 3 vibrant lavender bags, 3 clear lavender bags, 4 dull teal bags, 5 wavy maroon bags.\nfaded white bags contain 1 plaid silver bag, 3 pale gold bags.\nlight orange bags contain 3 pale red bags, 3 dull purple bags, 3 bright cyan bags, 4 dim lavender bags.\nposh plum bags contain 1 clear silver bag, 2 clear maroon bags.\nvibrant indigo bags contain 3 pale lavender bags, 5 dotted purple bags, 5 dotted white bags, 2 wavy magenta bags.\ndotted beige bags contain 3 muted tomato bags, 3 clear brown bags, 1 plaid gray bag, 2 faded olive bags.\ndim plum bags contain no other bags.\npale white bags contain 3 vibrant beige bags.\nwavy salmon bags contain 1 dim black bag, 4 faded gray bags, 5 dim maroon bags.\npale chartreuse bags contain 5 mirrored white bags, 4 posh teal bags, 2 muted plum bags.\npale tan bags contain no other bags.\nvibrant black bags contain 4 vibrant tan bags.\nmirrored bronze bags contain 5 pale aqua bags, 2 wavy olive bags, 1 posh olive bag.\nbright teal bags contain 2 dark lavender bags, 5 muted fuchsia bags.\nstriped silver bags contain 5 dull cyan bags, 5 striped teal bags, 2 posh blue bags.\nshiny white bags contain 3 shiny violet bags, 3 dotted cyan bags, 3 dotted purple bags.\ndark salmon bags contain 5 dotted lime bags, 1 pale orange bag, 1 vibrant red bag, 5 wavy purple bags.\nvibrant crimson bags contain 4 clear red bags, 4 faded gray bags.\npale blue bags contain 5 striped cyan bags.\ndrab bronze bags contain 1 drab teal bag.\nwavy magenta bags contain 4 vibrant beige bags, 4 bright fuchsia bags, 1 mirrored yellow bag, 4 dim fuchsia bags.\nfaded violet bags contain 4 wavy gray bags.\ndrab cyan bags contain 1 light gray bag, 5 plaid bronze bags, 5 dull aqua bags, 2 vibrant gray bags.\ndotted turquoise bags contain 2 mirrored indigo bags, 4 plaid plum bags, 4 faded red bags, 3 dim gray bags.\ndotted olive bags contain 4 vibrant beige bags.\nposh turquoise bags contain 1 light fuchsia bag, 5 plaid red bags, 5 bright coral bags.\ndull tomato bags contain 5 light blue bags, 2 plaid plum bags, 3 dotted lime bags.\npale fuchsia bags contain 3 drab orange bags, 4 bright lime bags, 3 pale tan bags.\ndrab tomato bags contain 2 posh magenta bags, 3 vibrant fuchsia bags, 3 dim fuchsia bags.\nvibrant silver bags contain 1 posh turquoise bag.\npale black bags contain 3 dark coral bags, 3 dim plum bags, 4 shiny beige bags.\nwavy chartreuse bags contain 3 drab violet bags, 1 vibrant orange bag, 2 dim gray bags.\ndull crimson bags contain 3 mirrored plum bags, 2 dotted orange bags, 3 faded brown bags.\nclear beige bags contain 4 wavy tomato bags, 1 muted lavender bag, 5 bright magenta bags, 3 dotted indigo bags.\nshiny teal bags contain 3 drab red bags.\nbright lavender bags contain 4 drab fuchsia bags, 4 vibrant olive bags, 2 clear olive bags.\nposh tan bags contain 5 drab crimson bags, 5 bright lavender bags.\ndim turquoise bags contain 2 dim fuchsia bags.\nlight violet bags contain 4 wavy tomato bags, 5 dark green bags, 1 vibrant violet bag.\nbright crimson bags contain 2 posh white bags.\nstriped olive bags contain 3 light indigo bags.\nmuted crimson bags contain 1 wavy magenta bag, 1 mirrored fuchsia bag.\nmuted chartreuse bags contain 5 faded tan bags.\ndull white bags contain 5 faded red bags, 5 dim plum bags.\nbright lime bags contain 5 posh blue bags, 2 pale aqua bags, 3 light red bags.\nshiny fuchsia bags contain 4 faded olive bags, 2 dim turquoise bags, 1 plaid blue bag.\nfaded silver bags contain 2 muted red bags, 5 pale purple bags.\nlight plum bags contain 1 vibrant aqua bag.\ndark magenta bags contain 4 striped purple bags, 5 bright lime bags, 2 dull magenta bags, 2 dim black bags.\nclear cyan bags contain 3 bright brown bags, 3 mirrored gold bags, 2 faded plum bags, 5 shiny purple bags.\nplaid turquoise bags contain 5 posh orange bags, 4 light gray bags.\nclear brown bags contain 1 plaid brown bag, 5 posh violet bags.\nposh black bags contain 3 dark coral bags, 1 pale cyan bag, 2 faded gray bags.\nmirrored violet bags contain no other bags.\nbright fuchsia bags contain no other bags.\nstriped chartreuse bags contain 4 pale lavender bags, 2 wavy gray bags, 2 pale violet bags.\ndark tan bags contain 3 dotted white bags.\ndim gray bags contain 5 dim beige bags.\nplaid beige bags contain 4 wavy lavender bags, 4 clear lime bags, 3 posh magenta bags, 3 dotted crimson bags.\ndim aqua bags contain 3 wavy cyan bags.\nwavy teal bags contain 5 drab aqua bags, 5 vibrant beige bags, 1 plaid tomato bag.\ndark red bags contain 1 drab fuchsia bag, 1 pale gold bag, 5 dark tomato bags, 5 shiny beige bags.\nvibrant white bags contain 5 wavy aqua bags, 2 muted cyan bags.\nmuted turquoise bags contain 2 faded crimson bags.\ndark maroon bags contain 4 vibrant orange bags.\ndotted red bags contain 4 dark coral bags.\nstriped violet bags contain 4 drab teal bags, 1 pale gray bag.\nlight green bags contain 1 pale orange bag, 3 dim fuchsia bags.\nstriped purple bags contain 4 pale black bags.\nclear tomato bags contain 4 dark white bags.\ndim indigo bags contain 3 pale tan bags, 2 mirrored cyan bags, 5 dotted crimson bags, 4 wavy lavender bags.\nposh silver bags contain 4 mirrored orange bags, 5 dotted lavender bags.\ndim silver bags contain 5 faded purple bags, 5 striped olive bags, 5 striped tan bags.\nlight beige bags contain 2 bright plum bags, 2 dull salmon bags.\nposh yellow bags contain 4 dotted crimson bags, 5 dark salmon bags, 4 pale yellow bags.\ndark lime bags contain 3 posh crimson bags, 5 posh purple bags, 1 light black bag.\nclear silver bags contain 3 faded olive bags, 3 drab turquoise bags, 4 drab purple bags.\nvibrant cyan bags contain 5 vibrant plum bags.\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_07_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 7\n------------------------------------------\n--  Handy Haversacks\n--\n--  https://adventofcode.com/2020/day/7\n--\n--  Full Ada version.\n--  Rules as Vector's, small arrays within each rule.\n--\nwith Ada.Containers.Vectors,\n     Ada.Text_IO;\n\nprocedure AoC_2020_07_full_Ada is\n  use Ada.Text_IO;\n\n  type Base_Colour is\n    (aqua, beige, black, blue, bronze, brown, chartreuse, coral, crimson, cyan, fuchsia, gold,\n     gray, green, indigo, lavender, lime, magenta, maroon, olive, orange, plum, purple, red,\n     salmon, silver, tan, teal, tomato, turquoise, violet, white, yellow);\n\n  type Colour_Qualifier is\n    (bright, clear, dark, dim, dotted, drab, dull, faded, light,\n     mirrored, muted, other, pale, plaid, posh, shiny, striped, vibrant, wavy);\n\n  package BCIO is new Enumeration_IO (Base_Colour);\n  package CQIO is new Enumeration_IO (Colour_Qualifier);\n  package IIO is new Integer_IO (Integer);\n  use BCIO, CQIO, IIO;\n\n  type Colour is record\n    cq : Colour_Qualifier;\n    bc : Base_Colour;\n  end record;\n\n  type Contained_Spec is record\n    col : Colour;\n    num : Natural;\n  end record;\n\n  subtype Contains_Range is Integer range 1 .. 4;\n\n  type Contains_List is array (Contains_Range) of Contained_Spec;\n\n  type Rule is record\n    container   : Colour;\n    num_contain : Natural := 0;\n    contains    : Contains_List;\n    can_contain : Boolean;  --  Used for marking container bag rule without double-counting.\n  end record;\n\n  package Rules_Pkg is new Ada.Containers.Vectors (Positive, Rule);\n\n  rules : Rules_Pkg.Vector;\n\n  details : constant Boolean := False;\n\n  procedure Put (c : Colour) is\n  begin\n    Put (c.cq); Put (\"~\"); Put (c.bc);\n  end Put;\n\n  function Containing_Bags (c : Colour) return Natural is\n    --\n    procedure Scan_Containing_Bags (c : Colour) is\n      is_top : Boolean := True;\n    begin\n      for r of rules loop\n        for cti in 1 .. r.num_contain loop\n          if r.contains (cti).col = c then\n            is_top := False;\n            r.can_contain := True;\n            if details then\n              Put (\"   container of \"); Put (c); Put (\" is \"); Put (r.container); New_Line;\n            end if;\n            Scan_Containing_Bags (r.container);\n          end if;\n        end loop;\n      end loop;\n      if is_top and details then\n        Put (\"Top: \"); Put (c); New_Line;\n      end if;\n    end Scan_Containing_Bags;\n    --\n    can_contain_count : Natural := 0;\n  begin\n    for r of rules loop\n      r.can_contain := False;\n    end loop;\n    Scan_Containing_Bags (c);\n    for r of rules loop\n      if r.can_contain then\n        can_contain_count := can_contain_count + 1;\n      end if;\n    end loop;\n    return can_contain_count;\n  end Containing_Bags;\n\n  function Contained_Bags (c : Colour) return Natural is\n    contained : Natural := 0;\n  begin\n    for r of rules loop\n      if r.container = c then\n        if details then\n          Put (\"Container \"); Put (c); New_Line;\n        end if;\n        for cti in 1 .. r.num_contain loop\n          contained := contained +\n            r.contains (cti).num * (1 + Contained_Bags (r.contains (cti).col));\n        end loop;\n        exit;\n      end if;\n    end loop;\n    return contained;\n  end Contained_Bags;\n\n  procedure Get_Rules is\n    f : File_Type;\n    sep : Character;\n    new_rule : Rule;\n    new_spec : Contained_Spec;\n    bags_contain : String := \" bags contain\";\n  begin\n    Open (f, In_File, \"aoc_2020_07.txt\");\n    while not End_Of_File (f) loop\n      Get (f, new_rule.container.cq);\n      Get (f, new_rule.container.bc);\n      if details then\n        Put (new_rule.container);\n      end if;\n      Get (f, bags_contain);\n      if details then\n        Put (bags_contain & \": \");\n      end if;\n      new_rule.num_contain := 0;\n      loop\n        begin\n          Get (f, new_spec.num);\n        exception\n          when Data_Error =>  --  \"no other bags\"\n            Skip_Line (f);\n            exit;\n        end;\n        Get (f, new_spec.col.cq);\n        Get (f, new_spec.col.bc);\n        if details then\n          Put (new_spec.num, 2);\n          Put (\" \");\n          Put (new_spec.col);\n          Put (\"   \");\n        end if;\n        new_rule.num_contain := new_rule.num_contain + 1;\n        new_rule.contains (new_rule.num_contain) := new_spec;\n        loop\n          Get (f, sep);\n          exit when sep = ',' or sep = '.';\n        end loop;\n        exit when End_Of_Line (f);\n      end loop;\n      if details then\n        New_Line;\n      end if;\n      rules.Append (new_rule);\n    end loop;\n    Close (f);\n  end Get_Rules;\n  --\nbegin\n  Get_Rules;\n  Put_Line (\"Rules about bag contents:\" & rules.Length'Image);\n  Put_Line (\"Part 1: all possible direct or indirect containers of shiny gold:\" &\n              Containing_Bags ((shiny, gold))'Image);\n  Put_Line (\"Part 2: all bags contained by shiny gold:\" &\n              Contained_Bags ((shiny, gold))'Image);\n  --  Rules: 594\n  --  Part 1: all possible direct or indirect containers of shiny gold: 169\n  --  Part 2: all bags contained by shiny gold: 82372\nend AoC_2020_07_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_07_full_ada_vectors_2x.adb",
    "content": "--  Solution to Advent of Code 2020, Day 7\n------------------------------------------\n--  Handy Haversacks\n--\n--  https://adventofcode.com/2020/day/7\n--\n--  Full Ada version.\n--  Rules as Vector's, Vector of Contained_Spec each rule.\n--\nwith Ada.Containers.Vectors,\n     Ada.Text_IO;\n\nprocedure AoC_2020_07_full_Ada_Vectors_2x is\n  use Ada.Text_IO;\n\n  type Base_Colour is\n    (aqua, beige, black, blue, bronze, brown, chartreuse, coral, crimson, cyan, fuchsia, gold,\n     gray, green, indigo, lavender, lime, magenta, maroon, olive, orange, plum, purple, red,\n     salmon, silver, tan, teal, tomato, turquoise, violet, white, yellow);\n\n  type Colour_Qualifier is\n    (bright, clear, dark, dim, dotted, drab, dull, faded, light,\n     mirrored, muted, other, pale, plaid, posh, shiny, striped, vibrant, wavy);\n\n  package BCIO is new Enumeration_IO (Base_Colour);\n  package CQIO is new Enumeration_IO (Colour_Qualifier);\n  package IIO is new Integer_IO (Integer);\n  use BCIO, CQIO, IIO;\n\n  type Colour is record\n    cq : Colour_Qualifier;\n    bc : Base_Colour;\n  end record;\n\n  type Contained_Spec is record\n    col : Colour;\n    num : Natural;\n  end record;\n\n  package Contains_Pkg is new Ada.Containers.Vectors (Positive, Contained_Spec);\n\n  type Rule is record\n    container   : Colour;\n    contains    : Contains_Pkg.Vector;\n    can_contain : Boolean;  --  Used for marking container bag rule without double-counting.\n  end record;\n\n  package Rules_Pkg is new Ada.Containers.Vectors (Positive, Rule);\n\n  rules : Rules_Pkg.Vector;\n\n  details : constant Boolean := False;\n\n  procedure Put (c : Colour) is\n  begin\n    Put (c.cq); Put (\"~\"); Put (c.bc);\n  end Put;\n\n  function Containing_Bags (c : Colour) return Natural is\n    --\n    procedure Scan_Containing_Bags (c : Colour) is\n      is_top : Boolean := True;\n    begin\n      for r of rules loop\n        for ct of r.contains loop\n          if ct.col = c then\n            is_top := False;\n            r.can_contain := True;\n            if details then\n              Put (\"   container of \"); Put (c); Put (\" is \"); Put (r.container); New_Line;\n            end if;\n            Scan_Containing_Bags (r.container);\n          end if;\n        end loop;\n      end loop;\n      if is_top and details then\n        Put (\"Top: \"); Put (c); New_Line;\n      end if;\n    end Scan_Containing_Bags;\n    --\n    can_contain_count : Natural := 0;\n  begin\n    for r of rules loop\n      r.can_contain := False;\n    end loop;\n    Scan_Containing_Bags (c);\n    for r of rules loop\n      if r.can_contain then\n        can_contain_count := can_contain_count + 1;\n      end if;\n    end loop;\n    return can_contain_count;\n  end Containing_Bags;\n\n  function Contained_Bags (c : Colour) return Natural is\n    contained : Natural := 0;\n  begin\n    for r of rules loop\n      if r.container = c then\n        if details then\n          Put (\"Container \"); Put (c); New_Line;\n        end if;\n        for ct of r.contains loop\n          contained := contained +\n            ct.num * (1 + Contained_Bags (ct.col));\n        end loop;\n        exit;\n      end if;\n    end loop;\n    return contained;\n  end Contained_Bags;\n\n  procedure Get_Rules is\n    f : File_Type;\n    sep : Character;\n    new_rule : Rule;\n    new_spec : Contained_Spec;\n    bags_contain : String := \" bags contain\";\n  begin\n    Open (f, In_File, \"aoc_2020_07.txt\");\n    while not End_Of_File (f) loop\n      Get (f, new_rule.container.cq);\n      Get (f, new_rule.container.bc);\n      if details then\n        Put (new_rule.container);\n      end if;\n      Get (f, bags_contain);\n      if details then\n        Put (bags_contain & \": \");\n      end if;\n      --  If you forget the following, the executable built by\n      --  GNAT for Win64, Win32 breaks without STORAGE_ERROR.\n      new_rule.contains.Clear;\n      loop\n        begin\n          Get (f, new_spec.num);\n        exception\n          when Data_Error =>  --  \"no other bags\"\n            Skip_Line (f);\n            exit;\n        end;\n        Get (f, new_spec.col.cq);\n        Get (f, new_spec.col.bc);\n        if details then\n          Put (new_spec.num, 2);\n          Put (\" \");\n          Put (new_spec.col);\n          Put (\"   \");\n        end if;\n        new_rule.contains.Append (new_spec);\n        loop\n          Get (f, sep);\n          exit when sep = ',' or sep = '.';\n        end loop;\n        exit when End_Of_Line (f);\n      end loop;\n      if details then\n        New_Line;\n      end if;\n      rules.Append (new_rule);\n    end loop;\n    Close (f);\n  end Get_Rules;\n  --\nbegin\n  Get_Rules;\n  Put_Line (\"Rules about bag contents:\" & rules.Length'Image);\n  Put_Line (\"Part 1: all possible direct or indirect containers of shiny gold:\" &\n              Containing_Bags ((shiny, gold))'Image);\n  Put_Line (\"Part 2: all bags contained by shiny gold:\" &\n              Contained_Bags ((shiny, gold))'Image);\n  --  Rules: 594\n  --  Part 1: all possible direct or indirect containers of shiny gold: 169\n  --  Part 2: all bags contained by shiny gold: 82372\nend AoC_2020_07_full_Ada_Vectors_2x;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_08.adb",
    "content": "--  Solution to Advent of Code 2020, Day 8\n------------------------------------------\n--  Handheld Halting\n--\n--  https://adventofcode.com/2020/day/8\n--\n--  HAC 0.085 \"nice to have\"'s detected in this exercise:\n--    *     `  seen := (others => False);  `\n--\n--  Solved in HAC 0.099:\n--    *     I/O with enums, at least 'Image and 'Value.\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_08 is\n  subtype Machine_Code_Range is Positive range 1 .. 1000;\n  type Instr is (acc, jmp, nop);\n  code : array (Machine_Code_Range) of Instr;\n  oper : array (Machine_Code_Range) of Integer;\n  last : Natural := 0;\n  --\n  procedure Run (result : out Integer; ok : out Boolean) is\n    seen : array (Machine_Code_Range) of Boolean;\n    a : Integer := 0;\n    c : Integer := 1;\n  begin\n    --\n    for x in 1 .. last loop\n      seen (x) := False;\n    end loop;\n    while c <= last loop\n      seen (c) := True;\n      case code (c) is\n        when nop => c := c + 1;\n        when acc => a := a + oper (c); c := c + 1;\n        when jmp => c := c + oper (c);\n      end case;\n      exit when seen (c);\n    end loop;\n    ok := c > last;  --  Went past the last instruction: program terminated.\n    result := a;\n  end Run;\n  --\n  procedure Swap (c : Integer) is\n  begin\n    case code (c) is\n      when nop => code (c) := jmp;\n      when acc => null;\n      when jmp => code (c) := nop;\n    end case;\n  end Swap;\n  --\n  function Exit_Diagnostic (x : Boolean) return VString is\n  begin\n    if x then\n      return +\"correct exit!\";\n    else\n      return +\"infinite loop detected.\";\n    end if;\n  end Exit_Diagnostic;\n  --\n  asm : String (1 .. 3);\n  i : Instr := nop;\n  v, a1, a2 : Integer;\n  f : File_Type;\n  done_1, done_2 : Boolean;\n  test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  Open (f, \"aoc_2020_08.txt\");\n  while not End_Of_File (f) loop\n    Get (f, asm);\n    if asm = \"acc\" then i := acc; end if;\n    if asm = \"jmp\" then i := jmp; end if;\n    if asm = \"nop\" then i := nop; end if;\n    Get (f, v);\n    last := last + 1;\n    code (last) := i;\n    oper (last) := v;\n  end loop;\n  Close (f);\n  if not test_mode then Put_Line (+\"Instructions: \" & last); end if;\n  --\n  Run (a1, done_1);\n  --\n  --  Try fixing the machine code by swapping \"nop\" and \"jmp\" instructions:\n  --\n  for c in 1 .. last loop\n    Swap (c);\n    Run (a2, done_2);\n    exit when done_2;\n    Swap (c);\n  end loop;\n  --\n  if test_mode then\n    if a1 /= Integer_Value (Argument (1)) or\n       a2 /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Accumulator = \" & a1 & \";  \" & Exit_Diagnostic (done_1));\n    Put_Line (+\"Accumulator = \" & a2 & \";  \" & Exit_Diagnostic (done_2));\n    --  Part 1: validated by AoC: 1394\n    --  Part 2: validated by AoC: 1626\n  end if;\nend AoC_2020_08;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_08.txt",
    "content": "acc -17\nnop +318\njmp +1\nacc -10\njmp +394\nacc +43\nacc +47\nnop +570\njmp +176\nacc -9\njmp +322\njmp +73\nacc +4\nacc -4\njmp +460\njmp +228\nacc +25\nacc +39\njmp +50\nacc -12\nacc -14\nnop +275\njmp +489\nacc -11\njmp +338\nacc +21\nacc +10\njmp +1\nacc +20\njmp +445\nacc +7\njmp +419\nacc -8\nacc +32\njmp +181\nacc +19\nacc +5\nacc +46\njmp +417\nacc +28\nacc +23\nacc +16\njmp +225\njmp +317\njmp +309\njmp +69\nacc -6\nacc -6\njmp +127\nacc +49\nnop -38\njmp +467\nacc +0\nacc -12\nacc -14\njmp -46\nacc +14\nacc +2\nacc +2\njmp +311\nacc +33\njmp +364\nnop +234\nacc +24\nacc +37\nacc +18\njmp +22\njmp +303\njmp +414\njmp +318\nacc +22\nacc +27\njmp +1\njmp +150\nacc +34\nacc +15\nnop +200\nacc +6\njmp +320\nnop +534\nacc +29\njmp +147\nnop -20\njmp +255\njmp +10\nacc -15\nacc +3\njmp +338\nnop +362\nacc -4\njmp +1\njmp +286\nacc -1\njmp +497\nacc -4\nacc +23\nacc +4\njmp +400\nacc +35\nacc +50\njmp +133\nacc -17\njmp -90\njmp +7\nacc -17\njmp +472\nacc +20\njmp +280\njmp +133\njmp -15\njmp +16\nacc -19\nacc -2\njmp -64\nacc -17\njmp +1\njmp +385\nacc -5\nacc +34\njmp +382\nacc +24\nacc -17\nacc +0\nacc +15\njmp +466\njmp +300\nacc +16\njmp +302\nnop +479\nacc +16\njmp +71\nacc +23\njmp +1\nacc +8\njmp +154\njmp +410\nacc -8\njmp +402\nacc +48\nacc +42\nacc +22\nacc +35\njmp +50\njmp -7\nacc -13\nacc +37\nacc +24\njmp +243\njmp +410\nacc -3\nacc +45\njmp +416\nacc +2\nacc +25\njmp -109\njmp -41\njmp +318\nacc -8\nacc -12\njmp +169\nnop +393\nacc +7\nacc -12\nacc +35\njmp +381\nacc +41\nnop -98\nacc +15\nacc -19\njmp +218\nacc +24\nacc +47\njmp +65\nacc +29\njmp -129\nacc +23\nacc -13\nnop +60\njmp -26\nnop -4\nacc -5\nacc +13\nnop -12\njmp -13\njmp -53\nacc +21\njmp +276\nnop -27\njmp +165\nacc +42\nnop +43\njmp +1\nacc +26\nacc +22\nacc -3\njmp +405\nacc +29\nnop -118\nacc +21\nnop -190\njmp +217\nacc -1\nnop +223\nacc -8\nacc +45\njmp +49\nacc +8\nacc +22\njmp +209\nacc +44\njmp +66\nacc +7\nacc -7\nacc +48\njmp +318\nnop +398\nacc +2\njmp +16\nnop +207\nnop +358\nacc +45\nacc +48\njmp +267\nnop +248\nacc +26\njmp +307\nacc +27\njmp -197\njmp -68\nacc +34\nacc +25\nacc -13\njmp +133\njmp -77\nacc -13\nacc +10\njmp -193\njmp -62\nacc +4\nacc -14\njmp +261\njmp +151\njmp +208\nacc -10\njmp +40\nacc +31\njmp -216\nacc +23\nacc +34\njmp +364\nnop +205\nacc -3\nacc +14\njmp +59\nnop +359\nacc -4\njmp +1\njmp -248\nacc +47\nacc +35\njmp +184\nacc +16\nnop -92\nacc -12\njmp +354\nacc +27\njmp -152\nacc -14\nacc -16\nacc +43\njmp +147\nacc +45\nacc +24\nacc +6\nnop -46\njmp +21\nacc +26\njmp +1\njmp +293\nacc -8\nacc +12\nacc -19\nacc -9\njmp +94\njmp +299\nacc +10\nacc -2\njmp +75\nacc -7\nacc +3\nacc +47\njmp +171\nacc +16\nacc +44\nacc -3\njmp +14\nacc +30\nacc +34\njmp -178\nacc +35\nnop -238\nacc +39\njmp +1\njmp -133\nacc +34\nacc -6\njmp -276\nacc +1\njmp -207\nacc +10\njmp -43\njmp -302\nacc -1\nnop -29\njmp +1\nacc +17\njmp -281\nacc +17\njmp -109\njmp +1\nacc +13\nnop -9\njmp +245\nacc +5\nnop -15\nacc +3\nacc +7\njmp +65\nacc -11\njmp -313\nacc +47\njmp +29\njmp -289\nacc +18\nacc -17\nnop +73\nacc -12\njmp +80\nacc +32\nacc -4\nacc +3\njmp -126\nacc +16\njmp -275\nnop -188\nacc -3\nacc +14\njmp -155\nacc +33\nacc -19\nnop -166\nacc +20\njmp +30\nnop -169\nacc +49\nnop +168\njmp -24\nnop -345\nacc +34\njmp -40\njmp -56\njmp +29\njmp +191\nacc +24\njmp +219\nacc +34\nacc +27\nacc +11\njmp -260\njmp -339\nacc +15\nnop +16\njmp +1\njmp +138\njmp +1\njmp +1\njmp +14\nacc -11\nacc +45\njmp -19\nacc +0\njmp +27\nacc +0\nnop +128\njmp -65\nnop -23\njmp -318\njmp -325\njmp +1\njmp -229\njmp -270\njmp -137\nacc +34\nacc +7\njmp +1\njmp -346\nacc +18\njmp +37\nacc +40\nacc -16\nnop -146\nacc +35\njmp -12\nacc +1\nacc +27\nacc +44\nacc +8\njmp -276\nacc +16\nacc +42\nnop -342\nacc +13\njmp -165\nacc -11\nacc -17\nacc -10\njmp -26\nacc +10\nacc +43\njmp -276\nacc +5\nacc +34\nacc +17\nacc -9\njmp +99\nacc +29\njmp -370\nacc -11\njmp -412\nacc +47\nacc +21\nacc -12\njmp -136\njmp -124\nacc +12\nacc +0\nacc +25\nacc +27\njmp -290\nacc +5\nacc +49\nacc +32\nnop +29\njmp -202\nnop -296\nacc -12\nacc +9\nacc +21\njmp +23\njmp -345\nacc +26\nnop -123\njmp -373\nnop +118\njmp +43\nacc -15\njmp -386\njmp +1\nnop -370\nacc +47\nnop -141\njmp -426\nacc +42\nacc +12\nacc +4\nnop -103\njmp -122\nacc +23\nacc -4\nacc +11\njmp -314\njmp -73\nnop -1\njmp -411\nacc +13\nacc +9\nnop -372\njmp -293\nacc +46\nacc +3\nacc -1\njmp +86\nacc +36\njmp +100\nacc +27\nacc +49\nnop -4\nacc +47\njmp -445\nacc +31\nacc +47\nacc -11\nacc +14\njmp -181\nnop -438\nacc +31\njmp -428\nnop -115\nnop -244\njmp -464\njmp -29\nnop -240\njmp -241\nacc -12\njmp -329\nnop +78\nacc +6\njmp +1\nacc +49\njmp -322\njmp -133\nacc +20\nnop -83\nacc +35\nacc +29\njmp -41\nacc +15\njmp -46\njmp -29\nacc +45\nacc -14\nacc +21\njmp -366\nnop +84\nacc -6\nacc +25\nacc -17\njmp -326\nacc -5\nnop -159\nacc +5\njmp -171\nacc +42\njmp -28\nacc +42\nacc -11\nacc +45\nacc +19\njmp -305\nacc +38\nacc -13\nacc -16\njmp -134\nacc +45\njmp -256\nacc -15\nacc -18\nacc +28\njmp -114\nacc -11\nacc +47\nnop -420\njmp -90\nnop -330\njmp +13\nacc -15\nacc +9\njmp -159\nacc -12\nacc +0\nacc +0\njmp -538\nacc +31\nacc +24\nacc +32\nacc -16\njmp -95\njmp -466\nacc +19\nacc +2\njmp -172\nacc -12\njmp -207\nacc +39\nacc +18\nacc +5\njmp -211\nnop -507\njmp +1\njmp -197\nnop -227\nacc +28\njmp -494\nacc +22\nacc +2\nacc -14\njmp -377\nacc +8\nacc +29\njmp -573\nacc -17\nacc +14\nacc +29\nacc +11\njmp -351\nacc +9\nnop -540\nacc +30\nnop -344\njmp -564\nacc -4\nnop -465\njmp -293\nacc -18\nacc +5\nacc +29\njmp -302\nacc -17\nacc +14\nacc +2\nacc -11\njmp -527\njmp -563\nacc +14\nacc +10\njmp -505\nacc +43\njmp -188\nnop -448\nacc +44\nacc +3\nacc +16\njmp +1\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_09.adb",
    "content": "--  Solution to Advent of Code 2020, Day 9\n------------------------------------------\n--  Encoding Error\n--\n--  https://adventofcode.com/2020/day/9\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_09 is\n  contig_max, last_data, n, min, max,\n  x, t : Integer;\n  res_no_pair, weakness : Integer := 0;\n  f : File_Type;\n  mem_max  : constant := 24;\n  subtype Mem_Range is Integer range 0 .. mem_max;\n  mem : array (Mem_Range) of Integer;\n  found : Boolean;\n  test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, \"aoc_2020_09.txt\");\n    for i in Mem_Range loop\n      Get (f, mem (i));\n    end loop;\n    n := 0;\n    File_Read :\n    while not End_Of_File (f) loop\n      Get (f, last_data);\n      found := False;\n      if part = 1 then\n        --  Find a pair of numbers in the recent data whose\n        --  sum is the number read just now (last_data).\n        Scan_Mem :\n        for j in Mem_Range loop\n          for k in j + 1 .. mem_max loop\n            if last_data = mem (j) + mem (k) then\n              found := True;\n              exit Scan_Mem;\n            end if;\n          end loop;\n        end loop Scan_Mem;\n        if not found then\n          res_no_pair := last_data;\n          exit File_Read;\n        end if;\n      else\n        --  Find a contiguous set of at least two numbers in the list\n        --  which sum to the invalid number from part 1.\n        contig_max := n + mem_max;\n        Contig_Scan :\n        for j in n .. contig_max loop\n          for k in j + 1 .. contig_max loop\n            t := 0;\n            min := mem (j mod (mem_max + 1));\n            max := min;\n            for i in j .. k loop\n              x := mem (i mod (mem_max + 1));\n              t := t + x;\n              if min > x then min := x; end if;\n              if max < x then max := x; end if;\n            end loop;\n            if t = res_no_pair then\n              weakness := min + max;\n              exit File_Read;\n            end if;\n          end loop;\n        end loop Contig_Scan;\n      end if;\n      mem (n) := last_data;\n      n := (n + 1) mod (mem_max + 1);\n    end loop File_Read;\n    Close (f);\n  end loop;\n  if test_mode then\n    if res_no_pair /= Integer_Value (Argument (1)) or\n       weakness /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:  Not a sum of a pair: \" & res_no_pair);\n    Put_Line (+\"Part 2:  Encryption weakness: \" & weakness);\n    --  Part 1: officially validated by AoC: 138879426\n    --  Part 2: officially validated by AoC: 23761694\n  end if;\nend AoC_2020_09;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_09.txt",
    "content": "42\n27\n23\n19\n4\n26\n31\n29\n11\n49\n38\n9\n45\n1\n40\n46\n39\n28\n44\n16\n13\n5\n32\n17\n50\n12\n20\n6\n7\n10\n22\n14\n18\n60\n59\n8\n19\n9\n11\n15\n21\n23\n39\n24\n25\n16\n26\n13\n29\n17\n27\n28\n20\n35\n30\n31\n22\n32\n44\n33\n38\n47\n34\n36\n37\n41\n55\n64\n40\n42\n43\n46\n39\n45\n61\n48\n50\n52\n65\n62\n53\n67\n72\n69\n70\n74\n73\n98\n86\n76\n79\n81\n108\n84\n82\n91\n160\n153\n93\n253\n100\n102\n105\n115\n175\n166\n151\n149\n142\n218\n147\n152\n162\n155\n161\n163\n165\n173\n255\n184\n191\n193\n293\n195\n357\n252\n295\n220\n257\n404\n289\n291\n322\n294\n314\n415\n343\n316\n318\n324\n328\n512\n364\n517\n379\n384\n511\n636\n615\n574\n472\n477\n509\n644\n1021\n605\n585\n608\n610\n800\n634\n640\n1122\n642\n1255\n692\n841\n893\n981\n763\n1313\n1586\n1046\n949\n986\n1057\n1062\n1094\n1444\n1300\n2393\n1193\n1250\n1244\n1274\n1475\n1282\n1405\n1334\n1533\n1585\n1604\n1744\n2467\n1712\n2986\n2043\n2193\n2255\n2048\n3250\n2338\n2287\n2437\n3711\n2443\n2526\n2494\n2518\n2556\n3382\n2938\n2990\n3527\n4149\n5876\n4660\n4993\n4050\n4724\n4091\n4236\n4241\n4303\n4781\n4625\n4730\n4805\n4880\n4937\n5432\n7280\n9717\n5074\n5494\n9027\n5928\n9505\n7577\n8966\n8141\n8286\n8291\n13021\n12377\n10162\n9535\n8544\n13907\n14235\n14459\n9610\n9685\n19222\n17294\n10506\n18637\n18683\n14040\n33262\n22526\n21882\n15718\n17751\n16427\n16432\n16835\n35110\n28293\n18079\n19050\n28322\n34586\n30339\n40277\n19295\n26520\n20191\n24546\n26224\n26933\n29758\n33090\n47837\n34506\n34914\n32553\n64269\n34178\n52868\n62471\n35885\n37374\n37129\n38270\n38345\n96649\n39486\n43841\n57636\n70898\n44737\n46415\n68387\n66887\n74155\n71307\n85211\n66731\n67059\n67467\n68438\n110684\n82300\n73014\n80622\n74230\n76615\n75399\n106217\n77831\n152678\n126074\n116044\n91152\n111624\n113474\n141117\n133618\n133790\n138366\n134198\n173276\n142668\n157699\n135905\n158453\n206696\n212520\n147244\n157237\n365198\n152014\n239548\n168983\n191305\n224942\n202776\n254591\n276458\n272564\n247092\n267408\n267816\n402014\n301121\n292651\n278573\n506956\n283149\n293142\n304481\n309251\n494139\n565215\n320997\n343319\n441547\n371759\n785529\n449868\n692756\n457367\n537740\n592400\n514500\n761848\n546389\n711265\n561722\n1157615\n585793\n571715\n846991\n1100293\n597623\n874466\n715078\n778364\n881059\n784866\n793187\n813306\n821627\n907235\n1452774\n971867\n995107\n1157508\n1060889\n1076222\n1118104\n1108111\n1340086\n1370659\n1169338\n1183416\n1375987\n1634933\n1508265\n1419250\n1493442\n1499944\n2407179\n1665925\n1578053\n1889528\n1720541\n1728862\n1879102\n1966974\n2400975\n3213983\n2230227\n2137111\n3457155\n2448197\n3379046\n2352754\n2539997\n3306915\n2993386\n5013979\n2912692\n2919194\n3085175\n3071495\n3165869\n3243978\n3545027\n3298594\n5846912\n3449403\n3607964\n3846076\n4104085\n4940972\n4367338\n4489865\n6764070\n4800951\n4892751\n5265446\n5271948\n6362095\n5831886\n6291980\n6237364\n5984187\n6615272\n6156670\n6315473\n6409847\n6542572\n7144670\n11945621\n8593950\n9606073\n7454040\n7950161\n8471423\n9382616\n17777507\n9290816\n11103834\n10537394\n10158197\n17211067\n12654075\n11816073\n18200023\n17719106\n12140857\n12299660\n14106831\n12472143\n16148645\n12952419\n13687242\n15094831\n15404201\n15925463\n16744856\n23009537\n17240977\n26306842\n20695591\n19828210\n20394650\n21641228\n21974270\n39754393\n23956930\n36543295\n24115733\n24440517\n24771803\n37045429\n25252079\n25424562\n29216999\n33515452\n41177542\n28782073\n30499032\n42169418\n54455962\n33985833\n37069187\n37936568\n44600013\n40523801\n40222860\n42035878\n59019699\n53988802\n57631185\n54206635\n48556250\n54034152\n50196365\n50023882\n50676641\n54469078\n58940014\n57999072\n104652327\n69305874\n59281105\n64484865\n71055020\n105132603\n82536581\n80746661\n78159428\n155328968\n82258738\n88779110\n104665443\n159121405\n98580132\n130814988\n98752615\n99232891\n100220247\n123424879\n100700523\n169617468\n112468150\n213328040\n117280177\n135539885\n217798623\n123765970\n142644293\n149214448\n163283242\n158906089\n160418166\n166938538\n171037848\n255112443\n138879426\n197332747\n197813023\n197985506\n231035235\n241046147\n388836471\n340655316\n213168673\n277698343\n282085618\n236234120\n252820062\n278184178\n266410263\n262645396\n272980418\n288093874\n364271285\n297785515\n299297592\n305817964\n550739270\n503150711\n336212173\n700483458\n395145770\n570179492\n411154179\n444203908\n449402793\n465988735\n822999554\n524327994\n637251703\n489054182\n498879516\n515465458\n551164596\n585879389\n535625814\n700963734\n587391466\n597083107\n785614966\n635509765\n893209430\n1004519640\n900208361\n959669366\n806299949\n1137043985\n1229818874\n1897729070\n893606701\n1059953808\n955042917\n987933698\n1013382176\n1014344974\n1024679996\n1034505330\n1121505203\n1336473499\n1621763103\n1810294962\n1601602747\n1497291468\n1953163238\n2428063052\n1441809714\n1959562557\n1706508310\n1699906650\n2922409066\n1819682125\n1881540399\n1907951675\n1848649618\n1906988877\n1942976615\n1968425093\n2001315874\n3927987650\n2048850304\n2734411980\n2156010533\n2618796671\n2778283213\n2939101182\n3043412461\n3148318024\n4436392650\n3141716364\n7069704014\n3555157928\n3406414960\n3519588775\n3817074711\n4098987148\n5821695674\n3730190017\n3755638495\n7572713206\n6878508041\n3911401708\n6548131324\n4779599087\n5353208651\n4204860837\n4774807204\n5095111715\n7317816668\n5919999577\n7578109014\n6191730485\n10966537689\n6958791075\n6661305139\n6926003735\n6961572888\n9299972552\n7249778792\n7485828512\n10459533032\n13150521560\n10396591322\n8979668041\n9558069488\n8116262545\n8686208912\n10128015855\n13461016116\n11130864572\n11286842200\n9869918919\n11015111292\n12111730062\n16465496553\n20419807191\n20573180780\n13920363963\n15077835433\n13587308874\n14211351680\n25537368465\n28059009292\n14735607304\n15602091057\n19973051112\n17674332033\n16802471457\n17095930586\n17986181464\n18244278400\n18556127831\n19997934774\n23126841354\n20885030211\n24605526223\n21981648981\n38975935022\n28577226615\n27507672837\n27798660554\n28131715643\n28322916178\n54053770455\n35340208986\n29813442737\n30337698361\n31831537890\n41979583755\n32404562514\n36230459864\n33898402043\n41113022818\n37980960797\n39441158042\n45108490335\n79093983615\n42866679192\n44011871565\n45490556434\n46587175204\n53813186871\n56084899452\n69435938996\n55306333391\n63138869540\n69238611029\n58660614539\n70385523311\n60151141098\n62742260875\n62169236251\n65729939933\n66302964557\n68635022378\n70128861907\n73339560085\n86603579252\n77422118839\n164025698091\n86878550757\n88357235626\n100400362075\n89502427999\n233461637087\n101893508595\n109119520262\n129587080094\n113966947930\n115457474489\n118811755637\n120829850790\n121402875414\n199715942001\n122320377349\n127899176184\n128472200808\n175422484819\n134937986935\n141974582463\n143468421992\n164300669596\n165779354465\n166924546838\n187278912832\n216465630851\n214367310005\n235369823344\n191395936594\n211013028857\n246710931821\n223086468192\n232778703567\n326333923529\n236860349903\n287182229879\n242232726204\n366640488839\n306275252059\n257258364284\n522740882910\n357835731997\n276912569398\n278406408927\n332703901303\n739206513761\n355696606190\n380146664470\n354203459670\n642878836069\n402408965451\n405763246599\n414482404786\n760244697448\n599419192406\n919791405467\n459946818095\n632609175588\n479093076107\n660478711729\n499491090488\n690539633300\n534170933682\n535664773211\n679321534849\n555318978325\n609616470701\n756612425121\n812577342609\n932123093709\n734350124140\n1140391361918\n1150486451395\n1851914499176\n1096302879899\n808172212050\n820245651385\n874429222881\n939039894202\n959437908583\n1632822993994\n1089489912007\n1394828835869\n978584166595\n2611407160589\n1033662024170\n1069835706893\n1695710340243\n1687006565490\n1164935449026\n1289669102465\n1343966594841\n1490962549261\n2524624573431\n1972701918372\n1542522336190\n1628417863435\n1682601434931\n1694674874266\n1897662124057\n1747212106252\n2717907775442\n1813469117083\n2103975343228\n2661185601526\n2012246190765\n2048419873488\n2103497731063\n2859610323292\n2729372364413\n2198597473196\n2234771155919\n3338088975953\n2454604551491\n2508902043867\n3091178701093\n3868591168272\n4466850742256\n3170940199625\n3237197210456\n3225123771121\n3311019298366\n3377276309197\n3441886980518\n3560681223335\n3759458297017\n6921455293747\n4048240273002\n5490306854006\n4060666064253\n4871856514057\n4689375707410\n5536686449149\n4927969837609\n4433368629115\n4707499517063\n5325949857012\n4963506595358\n10092395493372\n7502553044771\n7878439716688\n6396063970746\n6536143069487\n6408137410081\n7820124361270\n10727676815892\n7070477595383\n8249132823254\n8268180740398\n7621347287588\n11115636927144\n8481608902117\n8108906337255\n8494034693368\n8750041771663\n9122744336525\n9140868146178\n9361338466724\n9396875224473\n11103563487809\n9671006112421\n10289456452370\n11359570566104\n12804201380827\n14414582786175\n14890098664114\n12932207040233\n12944280479568\n13478615005464\n15179383932638\n14691824882971\n20226307824334\n16115381980956\n15730253624843\n16102956189705\n16590515239372\n17231650673780\n16602941030623\n26282816386291\n18502206612902\n24030966810292\n18537743370651\n18758213691197\n19067881336894\n19960462564791\n29535148070856\n21649027018474\n24163771946931\n27983585313465\n25876487519801\n27834379143682\n26410822045697\n26422895485032\n28170439888435\n41102646928668\n30422078507814\n32705897220328\n42141075670540\n31833209814548\n35733857286682\n37192113238571\n33834591704403\n35105147643525\n37039949983553\n37295957061848\n37605624707545\n37826095028091\n38718676255988\n39028343901685\n41609489583265\n45812798965405\n65266418875599\n50040259466732\n66702261569453\n52287309565498\n56004819032117\n52833717530729\n54593335373467\n58592518396249\n66155935794496\n62255288322362\n64539107034876\n65667801518951\n84666927345277\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_10.adb",
    "content": "--  Solution to Advent of Code 2020, Day 10\n-------------------------------------------\n--  Adapter Array\n--\n--  https://adventofcode.com/2020/day/10\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2020_10 is\n  use HAT, Interfaces;\n\n  subtype Jolt is Natural;\n  --  ^ Full Ada: it's better to define an incompatible\n  --    type for Jolts:  `  type Jolt is new Natural;  `.\n  Max_Adapters : constant := 1000;\n\n  subtype Adapter_Range is Integer range 1 .. Max_Adapters;\n\n  j : array (Adapter_Range) of Jolt;\n\n  top : Natural := 0;\n  jmax : Jolt := 0;\n  verbose : constant Boolean := False;\n\n  procedure Search (result : out Integer) is\n    c : Jolt := 0;\n    diff_1, diff_3 : Natural := 0;\n    seen : array (Adapter_Range) of Boolean;\n    --\n    function Check_all_used return Boolean is\n      ok : Boolean := True;\n    begin\n      for i in 1 .. top loop\n        ok := ok and seen (i);\n      end loop;\n      return ok;\n    end Check_all_used;\n    --\n  begin\n    for i in 1 .. top loop\n      seen (i) := False;\n    end loop;\n    while c < jmax loop\n      Steps :\n      for step in 1 .. 3 loop\n        for i in 1 .. top loop\n          if not seen (i) then\n            if j (i) = c + step then\n              if step = 1 then diff_1 := diff_1 + 1; end if;\n              if step = 3 then diff_3 := diff_3 + 1; end if;\n              seen (i) := True;\n              if verbose then\n                Put_Line (\n                  +\"current \" & c &\n                   \"  step \" & step &\n                   \"  found adapter \" & i &\n                   \" rated \" & j (i) & \" Jolts\"\n                );\n              end if;\n              c := j (i);\n              exit Steps;\n            end if;\n          end if;\n        end loop;\n      end loop Steps;\n    end loop;\n    if not Check_all_used then\n      Put_Line (\"Nooo - some adapters are not used!\");\n    end if;\n    diff_3 := diff_3 + 1;  --  3 jolts from the last adapter to the device.\n    result := diff_1 * diff_3;\n  end Search;\n\n  procedure Count_Possibilities (result : out Integer_64) is\n    cache : array (Adapter_Range) of Integer_64;\n    --\n    function Count (from : Jolt) return Integer_64 is\n      sum : Integer_64 := 0;\n    begin\n      if from = jmax then\n        return 1;\n      end if;\n      for step in 1 .. 3 loop\n        for i in 1 .. top loop\n          if j (i) = from + step then\n            if cache (i) = 0 then\n              --  We compute only once the number of combinations\n              --  for a given joltage level. Without cache, the\n              --  computation would take an insane amount of time.\n              cache (i) := Count (j (i));\n            end if;\n            sum := sum + cache (i);\n          end if;\n        end loop;\n      end loop;\n      return sum;\n    end Count;\n  begin\n    for i in 1 .. top loop\n      cache (i) := 0;\n    end loop;\n    result := Count (0);\n  end Count_Possibilities;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  puzzle_1 : Jolt;\n  puzzle_2 : Integer_64;\n  f : File_Type;\nbegin\n  Open (f, \"aoc_2020_10.txt\");\n  while not End_Of_File (f) loop\n    top := top + 1;\n    Get (f, j (top));\n    if j (top) > jmax then\n      jmax := j (top);\n    end if;\n  end loop;\n  Close (f);\n  --\n  Search (puzzle_1);\n  Count_Possibilities (puzzle_2);\n  if compiler_test_mode then\n    if puzzle_1 /= Integer_Value (Argument (1)) or\n       puzzle_2 /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Number of adapters: \" & top);\n    Put_Line (+\"Max jolts: \" & jmax);\n    Put_Line (+\"Result of puzzle 1 (diff_1 * diff_3 when using all adapters): \" & puzzle_1);\n    Put_Line (+\"Result of puzzle 2 (number of ways adapters can be arranged):\" & Integer_64'Image (puzzle_2));\n    --  Part 1: validated by AoC: 2277\n    --  Part 2: validated by AoC: 37024595836928\n  end if;\nend AoC_2020_10;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_10.txt",
    "content": "99\n104\n120\n108\n67\n136\n80\n44\n129\n113\n158\n157\n89\n60\n138\n63\n35\n57\n61\n153\n116\n54\n7\n22\n133\n130\n5\n72\n2\n28\n131\n123\n55\n145\n151\n42\n98\n34\n140\n146\n100\n79\n117\n154\n9\n83\n132\n45\n43\n107\n91\n163\n86\n115\n39\n76\n36\n82\n162\n6\n27\n101\n150\n30\n110\n139\n109\n1\n64\n56\n161\n92\n62\n69\n144\n21\n147\n12\n114\n18\n137\n75\n164\n33\n152\n23\n68\n51\n8\n95\n90\n48\n29\n26\n165\n81\n13\n126\n14\n143\n15\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_11.adb",
    "content": "--  Solution to Advent of Code 2020, Day 11\n-------------------------------------------\n--  Seating System\n--\n--  https://adventofcode.com/2020/day/11\n--\n-------------------------------------------------------------------------\n--\n--  HAC 0.084 version.\n--\n--  NB: when run from HAC with the full-size data (\"aoc_2020_11.txt\"),\n--      the HAC virtual machine shows its capacity of slowing down your computer ;-) .\n--      For performance, better use your preferred full Ada compiler...\n--\n--  HAC 0.084 \"nice to have\"'s detected in this exercise:\n--\n--    *     ` aaa : constant Character := 'a';`\n--                       HAC should detect an expression as a static (compile-time-known) value\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_11 is\n  w : constant := 10;  h : constant := 10;  name : constant VString := +\"aoc_2020_11_mini.txt\";\n  --  w : constant := 93;  h : constant := 98;  name : constant VString := +\"aoc_2020_11.txt\";\n  --\n  type Map_Type is array (1 .. h, 1 .. w) of Character;\n  --\n  --  empty    : constant Character := 'L';  --  Not used. See remarks above.\n  --  occupied : constant Character := '#';  --  Not used. See remarks above.\n  --\n  procedure Move (\n    current_map : in     Map_Type;\n    new_map     :    out Map_Type;\n    simple_rule : in     Boolean;\n    change      :    out Boolean\n  )\n  is\n    function Count_Visible_Occupied (i, j : Positive) return Natural is\n      occ : Natural := 0;\n      --\n      procedure Scan_Direction (di, dj : Integer) is\n        ii : Integer := i + di;\n        jj : Integer := j + dj;\n      begin\n        loop\n          exit when ii not in 1 .. h;\n          exit when jj not in 1 .. w;\n          case current_map (ii, jj) is\n            when '#'    => occ := occ + 1; exit;\n            when 'L'    => exit;\n            when others => exit when simple_rule;\n          end case;\n          ii := ii + di;\n          jj := jj + dj;\n        end loop;\n      end Scan_Direction;\n    begin\n      for di in -1 .. 1 loop\n        for dj in -1 .. 1 loop\n          if di /= 0 or dj /= 0 then\n            Scan_Direction (di, dj);\n          end if;\n        end loop;\n      end loop;\n      return occ;\n    end Count_Visible_Occupied;\n    --\n    threshold : Positive;\n  begin\n    if simple_rule then\n      threshold := 4;\n    else\n      threshold := 5;\n    end if;\n    change := False;\n    for i in 1 .. h loop\n      for j in 1 .. w loop\n        new_map (i, j) := current_map (i, j);\n        case current_map (i, j) is\n          when 'L' =>\n            if Count_Visible_Occupied (i, j) = 0 then\n              new_map (i, j) := '#';\n              change := True;\n            end if;\n          when '#' =>\n            if Count_Visible_Occupied (i, j) >= threshold then\n              new_map (i, j) := 'L';\n              change := True;\n            end if;\n          when others =>\n            null;\n        end case;\n      end loop;\n    end loop;\n  end Move;\n  --\n  procedure Show (map : Map_Type) is\n  begin\n    for i in 1 .. h loop\n      for j in 1 .. w loop\n        Put (map (i, j));\n      end loop;\n      New_Line;\n    end loop;\n    Skip_Line;\n  end Show;\n  --\n  function Count_Occupied (map : Map_Type) return Natural is\n    occ : Natural := 0;\n  begin\n    for i in 1 .. h loop\n      for j in 1 .. w loop\n        if map (i, j) = '#' then\n          occ := occ + 1;\n        end if;\n      end loop;\n    end loop;\n    return occ;\n  end Count_Occupied;\n  --\n  f : File_Type;\n  map_start : Map_Type;\n  map : array (0 .. 1) of Map_Type;\n  c : Natural := 0;\n  changed : Boolean;\n  verbose : constant Boolean := False;\n  part : Positive := 1;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  Open (f, name);\n  for i in 1 .. h loop\n    for j in 1 .. w loop\n      Get (f, map_start (i, j));\n    end loop;\n  end loop;\n  Close (f);\n  --\n  for simple_rule in reverse Boolean loop\n    map (c) := map_start;\n    loop\n      if verbose then Show (map (c)); end if;\n      Move (map (c), map (1 - c), simple_rule, changed);\n      exit when not changed;\n      c := 1 - c;\n    end loop;\n    if compiler_test_mode then\n      if Count_Occupied (map (c)) /= Integer_Value (Argument (part)) then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n    else\n      Put_Line (\n        +\"Part \" & part &\n        \": stabilized at \" & Count_Occupied (map (c)) & \" occupied seats.\"\n      );\n    end if;\n    part := part + 1;\n  end loop;\n  --  Part 1: Example: 37. Input (aoc_2020_11.txt): validated by AoC: 2386\n  --  Part 2: Example: 26. Input (aoc_2020_11.txt): validated by AoC: 2091\nend AoC_2020_11;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_11.txt",
    "content": "LLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LL.LLLLLLLLL.LLL\nLLLLLLLL.L.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLL.LLL.LLLLL.LLLL.L..LLLLLL.LLLLLLLL\nLLLLLLLLLLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLLLLLLL..LLLLLLLL.L.LLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLL.LLLLL.LL\nLLLLLLLLLL.LLLLL.LLL.LLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLL..LLLLLL.LLLLLLLL\nLLLLLLLLLL..LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LL.LLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLL.L\nL.LL.L...LL......LLL........LL...L.L.L...L...L....L........LL......L.............LL..LL.L...L\nLLLLLLLLL..LL.LLLL.L.LL.LLL.LLLLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL\nLLLLLL.LLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLLLLL.LL.LLLLLLLLL.L.LLLLL.LLLLL.L.LLLL.LLLLLLLLLLLLLLLL\nLLLLLLLLLL.L.LLLLLLLLL.LLL..LLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLL.L.LLLL.LLLLLLL.LLLLLLLL\nLLLLLLLL.L.LLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL.LLLLLLL.L.LLLLLLLLLL.LLLLLLLLLLLLLL.L\n...L..L..L..L...L..L...L............L......L.....L...LLL.........L..L.LL.LL.LL.LLLL..........\nLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLL.LLL.LLL.LLLLLLLL\nLL.LLLLLL..LLLLLLL.LLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLLLLLL\nLLLLLLLLLLLLLLLLLL.LLLLLLLL.L.LLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLL.LL.LL.LLLLLLLLLLLLLLLLLL.LLLL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL..LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.L.LL.LLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLL.LL.LLLLLLLLL.LLLLLLL.LL.LL.LLL.LLLLLLLLLL.LLLLLLLL\nLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLL.LL.LLLLL.LLLLLL.LLLLLLL.LLL.LLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LL.LLLLLLL.LL.LLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL\nLLLLLL.LLL..LL.LLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLL.LLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLL.LLLL.LLL.LLLLLLLL..LLLLLLLLLLLLLLLLLL.LLLLLLLLL\n.LL...L......LLL.....L..LL..L.....L.LLLL.L......L.......L...L....L.L..L..LL.L.L.....L.L......\nLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLL.LL.LLLLL\nLLLLLLLLLL.LL.LLLL.LLLLLLLLLLLLL.LL.LLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLL..LLLLLLLL.LL.LL.LLLLLLLL\nLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLL.L..LLLLLLLLL.LLLLLLLLLLLLLLLL\nLLLLLLLLLL.LL.LLLL.LLLLLLLLLLLLLLLL.LLLLLL.LL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLL.LLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLL.LLL.LLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLL..LLLLLLL\nLLLLLLLLLL.LLLLLLLLLLLL.LLL.LLLLLLLLLLLLLLLLLLLLLLL.LLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLL.L\nLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLL.LLLLLLLLLLLLL.LLLLLLLLL.L.L.LLL.LLLLL..LLLLLLLLLLLLL.LLLLLLLL\nLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLL..LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLL.LLLLLLLL\nLLLLL...L..L.L..L.L..LL..L..L...L.LL.LLLLL.L...........L....LLLLLL..L..L..L.LL.LL...LL.L.....\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLLLL.LLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL..LLLLL.LLLLLLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLLLLL\nL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL..LLLLL.LL.LLLLLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLL..LLLLLLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL..LLLLLLLL.LLLLLLL.LLLLL.LL.LLL.LLLL.LL.LL.LLLLL\n.L....L.L.L...LL..L.L.LL..L.LL..LL..LLL.LL..L..L.LL..L.......L.....L...LL......LLLL...L.....L\nLLLLLLLLLL.LLLLLLLLLLLL.L.L.LLL.LLL.LLLL..LLL.LLLLL.LLL.LLLLLLLLLLLL..LLLLLLLLLLLLLL..LLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LL.LLLL.LLLL.LLLLLLLLL.LLLL.LLLLLLL.LLLLL.LLLLL..LLLLLL.LLLLLLLLL\nLLLLLLLLLL.LLL.LLLLL.LLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLL..LLLLLLL.LLLLLLLL.LLLLLLL.LLLL.LLLL.LLLLLLLLL.LLLLLLL.L.LLL.LLLLLLLLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLL.LLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLL..LLLLLLLL\nL......LLLL...LLL.L..L.LL...LL.L.....L.LL...L...LL..LL..LLL..L.L.LLL..L..L...L.LLL..L....L...\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLL.LL..LLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLL\nLLLLLLLLLL..LLLLLL..LLLLLLL..LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLL.L.LLLLLL\nLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL..LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLL.LLLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.L.LLL.LLLLLL.LLL.LLL.LL.LLLLL\n..LL.LLLLL.L...L...LL.......L.........LL..L.LLL.....LL..L.L.LL..L..L.L..L.L..L...L.L.......LL\nLLLLLLLLLL.LLL.L.L.LLLLLLLLLLL.LL.L.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLL.LLLLLLLLLLLLLLLLL\nLLLLLLLLLL.LLLL.LLLLLL..LLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLLL.L..LLLLL\nLLLLLLLLLLLLLLLLLLL..LLLLLLLL.LL.LL.LL.LLLLLL.LLLL.LLLLLLLL..LL.LLLLLLLLLLLL.LLLLLLL.L.LLLLLL\nLLLLLLLLL..LLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.L.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLL..LLLLLLLLLLLL.LLLLLL.LLLLL.LLL.LLLLLLL.LLLLL.LLLLL..LLLLLLL.LLLLLLLL\nLLLLLLLL..LLLLLLLL.LLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLL.LL.LLLL.LLL.LLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLL..LLLLL.L\nLL...LL........L.L....L..L....LLL.L...LL.L......L.LL..L...L.L.L.L....L..L.L...L.L.L....L.L..L\nLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.L.LLLLLLLL.LLLLLLLL.LLLLLL..LLLLLLL.LLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LL.LLLLLLLLLLLLL\nLLLLLLLLL..LLLLLLL.LLLLL.LLLLLLL.LL.LLLLLLLLL.LLLLL.LLL.LLLLLLL..LLLL.LLL.LL.LLLLLLL.LLLLLLLL\nLL.LLLLLLL.LLLLLLL.LLLLL.LL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLL\nL.LL.LLLLLLLLLLLLL.LLLLLLLL.LL.L.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL..LLLLLLL.LLLLLLLL\nLLLLL.LLLL.LLLLLLL.LLLLLLLL.L.L.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLL.LLLLLLLLLLLLLLLL\nLLLLLLLLLL.LLLLLLLLLLLLL.LL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLL.L.LLLL.LL.LL.LLLLL\n...L.....L............L...L.LL.L.L.L.L...LLL.L.LL.......LL.L.LLLL..LL......L...LLL..L....L...\nLLLLLLLL.L.LLLLLLLLLLLLLLLL.LLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLL..LLLLLLLLLLL.L.LLLLLLLLLLLLLLLL\nLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLLLLL\n.LL.LLLL.L.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLL..LL.LL.L.LLLLL.LLLLLLLLLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLL..LLLLLLLL.LLL.LLLLLLLLLLLLL.L.LLL.LLLLLL.L.LLLLL.LLLLLLL.\nLLLLLLLLLLLL.L.LLL.LLLLLLLL.LL.LLLL.LLLLLLLLL.LLL.L.LLL.LLLLLLL.LLLLLLLLLLLL.LLLLLL..LLLLL..L\n.L..LL.......L..L..L.L........LL...LL.LLLLL........L.LLL......L..L.....L.LL....LLL.....LLL.L.\n.LLLLLLL.L.LLLLL.L.LLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL..LLLLLLLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.L.LLLLLLLLLLLL.LLLLLLLL\nLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLL.LLLLLLLLLLLL\nLLLLLLLLLLLLLLLLLL.LL.LL.LL.LLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL\nLLL.LLLLLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL..LLLLLLLLLLL.LLLLLLL.LLLLLLLL\nLLLLL.LLLLLLLLLLLL.LL.LLLLL.LLLLL.L.LLLLLL.L..LLLLLLLL..LLLL.LLL.LLLLLLLLLLL.LLLLLLLLLLLL.LLL\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL\nLL..L....L...L.L........L.L....L..L..L...L..L..L........L...LLL..L.LL..L........LL..........L\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLL.L.LLLLLLLLL.LLLL.LL.LLLLL.LLLLLLLLLLL.LL.LLLLLLL.\nLLLLLLLLLL.LLLLLLL.LLLLLL.L.LL.L.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLL.LLL.LLL.L.LLLLLLLLL.LLLLLL.LL.LLLLLL..LLLLL.LLLLLL.LLL.LLLLLLLLLLLL\nLLLLLLL.LL.LLLL.LL.LLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLL.LLLLLLLL\n.LL.LLLLLLL.LLLLLLLLLLL.LLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL\nLL.LLLLLLLLLLLLLLL.LLLLLLL..LLLLLLLLLLLLLLLLL.LLLLLLLLL..LLLL.L.LLLLLLLLLLLLLL.LLLLL.LLLLLLLL\n.....L.....LLLL......LL.L...LL...L..L........L...L..LL..LL.LL.LL..LL...L.......L..LLL..L...LL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLL.L.LLL.LLLLLL.LLLLLL..LLLLLLLL\n.LLLLLLL.L.LL.LL.L.LLLLL.L..LLLLLLLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLLLLLL.LLLLLL.LLLL.LL.LLLLLLLL\nLLLLLLLLLL..LLLLLL.LLLLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LL.LLL.LL.LLLL.\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLL.LLL.LL.LL.LLLLL.LLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLL.LLLL.LL.LLL.L.LLL.LLLLLLL.LLL.L.LLLL.LLLLLLLLL.LLLLLLLL\n..L...LLL..LL...L.L.LLLL..L.L...L..LLL...L...LLL.....L.....LL.L....L....L.L..L.L.L....L..L..L\nLLLLLLLLLLLLLLLLLL.LLL.LLLL.LLLLLLL.LLLLLLLLL.LL.LLLL.LLLLL.L.L.LLLLL.LLLLLL.LLL.LLL.LLLLLL.L\nLLLLLLLLLL.LLLLLLLLLLLLLLLL.LL.LL.L.LLLLLLLLL..LL.LLLLL.LLLLLLLLLLL.L.L.L.LL.LLLLLLL.LLLLLLLL\nLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLL.LL.LLLLLLLLLLLLLLLLLLL.LL.LL.L.LLLLL.LLLLLLLLL.LLLL.LLLLLLLL\nLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.L.LLLLLLL.LLLLLLLLLLLL.LLLLLLL..LLLLLLL\nLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLL.LLL..LL.LLLLLLLL\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_11_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 11\n-------------------------------------------\n--  Seating System\n--\n--  https://adventofcode.com/2020/day/11\n--\n--  Full Ada version.\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_11_full_Ada is\n\n  procedure Solve (w, h : Positive; file_name : String) is\n    --\n    type Map_Type is array (1 .. h, 1 .. w) of Character;\n    --\n    empty    : constant Character := 'L';\n    occupied : constant Character := '#';\n    --\n    procedure Move (\n      current_map : in     Map_Type;\n      new_map     :    out Map_Type;\n      simple_rule : in     Boolean;\n      change      :    out Boolean\n    )\n    is\n      function Count_Visible_Occupied (i, j : Positive) return Natural is\n        occ : Natural := 0;\n        --\n        procedure Scan_Direction (di, dj : Integer) is\n          ii : Integer := i + di;\n          jj : Integer := j + dj;\n        begin\n          loop\n            exit when ii not in 1 .. h;\n            exit when jj not in 1 .. w;\n            case current_map (ii, jj) is\n              when occupied => occ := occ + 1; exit;\n              when empty    => exit;\n              when others   => exit when simple_rule;\n            end case;\n            ii := ii + di;\n            jj := jj + dj;\n          end loop;\n        end Scan_Direction;\n        --\n      begin\n        for di in -1 .. 1 loop\n          for dj in -1 .. 1 loop\n            if di /= 0 or else dj /= 0 then\n              Scan_Direction (di, dj);\n            end if;\n          end loop;\n        end loop;\n        return occ;\n      end Count_Visible_Occupied;\n      --\n      threshold : Positive;\n    begin\n      if simple_rule then\n        threshold := 4;\n      else\n        threshold := 5;\n      end if;\n      change := False;\n      for i in 1 .. h loop\n        for j in 1 .. w loop\n          new_map (i, j) := current_map (i, j);\n          case current_map (i, j) is\n            when empty =>\n              if Count_Visible_Occupied (i, j) = 0 then\n                new_map (i, j) := occupied;\n                change := True;\n              end if;\n            when occupied =>\n              if Count_Visible_Occupied (i, j) >= threshold then\n                new_map (i, j) := empty;\n                change := True;\n              end if;\n            when others =>\n              null;\n          end case;\n        end loop;\n      end loop;\n    end Move;\n    --\n    procedure Show (map : Map_Type) is\n    begin\n      for i in 1 .. h loop\n        for j in 1 .. w loop\n          Put (map (i, j));\n        end loop;\n        New_Line;\n      end loop;\n      Skip_Line;\n    end Show;\n    --\n    function Count_Occupied (map : Map_Type) return Natural is\n      occ : Natural := 0;\n    begin\n      for i in 1 .. h loop\n        for j in 1 .. w loop\n          if map (i, j) = occupied then\n            occ := occ + 1;\n          end if;\n        end loop;\n      end loop;\n      return occ;\n    end Count_Occupied;\n    --\n    f : File_Type;\n    map_start : Map_Type;\n    map : array (0 .. 1) of Map_Type;\n    c : Natural := 0;\n    changed : Boolean;\n    verbose : constant Boolean := False;\n    part : Positive := 1;\n  begin\n    Put_Line (file_name);\n    Open (f, file_name);\n    for i in 1 .. h loop\n      for j in 1 .. w loop\n        Get (f, map_start (i, j));\n      end loop;\n    end loop;\n    Close (f);\n    --\n    for simple_rule in reverse Boolean loop\n      map (c) := map_start;\n      loop\n        if verbose then Show (map (c)); end if;\n        Move (map (c), map (1 - c), simple_rule, changed);\n        exit when not changed;\n        c := 1 - c;\n      end loop;\n      Put_Line (\n        +\"  Part \" & part &\n        \": stabilized at \" & Count_Occupied (map (c)) & \" occupied seats.\"\n      );\n      part := part + 1;\n    end loop;\n    New_Line;\n  end Solve;\n  --\nbegin\n  Solve (10, 10, \"aoc_2020_11_mini.txt\");\n  Solve (93, 98, \"aoc_2020_11.txt\");\nend AoC_2020_11_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_11_mini.txt",
    "content": "L.LL.LL.LL\nLLLLLLL.LL\nL.L.L..L..\nLLLL.LL.LL\nL.LL.LL.LL\nL.LLLLL.LL\n..L.L.....\nLLLLLLLLLL\nL.LLLLLL.L\nL.LLLLL.LL\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_12.adb",
    "content": "--  Solution to Advent of Code 2020, Day 12\n-------------------------------------------\n--  Rain Risk\n--\n--  https://adventofcode.com/2020/day/12\n--\n--  Compute destination of a ship following navigation\n--  instructions (interpreted in two different ways).\n--\nwith HAT;  --  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n\nprocedure AoC_2020_12 is\n  use HAT;\n  --\n  function D2R (a : Real) return Real is\n  begin\n    return (Pi / 180.0) * a;\n  end D2R;\n  --\n  procedure Rotate (x, y : in out Real; a : Real) is\n    nx : Real;\n  begin\n    nx := Cos (a) * x - Sin (a) * y;\n    y  := Sin (a) * x + Cos (a) * y;\n    x  := nx;\n  end Rotate;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  c : Character;\n  i, res : Integer;\n  wx, wy, a, x, y, d, res_r : Real;\n  f : File_Type;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, \"aoc_2020_12.txt\");\n    x := 0.0;\n    y := 0.0;\n    a := 0.0;\n    wx := 10.0;\n    wy :=  1.0;\n    while not End_Of_File (f) loop\n      Get (f, c);\n      Get (f, i);\n      d := Real (i);\n      if part = 1 then\n        case c is\n          --  Move the ship directly.\n          when 'N' => y := y + d;\n          when 'S' => y := y - d;\n          when 'E' => x := x + d;\n          when 'W' => x := x - d;\n          when 'L' => a := a + D2R (d);\n          when 'R' => a := a - D2R (d);\n          when 'F' =>\n            x := x + d * Cos (a);\n            y := y + d * Sin (a);\n          when others => null;\n        end case;\n      else\n        case c is\n          --  Move a waypoint which is relative to the ship's position.\n          when 'N' => wy := wy + d;\n          when 'S' => wy := wy - d;\n          when 'E' => wx := wx + d;\n          when 'W' => wx := wx - d;\n          when 'L' => Rotate (wx, wy, +D2R (d));\n          when 'R' => Rotate (wx, wy, -D2R (d));\n          when 'F' =>\n            --  Move the ship forward to the waypoint.\n            x := x + d * wx;\n            y := y + d * wy;\n          when others => null;\n        end case;\n      end if;\n    end loop;\n    Close (f);\n    res_r := abs x + abs y;\n    res := Integer (res_r);\n    if compiler_test_mode then\n      if res /= Integer_Value (Argument (part)) then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n    else\n      Put_Line (\n        +\"Part \" & part &\n        \": Manhattan distance of the ship to (0,0): \" &\n        res & \"  (\" & res_r & ')');\n    end if;\n  end loop;\n  --  Part 1: validated by AoC: 1631\n  --  Part 2: validated by AoC: 58606\nend AoC_2020_12;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_12.txt",
    "content": "N1\nR90\nS5\nR180\nN3\nW1\nL180\nF92\nR270\nE4\nF4\nW4\nW4\nL180\nS2\nW2\nF90\nE1\nS5\nW3\nF78\nS5\nR180\nF100\nN1\nW3\nL90\nL90\nN1\nF94\nW2\nR90\nF49\nW2\nF26\nR180\nW1\nS5\nR180\nW4\nS3\nR90\nW3\nS4\nE5\nS1\nF13\nN5\nR270\nE2\nR270\nS5\nF3\nE3\nF4\nS3\nR270\nS1\nW4\nR90\nS4\nL180\nN4\nF81\nW2\nR90\nF61\nR90\nF13\nN3\nR180\nW1\nF98\nS5\nF50\nW5\nS3\nW5\nR90\nF17\nS5\nF70\nF7\nE2\nF87\nE1\nL270\nF59\nE2\nR180\nN5\nF59\nL90\nN5\nW5\nF10\nN3\nE1\nR90\nW1\nS2\nR90\nN5\nF25\nR90\nE2\nF57\nR180\nE1\nN3\nW2\nF85\nL90\nF50\nW2\nR90\nS3\nR90\nF27\nE1\nS1\nL90\nF32\nL90\nW3\nR90\nE1\nF39\nS5\nE4\nF50\nW4\nL90\nF63\nN2\nF67\nW3\nR90\nF4\nN2\nR90\nF90\nN5\nL180\nF24\nE5\nN3\nL180\nF67\nE3\nL90\nS3\nF49\nR90\nE5\nF89\nW5\nF62\nF39\nF33\nW1\nR90\nF18\nS3\nR90\nN4\nF47\nN5\nN3\nW2\nS5\nL90\nE4\nL90\nW2\nR90\nW5\nL90\nW5\nN4\nF64\nR90\nS2\nW4\nR90\nN3\nF18\nL90\nS4\nL90\nF31\nS4\nL90\nF79\nR90\nF69\nN3\nE4\nF64\nN2\nE4\nR90\nF20\nR180\nE1\nF85\nW1\nS5\nS2\nF21\nR90\nF43\nN1\nF18\nS5\nR180\nF52\nL180\nW4\nF5\nL90\nF70\nS4\nN3\nR180\nF64\nR90\nF17\nR90\nE5\nF85\nN1\nF74\nE5\nF21\nN1\nF35\nN1\nF65\nW2\nF67\nN1\nE5\nF79\nS4\nR90\nF20\nR180\nW5\nL180\nS4\nF56\nS4\nL90\nE5\nF13\nS5\nF38\nW1\nS2\nL90\nN4\nE3\nR180\nW3\nN1\nR90\nF52\nN5\nF23\nE5\nF82\nE5\nS2\nE3\nN3\nS2\nL90\nN1\nR90\nS5\nF60\nW1\nN2\nW1\nN3\nE4\nF2\nE2\nL90\nS1\nL90\nE4\nN1\nR180\nE2\nR180\nF93\nF94\nL90\nS4\nE5\nR90\nF5\nS2\nE2\nS3\nE4\nR180\nF56\nE2\nN2\nF3\nR90\nW2\nF94\nW5\nF47\nL180\nF68\nE5\nF63\nS3\nE4\nF93\nL90\nS5\nL180\nW5\nS5\nW3\nL180\nF34\nR90\nF87\nW4\nS1\nW3\nR270\nS1\nE1\nF78\nE4\nR90\nF91\nW4\nS3\nW1\nF41\nN4\nE1\nF66\nS1\nW5\nF62\nN2\nW2\nL90\nW1\nF23\nL270\nN2\nW2\nS3\nF9\nR90\nF2\nE4\nF61\nL90\nW5\nN4\nF97\nL90\nF93\nN5\nL270\nR90\nW1\nR90\nR90\nN4\nE1\nF72\nN4\nR270\nF24\nW1\nF79\nS1\nE3\nN4\nE3\nL90\nW2\nS1\nR270\nW5\nF24\nE5\nS4\nF22\nL180\nF57\nS5\nR90\nN4\nW3\nF18\nN2\nR90\nE3\nF55\nN2\nR90\nS5\nF4\nW3\nL90\nN2\nW3\nL270\nE4\nR90\nF46\nS5\nN1\nF16\nN1\nR90\nF8\nL180\nN2\nW3\nN4\nE1\nS3\nL90\nF4\nE5\nN5\nE3\nR90\nF35\nN2\nF68\nF33\nE5\nF38\nE4\nF27\nR180\nS5\nF47\nR90\nF43\nR90\nS1\nF84\nL180\nF47\nR90\nN4\nE4\nF77\nR180\nN1\nE2\nS4\nF45\nS1\nL90\nE5\nF40\nL90\nW5\nF25\nW4\nR90\nF80\nN5\nE2\nF74\nW3\nN3\nE4\nF48\nN3\nR90\nN2\nW1\nL90\nS2\nF35\nL90\nE5\nR180\nW5\nN2\nE1\nL90\nN2\nF78\nS5\nR270\nS5\nR90\nN5\nE3\nL90\nS5\nF13\nS5\nF52\nL90\nN2\nR180\nE1\nF41\nS1\nF20\nN4\nF34\nN2\nF45\nE5\nL90\nW3\nL270\nN5\nF52\nR90\nN5\nE5\nN2\nW2\nW5\nR270\nW5\nF10\nN3\nF63\nN4\nF53\nL90\nE5\nL270\nF17\nN1\nL90\nF26\nF93\nR90\nS5\nR270\nS5\nR180\nN4\nF58\nL180\nF40\nS2\nF54\nN5\nF70\nW1\nN4\nW1\nL90\nW5\nR90\nN2\nR90\nS5\nF95\nW4\nL180\nE3\nF68\nS1\nF56\nR90\nW1\nL180\nF66\nR90\nS2\nF57\nL90\nE1\nF42\nS4\nF44\nL90\nF42\nE4\nR90\nS4\nW5\nR90\nE4\nS4\nE5\nF27\nR90\nN1\nR90\nE5\nR90\nW4\nS1\nF81\nN5\nR180\nS4\nE4\nF68\nS3\nL90\nE4\nE4\nL180\nE3\nF8\nW2\nL90\nS4\nL180\nN2\nL180\nE1\nR90\nW5\nN4\nW4\nR90\nF1\nS5\nE2\nL90\nF49\nN4\nW3\nR90\nE5\nF33\nR180\nS4\nE5\nS2\nF79\nW4\nF38\nR90\nF1\nL90\nF56\nL270\nN2\nL90\nE2\nL90\nF25\nW1\nS4\nL270\nW3\nR90\nN2\nF68\nE1\nR180\nW3\nR90\nW3\nR90\nS3\nF4\nW3\nN3\nR90\nW3\nN1\nF54\nW2\nS5\nE4\nF76\nF47\nN1\nF32\nL180\nL90\nF19\nN2\nE5\nL90\nE1\nL90\nE3\nR90\nF48\nR270\nS3\nR180\nS4\nF53\nR90\nF90\nE4\nF100\nL90\nF49\nN1\nW1\nF56\nE2\nN5\nL90\nF39\nR90\nW2\nF26\nE4\nN4\nL90\nF9\nL90\nF41\nW5\nN4\nS1\nW4\nN3\nR90\nN5\nL270\nF82\nL90\nF75\nS5\nF25\nS4\nF67\nN4\nF57\nE4\nN4\nF73\nW5\nL90\nE2\nR180\nN5\nL270\nW3\nF95\nW2\nS4\nE1\nR180\nN3\nW2\nN1\nF28\nN2\nR90\nE3\nS1\nF41\nE4\nN1\nR90\nF12\nL90\nN2\nS2\nE3\nF31\nW1\nL90\nE5\nS1\nF12\nR180\nW5\nR90\nF26\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_13.adb",
    "content": "--  Solution to Advent of Code 2020, Day 13\n-------------------------------------------\n--  Shuttle Search\n--\n--  https://adventofcode.com/2020/day/13\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2020_13 is\n  use HAT, Interfaces;\n\n  --  Taken from MathPaqs (Euclidean_Ring_Tools, de-generic-ized for HAC):\n\n  procedure GCD_and_Bezout (a, b : in Integer_64; s, t, the_gcd : out Integer_64) is\n    --  Finds the GCD and s, t for the\n    --  ` GCD (a, b) = a * s + b * t ` factorization (Bezout theorem).\n    --  Program 1.8, Introduction to number theory, RBJT Allenby & EJ Redfern\n    ta, tb : array (1 .. 3) of Integer_64;\n    q, r : Integer_64;\n  begin\n    ta (1) := 1;         tb (1) := 0;\n    ta (2) := 0;         tb (2) := 1;\n    ta (3) := a;         tb (3) := b;\n    while tb (3) /= 0 loop\n      q := ta (3) / tb (3);\n      for i in 1 .. 3 loop\n        r := ta (i) - q * tb (i);\n        ta (i) := tb (i);\n        tb (i) := r;\n      end loop;\n    end loop;\n    s :=       ta (1);\n    t :=       ta (2);\n    the_gcd := ta (3);\n  end GCD_and_Bezout;\n\n  answer_1, answer_2, d, earliest, sk, tk, sum, prod, gcd : Integer_64;\n  freq_inp, earliest_inp, n : Integer;\n  dmin, idmin : Integer_64 := 0;\n  f : File_Type;\n  freq : array (1 .. 1000) of Integer_64;\n  sep : Character;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\nbegin\n  Open (f, \"aoc_2020_13.txt\");\n  Get (f, earliest_inp);\n  earliest := Integer_64 (earliest_inp);\n  n := 0;\n  loop\n    n := n + 1;\n    Get (f, freq_inp);\n    freq (n) := Integer_64 (freq_inp);\n    exit when End_Of_File (f);\n    Get (f, sep);\n  end loop;\n  Close (f);\n  prod := 1;\n  for k in 1 .. n loop\n    if freq (k) > 0 then\n      d := freq (k) * (1 + earliest / freq (k));  --  Next departure after earliest\n      if k = 1 then\n        dmin := d;\n        idmin := 1;\n      elsif d < dmin then\n        dmin := d;\n        idmin := freq (k);\n      end if;\n      prod := prod * freq (k);\n      if verbose then\n        Put_Line (\n          +\"  frequency:\"      & Integer_64'Image (freq (k)) &\n          \", first departure:\" & Integer_64'Image (d) &\n          \", delta time: \"     & (k - 1)\n        );\n      end if;\n    end if;\n  end loop;\n  if verbose then\n    Put_Line (\"First bus for you : ID \" & Integer_64'Image (idmin));\n  end if;\n  answer_1 := (dmin - earliest) * idmin;\n  --  Chinese remainder theorem (the frequencies are assumed to be coprime)\n  sum := 0;\n  for k in 2 .. n loop\n    if freq (k) > 0 then\n      GCD_and_Bezout (prod / freq (k), freq (k), sk, tk, gcd);\n      if gcd > 1 then\n        Put_Line (\"Not coprime, Chinese remainder theorem cannot be used.\");\n        return;\n      end if;\n      sum := sum + (freq (k) - Integer_64 (k) + 1) * sk * (prod / freq (k));\n    end if;\n  end loop;\n  sum := sum mod prod;\n  answer_2 := sum;\n  --\n  if compiler_test_mode then\n    if answer_1 /= Integer_64'Value (To_String (Argument (1))) or\n       answer_2 /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (\"Part 1: first bus for you (encoded answer):\" & Integer_64'Image (answer_1));\n    Put_Line (\"Part 2: earliest timestamp for first bus in correct sequence:\" & Integer_64'Image (answer_2));\n    --  Part 1: validated by AoC: 222\n    --  Part 2: validated by AoC: 408270049879073\n  end if;\nend AoC_2020_13;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_13.txt",
    "content": "1000511\n29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,0,0,0,0,0,409,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,13,19,0,0,0,23,0,0,0,0,0,0,0,353,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_14.txt",
    "content": "mask = 00101X10011X0X111110010X010011X10101\nmem[41248] = 4595332\nmem[26450] = 60\nmem[32210] = 982366\nmem[1060] = 234632920\nmem[20694] = 38159\nmem[45046] = 58906955\nmask = 010110010X1101XX11X0100001X0000X00X1\nmem[16069] = 7758\nmem[55864] = 2473265\nmem[37095] = 103513009\nmem[4911] = 1002\nmem[63231] = 6932274\nmem[21265] = 72322159\nmem[43724] = 16591353\nmask = 01001X01X101011101010101011X1X000000\nmem[63470] = 30339812\nmem[16920] = 471738\nmem[1014] = 29735753\nmem[61061] = 6866\nmem[8437] = 9138168\nmem[46487] = 1819945\nmem[2985] = 15040783\nmask = 0X10X1101111001X1X100X1X00011100XX11\nmem[32836] = 12902\nmem[60365] = 24782\nmem[29953] = 10085\nmem[18214] = 1160\nmask = 001011X10X11100000100X0X0X0X01011001\nmem[39434] = 37383633\nmem[278] = 670174555\nmem[34062] = 20749996\nmem[2583] = 6222093\nmask = 01X111X1001101X11110100XX001X1000XX1\nmem[6075] = 49890\nmem[9363] = 2392780\nmem[24967] = 218861\nmask = X110111X1XX1010101111X01XX1000X001X1\nmem[41334] = 11836\nmem[24242] = 7263066\nmem[17289] = 64986060\nmem[2583] = 4702503\nmem[21650] = 103905\nmem[134] = 486675\nmask = 00X010100110XXXX111000XXX1000011000X\nmem[45307] = 37940\nmem[16597] = 224911\nmem[17943] = 392744\nmem[55001] = 622484\nmem[35954] = 470\nmask = 11X01011X11000X1X1100X100X011101X011\nmem[1005] = 56755\nmem[16146] = 4333571\nmem[32347] = 10486693\nmem[11452] = 377363\nmem[25158] = 328161913\nmem[51956] = 250388\nmem[10044] = 34078606\nmask = 011011X1X111010111110000X001X1X00110\nmem[8773] = 10575925\nmem[33116] = 175\nmem[36101] = 14593\nmask = 0100010X110X0101010XX10X011111XX1101\nmem[21083] = 1922\nmem[3653] = 912\nmem[26768] = 7321934\nmem[49134] = 17616\nmem[62950] = 41565481\nmem[12957] = 2136786\nmem[10324] = 17788\nmask = X11X0X0X11010101110X01111010X1100X11\nmem[5462] = 18755\nmem[39408] = 2435211\nmem[49271] = 6589\nmask = X1X011XX01X100010110001X0X0X111X1100\nmem[52570] = 2166\nmem[28731] = 16573421\nmem[18265] = 1192\nmem[22435] = 10856992\nmem[19263] = 7550\nmem[30541] = 434738\nmem[36101] = 869138\nmask = 010001X001010001XX010100000010110X01\nmem[52893] = 125505223\nmem[22919] = 597\nmem[62950] = 54107\nmem[52797] = 7649588\nmem[30421] = 3968\nmem[30429] = 614720\nmask = 01X0X10001X100010X1011XX00000X111X00\nmem[44718] = 11141064\nmem[42713] = 206218234\nmem[51781] = 527553473\nmem[1967] = 27527823\nmem[6386] = 5404\nmask = 00101X10XX11X0XX1110001000001110X11X\nmem[62339] = 72046594\nmem[14657] = 3243652\nmem[750] = 40239\nmem[134] = 1936539\nmem[5775] = 266384125\nmask = 011X111XXX110X01X11X000X00010100011X\nmem[2956] = 438895\nmem[41520] = 7282\nmem[42192] = 34769\nmem[8837] = 2587\nmask = 01XX11100101000X0X10011XX01010011101\nmem[12515] = 450388\nmem[62175] = 649233\nmem[54743] = 129273\nmem[10284] = 159823\nmem[31311] = 16983\nmem[56137] = 852771967\nmask = 11010X1X01010101X1010X11101111X00010\nmem[47190] = 526627409\nmem[34299] = 540572\nmem[61226] = 61426238\nmem[12892] = 61446\nmem[33421] = 4192\nmask = 0110111111X10101111010100XX01XX10100\nmem[41685] = 258\nmem[26983] = 60795579\nmem[28064] = 10483\nmem[33070] = 66557269\nmem[12624] = 448724\nmem[38125] = 141175913\nmask = 010X1X00X101000X0111010101XX01011000\nmem[12957] = 7693971\nmem[45285] = 4628\nmem[48546] = 799\nmem[17857] = 7578026\nmask = 00101X100101X0010110000000XX1010X110\nmem[41841] = 234511\nmem[27387] = 2990\nmem[24636] = 1269957\nmem[15638] = 428392\nmem[22064] = 272\nmask = 0XXX10X01011X011111000000XX0X100X010\nmem[26764] = 482715793\nmem[8422] = 70439\nmem[17857] = 28381730\nmem[4524] = 750659820\nmask = 11101100010100X1011000111000XX00X010\nmem[52570] = 517468200\nmem[25263] = 11113122\nmem[33421] = 32762600\nmask = 11101X01XX1000010X10111000X1101X0X00\nmem[16577] = 910\nmem[32450] = 16924479\nmem[4421] = 24801362\nmem[46638] = 8546454\nmask = 01X11X1101110101X1X1X010000XX101X001\nmem[34209] = 24703796\nmem[30481] = 831\nmem[46487] = 147322\nmem[38619] = 11686\nmem[26615] = 1174\nmask = 010X0X00110100X1XX000010110XX100X001\nmem[53587] = 198046\nmem[38420] = 22334\nmem[20181] = 962\nmask = XX101101X01000010XX01111001111010100\nmem[33812] = 107321\nmem[8613] = 7395\nmem[1117] = 149990\nmem[22919] = 23596\nmask = 1X01110110010X01X100000001111011X010\nmem[57800] = 254591077\nmem[6633] = 60308580\nmem[8980] = 104196938\nmem[5936] = 289911936\nmem[44806] = 297364592\nmask = 11X10XX0X1010X01010110XXX01111100X00\nmem[49271] = 177794\nmem[15368] = 259266583\nmem[19327] = 590\nmem[40243] = 24245\nmem[57130] = 1201404\nmem[22545] = 1831196\nmem[59161] = 25210381\nmask = 0X101X11111X010111100X110XX11000X10X\nmem[38749] = 2091454\nmem[45138] = 621877\nmem[52107] = 3430339\nmask = 0010X110X11X00101X100011XX111X000100\nmem[17228] = 252642\nmem[23892] = 13721\nmem[43787] = 2786942\nmem[55481] = 58875\nmem[513] = 892\nmem[62445] = 40312\nmask = 0010X11XXX11001011X01010X0111110X100\nmem[17415] = 7415167\nmem[9048] = 46059\nmem[2159] = 636711036\nmask = X010111X111X010X1110X10100XX1000X00X\nmem[38420] = 104527\nmem[24790] = 85\nmem[58634] = 127952377\nmem[8958] = 11672057\nmask = X01X111X00X110XX0X10000000000X0X0100\nmem[283] = 241\nmem[8898] = 36719\nmem[49134] = 217820\nmem[31884] = 419937\nmask = 0XX11110X1110X0101111000000100110X00\nmem[27694] = 6848\nmem[25843] = 331711\nmem[6688] = 581239\nmem[41591] = 171\nmask = 0100X100X1010X01010X001XX01XX1010101\nmem[30429] = 1103121\nmem[42192] = 7844667\nmem[21668] = 51727200\nmask = 001X1X10001X101XX1100X1000101100X010\nmem[4322] = 157863993\nmem[49962] = 9140\nmem[16964] = 1599\nmem[14443] = 2038\nmem[3767] = 16636129\nmem[13476] = 485497191\nmem[1663] = 163345\nmask = X101110111010101X1X10011001X10110000\nmem[13172] = 195\nmem[33921] = 5684133\nmem[1337] = 51317\nmask = X1XXX101110101X1010X0100XX111X101001\nmem[63928] = 4636\nmem[56436] = 3887978\nmem[6185] = 3037\nmem[7095] = 11521156\nmem[1663] = 121401\nmem[7218] = 20750\nmask = 010001001X0101010X00001XXX100XX10100\nmem[24149] = 309519\nmem[16287] = 12731276\nmem[29772] = 65227\nmem[37172] = 2824\nmem[17508] = 59271\nmem[22133] = 3806\nmask = 01X0X101011X000X0X101000100011111101\nmem[14401] = 158547520\nmem[37172] = 16841\nmem[40439] = 461272566\nmem[60909] = 478018315\nmem[43219] = 2154608\nmem[25369] = 46117\nmem[54852] = 79656\nmask = XX10111001X100X1X1100X1X0001110001X1\nmem[4213] = 900609324\nmem[19327] = 28071\nmem[30421] = 782\nmem[4804] = 17293\nmask = 0100X1000101X0010X010101X01000011001\nmem[18139] = 1546181\nmem[14021] = 33793814\nmem[46699] = 2014\nmem[51956] = 171606030\nmem[29702] = 475302805\nmem[18265] = 198549\nmask = 0101X0110X1X0101X1X1X01101001X001XX1\nmem[38962] = 132592128\nmem[9436] = 7464578\nmem[12650] = 49333\nmem[8837] = 3234578\nmask = 011X11101011X101111000XX001110001110\nmem[61694] = 1206\nmem[32263] = 20761769\nmem[2116] = 193628\nmem[13505] = 123039\nmem[62164] = 14323289\nmask = 1X101010100X0101X1110X01000101X00100\nmem[21385] = 1022949\nmem[51318] = 5667643\nmem[17420] = 36980027\nmem[29202] = 801\nmask = 0101X01XX11X0101X10110X1010001001001\nmem[15338] = 23103863\nmem[10488] = 4521\nmem[13172] = 17055515\nmask = X10111X11X01X111X100000000111011X111\nmem[36577] = 397263\nmem[8992] = 11944917\nmem[22064] = 738796\nmem[17310] = 1562710\nmem[30068] = 4950154\nmask = 011111X10111X10X010X00X1X100X0010001\nmem[31166] = 6551\nmem[62218] = 1528\nmem[11467] = 35999360\nmem[39578] = 11530695\nmem[30855] = 27864\nmem[18369] = 1610323\nmem[58953] = 12938251\nmask = 01X111010X1111X0010X0XX010000X000111\nmem[15411] = 1096\nmem[49541] = 3181\nmem[23568] = 276408\nmem[45168] = 1721\nmem[11394] = 155136\nmask = 1111X1X011010001X101010X100XX11001X1\nmem[61945] = 26647548\nmem[63262] = 110741\nmem[33783] = 158\nmem[12753] = 200460\nmem[43229] = 7579\nmem[37084] = 26507\nmask = 0100110011X10101010X00X01X11X1X10101\nmem[65089] = 636807464\nmem[5775] = 4440830\nmem[52107] = 69328099\nmem[38420] = 859060126\nmem[21272] = 1700\nmem[12062] = 176162\nmem[12094] = 8733\nmask = X100010111XX01X1X1010100X01101001X1X\nmem[44718] = 33650499\nmem[26507] = 165784650\nmem[12622] = 2023\nmem[5651] = 120398699\nmask = 110001011X010X0111X10X00011110001X00\nmem[44975] = 666498\nmem[11614] = 751\nmem[61354] = 5063\nmem[4396] = 1131\nmem[25418] = 882\nmem[49245] = 64151\nmask = 011X1X110111X1XX11X1100X01000X101001\nmem[59013] = 1141214\nmem[18016] = 95668408\nmem[30067] = 18132964\nmem[38900] = 286972459\nmem[42265] = 13529062\nmem[59369] = 6028326\nmask = 0110110X010100010XXX0X00X0011X101X1X\nmem[6479] = 8816055\nmem[28451] = 29446\nmem[61417] = 59156\nmem[6694] = 15597\nmem[29264] = 115437\nmask = 11110100110101011101XX0001X1X1110101\nmem[46886] = 114630\nmem[17383] = 452299\nmask = 010X110X11X10101000X001X011010000100\nmem[19215] = 487176198\nmem[59629] = 2120284\nmem[27009] = 3064\nmem[42335] = 22072\nmem[514] = 2010\nmask = 0100X1001101010X010000X0001000X00100\nmem[37232] = 2564\nmem[20561] = 29506163\nmem[27396] = 380700410\nmem[34075] = 868\nmem[24967] = 1882926\nmask = 010X1X01XX110111111X0XX0000X010X0101\nmem[61084] = 3068852\nmem[33028] = 188720342\nmem[17375] = 62850\nmask = X10X1X0X110101010X01001001101000X000\nmem[24149] = 1815\nmem[51489] = 197928369\nmem[27694] = 231814\nmem[11813] = 1002177793\nmem[526] = 104755102\nmem[22216] = 8396\nmask = 0110111101010001X1X0X11100X010001111\nmem[21083] = 2509191\nmem[13215] = 172339241\nmem[12386] = 106305632\nmask = X1X101X11101010101000X010X11101101X1\nmem[35709] = 64980388\nmem[51838] = 62510\nmem[48641] = 1174272\nmem[42157] = 149\nmask = 0X101100010100010X0X00X1100101111111\nmem[35807] = 1100541\nmem[10044] = 69616152\nmem[3047] = 142725213\nmask = 11101X1X10X101010111X001XX10X0X00100\nmem[38049] = 110\nmem[43097] = 14955394\nmem[61810] = 3545867\nmem[61238] = 5370\nmem[20585] = 191903\nmem[26133] = 24248\nmask = 010X110X011X00010110010100X0XXX1X011\nmem[15950] = 140910\nmem[12062] = 424527462\nmem[11876] = 236\nmem[5182] = 4776\nmem[50278] = 490\nmask = 010XX011011101X1110101110111110110X0\nmem[53736] = 2314\nmem[12633] = 5053\nmem[66] = 49557761\nmask = 01X01101X10101010101000X00111110100X\nmem[18849] = 911\nmem[20666] = 12891678\nmem[5609] = 10432\nmem[59720] = 22145720\nmem[17508] = 42631\nmem[8585] = 3448\nmask = 11X1X10X110101X101010X01X0011011X001\nmem[30601] = 9140827\nmem[30361] = 4166366\nmem[46057] = 16057\nmem[26983] = 251682577\nmem[63197] = 1603252\nmem[52893] = 462048575\nmask = 011011100111X00X11100X00100010001XXX\nmem[17534] = 25807901\nmem[4932] = 106350673\nmem[42192] = 735653575\nmem[10874] = 59007\nmask = 01000101110001X1XX001000001X1X011111\nmem[48049] = 386\nmem[1538] = 138451275\nmem[50333] = 15707\nmask = 0101100X01110111XX1X0000001011001X01\nmem[18139] = 102960\nmem[41277] = 5837\nmem[44484] = 29937\nmask = 11101XX10X1X0001011000100X010010X00X\nmem[30615] = 95201946\nmem[719] = 3697022\nmem[27391] = 150969140\nmem[62680] = 427952\nmem[7349] = 46922\nmem[17375] = 41348888\nmem[57800] = 1901\nmask = 0010X11X1X11X011111X0011001X01001111\nmem[46994] = 118757653\nmem[32947] = 23571\nmem[8653] = 1364\nmem[3767] = 6954112\nmask = 01001X0011010X000111X0X0X1X011011XXX\nmem[37908] = 88438829\nmem[20630] = 618075182\nmem[21520] = 101250753\nmem[10703] = 475904\nmask = 001001101XX10010111X1X10100111XX11X1\nmem[17310] = 2889476\nmem[2725] = 463419\nmem[65001] = 910330085\nmask = X1011011X111010101X110X1X1X0010110X0\nmem[15999] = 18586203\nmem[12825] = 51333145\nmem[29966] = 596120517\nmem[26866] = 141039\nmem[24223] = 415414\nmem[24403] = 16110598\nmask = 0XX00X01111X01110X011010101X01101010\nmem[43382] = 150995\nmem[28011] = 1021785\nmem[60339] = 7805893\nmem[37197] = 268431\nmem[17792] = 253366088\nmem[21437] = 24057926\nmask = XX1011X111100X00111X1100010111010011\nmem[18006] = 265940517\nmem[55921] = 1634\nmem[27656] = 17058\nmem[4911] = 3686\nmem[33243] = 8125794\nmem[47537] = 146165365\nmask = 110111011X01X1X10100X000010110111X0X\nmem[5775] = 176470\nmem[63017] = 24003454\nmask = 00011X001X11XX11111X01101010X0000010\nmem[1604] = 174349\nmem[42888] = 7159712\nmem[26615] = 1487\nmask = 01X11101100111111X000X1001110001011X\nmem[5344] = 8563500\nmem[21234] = 166162105\nmem[48935] = 10849963\nmask = 01000101XX0001111000XX0000X010010X00\nmem[24149] = 127627213\nmem[27338] = 43164114\nmem[47215] = 252815\nmem[47431] = 32732410\nmask = 01011100000100011X0X0XX101X111111100\nmem[13412] = 4193068\nmem[45046] = 148\nmem[63535] = 11659\nmem[6518] = 471308933\nmask = 111X111011X1X1X101111X000100001101X1\nmem[31114] = 118512878\nmem[41334] = 1604\nmem[7338] = 571\nmem[6001] = 4126415\nmem[5215] = 4392\nmem[47836] = 1862\nmem[22064] = 30804845\nmask = 0111010X11X1010X0101X1110011101X0111\nmem[13321] = 22426593\nmem[37095] = 5357\nmem[44281] = 467020\nmem[62680] = 2721559\nmask = 010001X0010100XX10010000011000101X00\nmem[30615] = 261491\nmem[31097] = 46202501\nmem[27880] = 6002395\nmem[51385] = 2780\nmem[51435] = 43181943\nmem[42192] = 107728750\nmask = 101011100X1100110X1X00X0101X10X11101\nmem[48366] = 859523\nmem[14111] = 859\nmem[21668] = 292390073\nmem[8073] = 858\nmem[12920] = 662378\nmask = X111X10011X10101X10101XX01111011X101\nmem[20630] = 4051571\nmem[55963] = 367\nmem[379] = 10962356\nmem[33028] = 37\nmem[24035] = 9459\nmem[50949] = 2030\nmask = 001011100X110X111X10101100011X010X11\nmem[8437] = 47226\nmem[41248] = 319\nmem[9624] = 3503\nmem[6875] = 5282\nmask = 11X111XX100101010100X01XX1X1001X1000\nmem[21292] = 1673693\nmem[51132] = 10346473\nmem[7504] = 4325\nmask = 111X010X1101011101X100010XX1X0111100\nmem[35415] = 6296\nmem[19215] = 1263591\nmem[49977] = 379136185\nmem[62950] = 28156510\nmem[8265] = 28662942\nmask = 01X110X01X1X0X11X1X00110000X01000100\nmem[54672] = 131784041\nmem[11394] = 24602\nmem[24646] = 10584\nmem[44349] = 4883\nmem[54743] = 2940969\nmem[8265] = 14841530\nmask = 0X10111X11100X0011X011XX00X011011010\nmem[49374] = 45910\nmem[25923] = 368017518\nmem[25114] = 8076340\nmem[62690] = 904875563\nmask = 010X11X0X1X1010X01010X01101001110101\nmem[39408] = 3080\nmem[6918] = 125955053\nmem[27880] = 29186\nmask = 01001101X101010X0101X1001111100010X1\nmem[11813] = 153838914\nmem[20585] = 1917\nmem[21385] = 1881773\nmem[8556] = 25758757\nmem[22435] = 802061\nmem[27631] = 13285866\nmask = 01101110111X0001011X10100X0100X10101\nmem[23441] = 186656612\nmem[2186] = 189388742\nmem[12866] = 874882\nmem[12947] = 23895\nmem[20630] = 77211\nmem[42083] = 63015239\nmem[51838] = 4984972\nmask = 00101110X111001X1X10001XX0X111XXX101\nmem[14789] = 244532376\nmem[21292] = 736136092\nmem[10874] = 513949\nmem[16755] = 12361\nmem[5416] = 22987\nmem[39578] = 106587\nmask = 010X11000X010001X1XXX0110011X1X1110X\nmem[43479] = 61\nmem[47199] = 15617564\nmem[18265] = 6027808\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_14_exm_1.txt",
    "content": "mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X\nmem[8] = 11\nmem[7] = 101\nmem[8] = 0\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_14_exm_2.txt",
    "content": "mask = 000000000000000000000000000000X1001X\nmem[42] = 100\nmask = 00000000000000000000000000000000X0XX\nmem[26] = 1\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_14_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 14\n-------------------------------------------\n--\n--  https://adventofcode.com/2020/day/14\n--\n--  Full Ada version only.\n--  This problem is too complicated for HAC 0.08x...\n--\nwith Ada.Calendar,\n     Ada.Containers.Hashed_Maps,\n     Ada.Text_IO,\n     Ada.Integer_Text_IO;\n\nwith Interfaces;\n\nprocedure AoC_2020_14_full_Ada is\n\n  --  Based on algorithm at https://gist.github.com/badboy/6267743\n  --\n  function Hash_64_32_shift (key : in Interfaces.Unsigned_64) return Ada.Containers.Hash_Type\n  is\n    use Interfaces;\n    k : Unsigned_64 := key;\n  begin\n    k := (not k) + Shift_Left (k, 18);     -- key = (key << 18) - key - 1;\n    k := k xor Shift_Right (k, 31);\n    k := k * 21;                           -- key = (key + (key << 2)) + (key << 4);\n    k := k xor Shift_Right (k, 11);\n    k := k +   Shift_Left  (k,  6);\n    k := k xor Shift_Right (k, 22);\n\n    return Ada.Containers.Hash_Type (k and (2**32 - 1));\n  end Hash_64_32_shift;\n\n  procedure Process_Data (\n    file_name : String;\n    verbose   : Boolean := False;\n    exit_part : Positive := 2\n  )\n  is\n\n    use Ada.Calendar, Ada.Text_IO, Ada.Integer_Text_IO, Interfaces;\n\n    package Addr_Map_Pkg is new\n      Ada.Containers.Hashed_Maps (Unsigned_64, Unsigned_64, Hash_64_32_shift, \"=\");\n\n    package MIO is new Modular_IO (Unsigned_64); use MIO;\n    package IIO is new Integer_IO (Integer_64);  use IIO;\n\n    addr, addr_f, addr_base, b, m_or, m_float, m_and, sum, v : Unsigned_64;\n\n    mame_s : String := \"ma\";\n    mask_s : String := \"sk = \";\n    mem_s  : String := \"m[\";\n    mem_s2 : String := \"] = \";\n\n    c : Character;\n    f : File_Type;\n    mem : Addr_Map_Pkg.Map;\n    use Addr_Map_Pkg;\n    cu : Cursor;\n    single_bit_mask : array (1 .. 36) of Unsigned_64;\n    last_X_bit : Natural;\n    --  Some post-game statistics:\n    written_addresses : Integer_64;\n    T1, T2 : Time;\n  begin\n    Put_Line (\"Processing data file: \" & file_name);\n    T1 := Clock;\n    for part in 1 .. 2 loop\n      mem.Clear;\n      Open (f, In_File, file_name);\n      while not End_Of_File (f) loop\n        Get (f, mame_s);\n        if mame_s (2) = 'a' then  --  \"mask\"\n          Get (f, mask_s);\n          m_or := 0;\n          m_and := 0;\n          b := 2 ** 35;\n          if verbose then\n            Put (\"  Masks: ------[\");\n          end if;\n          last_X_bit := 0;\n          for i in 1 .. 36 loop\n            Get (f, c);\n            if verbose then\n              Put (c);\n            end if;\n            case c is\n              when 'X'  =>\n                last_X_bit := last_X_bit + 1;\n                single_bit_mask (last_X_bit) := b;\n                m_and := m_and + b;\n              when '1'  => m_or := m_or + b;\n              when others => null;\n            end case;\n            b := b / 2;\n          end loop;\n          if verbose then\n            Put (']');\n            New_Line;\n            Put (\"  Masks: and: \"); Put (m_and, 39, Base => 2); New_Line;\n            Put (\"  Masks:  or: \");  Put (m_or, 39, Base => 2); New_Line;\n            if part = 2 then\n              Put_Line (\"   Single \"\"X\"\" bit mask list:\");\n              for i in 1 .. last_X_bit loop\n                Put (\"            \");  Put (i, 0);\n                Put (\" \"); Put (single_bit_mask (i),  39, Base => 2); New_Line;\n              end loop;\n            end if;\n          end if;\n        else  --  \"mem\"\n          Get (f, mem_s);\n          Get (f, addr);\n          Get (f, mem_s2);\n          Get (f, v);\n          if part = 1 then\n            --  Value is changed.\n            v := (v and m_and) or m_or;\n            mem.Include (addr, v);\n          else\n            addr_base := (addr or m_or) and not m_and;\n            if verbose then\n              Put (\"  Base address : \"); Put (addr_base, 0); New_Line;\n            end if;\n            --  Bit flipping\n            m_float := 0;\n            --  Get as much combinations of 0's and 1's as there are 'X'es:\n            for i in Unsigned_64'(0) .. 2 ** last_X_bit - 1 loop\n              m_float := 0;\n              for j in 1 .. last_X_bit loop\n                if (Shift_Left (Unsigned_64'(1), j - 1) and i) /= 0 then\n                  --  Flip the bit of the corresponding 'X':\n                  m_float := m_float + single_bit_mask (j);\n                end if;\n              end loop;\n              if verbose then\n                Put (\"  Compact \"\"Floating\"\" representation: \");  Put (i, 0, Base => 2);\n                Put (\", expanded : \");  Put (m_float, 0, Base => 2);\n              end if;\n              addr_f := addr_base or m_float;\n              if verbose then\n                Put (\"  Setting @ \"); Put (addr_f, 0); Put (\" value \"); Put (v, 0);  New_Line;\n              end if;\n              mem.Include (addr_f, v);\n            end loop;\n          end if;\n        end if;\n      end loop;\n      Close (f);\n      sum := 0;\n      written_addresses := 0;\n      if verbose then\n        Put_Line (\"----- Summary of memory dump (overwritten addresses only) -----\");\n      end if;\n      cu := mem.First;\n      while Has_Element (cu) loop\n        sum := sum + Element (cu);\n        written_addresses := written_addresses + 1;\n        if verbose or Key (cu) = 0 then\n          Put (Key (cu)); Put (\":\"); Put (Element (cu)); New_Line;\n        end if;\n        Next (cu);\n      end loop;\n      Put (\"    Part \"); Put (part, 0);\n      Put (\" rules.  Sum of all values left in memory: \"); Put (sum, 15);\n      T2 := Clock;\n      Put (\". Total of memory addresses written: \"); Put (written_addresses, 5);\n      Put_Line (\". Computation time: \" & Duration'Image (T2 - T1) & '.');\n      exit when part = exit_part;\n    end loop;\n    New_Line;\n  end Process_Data;\nbegin\n  Process_Data (\"aoc_2020_14_exm_1.txt\", True, 1);\n  Process_Data (\"aoc_2020_14_exm_2.txt\", True);\n  Process_Data (\"aoc_2020_14.txt\");\n  Process_Data (\"aoc_2020_14_jc.txt\");\n  --\n  --  aoc_2020_14.txt :\n  --    Sum of all values left in memory:  10717676595607\n  --    Sum of all values left in memory:   3974538275659\nend AoC_2020_14_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_14_jc.txt",
    "content": "mask = 00X1011010111X01X1X010X01X1111X11100\nmem[13879] = 56974\nmem[26072] = 842\nmem[47322] = 62104110\nmem[31450] = 372784\nmem[54364] = 2818920\nmask = 01000X10101XX0011000X00XXX00101X0101\nmem[13358] = 73976240\nmem[41121] = 3647124\nmask = 010000X01111X0011000X01010X1001100X0\nmem[49893] = 63539\nmem[63669] = 79316429\nmem[19136] = 256\nmem[1117] = 1244\nmem[56655] = 267815\nmem[22811] = 142\nmask = 0101011010111X0111X010110000XXX1010X\nmem[40297] = 21028792\nmem[16007] = 950419537\nmem[40907] = 2010\nmem[27377] = 525\nmem[0] = 209\nmem[41317] = 2312973\nmem[4641] = 1227100\nmask = X0X000101X111001110X011X1X1010X10100\nmem[24322] = 103589922\nmem[2572] = 1231\nmem[53327] = 814998856\nmem[30460] = 25015\nmask = 00000010XX101X11X0110100X0X001X010X1\nmem[50914] = 37339\nmem[50218] = 5021282\nmask = 0X0X00X01XX0110X1101X0X010000110X101\nmem[3780] = 51750101\nmem[8561] = 638\nmem[64747] = 215\nmem[51358] = 194347939\nmem[29912] = 9717\nmem[44684] = 418165\nmask = 0X0X00101011XXX11100001X0101X01101XX\nmem[1418] = 81827528\nmem[38228] = 399582\nmem[57488] = 7003\nmem[22080] = 112130\nmem[29467] = 2198074\nmem[32800] = 35048851\nmask = 010X00001011100111X0001X0100011010X1\nmem[16589] = 1922920\nmem[31011] = 88738170\nmem[35178] = 4791\nmem[17792] = 5560\nmem[50656] = 1695\nmem[22720] = 1584409\nmem[54364] = 1486\nmask = 01XX011010X110XXX1X001010X01000X1011\nmem[19230] = 13477\nmem[41397] = 781359\nmem[11599] = 7687201\nmem[2817] = 26775\nmask = X10001XX1000100X1X00001X01X100011100\nmem[288] = 1886\nmem[32911] = 326403\nmem[48084] = 66681\nmask = 00001000X011110X11011000X0X000XX10X1\nmem[41020] = 3202\nmem[21434] = 5634478\nmask = 00X0XX001011X0X1X10X100001110111X011\nmem[33545] = 1876\nmem[28976] = 581977039\nmask = 0X11011010111101011000X1101X000X1110\nmem[19071] = 770610413\nmem[20064] = 1694\nmem[43482] = 2871\nmem[46365] = 3148234\nmem[52059] = 3513\nmem[18760] = 1548\nmem[61977] = 605\nmask = 010X01XX1X11100X11001X10X10110000001\nmem[53801] = 111695\nmem[11683] = 168184\nmem[20469] = 1949\nmask = X1010110X01111011100X010000XX0000000\nmem[55872] = 2261951\nmem[13140] = 15964\nmem[45204] = 22572\nmask = X10X0000XX111X01100011X11X1100101101\nmem[56655] = 124863920\nmem[32800] = 20227\nmem[58864] = 42605725\nmem[59474] = 859\nmem[59729] = 141193\nmem[18342] = 1631\nmask = 01100XX01011100111X00010XX01X0XX010X\nmem[13572] = 3383121\nmem[32800] = 25726954\nmem[54193] = 54397\nmem[3305] = 251510\nmem[52294] = 33972\nmask = 0100X0XX10XX11X11101001010X1X110X100\nmem[3991] = 3201095\nmem[19248] = 1173\nmem[17507] = 684436\nmem[37324] = 694\nmem[11150] = 44468495\nmem[16853] = 3978967\nmem[10293] = 3552\nmask = X0X00000X01010011011011X1000X01XX001\nmem[54689] = 1224\nmem[36536] = 33407636\nmem[22811] = 296513\nmem[58491] = 109654\nmask = 010XX1111011000X1000X1000100X00011X0\nmem[20982] = 1468\nmem[15854] = 13972\nmem[55563] = 121451\nmem[28871] = 732\nmask = 00100X100001000001001101XX100X10XX10\nmem[37549] = 11144610\nmem[58939] = 280786876\nmem[38833] = 1473210\nmem[44075] = 571\nmem[21698] = 5427778\nmem[35937] = 544693\nmask = 0100011010111XX10X00011011X010110110\nmem[63719] = 36151477\nmem[43205] = 79985\nmem[9431] = 23613381\nmem[38228] = 93679\nmem[45544] = 946568\nmask = 0X000000101010011101110X11001000XX00\nmem[2730] = 8086855\nmem[50422] = 3607\nmem[9544] = 3738\nmask = 0X0XXXX010X1100111100010000001010010\nmem[17216] = 2231300\nmem[40965] = 30453\nmem[43536] = 1780\nmem[26440] = 712936\nmem[26845] = 445304638\nmask = 01X000X1X0101001101111X1000X0001X0XX\nmem[34736] = 35\nmem[23584] = 62941351\nmask = 01X000XX1110XX11XX10010000010X00X110\nmem[35014] = 2725\nmem[31317] = 3\nmask = 000XX0XX101010X1X0X111X0100001100001\nmem[372] = 21946096\nmem[10488] = 41777407\nmem[23528] = 1708407\nmem[60206] = 182569990\nmem[44075] = 816675\nmem[43028] = 618865\nmask = 0X00X000101X1X01110XX01XX0000011X001\nmem[955] = 17506\nmem[41317] = 3162029\nmem[37] = 9168685\nmem[24435] = 33494\nmem[10291] = 901681\nmem[26688] = 23163\nmask = 0100100110X111011XX10010101101101X00\nmem[53694] = 184478\nmem[38156] = 140154654\nmem[3645] = 99833620\nmem[5194] = 7438\nmem[13132] = 187583\nmem[10626] = 213169401\nmask = 0X00X11X1011000X100000XXX0001010XX11\nmem[58468] = 3932\nmem[47108] = 13422709\nmem[20791] = 25670347\nmask = 0100010010111000110000X1X11111X0X100\nmem[64332] = 58063181\nmem[20791] = 97103200\nmem[21178] = 704\nmask = 010X000010101X0X11X111001100X1X011XX\nmem[29912] = 96861\nmem[11661] = 15933204\nmem[31973] = 1597059\nmask = 010X0010001XX001110011X0000X00101110\nmem[54377] = 929\nmem[1578] = 1628469\nmem[9066] = 1039223\nmem[54819] = 131459054\nmem[59746] = 97979749\nmem[21742] = 919\nmask = 010X000010111X011110X100X00X0000X00X\nmem[25877] = 1030474\nmem[40848] = 441\nmem[19136] = 40\nmem[41305] = 509818516\nmask = 11010011XX111011110X111011X11X00X100\nmem[56916] = 23553145\nmem[43067] = 120593523\nmem[41993] = 121958\nmem[16589] = 469\nmask = 00000XX0101111011101X1011XX1001XXXX0\nmem[44363] = 1739\nmem[15915] = 49544\nmem[5729] = 173493396\nmem[29213] = 41122\nmem[50656] = 1531\nmask = 0X010X1010111X0111000X1XX10100X101XX\nmem[58111] = 1227\nmem[45142] = 3293\nmem[30952] = 2965075\nmem[25181] = 578696\nmem[50656] = 60702685\nmask = 0111011010111XX10100X100110101000X1X\nmem[59881] = 82070\nmem[60524] = 62394\nmem[35663] = 1981\nmem[27322] = 216531615\nmem[8965] = 14469\nmem[13388] = 1148662\nmem[13342] = 92607190\nmask = X1000XX110X0111XXX010010X00101110101\nmem[2228] = 40376\nmem[64755] = 1327525\nmask = 11010010X0XX10X11X0X1X011001101X110X\nmem[15280] = 2364003\nmem[19478] = 72063090\nmem[8497] = 28240\nmem[45678] = 2811\nmem[52231] = 39955\nmask = 0X001111X011000010X01011X1000XX00X11\nmem[24827] = 1639\nmem[13879] = 119218\nmem[17610] = 6101768\nmem[48448] = 3972\nmask = XX0000X0X11110X110001111011X00010101\nmem[65388] = 9968\nmem[26462] = 45065510\nmem[27496] = 70270\nmask = 01010X1X111X1001101X101X0XX000000001\nmem[10134] = 755\nmem[34940] = 3959699\nmem[26321] = 156\nmem[63789] = 36543477\nmask = X10X001010111001X1000100001XX00X101X\nmem[59095] = 888920\nmem[26072] = 189525541\nmem[41506] = 78022\nmask = 01X000101X1X10X11010X1X010X1010X011X\nmem[19618] = 43629\nmem[16853] = 176218496\nmem[27558] = 9383\nmask = 000000X01011101111001XX00000X0000110\nmem[47738] = 782\nmem[9654] = 14755\nmask = 01X0X0001X01X101110X00000000000X0101\nmem[21742] = 34626297\nmem[10621] = 1418350\nmem[45805] = 3784031\nmask = 01XX01001011101X010X001001X1010X0100\nmem[18511] = 458\nmem[4597] = 8053\nmem[34914] = 902\nmem[11895] = 2319205\nmem[54291] = 7059674\nmem[60178] = 1495\nmem[64432] = 22061\nmask = 1X110010001110011X0X01100X1XX0X01XX0\nmem[9055] = 462699\nmem[35882] = 554265333\nmem[50939] = 52443722\nmem[20552] = 160408413\nmask = 0100010010111001X100000X01X1001001X1\nmem[28976] = 404\nmem[64843] = 813\nmem[57066] = 899\nmem[16179] = 3033125\nmask = X101X01X101110X1110011X0X00010X01001\nmem[63922] = 122921015\nmem[47325] = 66631\nmem[34914] = 122827\nmem[41369] = 723416\nmem[26321] = 350572\nmem[10260] = 11917171\nmem[20396] = 112670\nmask = 00X100101011100111XX010X011X0XX001XX\nmem[11150] = 875126074\nmem[28760] = 25307778\nmem[14951] = 445519\nmem[54291] = 394307\nmem[19109] = 15584261\nmem[8221] = 524\nmask = 01000XX011111001100000001101X111X101\nmem[58015] = 18497\nmem[63992] = 530980167\nmem[26915] = 14357281\nmem[42401] = 12123838\nmem[65275] = 14601815\nmask = 010X00X0100011X011010010X00XX100010X\nmem[49005] = 39006890\nmem[121] = 119847895\nmem[16179] = 737050\nmem[52215] = 11770\nmask = 010XX0001X10X101110XX10X00000X100111\nmem[40066] = 1188\nmem[27727] = 10855\nmem[47207] = 113852179\nmask = 0X10011XX01X1011110000011X11X0XX101X\nmem[27558] = 1280\nmem[18441] = 312\nmem[22675] = 2746277\nmem[54987] = 120268\nmask = 1101XX1010111X011XX01XX0110000001110\nmem[8285] = 6819893\nmem[56655] = 10287\nmem[39027] = 158\nmem[25922] = 2798\nmem[22261] = 36850389\nmem[46394] = 48894888\nmask = X1X10010X011100111001000XX100X1X1X00\nmem[24614] = 1802\nmem[13232] = 499261\nmask = 01XX0X1010111XX11100X011010100X0X101\nmem[63992] = 12600674\nmem[56655] = 99142656\nmem[9273] = 302251593\nmask = XX000XXX1011101111XX0010000100111X00\nmem[18088] = 20379649\nmem[47508] = 111520085\nmem[38545] = 90881967\nmem[21514] = 16333\nmem[35731] = 816238944\nmask = 110111101X11X1011010X10010000111101X\nmem[13890] = 4842901\nmem[23610] = 19829\nmem[21900] = 31928769\nmem[10595] = 228191\nmem[13375] = 24467\nmem[45544] = 149815\nmask = 010XX1X0101X100X110X1111010X1100X10X\nmem[13358] = 7851\nmem[18277] = 1322\nmem[24517] = 6165\nmem[19856] = 93677767\nmask = 010X0110101XX0011100X000X00000100111\nmem[60820] = 549270\nmem[42355] = 609632\nmem[35546] = 241510\nmem[59340] = 57067\nmask = 010X00X0X0101X001X01111011X00XX01010\nmem[58491] = 456443643\nmem[49058] = 86242\nmem[24702] = 25105\nmem[35001] = 88082598\nmem[36988] = 23981732\nmem[54815] = 19064841\nmem[52231] = 329\nmask = 0XX0001X11101XX011X1X1000000110111X1\nmem[7504] = 475530227\nmem[29138] = 11235\nmem[56376] = 76699622\nmask = 0011XXX01011100X1110X111011XX1110X00\nmem[52184] = 60066\nmem[64705] = 2343316\nmem[43172] = 28305258\nmem[5362] = 2133\nmem[38763] = 2754100\nmem[52032] = 7390\nmem[2572] = 19579691\nmask = 010XX00010101001101X111X000101110011\nmem[29623] = 24098\nmem[8946] = 24951998\nmem[11382] = 184167\nmem[47522] = 6393093\nmask = XX01001010X11X011110X000XX000100X0X1\nmem[10260] = 661\nmem[25012] = 11390\nmask = 0100001010001101110101100XX110X01XX1\nmem[9055] = 297216\nmem[49887] = 26800\nmem[18511] = 3731\nmem[26845] = 42990\nmask = 00X0X00010101X1X1001100011X001100001\nmem[19591] = 197388201\nmem[51460] = 1032\nmem[9600] = 934060\nmem[58791] = 1646732\nmem[50283] = 1235563\nmem[26455] = 5018620\nmem[288] = 481559\nmask = 010X001010110X0X1X001111000XX010011X\nmem[13491] = 1626583\nmem[36536] = 239\nmem[56224] = 9125\nmem[28105] = 22015873\nmem[44531] = 8125\nmem[18760] = 25964\nmask = X101000011111X011110100011000X010X0X\nmem[58864] = 709865577\nmem[32976] = 303129\nmem[44109] = 8025520\nmem[51706] = 3030478\nmask = 00X01X0010101X0X1X011X110000X10101X1\nmem[53349] = 146801393\nmem[372] = 27164788\nmask = 0X00000010101X011XX11110X000XX1X0001\nmem[27091] = 1227\nmem[3194] = 234\nmem[37] = 4066397\nmem[43559] = 17240\nmem[36904] = 23282\nmem[9186] = 622901569\nmem[58468] = 208767\nmask = 00XX00X010X11101X101111001110100101X\nmem[9251] = 230\nmem[61367] = 78432672\nmem[37478] = 2594\nmem[64797] = 71052818\nmem[30018] = 11711518\nmem[20324] = 64836\nmem[61185] = 1433\nmask = 010000X0101X11001101011001100XXX0010\nmem[31581] = 232228\nmem[51766] = 13503\nmem[46129] = 1071\nmem[27845] = 3969749\nmem[17643] = 282089\nmem[60524] = 10654\nmask = 010X00X01X1110011XX01010XX00X0X10101\nmem[41317] = 20899132\nmem[17792] = 1949\nmem[1117] = 4931\nmem[21452] = 423952\nmem[29912] = 36667871\nmem[10260] = 15401611\nmem[28642] = 2840753\nmask = 000000X0101111011101XXXX000X001X01X1\nmem[57488] = 297477423\nmem[8228] = 240002\nmem[45051] = 1209316\nmem[65123] = 1339\nmask = 0100000010101X001111X1011X0001X0X00X\nmem[25750] = 10538421\nmem[59160] = 13024648\nmem[7581] = 521295867\nmem[44127] = 10349\nmem[20791] = 263486916\nmem[58844] = 37364\nmem[44165] = 213775351\nmask = 010X0X0010XX10011100001X0X0X1X0001X1\nmem[20221] = 7207\nmem[2326] = 247233\nmem[54001] = 1782454\nmem[41112] = 61297\nmem[45994] = 12285\nmask = 00X00010X0X1001111000010X0X1001XX10X\nmem[22080] = 50449\nmem[32446] = 69686\nmem[46129] = 6052251\nmem[45810] = 6931\nmem[2730] = 17348930\nmem[25557] = 22866081\nmem[53007] = 2662\nmask = 00000X1010111X0111011X01000X10X0XX01\nmem[26747] = 237030337\nmem[47589] = 912076\nmem[7333] = 105514\nmem[62613] = 1442076\nmem[293] = 1883\nmask = X1001X1010101111110XX010100000100X01\nmem[64864] = 522211793\nmem[381] = 395572639\nmem[39482] = 641\nmem[47108] = 37814\nmask = 00X00111101110111X001101001110XXX00X\nmem[16554] = 1304638\nmem[56666] = 189089562\nmem[12934] = 138931\nmem[63122] = 607569\nmem[37147] = 131399848\nmask = 0X1X11101XX11X0X11100111X100001111X0\nmem[24256] = 156773\nmem[14436] = 485469048\nmem[20781] = 376\nmem[23284] = 879110\nmem[2582] = 42478\nmem[39002] = 3578\nmask = 0000XX0X101010011XX000X0000X01100X01\nmem[40945] = 11048\nmem[36114] = 13782606\nmem[2325] = 185202507\nmem[33715] = 4806448\nmem[61649] = 3756998\nmem[55852] = 117\nmask = 01000000101X1011110010010XXX0XX11110\nmem[5881] = 13440134\nmem[22720] = 962895873\nmem[25142] = 11785\nmask = 0101011010111001010011100XX0011111XX\nmem[586] = 209\nmem[51207] = 145606\nmem[21220] = 62604\nmem[45100] = 34084913\nmem[30986] = 310031\nmem[56443] = 483530965\nmask = 0000100000X1X10X11X1100010100X011001\nmem[41487] = 38587945\nmem[21434] = 249215427\nmem[7230] = 111149021\nmask = X101X010XXX1100101X0X10100100111111X\nmem[40840] = 2606\nmem[63190] = 2447\nmem[60328] = 40915\nmem[45620] = 13499\nmask = 001X0010101110X1X1X0X11X0010X0X001X0\nmem[62719] = 785\nmem[19974] = 42859172\nmem[51864] = 44741\nmem[63056] = 27482866\nmask = X0X1X0101011X001X100101100101XX1X000\nmem[39205] = 10997188\nmem[14100] = 29987320\nmem[616] = 278639655\nmask = 0100000X10101X011X1111000X00X0111000\nmem[49278] = 610\nmem[9321] = 333537\nmem[22656] = 4066\nmem[8228] = 2791399\nmem[9251] = 3866\nmask = X00100X01011100X1X0XX000111011X00011\nmem[58260] = 459\nmem[18311] = 40779317\nmem[10291] = 3362\nmem[16865] = 1236\nmask = X100X000X010110111X0001100000001X011\nmem[1826] = 108687499\nmem[4087] = 243589\nmem[47489] = 474492676\nmem[4129] = 16244\nmem[29617] = 819406\nmem[43545] = 108512190\nmask = 010X0XX0101110X1X100X01X000X0X110100\nmem[57918] = 102433847\nmem[33825] = 9\nmem[372] = 230834\nmem[19591] = 7380\nmem[65409] = 98189\nmem[36391] = 3033\nmask = X101X000101111011000X10X100100100000\nmem[54029] = 347451\nmem[28001] = 82660784\nmask = 01X0000010101001X1000000X0X000110101\nmem[37266] = 1643\nmem[52294] = 242323894\nmem[40965] = 11451\nmem[52532] = 1191041\nmem[1994] = 1830445\nmem[16066] = 694\nmask = 0X100010X0X1XX0X01001X10X1100X110000\nmem[60293] = 92656839\nmem[8228] = 24889387\nmem[13951] = 25158\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_15.adb",
    "content": "--  Solution to Advent of Code 2020, Day 15\n-------------------------------------------\n--  Rambunctious Recitation\n--\n--  https://adventofcode.com/2020/day/15\n--\n--  Part 1 only.\n--  If we increase HAC's stack a bit, we can do both parts.\n--\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_15 is\n  type Preamble is array (1 .. 6) of Natural;\n  --\n  procedure Play (pre : Preamble; start : Positive; puzzle_id : Positive) is\n    compiler_test_mode : constant Boolean := Argument_Count >= 8;\n    stop : constant := 2020;\n    --  We memorize turn of spoken number (if any), indexed by spoken number.\n    mem : array (0 .. stop) of Natural;\n    not_seen : constant := 0;\n    prev, curr : Natural;\n    T1, T2 : Time;\n  begin\n    T1 := Clock;\n    for i in 0 .. stop loop\n      mem (i) := not_seen;\n    end loop;\n    for i in 1 .. start - 2 loop\n      mem (pre (i)) := i;\n    end loop;\n    prev := pre (start - 1);\n    for i in start .. stop loop\n      if mem (prev) = not_seen then\n        curr := 0;\n      else\n        curr := (i - 1) - mem (prev);  --  \"Age\"\n      end if;\n      if compiler_test_mode then\n        if i = 2020 then\n          if curr /= Integer_Value (Argument (puzzle_id)) then\n            Set_Exit_Status (1);  --  Compiler test failed.\n          end if;\n        end if;\n      else\n        if i = 2020 or i = stop then\n          Put (i); Put (\" : \"); Put (curr, 0); New_Line;\n        end if;\n      end if;\n      mem (prev) := i - 1;\n      prev := curr;\n    end loop;\n    T2 := Clock;\n    if not compiler_test_mode then\n      Put_Line (+\"----   Computation time: \" & (T2 - T1));\n      New_Line;\n    end if;\n  end Play;\n  --\n  example : array (1 .. 7) of Preamble;\n  puzzle : Preamble;\nbegin\n  --  No aggregates in HAC 0.083, we need to fill arrays element by element ...\n  example (1) (1) := 0; example (1) (2) := 3; example (1) (3) := 6;  --  2020th number is 436\n  example (2) (1) := 1; example (2) (2) := 3; example (2) (3) := 2;  --  2020th number is 1\n  example (3) (1) := 2; example (3) (2) := 1; example (3) (3) := 3;  --  2020th number is 10\n  example (4) (1) := 1; example (4) (2) := 2; example (4) (3) := 3;  --  2020th number is 27\n  example (5) (1) := 2; example (5) (2) := 3; example (5) (3) := 1;  --  2020th number is 78\n  example (6) (1) := 3; example (6) (2) := 2; example (6) (3) := 1;  --  2020th number is 438\n  example (7) (1) := 3; example (7) (2) := 1; example (7) (3) := 2;  --  2020th number is 1836\n  --\n  puzzle (1) := 15;\n  puzzle (2) := 12;\n  puzzle (3) :=  0;\n  puzzle (4) := 14;\n  puzzle (5) :=  3;\n  puzzle (6) :=  1;\n  --\n  for i in 1 .. 7 loop\n    Play (example (i), 4, i);\n  end loop;\n  Play (puzzle, 7, 8);\nend AoC_2020_15;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_15_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 15\n-------------------------------------------\n--  Rambunctious Recitation\n--\n--  https://adventofcode.com/2020/day/15\n--\n--  Full Ada version.\n--  Total run time: 0.42 seconds (i5-9400 @ 2.9 GHz).\n--\nwith Ada.Calendar, Ada.Text_IO, Ada.Integer_Text_IO;\n\nprocedure AoC_2020_15_full_Ada is\n\n  type Preamble is array (Positive range <>) of Natural;\n  --\n  procedure Play (pre : Preamble) is\n    use Ada.Calendar, Ada.Text_IO, Ada.Integer_Text_IO;\n    stop : constant := 30_000_000;\n    --  We memorize turn of spoken number (if any), indexed by spoken number.\n    type Big_Mem is array (0 .. stop) of Natural;\n    type P is access Big_Mem;\n    mem : constant P := new Big_Mem;  --  Heap allocation in case of small default stack size...\n    not_seen : constant := 0;\n    prev, curr : Natural;\n    T1, T2 : Time;\n  begin\n    T1 := Clock;\n    for m of mem.all loop\n      m := not_seen;\n    end loop;\n    for i in 1 .. pre'Last - 1 loop\n      mem (pre (i)) := i;\n    end loop;\n    prev := pre (pre'Last);\n    --\n    for i in pre'Last + 1 .. stop loop\n      if mem (prev) = not_seen then\n        curr := 0;\n      else\n        curr := (i - 1) - mem (prev);  --  \"Age\"\n      end if;\n      if i = 2020 or  i = stop then\n        Put (i); Put (\" : \"); Put (curr, 0); New_Line;\n      end if;\n      mem (prev) := i - 1;\n      prev := curr;\n    end loop;\n    T2 := Clock;\n    Put_Line (\"----   Computation time: \" & Duration'Image (T2 - T1));\n    New_Line;\n  end Play;\n\nbegin\n  --  Examples shown on https://adventofcode.com/2020/day/15 :\n  Play ((0, 3, 6));  --  2020th number is 436;  30m-th number is 175594\n  Play ((1, 3, 2));  --  2020th number is 1;    30m-th number is 2578\n  Play ((2, 1, 3));  --  2020th number is 10;   30m-th number is 3544142\n  Play ((1, 2, 3));  --  2020th number is 27;   30m-th number is 261214\n  Play ((2, 3, 1));  --  2020th number is 78;   30m-th number is 6895259\n  Play ((3, 2, 1));  --  2020th number is 438;  30m-th number is 18\n  Play ((3, 1, 2));  --  2020th number is 1836; 30m-th number is 362\n  --  The \"real\" puzzle:\n  Play ((15, 12, 0, 14, 3, 1));\n  --  ^ 2020th number is 249; 30m-th number is 41687\nend AoC_2020_15_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_15_full_ada_hashed_maps.adb",
    "content": "--  Solution to Advent of Code 2020, Day 15\n-------------------------------------------\n--  Rambunctious Recitation\n--\n--  https://adventofcode.com/2020/day/15\n--\n--  Full Ada version with hashed maps.\n--  Total run time: 2.46 seconds (i5-9400 @ 2.9 GHz).\n--\n--  *But* actually, in this context, a hashed map is overkill\n--  since the keys (the numbers) are in the range [0 .. stop] ...\n--\nwith Ada.Calendar, Ada.Containers.Hashed_Maps, Ada.Text_IO, Ada.Integer_Text_IO;\n\nprocedure AoC_2020_15_full_Ada_hashed_Maps is\n\n  type Preamble is array (Positive range <>) of Natural;\n  --\n  procedure Play (pre : Preamble) is\n    use Ada.Calendar, Ada.Text_IO, Ada.Integer_Text_IO;\n\n    function Identity_Hash (key : in Natural) return Ada.Containers.Hash_Type\n    is (Ada.Containers.Hash_Type (key))\n    with Inline;\n\n    function Simple_Hash (key : in Natural) return Ada.Containers.Hash_Type\n    with Inline\n    is\n      use Ada.Containers;\n    begin\n      return 2654435761 * Hash_Type (key);\n    end Simple_Hash;\n    pragma Unreferenced (Simple_Hash);\n\n    package Number_Map_Pkg is new\n      Ada.Containers.Hashed_Maps (\n        Natural,   --  Key is the number spoken\n        Positive,  --  Element is the turn (the index in a simple array)\n        Identity_Hash,\n        \"=\");\n\n    mem : Number_Map_Pkg.Map;\n    stop : constant := 30_000_000;\n    prev, curr : Natural;\n    T1, T2 : Time;\n  begin\n    T1 := Clock;\n    for i in 1 .. pre'Last - 1 loop\n      mem.Include (pre (i), i);\n    end loop;\n    prev := pre (pre'Last);\n    --\n    for i in pre'Last + 1 .. stop loop\n      if mem.Contains (prev) then\n        curr := (i - 1) - mem.Element (prev);  --  \"Age\"\n      else\n        curr := 0;\n      end if;\n      if i = 2020 or else i = stop then\n        Put (i); Put (\" : \"); Put (curr, 0); New_Line;\n      end if;\n      mem.Include (prev, i - 1);\n      prev := curr;\n    end loop;\n    T2 := Clock;\n    Put_Line (\"----   Computation time: \" & Duration'Image (T2 - T1));\n    New_Line;\n  end Play;\n\nbegin\n  --  Examples shown on https://adventofcode.com/2020/day/15 :\n  Play ((0, 3, 6));  --  2020th number is 436;  30m-th number is 175594\n  Play ((1, 3, 2));  --  2020th number is 1;    30m-th number is 2578\n  Play ((2, 1, 3));  --  2020th number is 10;   30m-th number is 3544142\n  Play ((1, 2, 3));  --  2020th number is 27;   30m-th number is 261214\n  Play ((2, 3, 1));  --  2020th number is 78;   30m-th number is 6895259\n  Play ((3, 2, 1));  --  2020th number is 438;  30m-th number is 18\n  Play ((3, 1, 2));  --  2020th number is 1836; 30m-th number is 362\n  --  The \"real\" puzzle:\n  Play ((15, 12, 0, 14, 3, 1));\n  --  ^ 2020th number is 249; 30m-th number is 41687\nend AoC_2020_15_full_Ada_hashed_Maps;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_16.adb",
    "content": "--  Solution to Advent of Code 2020, Day 16\n-------------------------------------------\n--  Ticket Translation\n--\n--  https://adventofcode.com/2020/day/16\n--\n--  Run-time with HAC:\n--    *  1.08  seconds for a Celeron N3350 @ max 1.1 GHz\n--    *  0.35  seconds for a i5-9400 @ 2.9 GHz\n--  Run-time with GNAT, AoC_Build_Mode = \"Fast\":\n--    *  0.009 seconds for a i5-9400 @ 2.9 GHz\n--\n--  HAC 0.084 \"nice to have\"'s detected in this exercise:\n--\n--    *     ` cc_match := (others => (others => True)); `\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2020_16 is\n  use HAT, Interfaces;\n\n  criteria : constant := 20;\n  subtype Criteria_Range is Positive range 1 .. criteria;\n  val_11, val_12, val_21, val_22 : array (Criteria_Range) of Integer;\n  --\n  function Is_Valid (value : Integer; c : Criteria_Range) return Boolean is\n  begin\n    return value in val_11 (c) .. val_12 (c) or else\n           value in val_21 (c) .. val_22 (c);\n  end Is_Valid;\n  --\n  --  In this problem we have as many columns as criteria:\n  subtype Column_Range is Criteria_Range;\n  ticket, my_ticket : array (Column_Range) of Integer;\n  --\n  or_str : String (1 .. 4);  --  \" or \";\n  ok, possible_row, single_match_only : Boolean;\n  cc_match : array (Column_Range, Criteria_Range) of Boolean;\n  unlinked : array (Column_Range) of Boolean;\n  cc, matching : Integer;\n  err : Natural := 0;\n  prod : Integer_64;\n  c, sep1, sep2, sep3 : Character;\n  f : File_Type;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant := 0;\nbegin\n  Open (f, \"aoc_2020_16.txt\");\n  for crit in 1 .. criteria loop\n    loop\n      Get (f, c);\n      exit when c = ':';\n    end loop;\n    Get (f, val_11 (crit));\n    Get (f, sep1);\n    Get (f, val_12 (crit));\n    Get (f, or_str);\n    Get (f, val_21 (crit));\n    Get (f, sep2);\n    Get (f, val_22 (crit));\n    if verbose > 0 then\n      Put (val_11 (crit), 0); Put (\" - \"); Put (val_12 (crit), 0);\n      Put (or_str);\n      Put (val_21 (crit), 0); Put (\" - \"); Put (val_22 (crit), 0);\n      New_Line;\n    end if;\n  end loop;\n  Skip_Line (f, 3);\n  --\n  --  Read my ticket.\n  --\n  if verbose > 0 then Put_Line (\"my ticket:\"); end if;\n  for col in Column_Range loop\n    Get (f, my_ticket (col));\n    if col < criteria then Get (f, sep3); end if;\n    if verbose > 0 then\n      Put (my_ticket (col), 0); Put (' ');\n    end if;\n  end loop;\n  Skip_Line (f, 3);\n  if verbose > 0 then New_Line; end if;\n  --\n  for col in Column_Range loop\n    unlinked (col) := True;\n    for crit in Criteria_Range loop\n      cc_match (col, crit) := True;\n    end loop;\n  end loop;\n  --\n  --  Read the nearby tickets.\n  --\n  while not End_Of_File (f) loop\n    possible_row := True;\n    for col in Column_Range loop\n      Get (f, ticket (col));\n      if col < criteria then Get (f, sep3); end if;\n      if verbose > 1 then Put (ticket (col)); end if;\n      ok := False;\n      for crit in Criteria_Range loop\n        if Is_Valid (ticket (col), crit) then\n          ok := True;\n          exit;\n        end if;\n      end loop;\n      if not ok then\n        if verbose > 0 then\n          Put (\"Invalid value: \"); Put (ticket (col), 0); New_Line;\n        end if;\n        err := err + ticket (col);\n        possible_row := False;\n      end if;\n    end loop;\n    if possible_row then\n      --  Each column in this row fits one or the other criterium.\n      --  We switch off possible combinations that don't match for this data row.\n      for col in Column_Range loop\n        for crit in Criteria_Range loop\n          if not Is_Valid (ticket (col), crit) then\n            --  This column is invalid for this criterium:\n            cc_match (col, crit) := False;\n          end if;\n        end loop;\n      end loop;\n    end if;\n    if verbose > 1 then New_Line; end if;\n  end loop;\n  Close (f);\n  --\n  --  Part 2 only: for each column, find THE matching criterium.\n  --\n  for round in Column_Range loop\n    single_match_only := True;\n    --  Find a column that fits only one criterium.\n    --  (Q: is this problem symmetric? Can we find a\n    --      criterium matching only one column?)\n    for col in Column_Range loop\n      if unlinked (col) then\n        cc := 0;\n        for crit in Criteria_Range loop\n          if cc_match (col, crit) then\n            cc := cc + 1;\n            matching := crit;\n            if cc > 1 then\n              single_match_only := False;\n              exit;\n            end if;\n          end if;\n        end loop;\n        if cc = 1 then  --  Column col is valid for only one criterium.\n          if verbose > 0 then\n            Put (\"  Column \"); Put (col, 0);\n            Put (\" fits only criterium: \"); Put (matching, 0);\n            New_Line;\n          end if;\n          unlinked (col) := False;\n          for other_col in Column_Range loop\n            if other_col /= col then\n              --  Cancel the matching criterium for other columns.\n              cc_match (other_col, matching) := False;\n            end if;\n          end loop;\n        end if;\n      end if;\n    end loop;\n    if verbose > 0 then\n      Put (\"Round \"); Put (round, 0); Put_Line (\" done.\");\n    end if;\n    exit when single_match_only;\n  end loop;\n  --\n  --  Columns for my ticket, for criteria \"destination\" (1 to 6).\n  --\n  prod := 1;\n  for crit in Criteria_Range loop\n    if verbose > 0 then\n      Put (\"Criterium: \"); Put (crit, 0);\n    end if;\n    for col in Column_Range loop\n      --  Find THE matching criterium.\n      if cc_match (col, crit) then\n        if verbose > 0 then\n          Put (\" column: \"); Put (col, 0);\n        end if;\n        prod := prod * Integer_64 (my_ticket (col));\n      end if;\n    end loop;\n    if verbose > 0 then\n      New_Line;\n    end if;\n    exit when crit = 6;\n  end loop;\n  if compiler_test_mode then\n    if err /= Integer_Value (Argument (1)) or\n       prod /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put (\"Part 1: ticket scanning error rate . . . . . . . .  : \");\n    Put (err, 0);   --  Validated by AoC: 23954\n    New_Line;\n    Put (\"Part 2: product of column numbers for \"\"destination\"\" :\");\n    Put (Integer_64'Image (prod));  --  Validated by AoC: 453459307723\n    New_Line;\n  end if;\nend AoC_2020_16;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_16.txt",
    "content": "departure location: 28-787 or 804-964\ndeparture station: 41-578 or 594-962\ndeparture platform: 50-718 or 733-949\ndeparture track: 27-846 or 862-949\ndeparture date: 50-241 or 249-957\ndeparture time: 44-81 or 104-972\narrival location: 45-292 or 299-954\narrival station: 46-650 or 657-974\narrival platform: 42-396 or 405-953\narrival track: 42-871 or 886-973\nclass: 31-808 or 829-964\nduration: 39-909 or 935-969\nprice: 49-350 or 364-970\nroute: 44-251 or 264-959\nrow: 50-539 or 556-952\nseat: 45-624 or 630-951\ntrain: 28-283 or 290-960\ntype: 44-334 or 340-951\nwagon: 43-699 or 716-961\nzone: 42-668 or 688-958\n\nyour ticket:\n131,67,137,61,149,107,109,79,71,127,173,157,167,139,151,163,59,53,113,73\n\nnearby tickets:\n436,66,560,233,594,569,437,864,15,350,199,146,265,166,666,490,494,689,170,869\n744,207,488,829,776,123,949,327,308,219,624,600,337,197,941,502,305,659,77,63\n941,201,228,759,490,232,469,631,660,305,562,339,237,185,290,123,411,536,64,772\n155,204,699,517,689,940,520,700,756,329,459,690,843,901,534,662,416,212,483,868\n715,465,463,519,304,133,561,309,216,367,440,239,899,78,602,566,453,535,487,482\n898,250,181,392,176,977,666,160,603,754,941,524,304,501,107,640,495,649,309,899\n936,143,507,778,162,652,134,520,316,523,316,393,769,405,458,195,620,832,161,611\n843,500,66,657,278,414,313,676,280,483,431,841,442,868,204,632,159,427,690,445\n764,303,208,865,127,832,533,758,508,518,14,173,473,227,194,424,344,835,325,606\n540,487,392,468,309,632,905,425,534,274,634,866,749,174,734,642,125,600,529,366\n640,57,896,574,646,170,688,597,384,312,193,273,724,315,938,440,207,63,425,201\n212,468,410,429,232,867,527,875,386,185,199,871,78,487,310,465,506,786,693,241\n161,863,209,420,904,771,864,227,761,220,537,623,287,366,161,507,443,251,832,693\n202,446,491,835,222,377,377,603,578,787,376,441,342,891,67,628,862,160,129,717\n521,208,909,490,806,492,733,750,507,472,314,353,212,473,571,81,50,612,304,157\n178,708,525,140,438,772,165,560,158,365,64,382,783,321,514,186,251,568,439,658\n319,697,507,238,316,55,668,629,667,80,663,368,772,214,76,439,949,133,311,452\n51,190,433,337,370,830,450,344,72,178,227,899,649,889,690,178,638,769,613,598\n895,460,557,769,936,386,743,418,528,845,661,791,737,863,507,129,179,532,935,737\n464,269,472,426,617,169,613,179,189,113,457,564,120,287,843,347,835,274,305,741\n181,528,250,907,189,498,599,309,155,840,198,741,769,132,159,336,210,223,164,537\n288,434,171,643,80,577,606,513,61,329,459,631,113,594,193,618,430,909,617,409\n189,178,281,329,300,612,613,566,532,434,79,887,322,935,518,427,487,5,907,904\n177,311,995,775,535,695,371,162,504,948,753,370,776,182,267,407,136,765,948,342\n737,420,898,875,118,764,574,374,233,52,612,186,534,462,836,272,172,193,471,160\n797,227,198,237,203,182,481,320,765,600,558,439,428,78,364,382,235,69,835,454\n447,385,322,132,299,429,829,484,865,529,519,845,938,340,201,65,886,471,785,288\n942,448,611,434,479,280,841,537,894,427,237,656,889,665,661,662,907,525,221,768\n303,437,386,276,867,559,71,114,347,185,572,578,881,196,595,366,279,465,762,225\n51,114,176,557,692,466,54,779,234,435,130,535,637,654,480,614,179,468,557,70\n535,717,599,490,632,371,178,458,138,499,207,574,507,115,656,741,636,434,370,845\n388,573,617,440,218,564,862,532,764,377,691,499,126,728,140,438,616,668,50,431\n440,519,944,6,516,524,137,76,496,272,307,611,906,782,946,127,735,482,567,376\n738,149,775,769,529,748,759,536,694,447,443,126,852,105,139,312,830,345,434,79\n184,689,766,273,51,547,758,607,772,531,380,149,349,318,232,184,408,387,485,323\n130,694,234,184,184,493,901,343,17,637,634,646,318,110,161,219,512,696,738,510\n659,939,577,158,291,136,560,291,279,642,182,489,121,183,869,705,151,750,733,274\n485,470,412,644,514,866,462,381,277,267,132,488,419,625,607,196,639,771,528,782\n558,844,893,653,137,234,406,535,145,429,516,388,473,748,509,314,451,420,334,806\n830,203,407,482,768,319,476,886,327,378,439,173,81,601,214,743,60,57,398,494\n132,171,67,240,74,908,770,621,318,52,562,201,920,190,312,942,478,120,221,461\n404,233,623,475,220,498,140,187,344,184,127,232,78,841,696,195,538,138,597,225\n485,308,624,840,944,641,773,517,526,388,775,184,842,290,617,788,465,475,597,772\n127,76,125,462,837,616,391,348,208,648,512,510,176,180,338,761,347,488,742,642\n668,235,183,186,745,836,718,624,239,224,228,757,56,801,634,217,787,343,63,762\n566,62,367,789,79,664,660,500,155,309,742,236,808,600,428,936,280,190,216,313\n561,694,449,280,662,609,513,566,769,185,57,429,655,300,148,903,452,64,900,536\n172,159,434,142,191,212,868,604,344,367,495,392,126,167,181,676,534,169,487,863\n770,61,942,159,427,334,908,233,626,470,736,302,466,516,568,611,897,320,301,657\n133,234,161,388,564,866,531,458,136,438,111,778,320,634,323,113,223,505,331,548\n376,648,236,322,871,516,304,405,209,121,641,868,375,385,537,572,274,510,284,773\n171,984,445,427,494,596,471,862,281,942,455,949,940,350,907,53,909,342,79,282\n196,742,223,221,142,389,175,392,594,135,653,130,198,199,571,108,416,698,897,893\n191,321,749,886,493,753,377,560,711,221,311,218,55,158,319,233,718,226,382,301\n58,72,159,69,111,371,71,461,334,124,104,663,624,312,410,247,477,834,835,119\n762,65,76,595,949,1,55,600,374,210,512,428,613,832,167,643,383,737,442,453\n470,611,780,888,472,373,611,270,126,433,227,188,434,497,647,529,488,908,267,653\n213,610,449,423,639,215,761,891,568,416,412,350,161,381,185,436,446,896,189,789\n474,51,347,840,846,376,421,330,539,559,535,980,56,188,177,576,194,307,189,105\n621,838,488,325,395,286,331,742,569,840,612,193,479,393,894,615,466,237,104,509\n457,197,300,683,783,322,633,328,372,892,566,439,659,521,163,909,617,561,348,634\n743,132,563,559,617,447,456,80,152,829,80,278,249,246,422,329,272,426,613,642\n479,736,894,484,776,518,110,221,320,429,299,834,864,468,994,840,345,770,465,760\n717,272,203,833,214,208,461,185,59,838,864,702,221,182,318,345,751,431,316,735\n371,178,333,374,558,337,865,842,225,405,372,63,277,563,381,446,787,518,749,114\n199,534,534,142,630,151,349,597,504,461,454,254,197,451,213,153,746,114,186,575\n639,431,938,241,904,760,834,479,464,151,67,693,716,101,170,509,438,570,104,601\n470,429,303,184,139,136,888,789,267,182,562,311,660,898,119,573,115,501,272,694\n939,832,492,943,61,615,526,423,560,769,718,998,160,76,504,141,136,771,445,739\n290,905,292,509,568,513,506,467,498,120,395,59,640,373,192,787,939,195,116,673\n638,862,697,235,374,567,405,643,906,421,447,111,427,335,777,605,406,903,866,409\n489,553,504,863,524,462,657,807,214,193,562,445,133,333,511,435,215,619,744,193\n475,612,240,458,845,694,522,438,793,735,173,618,521,200,441,610,396,238,282,278\n186,465,633,128,196,236,507,129,767,497,302,110,300,62,647,872,752,566,516,117\n199,136,485,167,250,769,937,4,181,694,777,174,421,595,70,869,601,143,392,647\n842,733,227,437,491,344,443,750,552,556,662,693,236,417,78,374,224,424,134,379\n868,430,202,553,429,515,935,465,174,391,167,134,158,138,190,905,771,499,394,562\n326,785,182,782,74,752,81,147,641,51,199,403,393,182,448,381,434,942,759,455\n869,846,430,197,452,747,899,668,86,268,268,333,276,563,773,497,742,394,209,410\n190,699,744,384,110,417,435,231,278,432,500,80,736,939,767,993,608,668,776,697\n125,152,612,215,666,138,831,468,754,132,64,691,105,661,884,938,461,104,845,640\n559,366,418,422,17,219,319,638,277,139,368,888,635,600,439,494,537,389,179,180\n949,435,908,442,53,104,314,693,270,210,413,614,516,202,166,436,565,595,936,398\n349,485,119,840,190,158,240,327,171,345,291,75,169,837,421,305,781,757,631,99\n898,302,373,845,559,198,412,530,68,453,662,941,54,574,540,71,570,350,299,165\n502,220,147,471,568,624,935,454,806,453,776,639,410,706,222,495,659,196,636,59\n425,469,18,131,331,535,346,500,438,783,268,71,786,57,115,573,622,764,452,159\n618,395,658,219,595,426,471,220,388,208,73,77,609,662,427,618,698,457,463,993\n528,451,215,232,390,56,201,718,485,668,432,477,536,331,155,137,649,540,276,739\n613,637,717,422,763,76,514,641,676,718,210,234,112,637,699,68,154,464,218,449\n768,557,945,695,265,900,197,864,318,139,179,906,751,869,757,224,312,629,478,218\n481,756,840,345,651,566,316,279,140,694,137,561,748,446,277,311,117,743,418,557\n292,246,502,212,268,564,196,368,151,785,122,166,172,645,459,183,316,185,224,537\n370,314,299,556,452,805,179,369,909,513,577,694,502,178,10,210,512,634,758,435\n482,401,109,396,249,156,304,197,350,373,61,405,939,829,645,749,556,745,831,59\n522,781,837,108,753,785,435,234,575,224,525,456,506,558,829,725,829,218,317,763\n430,568,830,979,199,331,317,515,426,130,65,120,838,948,647,560,154,371,768,752\n407,165,181,413,613,395,841,227,310,428,383,633,193,664,698,776,339,409,233,782\n481,275,630,776,343,766,688,630,228,892,631,626,446,896,594,63,431,935,782,750\n340,493,746,371,426,752,489,537,529,634,112,884,755,420,783,346,163,148,631,68\n417,379,504,138,733,163,147,869,112,613,274,270,301,374,833,142,541,890,784,518\n787,472,566,504,568,890,595,657,388,434,292,103,272,428,74,408,201,310,155,190\n350,280,418,410,482,466,473,62,304,317,743,316,122,684,749,898,520,774,573,642\n235,787,495,275,140,422,768,944,463,249,129,307,108,779,436,524,157,643,507,14\n230,646,390,649,867,829,609,100,133,186,690,831,415,381,376,645,393,615,716,634\n68,112,62,754,833,778,239,663,267,110,806,914,762,868,168,200,602,350,663,198\n625,347,513,513,842,507,330,160,489,532,226,193,130,423,444,567,307,222,63,111\n836,140,661,871,169,664,312,745,742,646,998,322,450,214,939,503,161,274,636,224\n344,603,649,492,478,772,377,281,250,411,497,719,517,758,643,183,600,464,315,559\n119,442,4,105,179,365,425,145,61,535,637,640,434,304,194,562,175,233,539,211\n477,337,374,215,778,68,830,141,272,196,483,347,460,118,165,326,693,443,164,867\n886,501,607,617,202,222,436,992,577,319,501,745,805,949,232,309,887,533,445,498\n471,783,436,899,561,396,431,379,906,407,942,208,611,840,449,304,286,519,163,274\n113,494,448,508,889,576,159,271,51,831,597,844,535,736,900,478,328,457,552,107\n603,905,104,906,898,871,435,318,327,158,381,536,458,854,178,347,455,606,106,897\n223,517,205,658,643,661,522,273,892,250,736,849,532,65,186,689,733,376,521,763\n232,166,699,128,378,626,478,534,937,81,617,81,529,333,441,502,903,170,756,603\n386,301,123,435,461,830,694,455,519,606,480,245,425,691,214,751,895,415,65,196\n203,418,776,525,935,833,171,394,194,180,745,140,981,608,614,775,833,630,193,457\n415,944,138,399,563,229,486,268,121,839,697,228,771,739,717,76,250,143,650,164\n454,808,116,72,214,458,292,485,634,746,326,754,238,69,72,647,348,487,166,996\n153,158,634,314,776,535,326,384,248,510,178,234,274,415,517,104,650,558,454,435\n864,805,184,109,895,76,210,114,904,597,751,277,504,649,612,618,164,178,12,749\n737,203,403,751,616,868,135,70,202,330,346,59,383,275,442,842,716,381,742,692\n652,846,312,130,456,406,207,182,444,650,62,182,304,212,485,69,782,187,132,892\n133,783,325,578,893,393,527,620,890,648,560,286,945,845,497,376,269,152,779,179\n507,698,459,661,251,835,976,603,165,233,222,365,643,665,531,649,744,519,126,326\n508,781,456,657,648,223,291,104,327,556,845,585,690,785,110,536,112,868,574,516\n539,612,197,394,188,936,642,440,664,349,231,414,249,445,304,548,457,443,944,145\n273,433,434,831,525,213,208,390,213,903,419,418,326,659,525,399,738,143,265,532\n896,269,870,376,434,114,113,338,498,898,866,290,395,72,428,831,135,324,176,947\n225,556,841,718,304,770,415,888,453,528,644,490,478,106,163,396,733,440,693,295\n384,627,842,476,396,774,169,562,129,373,177,51,430,205,130,316,660,624,128,56\n383,215,559,449,143,867,505,649,649,182,206,528,398,126,596,561,459,212,577,570\n831,128,519,536,395,644,526,119,336,836,837,619,646,774,619,109,473,843,185,349\n897,239,486,288,115,432,273,560,453,322,661,453,753,617,144,375,333,140,482,224\n528,224,561,382,643,523,219,518,134,5,641,538,753,836,161,417,341,562,607,537\n437,406,552,419,558,466,187,947,428,717,190,643,169,943,620,829,482,699,437,525\n382,318,630,318,223,495,520,105,514,737,148,421,627,695,374,808,210,196,147,160\n380,320,889,902,131,525,176,838,516,642,597,266,686,530,150,154,221,638,368,756\n196,273,155,190,534,488,231,641,475,865,742,807,698,204,240,427,272,396,654,333\n887,227,176,753,830,899,107,59,623,886,740,319,409,77,375,904,654,524,428,334\n754,441,229,483,162,494,226,888,477,322,114,834,790,151,477,837,64,126,751,364\n533,217,737,575,11,888,904,566,426,441,748,346,275,762,893,302,609,603,558,533\n558,194,717,752,388,53,664,765,854,445,903,599,118,645,70,372,773,347,557,745\n900,557,390,326,768,126,143,206,503,169,303,474,694,209,364,185,736,149,664,850\n682,891,442,863,474,830,119,746,662,155,781,214,421,308,461,274,365,524,153,889\n446,133,603,526,309,716,779,588,204,193,208,778,505,907,188,185,465,240,649,888\n153,144,324,248,498,889,772,433,61,843,331,486,380,840,498,116,576,237,786,127\n778,201,708,738,485,414,104,314,209,937,122,266,378,842,756,193,842,743,660,214\n68,141,763,380,642,180,733,837,741,457,450,534,451,941,534,630,436,469,706,188\n280,321,658,383,147,485,613,174,486,622,452,317,711,433,621,452,938,190,693,271\n481,668,239,459,308,533,442,319,154,844,422,50,517,193,837,894,621,343,230,243\n300,527,206,425,123,393,194,568,191,194,278,622,328,468,170,652,520,234,475,153\n209,142,5,51,408,370,57,754,115,214,571,511,201,716,134,223,866,474,408,697\n885,277,513,513,106,410,753,866,56,906,426,478,949,328,439,64,378,197,765,762\n557,576,230,323,227,484,608,404,455,343,570,947,163,321,155,738,349,277,172,495\n302,636,617,623,649,421,70,115,497,303,601,782,216,499,479,297,173,151,604,632\n844,442,307,142,54,459,601,510,754,327,219,750,114,935,739,86,636,804,236,181\n385,895,761,840,144,787,349,134,122,347,55,836,202,386,131,176,807,227,808,921\n414,326,457,781,946,787,224,517,426,307,597,185,444,241,196,903,211,240,445,363\n435,644,227,640,937,409,527,936,395,157,846,688,611,166,148,484,890,837,625,163\n411,62,612,448,154,276,117,243,66,304,657,571,805,396,606,469,429,280,150,322\n106,608,786,320,521,229,227,780,188,599,273,425,389,153,410,804,330,412,128,721\n54,935,207,830,697,985,596,120,200,143,564,340,375,841,831,894,842,521,531,691\n570,8,646,342,890,939,451,312,805,624,292,908,772,462,454,698,313,568,898,638\n138,241,61,124,524,436,109,559,586,411,642,310,386,81,639,170,220,320,862,389\n462,472,504,909,689,428,449,633,438,755,576,698,519,404,774,506,365,310,898,179\n621,173,315,321,299,174,444,379,619,311,197,431,422,940,179,10,539,206,619,630\n773,688,665,323,366,323,785,368,438,329,157,217,600,657,365,286,907,166,534,165\n565,393,431,864,288,775,63,528,72,760,142,598,161,465,389,241,210,489,535,231\n846,148,153,345,306,747,422,831,560,380,938,460,758,839,130,847,108,783,537,612\n246,122,767,806,424,769,314,522,273,166,839,575,182,194,760,617,480,168,604,487\n562,878,786,217,271,772,137,63,267,177,408,427,116,215,176,862,787,432,775,395\n867,534,55,741,234,689,419,416,639,603,566,684,606,947,221,140,162,568,435,865\n481,166,382,489,364,187,612,469,807,159,491,221,18,71,558,599,266,445,189,373\n839,535,338,787,68,269,142,649,415,666,604,189,303,521,396,167,320,65,780,232\n787,381,210,146,406,387,119,1,946,631,635,67,495,846,641,125,747,418,559,126\n396,396,311,418,434,695,844,427,388,629,304,140,228,496,239,465,449,59,130,459\n210,762,161,745,829,690,169,976,237,105,532,427,576,889,341,695,375,890,230,622\n205,346,438,870,894,601,761,412,455,613,936,324,456,178,492,279,14,409,236,328\n487,463,842,750,840,186,222,461,289,280,72,699,538,521,224,419,780,191,367,898\n139,187,389,643,349,502,300,367,561,130,186,345,143,137,739,756,77,129,601,628\n349,678,188,752,156,225,463,188,278,949,457,375,808,67,905,497,328,488,782,769\n77,418,829,134,532,445,276,535,650,698,322,181,496,393,139,931,865,458,148,453\n772,224,886,597,752,778,330,525,652,157,290,946,62,773,608,490,179,124,249,164\n901,213,286,411,305,392,909,158,139,642,392,304,175,529,125,473,578,569,740,315\n147,464,371,159,508,154,571,523,518,534,210,456,77,864,710,717,893,172,424,81\n782,125,55,182,631,523,481,556,174,107,369,130,53,328,530,580,104,180,135,451\n829,284,330,739,659,81,148,508,179,699,467,372,414,945,527,472,72,633,467,159\n218,563,469,976,306,320,838,604,241,769,940,317,383,443,805,455,618,128,645,488\n112,213,147,870,743,397,118,616,666,717,453,557,73,174,522,69,556,869,558,317\n893,323,841,333,109,638,140,527,665,493,210,295,390,199,328,346,408,610,150,126\n597,462,312,704,180,429,482,479,374,534,409,773,505,527,186,348,764,115,688,280\n900,943,941,470,484,385,532,618,224,523,753,594,621,602,681,528,455,229,448,898\n109,808,741,275,606,744,634,459,474,10,108,383,425,845,739,52,484,124,938,183\n165,488,740,429,503,113,620,60,304,514,834,73,76,324,168,141,532,718,318,713\n515,761,560,561,371,505,188,617,833,420,753,177,869,884,183,527,165,130,518,909\n619,77,573,306,515,306,157,945,239,305,665,836,428,442,394,440,201,866,684,116\n808,763,568,507,149,434,503,164,112,75,939,775,145,448,844,21,468,444,496,889\n980,524,175,500,233,416,151,864,110,203,936,415,74,616,479,691,617,470,842,639\n483,308,315,20,577,209,864,567,569,780,201,716,892,766,869,557,602,907,224,632\n585,212,382,778,605,846,602,364,220,251,113,745,511,767,522,146,237,105,750,528\n977,180,597,938,81,668,171,778,436,304,199,197,718,864,466,609,716,347,605,348\n576,938,215,381,483,350,160,772,131,182,126,831,248,306,622,599,520,416,504,201\n648,754,640,159,76,396,753,56,111,690,644,108,588,372,439,665,635,509,80,203\n203,807,844,190,317,949,639,654,735,603,603,490,413,604,377,315,370,327,779,127\n573,482,656,492,241,417,325,126,806,165,407,890,753,617,347,372,165,236,869,596\n907,64,218,516,366,840,233,291,892,122,575,6,424,187,482,665,616,510,232,531\n325,806,514,395,475,532,209,412,483,391,480,554,939,607,224,153,602,124,894,119\n832,234,384,318,449,980,374,330,221,659,598,235,408,74,906,50,436,718,647,569\n179,749,599,150,759,350,75,59,405,568,476,866,757,505,689,230,600,285,641,668\n389,510,565,75,264,452,463,537,53,650,526,54,450,59,629,377,81,62,466,746\n235,764,889,230,148,935,517,893,717,832,808,754,346,444,907,648,450,890,407,984\n427,377,486,453,71,115,567,524,777,529,279,762,544,667,623,290,207,688,571,181\n334,388,472,470,277,217,485,549,894,945,612,573,597,768,438,774,435,128,500,305\n986,141,211,116,213,302,534,300,598,777,171,841,444,128,183,76,122,131,325,447\n904,807,782,62,215,119,442,395,229,52,160,641,185,249,602,772,627,236,482,448\n18,69,835,599,760,111,784,109,660,782,937,328,125,126,281,198,766,128,417,176\n226,59,511,514,665,643,120,689,517,331,556,411,424,427,935,164,426,275,194,584\n300,140,127,746,595,390,502,512,274,69,520,463,170,207,742,188,375,944,127,339\n657,479,173,329,126,112,266,808,575,203,176,316,947,270,218,481,978,768,423,563\n202,429,520,643,471,778,369,211,125,285,292,207,736,606,774,162,396,696,427,693\n320,233,870,887,501,168,13,299,778,110,646,533,477,154,457,474,317,457,128,751\n338,783,162,199,755,420,436,838,890,223,378,603,290,907,181,506,301,635,889,205\n846,129,187,232,313,756,524,63,610,393,431,60,196,638,539,482,617,805,782,882\n449,774,650,625,484,471,806,304,456,443,70,907,904,394,716,267,619,603,236,641\n835,300,278,444,54,783,450,144,516,390,718,777,84,528,61,200,766,348,662,173\n79,652,480,558,210,649,421,212,736,232,350,329,444,624,768,835,111,146,770,602\n778,892,327,612,213,909,458,697,402,127,163,846,488,892,735,459,889,769,482,869\n596,223,62,412,396,319,533,745,473,321,642,563,576,543,694,78,188,374,290,279\n868,557,782,570,870,463,433,659,785,567,630,441,862,659,446,348,201,65,336,341\n463,835,138,829,940,474,473,344,210,568,436,113,834,316,427,124,620,656,313,578\n60,414,625,415,608,106,453,620,408,598,832,690,331,63,607,457,364,182,539,838\n667,438,458,81,202,487,80,288,413,494,452,609,326,565,409,283,907,467,514,647\n893,319,561,225,490,943,658,394,129,465,417,459,563,579,836,164,265,323,312,942\n264,308,375,833,539,411,561,66,292,564,121,383,203,870,403,405,207,774,832,442\n438,71,218,766,454,505,504,116,890,619,995,316,771,763,364,373,767,480,439,660\n475,322,522,173,215,485,311,151,532,655,735,59,173,689,434,106,425,478,139,189\n269,382,107,487,233,532,58,471,787,69,216,895,596,314,284,194,662,842,52,839\n192,506,574,77,64,575,275,445,885,315,643,223,380,59,770,232,574,376,127,381\n198,890,449,749,80,275,114,305,131,754,943,150,211,140,561,761,58,4,158,210\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_17.adb",
    "content": "--  Solution to Advent of Code 2020, Day 17\n-------------------------------------------\n--  Conway Cubes\n--\n--  https://adventofcode.com/2020/day/17\n--\n--  NB: Was able to recycle parts from another \"Game of Life\"\n--      puzzle: Seating System (Day 11).\n--\n--  Run time with GNAT (use the aoc_2020.gpr project file,\n--          AoC_Build_Mode = \"Fast\", or compile with\n--          gnatmake -O3 -gnatpn -I../../../src aoc_2020_17):\n--    *  0.18 seconds on a i5-9400 @ 2.9 GHz\n--\n--  Run time with HAC (Virtual Machine + no compilation optimization:\n--          we expect a big slowdown with this problem (many nested loops):\n--    *  (too many) seconds, on a i5-9400 @ 2.9 GHz\n--\n--  HAC 0.084 \"nice to have\"'s detected in this exercise:\n--\n--    *     ` map (0) := (others => (others =>  (others => (others => False)); `\n--\nwith HAT; use HAT;  --  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n\nprocedure AoC_2020_17 is\n  --\n  max : constant :=  10;\n  min : constant := -max;\n  subtype R is Integer range min .. max;\n  type State is (Inactive, Active);\n  type Map_Type is array (R, R, R, R) of State;\n  --\n  procedure Move (\n    current_map : in     Map_Type;\n    new_map     :    out Map_Type;\n    wmin, wmax  : in     Integer    --  Relative and absolute range in 4th dimension\n  )\n  is\n    dl_max : Natural;\n    function Count_Visible_Occupied (i, j, k, l : Integer) return Natural is\n      occ : Natural := 0;\n      --\n      procedure Scan_Direction (di, dj, dk, dl : Integer) is\n        ii : constant Integer := i + di;\n        jj : constant Integer := j + dj;\n        kk : constant Integer := k + dk;\n        ll : constant Integer := l + dl;\n      begin\n        loop\n          exit when ii not in R;\n          exit when jj not in R;\n          exit when kk not in R;\n          exit when ll not in R;\n          case current_map (ii, jj, kk, ll) is\n            when Active   => occ := occ + 1; exit;\n            when Inactive => exit;\n          end case;\n        end loop;\n      end Scan_Direction;\n      --\n    begin\n      for di in -1 .. 1 loop\n        for dj in -1 .. 1 loop\n          for dk in -1 .. 1 loop\n            for dl in -dl_max .. dl_max loop\n              if di /= 0 or else dj /= 0 or else dk /= 0 or else dl /= 0 then\n                Scan_Direction (di, dj, dk, dl);\n              end if;\n            end loop;\n          end loop;\n        end loop;\n      end loop;\n      return occ;\n    end Count_Visible_Occupied;\n    --\n    occ : Natural;\n  begin\n    if wmax = 0 then\n      dl_max := 0;\n    else\n      dl_max := 1;\n    end if;\n    for i in R loop\n      for j in R loop\n        for k in R loop\n          for l in wmin .. wmax loop\n            new_map (i, j, k, l) := current_map (i, j, k, l);\n            occ := Count_Visible_Occupied (i, j, k, l);\n            case current_map (i, j, k, l) is\n              when Active =>\n                if occ < 2 or else occ > 3 then\n                  new_map (i, j, k, l) := Inactive;\n                end if;\n              when Inactive =>\n                if occ = 3 then\n                  new_map (i, j, k, l) := Active;\n                end if;\n            end case;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n  end Move;\n  --\n  function Count_Occupied (map : Map_Type; wmin, wmax : Integer) return Natural is\n    occ : Natural := 0;\n  begin\n    for i in R loop\n      for j in R loop\n        for k in R loop\n          for l in wmin .. wmax loop\n            if map (i, j, k, l) = Active then\n              occ := occ + 1;\n            end if;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    return occ;\n  end Count_Occupied;\n  --\n  map : array (0 .. 1) of Map_Type;\n  c : Natural := 0;\n  cc : Character;\n  f : File_Type;\n  size : Integer;\n  cycles : constant := 6;\n  low, high : Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  wmin, wmax : Integer;\nbegin\n  for dim_4 in Boolean loop\n    if dim_4 then\n      wmin := min;\n      wmax := max;\n    else\n      wmin := 0;\n      wmax := 0;\n    end if;\n    --\n    for x in R loop\n      for y in R loop\n        for z in R loop\n          for w in wmin .. wmax loop\n            map (0)(x, y, z, w) := Inactive;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    --\n    Open (f, \"aoc_2020_17.txt\");\n    size := 8;\n    low := -size / 2;\n    high := low + size - 1;\n    if low - cycles < min or high + cycles > max then\n      Put_Line (\"Test (hyper)space is too small\");\n      return;\n    end if;\n    for x in low .. high loop\n      for y in low .. high loop\n        Get (f, cc);\n        if cc = '#' then\n          map (0)(x, y, 0, 0) := Active;\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n    for cy in 1 .. cycles loop\n      Move (map (c), map (1 - c), wmin, wmax);\n      c := 1 - c;\n    end loop;\n    --\n    if compiler_test_mode then\n      if Count_Occupied (map (c), wmin, wmax) /= Integer_Value (Argument (1))\n      then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n      exit;\n      --  ^ This is for HAC & compiler testing: we skip part 2, takes too long.\n    else\n      if dim_4 then\n        Put (\"Part 2, 4\");\n      else\n        Put (\"Part 1, 3\");\n      end if;\n      Put (\n        +\"-dimensional: number of active cells is \" &\n        Count_Occupied (map (c), wmin, wmax));\n      New_Line;\n    end if;\n  end loop;\nend AoC_2020_17;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_17.txt",
    "content": "###..#..\n.#######\n#####...\n#..##.#.\n###..##.\n##...#..\n..#...#.\n.#....##\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_18.txt",
    "content": "2 * 9 + 5 + ((8 + 6 + 5) * (2 + 3 * 9 + 3) + 5) * (7 + 9 + 7 + 3 * 7) * 5\n7 + (2 + 8 * 8 * 2 + (4 * 3 * 9 + 4 * 4)) + 4 * 3\n6 + 9 * 2 * 2 + (2 + (7 * 6 * 6) + 4 * (7 * 8 * 2 + 4) * 7) + 7\n2 + ((3 * 6 * 5 * 4 + 7 * 7) + 5 * 4 * 5 * (8 * 7 + 9) + 8) * (4 + 6 * 5)\n(7 * 6 * 3 + 4 * 3 * 9) + (6 * 6 * (4 + 6 + 4) + 7 + 2 + (9 * 8 * 9 + 9 * 7 * 4)) + (3 * 4 + 3 + 2) * 8\n(3 + (7 * 7 + 9 * 9 * 6)) * 3 * 5 + 4 * 8\n8 + 9 * (2 + 2 * 5 + 9 * 2) * 2 + ((6 + 4) * 4 + (4 * 7 + 3 * 3 + 7) * (4 * 5 + 8 + 8 + 7 * 6) + (6 + 2) + 5)\n(2 + 2 * 9 * 7) * ((9 + 8) * 3 * 6 + 6 + (5 * 4 * 4 * 3)) + 9 + (3 + 2)\n2 + 7 * 3 + ((7 + 7 * 3) * 6 + 8)\n2 + 7 + 6 + (4 + 7 * 7) + 9 * 2\n(9 * 2 * 4 * 4) + 4\n8 + (8 + 8 + 7) * (5 * 4 + 4 + 5 * 5) * 9 + 8\n(6 * (4 * 2 + 4 + 7 + 4) + 4 * 7 + (7 + 5 + 3 + 3 * 7) * 6) * 6 + 3 + 6 + 5\n5 + ((7 * 3 * 2) + 9 * (9 + 2) * 6)\n(3 * (2 * 2 * 3 * 7 * 2) * 8) * 8\n((3 + 2) + 5 + 7 + 3 * (8 + 4 + 5 * 8 * 9)) + 7 * 3 * 6\n7 * 6 + 8 * 4 + ((7 + 5 + 2 + 4 * 9 + 9) * 7 + 5)\n6 * (6 * (4 + 8 + 6) * 6)\n4 + 3 + (6 * (2 * 8))\n(2 * 8 * (3 + 8 + 3 + 2) * (8 * 4 + 2 + 8) * 9 + 7) * 8\n4 * (3 + 9) + 9 + 4 + 8 + 4\n((6 + 3 + 5 + 6 + 6) * 9 * (2 + 7 * 4 * 9 + 3 * 7) + 6) * (3 * 9 + 2 + 7 * 3) * 6\n8 * (5 + 4 * 3) + 3 * 7 + 6 * 4\n4 + 6 + 6 + (4 + 9 + 3 + 3 + 3) + (2 + 6 * 2 + 3 + 4) * (2 * 4 + 9 + 3)\n7 + (3 + 2 * 4 + 4 * 9 + 2) * 2 * ((8 * 6 + 6 * 2 + 7 + 7) + (2 + 8 * 7 + 6 * 9) + 7 * 6) * 7 + 8\n3 * (8 * 7 * (5 + 2 + 8 * 9))\n6 * 9 + 2 + 8 + (4 * 3 * 4 + 6)\n(2 * 6) + 7 * 9 + (3 * 9 + 8 * 4 * 3 * 5) * (9 * 7)\n5 * 2 + (3 + 5 * (5 + 7 + 7 + 4) * 2)\n9 + 4 * (8 + 3 * 2 + 9 * 6 * 4) * 9 * 6\n6 + (6 * (2 * 5 * 4 * 7 * 3) * 9 + 4 + 6 * 3) + 4 * 8\n(6 + (4 * 7) + 6 * 5) + 4 + 7 + 2\n3 + 4 * 9 + 9 * 8 + (3 * 4 + (9 * 6 * 9 * 2) * 5 + 8)\n8 + (3 + (9 * 3) + (6 * 4) + 8 * 6 + 8) + 5\n(7 + 6 * 3) * 2 + 5\n6 + 6 + ((6 + 7) * 9 + 5) * 2\n(3 * 3 * 2 * 5) + 9 * 9 + 3\n(8 * (6 + 2) + 4) * 9\n(4 * 6 * 6 * 3) * 9 * 4 + 4 * 4 * 9\n5 * 5 + ((8 * 9 * 2 + 5) + (3 + 7 * 5 + 2) + 2 + 8 + 5)\n9 + 8 * (6 + 2 * 2) + 7 + 4 * 9\n7 * 8 + (9 + (9 + 4 + 6 * 6 * 9 * 6)) * 8 * 5\n9 * 7 + 8 + 7 * (4 * 2 + (6 + 3 * 4 + 6 * 6 + 6) * 2) + 9\n8 + 2 + (4 * 3) + (2 + 8) * 5 * 7\n2 * 7 * 7 * 8 + (3 * 4 * (7 * 4) + 5 * 8)\n2 * ((6 + 7 + 6 + 2) * 4 + (9 + 4 * 5) + 8 + 6 * 7)\n(6 + 4 * 4 + 9 * (4 + 9 * 5 + 9 + 9 * 9) + 7) * 2\n8 + 9 * (4 + (6 + 4 * 3 * 6 * 6) + 7 + (6 * 2 * 8) + (9 + 5 * 3 + 3 * 3) * 9) * 9 * 4\n(8 + 8 * 9 + 9 + (7 + 8 * 3)) * (6 + 4 * 7)\n2 + (6 * 3 * 5 * 5) + 4 + 9 + (4 + 9 + 9) + 4\n8 + 3 + 8 + (4 + 6 * 6 * 2 * 5) + 5 * 5\n2 * 4 + (7 + 6 + 9 + 5 + 9 + 2)\n(5 * 5 + (5 + 7 + 4 + 3 + 7) * 4) + ((6 * 4) + 2 * (8 + 8 + 4 * 4) * (7 * 7 * 2 + 3) + (8 + 6 + 8 * 2 * 8 + 8)) * 7\n3 * 4 * (7 + 6 * 4 + 6 * 3) * 4 + 4 + ((8 * 6 + 2 + 5 + 7 + 6) + 6)\n9 + (9 * 7 + 2 * 9) + 8 + 6\n4 + 6 + 7 + 6 * 3\n5 * ((4 + 4) + 4 + 7 * 9) * 6\n9 * 6 + 6 + (4 + (5 + 9 + 2 + 9 * 5 + 8) * 4 * 8 * (3 * 4 + 7 * 6 * 3) + 7) * (4 + 4 * (6 + 7 * 6 * 7 * 9)) * 5\n6 + (2 + 4 + 6 + 6 + (8 * 7 * 2 + 6)) + 5 + 9 + 2 + (8 * 7 * (9 + 8 * 6 * 6 * 7 * 3))\n6 + 9 + 7 + 8 + (8 * 6 * (5 + 5 * 7 + 3) * 8 * (4 + 8 * 2 + 9))\n(9 + 3 + 8 + 4 + 8 + 4) * 6 * 3 * 6\n5 * ((5 + 7 + 2 * 3 + 4 + 3) + 3) + 6 + 4\n2 * (8 * 4 + (9 * 3) * (7 + 2 + 3 * 4) * 7) * (6 + 9 + 7) + 5 + 4 + 7\n9 * (9 * (8 * 9 + 5 * 3 * 2) + (9 + 7 + 8 * 8) * (9 * 7 + 6)) * 3 * 3 + 8 * 6\n5 * ((2 + 5) * (8 + 2 * 6 + 6 + 3) + 9 + 3 + 9) * (7 * 4) + (3 * 7 + 8 + 5 + 2 + (7 * 7 + 6)) + 4 * 7\n(2 + 8 + 6 + 6 + 8 + 3) + 5 + (5 + 7 * 8 * 5 + 5 * (2 * 4 * 2 + 2 + 6))\n5 + 6 + (9 * 7 * (6 * 8 * 4 + 7 * 2 * 4) + 3 * 5) + 4 + (2 * 4 * 6 * (9 + 6 + 7))\n5 + 6 * (7 + 5 * (4 * 3 * 9))\n6 * 8 + 4 + (2 + 8 * 6 * 2 + (5 + 9) * 3) + 6\n(7 + 5) * 7 + 5 * (6 + 4 * 9 + 6 * 2)\n9 * (9 + (5 + 9 * 7 + 7 * 2 + 2) * 9 + 8 + 5 * 6) + (5 + 5 * (2 + 4 + 7 + 9 + 6) + 2) * 9 * (3 + 5 + (8 + 2 * 2 + 7 * 7 * 6))\n7 * (7 + 3 * 8 * 9 * 9 + (5 * 2)) + 5\n9 * 9 * (8 + 3 + (2 + 9 + 6 + 6)) * 4 + 2 + (2 + 9 + 6)\n((9 * 4 * 9 * 3 + 2 * 5) + (7 + 2 * 4 * 3 * 6 * 8) * 7) * 3 * 9\n(3 + (8 + 6 * 6 * 5) + (3 * 5 + 8 * 5) + 7 * (2 + 3 * 7)) + (8 * (6 * 8 * 5 + 8 * 2)) + 8\n4 * 4 + 5 * 8 * (2 * 2 + 8) * 8\n7 * 8 + (5 * 4) * 7 + 2 + 9\n((4 * 9) * 4 * 8 * (4 * 6 * 5 * 2) * 5 + 9) + 7 * 2 + 8\n((4 * 3 * 9 + 7 * 7) * (7 + 3 + 7) + 9 + 6 + 8 + (3 + 2 * 6 * 2 * 9)) * 2 + (7 + (9 * 9) + 6) * 3 + 6\n8 + (9 * 8 + (2 + 3 * 3) + 4 + 4 + 4) + 4 * (5 * 4 + 4 * 6) * 7 + 8\n9 + 8 * ((2 * 5 + 7 * 2) + 3 * 4 * 3 * 8 * (2 * 6 + 6 + 3 * 5 + 6)) + (8 + 9 * 8 * 2 * 3 * 9)\n8 + (9 * (8 * 5))\n(5 * 4 * 9 * 3) + 7 + (3 + 7)\n3 * (2 * 8 + 2 * (8 * 3 * 8 + 8)) * 7 + (6 + 7)\n3 + 4\n2 * 8 + ((8 + 9 + 6 * 7 * 4 + 5) + 2 + (5 * 2 + 8)) * 4 + 2\n2 + 5 * 7 * 4 * (3 + 9 * (4 + 5 * 7) + 4) + 5\n5 + 7 * (6 * 9 + 9 + 5 * 3) + 8\n4 + (8 + 6 + 5 + 5 * (2 + 6) * 5)\n5 * 4 + 3 + ((4 * 5 * 7 * 6) + (7 * 7 + 6 + 8 * 9 + 4) + 5 + 2 * 7 * 5)\n9 * (8 + (4 + 9 * 8 + 7 * 3) + 3 * 9) + (7 * 7 + 5 * (5 + 7 + 3 * 9))\n4 * 6 + (2 + 6)\n6 + 2 * 2 + 4\n4 + 9 * 7 * (2 + 5 * 4) * 9\n(2 + 4 * (2 * 9 * 4 * 8 + 5 + 4)) + 4 + (8 * 7) + 7 + (3 + 5 * 7)\n9 * 8 * 8 * (6 + 6 * 2 + 5 * 7 + 3) + 6 + 8\n(3 + 9 + (7 * 2 + 2 + 3 + 2)) + (4 * 6)\n((6 + 3) + 3 * 8 + 7 * 7 + 8) + (9 + (8 * 6 + 7) + 2 + 5 * 4) + 5 + 3\n8 * ((5 + 2 * 9 + 2 + 7) * 7 * 7 + 7) * 4 + 8 + (4 * (3 * 9 + 3) + (2 * 9 * 4 * 9 * 7 + 6) + 6) * (8 + (2 + 5 * 3 + 8) + 4 + 8)\n5 + 4 + 7 * (4 + (5 * 5 + 3 * 3 + 8 + 7) + 3 + 8 * 6)\n((9 + 5 * 5 * 6 + 4) + (2 + 2) * 2) * (9 * 9 + 7 * 7 * 6) + 9 + 6 + 2 + (9 * (5 * 9) + 3 * 5 * (5 * 2 * 4 * 7))\n2 * (9 * (5 + 9 * 2 * 9) * 9 + 6) * (2 * 6) * 5 + (3 + 9 + 4 + 6 + (4 * 5 * 7 + 6) + (6 + 7)) * 7\n3 * 8 * 8 * 9 * 2 + 3\n6 * 8 * 6 + (2 + 7) + 5\n(6 * (3 * 4 + 6 + 9) * (2 + 8 + 3 * 8 + 3 * 2)) * 7 * 9 * 7\n8 + (4 + 9 + 2 + 9 * 2 + 9)\n5 + 7 + 6 + ((2 * 2 + 7 + 3 + 9) + 2 + 8) * 7\n(3 * 2) * 2 * 7 * 5\n9 + ((4 * 3 + 3 * 6 * 2 * 9) * 5 * 7 * 3) * 4 * 7 * 2\n(2 * 2 + 9 + 7) + (6 + 4 * 9 * 5) + 6 * 8 * 3 + 8\n8 * 8 + (7 * 9 + 6 * 7 * (2 * 2) * (4 + 2 + 8 * 2 * 3)) + 4\n(3 * (7 * 9 * 6) + 2 + (2 * 6)) * (4 * 3 * 7)\n2 + (2 * (6 + 9 + 9 * 6)) * (7 + 7 * 3 + 8) + 7 + 3\n9 + (5 * 2 + (8 * 4) * 7 * 5) + 9 + 4\n2 + 4 * 4 + 8 * 3 + 5\n8 * 2 * (8 * (7 * 3 * 5 + 7) * 5 + 6 * 4 + 9) * 8 * 2 * 8\n((7 + 4) + 7 * 3 + 6 * (3 + 6 + 8) * (5 + 4)) * 2 * (7 + (2 + 3 * 5) * 5 + 3 + 6) * ((6 + 3 + 4 + 2 + 3) + 4 * (3 * 7 + 2))\n(2 + (3 * 8 * 2)) + 2 * ((3 + 6 + 3 + 7) * 5 * (9 * 2 + 6 + 7 + 3))\n(6 + (7 * 2 + 4 * 9 + 5 * 2) + 4 + 8 * (4 * 8 * 5 + 7) + 9) * 7 + 2 * 9\n2 + (6 + 4 * 2 + (7 * 2)) * (8 * 6 + 6 * 4 + 5 * (5 * 4 + 9))\n(6 * 3 + (5 * 8 * 4 + 7)) + 7 * 7 + 9 + 9 + 7\n(2 * 9 * 7 * 5 * 7 + 5) * 8 + (8 * (9 + 9 * 8) * 7) * 4 + 5\n6 + (3 + 8 + 4 + 9 * 7)\n4 * 8 + 2\n((8 * 8 + 4 + 9) + 9 * 7 + 8) * 8 * (5 + 7 * 5) * 2 + ((3 * 2 + 6 + 6 * 3) * 8 + 9 * 9 * (9 * 6)) + (4 * 8 * (5 + 8 * 5 * 8) * 6 * 9 + 8)\n(3 * 6 * 7) * (4 + 8) + 9\n6 * ((9 * 3 * 4 + 9 * 2) + 7 + 2 * 6)\n6 + (7 + 8 + 2 * 5 * 2) * 7 + (5 + 3) * 7\n7 + ((6 * 8 * 6 * 3) * 9 * 3) + 9 + ((3 + 4 * 2 * 6) * 4 * 3) + 5 + 3\n(4 + 3 * (5 * 2 * 2)) + 5\n4 * 3 * (6 * (4 + 3 + 9 * 3)) + (4 * 2 * 5 + (9 * 2) * (6 + 8 + 9 + 6 * 8 + 8) + 2) + 6 + 8\n7 * 5 * 9 + 7 + (5 * (9 + 8 + 3 * 6 * 3)) * ((3 + 5) * (7 + 9 + 3 + 6 * 2) * 3 + 9)\n((3 + 3 * 9 + 4 * 8 * 2) + 6) + 2 * (5 * (2 * 5 * 7 + 8 + 6) * 2 + 8 + 3 + 6) + (4 + 6 + 4)\n(2 * 8 + 8 + 4 + 3 + 5) + 7\n6 + (6 * 5 * 9 * 6)\n8 + 2 + 6 + 3 + (9 + 6 + (7 * 3) + 5 + 4 + 8)\n6 + 7 * (3 * 7 * 5 + (9 + 6 + 6) * 7) * (3 + 4 + 7 * 4 + 6) * 4 * 4\n9 * 9 * (4 * 4 * (3 * 2 * 2 + 4 + 7 * 3) * 7 * 5 + (7 * 4)) + 5\n9 * ((6 + 3 * 6 + 2) + 4 * (9 * 8 + 8)) + 5 * 6 * 4 + 4\n(8 * 9 + (8 + 5 + 8 + 5 + 3)) + 3 + 6 * 4 * 2 * 4\n8 + (3 * 6 * 7) * 4 * 4 * 3\n(6 * 8 + (2 * 2 + 3 * 8) + 6 * (4 * 9)) * 6 * (2 * 8 + 7 * (8 + 9 + 6 * 9 + 3 + 3))\n3 + 8 * 2 + (8 * 3)\n4 + 3 * 2 * (5 + 3 + 5 + (6 * 5 * 3 * 6 * 6)) + 9 + 7\n(3 + 5 + (3 + 9 + 9 + 7) * 7 * 6) + 7 * 5 * (5 + 3)\n2 + ((7 + 2 + 9 + 2 + 6) * 3 * 2 * 5 * 5 + 2) + 2\n6 * 8 * (2 + 4 * 9 * 5) + 9 + 3\n4 * (6 + 9)\n5 * 2 + 3 * 2 * (5 * 3 * 9 * 7 + (6 + 4 * 5 + 6) * (6 * 2 * 2)) * (9 + 6 + 9 + (8 + 9 + 9))\n5 + (4 * 4 * 5 * (4 * 2 * 4 * 2) * 7) * 2\n3 * 2 + ((4 * 6 * 8) + 9 * (3 * 9 * 8 * 2))\n(3 * 5 + 6 * 8) + 5 + ((2 + 9) + (3 + 4 * 2 * 5 * 3) + 4 + (3 * 7)) * 6\n6 + 3 + 2 + 4 + (6 * 2 + 6 + 4) * 2\n(5 + (5 + 6 + 7 * 2) + 7 + 4 * 5) + 5 * 6 * 9\n4 * 7 * (3 * 2) + 4\n(5 + 4 + (8 + 3 + 7 * 2)) * (6 + (5 + 7 + 3 * 8 + 4) * 5 + 6 * 6 * 5) + 7\n2 * 5 + (5 + 4 + 3) + (9 * 3 + (7 * 6 * 9 * 4 * 3 * 2)) * 3 + 2\n(8 * 2 + 3) + 5 * 2 * 9 + 9 + (3 + 4)\n9 + 6 * ((4 * 7 * 9 * 5 * 4 * 5) + 8 * 8 * 7) * 7\n5 * 4 + ((3 + 2 * 5 * 6 + 7) + 7) + 2\n3 * 9 + 4 * 9\n9 + 7 + (7 + 5 + 3 * (5 + 7 * 8 * 7 + 5 + 7)) + (7 * 6 + 5 * 8) + (8 + (2 + 3 * 3 + 4) + (6 * 9 * 9) * 8) * 6\n8 * (2 * 7 * 3 * 4) + 9 * 3 + 7\n6 + (8 + (7 + 5 * 8 * 5) + 5 * 6 + (8 * 6) + 6) * 3\n7 + 3 * 4 * 6 + 9\n8 + 8 + ((8 * 9 + 6 + 3 * 9) + 3 + 4 * 8)\n9 + 4 + 6 + 3 + 2 + (2 * 6 + 8 + 3)\n(5 * 2) + 4 + 7 * 9 + (5 + 5 + 3 * 5)\n5 * 5 * 2 * 5 + (9 + 7 + 5)\n(2 * 5) + 7\n5 + 7 * 9 + 3 * 5\n(8 * 7 + 9 * 5) + 3 * (6 * 5 + (2 * 7 * 2 * 7 + 7 * 2) + 4) + 3\n(6 + 6 + 6 + 9) + 9 + (3 * 5 + 4 + (6 * 3) * 4) * 3 + (8 + 7 * 5 * (3 * 3) + 6) * 3\n((2 * 8 * 3 + 2 * 6 * 5) * 5 + (7 * 3 + 5 + 6 * 9 * 4) * (5 * 6 + 8 + 4 * 7 * 5)) + 6 + (9 * (9 + 7 * 8 * 3) + 7 * (5 * 9 + 6 + 5 + 4 + 8) * 8 + 8) * 5\n2 * (5 + 2 * 2 * 3 + (4 + 3)) * (6 + 6 + 2 * 9 + 9 * 3) * 8 * 8\n9 * (9 + 3 + 8 + 5) * (2 * 5 * (6 + 8) * 9) * (4 + 3 * 8 * 9 * 4 + 4) * (3 * 9 * 8 + (6 * 6 + 9 + 5) + 2 * (8 + 2 * 7))\n2 * 5 * 9 * 8 * ((7 * 2 * 3) + 3)\n2 * (6 * 7 * 2 * 4 + (5 * 4 + 7 + 3 + 7) + 5) * (7 + (6 + 3) * (8 + 8) * 3 * (5 + 2)) * 3 * 8 * 7\n2 * 5 * (4 * 9 + 2 + 5 * 2) + 6 * 5 + (6 * 6 * 4 * 8 * 4)\n4 + 8 * 4 + 4 * 3 + (7 + 2 * 2 * 5 * 2 + 8)\n(8 * (4 + 5 + 9 * 9 + 8) * 4 + (8 + 7 + 9 * 4 * 4 + 3)) * 7 * 8 * 3\n8 * 9 + ((2 + 5 + 8 * 9 + 5) + 2) * 7 * 4 + 5\n3 + (5 * 8 * 6 * (7 + 4 * 2 + 2 * 4 * 2) + (9 + 6) * 9) + 4\n9 * 7 + 4 + (7 + 9 + (9 * 9 + 8 * 4 * 5 * 8) + 5) + 3\n2 * 2 + 6 + (3 * 9 + 6 + (4 * 4 * 6 + 2 * 5)) * 5\n6 * 3 * (3 + 8 * 7) + 9\n7 * 2 * 6 * (3 * 3 * 8 * (2 + 7 * 9 + 8))\n9 * 7 + 6 * (7 * (3 + 6 + 7) + 3) + (9 * 6 + (2 + 9 * 3) + (7 * 8 * 8 + 6 * 3 * 5) * 9)\n3 * 4 * 4 * 6 + 2 + (6 * 3)\n4 * (5 + 7) + 8\n5 * 3 * 9 + 9 + 9 * 2\n8 + (8 * 9) * 7 + 6 * 9\n9 + 9 * (3 * 8) * 3 + 2\n6 + (8 + 6 + 2) * (9 * 9 * 8)\n5 + 4 * 3 + (2 * 2 * (2 + 3 + 4 + 7 * 3) + 5 + 3) + 6\n9 * 2 + 3 * 8 * 9\n5 * 2 * 7 * ((5 + 6 * 4 + 6 + 3 + 5) * 7 + 9 + 4) * (7 + 3 * 7)\n2 + ((5 + 3 * 4 + 2) * 2 * 6 + (8 * 8 + 8) * 3 * (3 * 8 * 5 * 6 + 5))\n5 + (6 + 9 + 4 + (3 * 7)) * (4 + 6 * 5 * (7 + 8 * 3 + 3 * 9) + (9 + 8 + 3))\n4 * 2 + 9 + (9 * 6 * 9 * (9 * 4 + 3 * 2 * 6 + 8) + 7 + 9) * (5 + 7 * 9 * 5) + (8 + 9 + 4 * 5 * 8)\n7 + 8 * 3 + (5 + 2 * 2 + 6 * 8) + 7\n8 + ((9 * 7 + 5 * 8 + 3 + 6) * 4) + 6 * 4 + 4 + 3\n(6 + 2 + 4 + 7) * (2 + 6 * 7 * (4 * 3 + 9 + 5 * 5) + 5 + (2 + 3 * 5 * 5 * 6)) * 2\n(6 + 9) + 4 * 9\n4 * (4 * 5 + 9 * (9 + 5 * 7 * 6 * 7 + 9))\n2 * 5 + ((7 + 3 * 3 * 9 + 8 + 4) * 4 * 6) + 3 + 6 + (4 + (2 * 7) + 5)\n(7 + (4 * 5 + 2 + 2 * 2 + 8)) * 5 + 5 + (3 + 8 + 6 * 6) * 9\n5 + 4 + 4 + 7 * (2 + 6 + (3 + 6 + 7) + 6 * 9) * (2 + 8)\n8 + ((4 * 3 * 2) + 4) + 5 * 7 * 3 * 5\n4 * 4 + 9 + (8 + (6 * 5 * 2 + 8 * 3 + 8) + 4 * (2 + 6 * 2 + 4 + 3 + 2) * (4 + 5))\n(9 + 8 * 8 + (5 * 8 * 7 * 8 + 9 * 6)) * 9 + 5 * 2\n7 + 8 * (2 + (5 + 7 + 3 + 9 * 8 + 8) * (2 * 9 * 7) + 3 + 4) * 8 + 5 + 2\n5 + 2 * (5 * 7 * 6 * 4 * 2 + (7 + 2 + 7 + 9 + 4))\n6 * 8 * 7 * 8 * 9 + 9\n5 + 8 + 7 * 5 * (8 * 8 * 5 + 7 + 9) + 6\n9 + 2 * 3 * 5\n8 * 5 + (2 + (4 + 9 + 5 * 6 + 8) + 9 * (4 + 4 * 5 * 3) * (5 * 7 * 8 + 3 * 3 + 3) + 5)\n7 + 3 + (2 * 2 + 5 * 8 + 3) + (8 + 3 + (6 * 5 + 4 * 5))\n6 * ((2 * 6 + 6 * 2 + 5 + 4) * 8 + 8 * 9) * (5 * 2 + 4 + 6 * 3) + ((6 + 8 + 8 + 6 + 7 * 6) + 8 * 9 * 2 * 2 * (8 + 3 + 7 * 5 * 3)) * ((5 + 9) * 4) + 4\n(3 * 8 * 5) + 8 + (3 + 7 + 2 * 3 * 8) * 5\n7 + 3 * 9 + (2 * (2 + 9 + 9 + 8 + 9) * (8 * 6)) * 4 * 9\n7 + 9 + (3 + 7 + 2 + 6)\n4 * (6 + (3 + 6 + 3) * (9 * 7 * 4 + 3 + 4) + 8 * 7 + 4)\n((9 + 6) * 3 + 2 * 5) + (6 * 5 + 4 + 3)\n3 + (4 * (2 + 4 + 4 + 2)) * 4 * 7 + 5 + 5\n(5 * 9 * 2 * (7 * 9 * 8) + 2) + 6 + 2 + 8 + 9\n5 + 4 * 4 + (2 * 3 + 8 + 8) * 6 * (9 * 8 + (8 * 9 * 5) + 9)\n3 * 5 * (8 + 3 + 7) + 4 + 6\n6 + 7 * (9 + (2 + 7 + 2 * 2)) * 3\n(9 * (4 * 3)) + 9 * 4 + (9 * 5 + 5 * (6 * 2 + 8 * 8) + 2) + 9 + 8\n6 * 7 + 7\n7 + (9 * 6 * 8 + 9 * 2) * 4 * (9 * 4 * 6 + (8 * 5 * 8)) * 7\n8 + 5 + ((8 + 2 * 6) + (9 * 3 * 8)) + 7\n4 * 8 * (6 + (4 + 5) + 5 * 3)\n(3 * 2 + 6) + 3 + 3 + 8 * 6 * 7\n9 * 3 * 3 + (4 * (6 + 3) * 4) + 2 * 9\n5 + 9 + 7 + 4 * (9 * 3)\n((8 * 9) + (7 + 5 + 6) + 3 * (5 + 7 + 6)) + 5 + (3 * 8 * 3) * 2\n9 + 6 * 5 * ((4 * 4) + 7 * 3) + (3 * 6)\n7 + (8 + 7) + 4 * (3 + 3) * 7 * 9\n((6 + 7 + 4 + 7) * 7 + 9 + (9 * 7 + 5 + 7 + 7) + 9 + (7 + 3 + 2 * 6 + 9)) + 2 + (4 * 7 + 9 * 3 * 2 * (5 + 9 + 3)) * 5\n9 * (3 + (9 * 9)) + 9 * 8 + 4 * 2\n(8 * 8 + 6 + 9 + 8 + 2) + 6 * 5 + 5 * 4\n3 + 3 + 4 * (6 * 6) + 2 * 8\n(5 * 9) * (8 * (2 + 6 * 9) * 7 + 7)\n8 * 5 + (8 + 8 + 8 * 4) + 3 * 8 * (8 + 6 * 3 + 4)\n4 * 9 + (5 * (8 * 3) + 4) * 5 + (3 * 3)\n(2 + 2 * 4 * 3) + 8 * ((2 * 6 + 5 + 6 * 2) * 3) + 2\n((5 * 4 + 2 + 7 * 6) + (7 * 5 + 4) + 9 + 7 + 7) + 3\n2 + 3 + 9 * 9 + (9 * (2 + 8 + 7) * 3)\n3 * 7\n(4 + 2 * 5) + 2\n5 * 5 * (5 + (8 + 8 + 8) + 3 * 2 * 4) * 9 * 2 + 8\n4 + 5 * 3 * 5 + (4 + (3 + 8 + 4) + 7) + 7\n(4 + 7 + 6 + 2 * 7) + 7\n4 * 2 * 4\n(4 * 4 + (6 * 6 * 7 * 2) * 4 * 6 * 7) * ((9 + 5 + 9) + 8) * (5 + 8 + 2 + (9 + 8 * 2 + 9 * 8) * 8 + 3) * 6\n5 + 8 * 9 + ((7 * 9 * 3 * 7) * 2 + (2 + 2 + 3 * 6 + 6) + 5 + 4)\n3 * 8 + 2 + (7 + 8 + (8 + 7 + 7 * 6 + 2) + (3 + 2) + 5)\n4 + 4 * 6 * 5\n4 * 9 * ((9 + 2) + 4 + 2 * 5) * ((6 * 9 * 5 + 8) * (7 + 7)) * (8 * 7 + 9 + 7 * (2 + 9 + 9 + 4 + 8) + 9) * 6\n(8 * (2 + 3 + 7 * 3 + 2) * 2 * 4 + 7) + 4 + 3 * 2\n(6 + (2 * 5 + 3 * 2 * 4 * 7)) * 6 + 4 + 6 + 9 + 9\n(8 + 8 * 6 * (4 + 3 + 4 + 8 * 2 * 4) + 7) + 2\n8 + 9\n8 + 8 * 4 + 4 * ((9 * 2) + 2)\n(3 + 3 + 9 * 9 + 5 * 2) + 5 + 7\n2 + (7 * 5 * 2)\n8 + (5 + 3 + 8 * (3 + 2) * 6) + 9 * 9 * 8 * 9\n8 + (2 * 5 + (9 * 7 * 4 * 2) * (7 * 4) * 4 * 6) * 9 + 3\n4 * 7 + 4 * 4 * (2 + (2 * 8 + 2 * 5 + 2) * 7)\n8 * 5 + 8 + (6 * 9 * 8 * 2 + 5 + (4 * 5 + 4 + 3 + 3)) + 4\n9 + 9 * 2 * 9 + (5 + 2 + 6 + 3 * (5 * 2 + 8 * 9 + 6 + 7))\n4 * 9 + 2\n4 + 4 * (3 + (4 + 9 * 8 * 7 * 3 * 3) * 2 + 9) + (2 * 7) + 8\n((5 + 8 + 5 * 2 * 5 * 3) * 5 * 6 + 2) + (5 * 9 * 6 + 2 * (4 + 8 + 9 * 9 * 8 * 3) * 2) + (8 * 6 + 2)\n3 + 7 + (9 * (2 * 6 + 3) + 4) * (3 + 4 * 8)\n((2 * 2 + 5 * 6 + 7 * 2) * 5 + 9 + 6) * 5\n(8 * 6 * (3 + 8) + 9 + 7 * 5) * 3 * 2 * 3 * 5 * 5\n((2 + 9 * 4 + 8) * (5 + 5 + 6) * 6 + 9 * 8 + (6 + 9)) * (9 + 8) * 6 * 6 + 9 + 7\n(6 * 5 * 6 * 5 * 3) * 6 * 9 * 9\n(5 * 4 * (5 * 3 * 3) * (5 + 6 + 2 + 2 * 9 * 3)) + (3 + 6 * 3 * 3 + 3 * (8 * 5 + 3)) * (9 + 3 * 9) + (7 + 4 + 3 * 8 * 8)\n(4 + (9 + 2 * 3 + 9 + 6) + 2) + 2 * 7 * 5\n9 + 8 + (3 + (7 * 7 + 2 * 8 + 6 * 2) * 8 * 6 * (9 + 7 + 4))\n(7 + 3) * 7 * (4 + 4 * (2 + 3 + 4 + 6) + 7) + 6 + 2\n(8 * (5 * 9 * 6) * 3 * (7 * 5)) + 5 + 3\n(2 * 6 + (7 + 5) * 7 + 3) * 5 + 3 * 2\n((9 + 4) * 6 * 2 * 3 + 6) * ((2 + 6 + 4 * 7 + 4 * 7) * (7 + 9 + 2) * 2) + 7 * 2\n3 * (9 + 9 + 5 + (9 + 7 * 7 + 8 + 2 + 6) + (9 * 8 + 8 * 8 * 7) * 3) + (7 + 9 * 4 + (6 + 4) + 2) + 9\n9 + (2 * 5 + 9) + 9 + 7\n3 * 9 + ((2 + 4 * 4) * 3 + 5 * 3 * 5 + (4 + 8 * 3 * 4)) + 6 * 5\n3 + (7 * 2 + (4 + 6 * 6)) * 2 + (4 * 5 + 2 + 6 + (7 * 6 + 6 + 7)) * 6 + 9\n6 + 5 * (3 + 5 + 2 + (9 + 6 * 3) + 3 + 7) * 3\n4 * ((4 + 4 * 8 + 7 + 2 + 4) * (4 + 4 + 8 * 4 + 4 + 3) + 9 * (6 * 4 * 9 * 9) * 2 * (6 + 6 * 9 * 3 + 4)) + 7\n9 + 8\n7 + (9 + (5 * 6 * 5 * 3 * 3))\n7 * 9 + 4 + 6 + ((9 * 2 + 9) * 7 * 9) + 6\n((8 + 7 * 8 * 6 * 9 + 2) + 4 + 6 * 9 * (5 * 6 * 9 * 8) * 7) * 5 + 5\n2 + 2 * (4 + 3 + 6 + 4 + 5) * (7 * 5 * 5 * 6 + 4 + (6 * 8 * 4 + 7))\n(3 + (9 + 2 * 3)) + 2 * 7\n(5 + 8 * 5 * (9 * 6 + 4 * 6 + 5)) + 5 * ((3 * 9 + 7) + 9 + (2 * 6 * 4 * 3 + 4 * 4) + 7 + (5 * 4 * 9 + 9 * 7) * 5)\n((7 + 2 * 5 * 3) + 4) * 8\n6 * (3 + 7 * (2 + 6) + 6 + (9 * 8 * 7) * (5 * 4 + 7 + 8 * 8)) + 6 * 6\n(6 + 9 * (2 + 2 * 2 * 3 * 7 + 8) * 3 * 5 * 4) + 2\n5 + 2 + (9 + 4 * 7 + 3 + 8) * (4 + 8 * (3 + 2 * 7 * 4)) + 8 + (4 + 5)\n(8 * 9 + 9 + 4 * 5) + 2 * 2 * 9 + (3 + 9) + 5\n4 * 7 + ((5 + 7) * 3) * 9 * 9\n6 + 6 * 4 * ((8 + 9 * 7 * 3 + 9 * 8) + 4) * 3 * 4\n4 * (6 * (9 * 9 + 4 * 2 * 3) * 2) + 8 * 5 * 3\n7 + 4 * (8 * 2 * 2 * 3 * 8 * 8) * 7 + 2 + 5\n8 * ((2 * 3 * 5 * 9 * 2 + 6) * 4 * (7 + 3 * 4 + 7 * 5 + 5) * 3) * 7 + ((9 + 8 + 5) * 8 * (5 * 8 * 9 + 3 + 9) * 5)\n5 * (7 + 2 + 9) + 9 * (5 + 8) + 3 * 6\n6 * ((9 * 5 + 7) * (8 + 9 + 9 * 7 + 3 + 4))\n((7 + 2 * 6 * 5) * 7 + 2) * 8 * 7\n9 + ((7 + 8 * 9 * 4 * 4 + 6) + 8) * (9 + (7 + 2 + 6 * 3))\n(3 + 6 * (6 * 9 * 4)) + 6 + 5 * 9 + (4 * 6 * 8) * ((7 + 2 * 9 * 4 + 4) + 9 + (6 + 2) + 5)\n2 + 4 + 6 + 2 * ((8 * 3 * 2 + 7 * 6 + 3) + 4 + 5 + 5 * 5)\n6 + ((6 * 5 * 3 + 9) + (7 + 7 * 8 + 9 * 7 + 6))\n(9 + 3 * 3 + (6 * 4 * 2 * 9 + 7 + 4) * 2) * 9 * 2\n4 * ((8 + 4) * 2) * (7 + 6 + 3)\n9 * 2 + (9 + (7 * 4) * 9 + 8 + (4 + 4) + 7) + (6 * 6 * 3 * 3) * ((9 * 4) * 5 * (6 + 3 + 8) + 5 * 7) + 2\n5 + ((9 + 3 + 4 + 2) + (5 + 3) + (4 * 2)) * 7\n(8 * 7) + 9 + 6 + 7 * 9 * ((5 + 8 + 5 * 5 + 7 + 2) * 2 + 6)\n(9 * 3 * 6) * 4 + 5 * 4 * 3\n5 * ((7 + 4 * 5 + 8) + 2) * 9 + 3\n2 * 2 + ((2 * 2) * (7 * 5 * 6 + 9)) * 2\n4 + ((5 * 5 + 2 + 2) * 3 * 6 + (4 * 3 * 3 + 4 + 7)) * 3 + 3 + (4 + (6 + 9) + 4 + 6 * (2 * 3) * (5 + 8 * 2 * 8)) + 9\n2 * 9 + 5\n2 + ((6 + 7 + 9) * 9 + 9) + 9 * 5\n2 + 7 * (9 * 7 + (6 + 5 + 2)) + 8 + 5\n3 * (7 * 4 + 8 * 8 * 6 * 8) + 5 + 2\n8 + (5 * 2 * 3 + 5 + 8 * 3) * 3 * (9 * (2 + 8) * (7 + 3 + 5 + 4 * 9) * 6 + 5 + (8 + 9)) + 4 + 3\n4 + 7 * ((8 * 5 * 2) + 3) + 2\n4 + 6\n(5 * (7 * 6 + 3 + 4) + 9 + (8 + 9) + (5 * 6) * 4) * 8\n6 + ((7 + 5 + 7 * 3 + 8 + 3) * 5 * 2 * 4 + 5 + 4)\n5 + 4 + ((6 + 6 + 5 + 7 * 8) * (2 + 4 * 3 * 8 + 3) + (4 + 3) + 2) + 9\n7 * 3 + 6 + 6 * 4 * 6\n(4 * 9 + 2 + 4 + 9) * 6 + 6 * (4 * 9 * (6 * 9 * 3 * 6 * 2 * 7) + 5 + 3 * 3) + 3 * 8\n(5 + (4 * 8) + (5 * 5)) + (2 + 5 * 8)\n9 + 3 * 3 * 8 + (3 + 4 * 2 + (6 * 7 * 2 + 4 + 6 * 9) * 4) * 3\n3 * 6 + 2 + (8 * 6 * 6 + 8 + 8) * ((7 + 3 * 4 * 5) * 4 + 9 * (7 + 4 + 5 * 9 + 8 + 3) * (7 * 8 * 5 + 5 + 7 + 6)) + 4\n6 + 4 + (5 + 7 * 6)\n5 + 3 * 8 + 6 + 3\n6 + 2 + 9 + 8 + (7 + (8 + 2 * 8 + 3 + 8) * 8) * (8 * 8 * (7 + 9 * 2 + 7 * 4) * 4 + (7 + 6 + 7 * 4 + 5))\n3 + 8 + 4 + (8 + 7) * ((7 + 5) + 8 + 4 + (9 * 7 * 8 * 6) + (7 + 6 + 8 * 3)) + 5\n4 + 2 + 6 * (8 + 2 * 2 * 7) * 2 * 8\n2 + 6 * 4 + 6 + (8 + 4 + 6 * 8 + (6 + 4 * 9 * 8 * 3 + 6) * (3 * 5 * 2 + 2 + 7 * 2)) * 3\n6 + 6 * 4 + ((9 * 8 * 5) * 4 * 9 * (2 + 9 * 4 + 8 * 8) * 7)\n3 * 3 + (2 + 9 * 6 + 3) * ((3 + 2 * 2 + 8 * 8 * 3) + 8 * 9) * 4 + 9\n(2 * 7 + 2 * 2) * 8 + 6\n5 + (3 + 9 + 3 + 9 * 4 + 6) + 3 * 7 * 5 * 5\n((9 + 7 * 4 * 5 + 6 * 8) + 5 * 3 * (2 * 7 + 3 + 5 * 4 + 9)) * 5 * 8\n7 + 2 + (5 + (8 + 2 * 2 * 9 + 6) * 4 + 2 * 5) * 3 + 5\n7 + (8 + 6 * (9 + 6 * 3 * 9 * 8 + 7))\n7 + 2 + 7 * (9 + 4 + 3 * 3 + 9)\n7 + ((5 + 7 * 4 * 3) + 4 * (9 * 5 + 2 * 5 * 6 + 2)) * 3 * ((3 + 3 + 4 + 8) * (4 * 5 * 7 * 4 + 9) + 8 + 3) * 7\n(3 * 9 * 8 + 8 + (5 * 3 + 6 * 3 + 2) + (8 + 9 + 3)) * 5 * 4 * 4 * 3\n9 * 6 + (9 * 6 + 3 * (7 * 4 * 2 + 9) + 3)\n(3 + 6 * (6 * 5 * 8 * 9) + (7 + 5 * 5 + 5 + 8 * 8)) * 6 + (9 + 8 + 7 * 5 + (8 + 3 * 4 + 8 * 9) * 7) * 8 + 6\n(9 * 7 + (4 * 8 + 9 + 6) * 3 * 7 * (9 * 7)) + (5 * 9 * (3 * 4 * 7 + 6) * (8 * 9 + 5 + 2 + 9))\n5 * (8 * 3) + 9 * ((8 * 3 * 4) * (6 * 2) * 3 + 6 * 6 * 8) * ((2 * 3 * 6 + 4 * 2 + 5) * 8 * 6 * 2)\n3 + (4 * (6 + 5 * 3 + 9 + 3) * 2 * (8 + 7 * 8 * 7 + 5) * (8 + 8)) + (8 * 5 + 8 + 6 * 9 * 4) + 8 * 4 + 3\n(3 * 6 * 7 * (3 + 7 * 4) * 8 * 8) * 5 + 6 * 6 + (4 * (9 + 5 * 8 * 9 * 6 * 6) * 3) + ((7 * 8 * 6 + 2 + 5 * 6) * 2 + 3 + 5 * (3 * 8) + 6)\n(2 + 4 * 9) + (7 + 2 + 7 * 7 * (3 + 8 * 4 + 2) * (7 + 5)) * 9 * 7\n4 + (8 + 2 + 5 + 2 + 9 + 4) + 7 + 6 * 4\n3 * 8 + (8 + 5) * (7 + 5 + 6)\n5 + (5 + (7 + 5)) * 8 * 6 * ((9 + 3 * 2 * 5 + 2 + 9) * 2 + 5 + 3 * 6) * ((2 + 2 * 9) * 6 * 8 * 7 * (4 * 5) * 6)\n7 + 3 * 6 + ((5 + 2 + 6 + 5 + 5 * 4) * 4 * 9)\n5 * 4 + 8 * 3\n(8 + 6 * 6 + 5) + 9 + (6 + 3) + 7 + 6\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_18_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 18\n-------------------------------------------\n--  Operation Order\n--\n--  https://adventofcode.com/2020/day/18\n--\nwith Ada.Text_IO, Interfaces;\nwith AoC_2020_18_Weird_Formulas;  --  Variant of MathPaqs' Formulas.\n\nprocedure AoC_2020_18_full_Ada is\n  use Ada.Text_IO, Interfaces;\n  --  Set `*` as a fake `-`, in parsing and in evaluation.\n  package WF_1 is\n    new AoC_2020_18_Weird_Formulas (Long_Float,\n      Plus      => \"+\", Minus      => \"*\", Times      => \"*\",\n      plus_char => '+', minus_char => '*', times_char => '_'\n    );\n  --  Swap `+` and `*`, in parsing and in evaluation.\n  package WF_2 is\n    new AoC_2020_18_Weird_Formulas (Long_Float,\n      Plus      => \"*\", Minus      => \"-\", Times      => \"+\",\n      plus_char => '*', minus_char => '-', times_char => '+'\n    );\n  --\n  sum : Integer_64;\n  f : File_Type;\nbegin\n  for part in 1 .. 2 loop\n    Open (f, In_File, \"aoc_2020_18.txt\");\n    sum := 0;\n    while not End_Of_File (f) loop\n      sum := sum + Integer_64 (\n        (if part = 1 then WF_1.Evaluate (WF_1.Parse (Get_Line (f)))\n                     else WF_2.Evaluate (WF_2.Parse (Get_Line (f)))));\n    end loop;\n    Close (f);\n    Put_Line (\"Part\" & part'Image & \": sum is\" & sum'Image);\n    --  Validated by AoC:  14006719520523\n    --  Validated by AoC: 545115449981968\n  end loop;\nend AoC_2020_18_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_18_weird_formulas.adb",
    "content": "with Ada.Characters.Handling;           use Ada.Characters.Handling;\nwith Ada.Exceptions;                    use Ada.Exceptions;\nwith Ada.Numerics.Generic_Elementary_Functions;\nwith Ada.Strings.Fixed;                 use Ada.Strings.Fixed, Ada.Strings;\nwith Ada.Unchecked_Deallocation;\n\npackage body AoC_2020_18_Weird_Formulas is\n\n  package REF is new Ada.Numerics.Generic_Elementary_Functions (Real);\n  package RIO is new Ada.Text_IO.Float_IO (Real);\n\n  subtype Leaf is S_Form range nb .. var;\n  subtype Neutral is Unary range plus_una .. accol;\n  subtype Built_in_function is S_Form range abso .. max;\n  subtype Binary_operator is Binary range moins .. puiss;\n\n  type S_Form_Set is array (S_Form) of Boolean;\n\n  par_or_terminal : constant S_Form_Set :=\n    (par | croch | accol | nb | var => True, others => False);\n\n  symmetric : constant S_Form_Set :=\n    (min | max | plus | fois => True, others => False);\n\n  function Conv_strg (s : S_Form) return String is\n  begin\n    case s is\n      when plus_una   => return \"+\";\n      when moins_una  => return \"-\";\n      when abso    => return \"Abs\";\n      when sign    => return \"Sign\";\n      when step    => return \"Step\";\n      when round   => return \"Round\";\n      when trunc   => return \"Trunc\";\n      when floor   => return \"Floor\";\n      when ceiling => return \"Ceiling\";\n      when expn    => return \"Exp\";\n      when logn    => return \"Log\";\n      when sqrt    => return \"Sqrt\";\n      when sinus   => return \"Sin\";\n      when arcsin  => return \"Arcsin\";\n      when cosinus => return \"Cos\";\n      when arccos  => return \"Arccos\";\n      when tg      => return \"Tan\";\n      when arctg   => return \"Arctan\";\n      when sh      => return \"Sinh\";\n      when arcsinh => return \"Arcsinh\";\n      when ch      => return \"Cosh\";\n      when arccosh => return \"Arccosh\";\n      when th      => return \"Tanh\";\n      when arctanh => return \"Arctanh\";\n      when min     => return \"Min\";\n      when max     => return \"Max\";\n      when par     => return \"(\";\n      when croch   => return \"[\";\n      when accol   => return \"{\";\n      when fois    => return \"*\";\n      when plus    => return \"+\";\n      when moins   => return \"-\";\n      when sur     => return \"/\";\n      when puiss   => return \"^\";\n      when Leaf    => return \"\";\n    end case;\n  end Conv_strg;\n\n  function conv_symb_una (c : Character) return S_Form is\n  begin\n    if c = plus_char then return plus_una;\n    elsif c = minus_char then return moins_una;\n    else return nb;\n    end if;\n  end conv_symb_una;\n\n  function conv_symb (c : Character) return S_Form is\n  begin\n    return (\n      if    c = plus_char  then plus\n      elsif c = minus_char then moins\n      elsif c = times_char then fois\n      elsif c = '/' then sur\n      elsif c = '^' then puiss\n      elsif c = '(' then par\n      elsif c = '[' then croch\n      elsif c = '{' then accol\n     else nb);\n  end conv_symb;\n\n  function Conv_mstr (s : S_Form) return String is\n  begin\n    return To_Upper (Conv_strg (s));\n  end Conv_mstr;\n\n  procedure Put (f : Formula; style : Output_style := normal) is\n  begin\n    Put (Ada.Text_IO.Current_Output, f, style);\n  end Put;\n\n  procedure Put (t : in Ada.Text_IO.File_Type; f : Formula; style : Output_style := normal) is\n  begin\n    Ada.Text_IO.Put (t, Image (f, style));\n  end Put;\n\n  function Almost_zero (x : Real) return Boolean is\n  begin\n    return abs x <= Real'Base'Model_Small;\n  end Almost_zero;\n\n  function Image (f : p_Formula_Rec; style : Output_style) return String;\n\n  function Image_simple (f : p_Formula_Rec; style : Output_style) return String is\n    x : Real;\n    use Ada.Text_IO, RIO;\n    s : String (1 .. 40);\n  begin\n    if f = null then\n      return \"\";\n    end if;\n    case f.s is\n      when nb =>\n        x := f.n;\n        if Almost_zero (x - Real'Floor (x)) and then\n          abs x < Real (Long_Integer'Last)\n        then\n          return Trim (Long_Integer'Image (Long_Integer (x)), Left);\n        else\n          begin\n            Put (s, x, 5, 0);\n          exception\n            when Layout_Error =>\n              Put (s, x);\n          end;\n          return Trim (s, Left);\n        end if;\n      when pi =>\n        return \"pi\";\n      when var =>\n        return To_String (f.v);\n      when moins_una =>\n        return minus_char & Image (f.left, style);\n      when plus_una =>\n        return plus_char & Image (f.left, style);\n      when Binary_operator =>\n        return Image (f.left, style) & Conv_strg (f.s) & Image (f.right, style);\n      when Built_in_function =>\n        if f.s in Binary then\n          return Conv_strg (f.s) & '(' &\n            Image (f.left, style) & ',' &\n            Image (f.right, style) &\n          ')';\n        else\n          return Conv_strg (f.s) & '(' & Image (f.left, style) & ')';\n        end if;\n      when par =>\n        return '(' & Image (f.left, style) & ')';\n      when croch =>\n        return '[' & Image (f.left, style) & ']';\n      when accol =>\n        return '{' & Image (f.left, style) & '}';\n    end case;\n  end Image_simple;\n\n  function Image (f : p_Formula_Rec; style : Output_style) return String is\n  begin\n    if f = null then\n      return \"\";\n    end if;\n    if style = bracketed and then f.s not in Leaf then\n      return '{' & Image_simple (f, style) & '}';\n    else\n      return Image_simple (f, style);\n    end if;\n  end Image;\n\n  function Image (f : Formula; style : Output_style := normal) return String is\n  begin\n    return Image (f.root, style);\n  end Image;\n\n  function Deep_copy (f : p_Formula_Rec) return p_Formula_Rec is\n    g : p_Formula_Rec;\n  begin\n    if f = null then\n      return null;\n    end if;\n    g := new Formula_Rec (f.s);\n    case f.s is\n      when nb =>\n        g.n := f.n;\n      when pi =>\n        null;\n      when var =>\n        g.v := f.v;\n      when Unary =>\n        g.left := Deep_copy (f.left);\n      when Binary =>\n        g.left  := Deep_copy (f.left);\n        g.right := Deep_copy (f.right);\n    end case;\n    return g;\n  end Deep_copy;\n\n  procedure Dispose is new Ada.Unchecked_Deallocation (Formula_Rec, p_Formula_Rec);\n\n  procedure Deep_delete (f : in out p_Formula_Rec) is\n  begin\n    if f /= null then\n      case f.s is\n        when Unary =>\n          Deep_delete (f.left);\n        when Binary =>\n          Deep_delete (f.left);\n          Deep_delete (f.right);\n        when others =>\n          null;\n      end case;\n      Dispose (f);\n      f := null;\n    end if;\n  end Deep_delete;\n\n  Closing : constant array (Character) of Character :=\n    ('(' => ')',\n     '[' => ']',\n     '{' => '}',\n     others => 'X');\n\n  c_fin : constant Character := Character'Val (0);\n\n  procedure Check (expected, found : Character) is\n  begin\n    if expected = found then\n      return;\n    end if;\n    if found = c_fin then\n      Raise_Exception (\n        Parse_Error'Identity,\n        \"End of formula reached, '\" & expected & \"' is missing\");\n    else\n      Raise_Exception (\n        Parse_Error'Identity,\n        \"'\" & expected & \"' was expected, found '\" & found & ''');\n    end if;\n  end Check;\n\n  procedure Check_brackets (open, close : Character) is\n  begin\n    Check (expected => Closing (open), found => close);\n  end Check_brackets;\n\n  function No_Spaces (s : String) return String is\n    t : String (s'Range);\n    j : Integer := s'First - 1;\n  begin\n    for i in s'Range loop\n      case s (i) is\n        when ' ' | ASCII.HT | ASCII.CR | ASCII.LF =>\n          null;\n        when others =>\n          j := j + 1;\n          t (j) := s (i);\n      end case;\n    end loop;\n    return t (t'First .. j);\n  end No_Spaces;\n\n  digit         : constant Character_Set := ('0' .. '9' | '.' => True, others => False);\n  expo          : constant Character_Set := ('e' | 'E' => True, others => False);\n  digit_or_expo : constant Character_Set := digit or expo;\n\n  first_symbol_after_expo : constant Character_Set :=\n    ('0' .. '9' | '+' | '-' => True, others => False);\n\n  procedure Parse (f : out Formula; s : String) is\n    str : constant String := No_Spaces (s) & c_fin;\n    i : Integer;\n    --\n    function Expression return p_Formula_Rec is\n      --\n      function Term return p_Formula_Rec is\n        --\n        function Factor return p_Formula_Rec is\n          --\n          function Number return p_Formula_Rec is\n            n : constant p_Formula_Rec := new Formula_Rec (nb);\n            j : constant Integer := i;\n          begin\n            while\n              digit_or_expo (str (i)) or else\n              (expo (str (i - 1)) and then first_symbol_after_expo (str (i)))\n            loop\n              i := i + 1;\n            end loop;\n            n.n := Real'Value (str (j .. i - 1));\n            return n;\n          end Number;\n\n          function Variable_or_function return p_Formula_Rec is\n            n : p_Formula_Rec;\n            j : constant Integer := i;\n          begin\n            loop\n              i := i + 1;\n              exit when not following_character (str (i));\n            end loop;\n            declare\n              chj : constant String := str (j .. i - 1);\n              mch : constant String := To_Upper (chj);\n            begin\n              if str (i) = '(' then\n                for s in Built_in_function loop\n                  if mch = Conv_mstr (s) then  -- Found a built-in function\n                    n := new Formula_Rec (s);\n                    exit;\n                  end if;\n                end loop;\n                i := i + 1;\n                if n = null then\n                  Raise_Exception (Parse_Error'Identity, \"User functions not yet supported\");\n                else\n                  n.left := Expression;\n                  if n.s in Binary then  --  Function with two arguments: read 2nd argument\n                    Check (',', str (i));\n                    i := i + 1;\n                    n.right := Expression;\n                  end if;\n                  Check_brackets ('(', str (i));\n                  i := i + 1;\n                end if;\n              elsif mch = \"PI\" then\n                n := new Formula_Rec (pi);\n              else\n                n := new Formula_Rec (var);\n                n.v := To_Unbounded_String (chj);\n              end if;\n            end;\n            return n;\n          end Variable_or_function;\n\n          --  Factor\n          n, n1 : p_Formula_Rec;\n          c     : Character := str (i);\n        begin\n          n := null;\n          if digit (c) then\n            n := Number;\n          elsif letters (c) then\n            n := Variable_or_function;\n          elsif c = minus_char or c = plus_char then\n            n := new Formula_Rec (conv_symb_una (c));\n            i := i + 1;\n            n.left := Factor;\n          end if;\n          c := str (i);\n          case c is\n            when '^' =>\n              --  NB: right-associative in this parser.\n              --     x^y^z means x^(y^z) like in R and unlike\n              --     in Excel where x^y^z means (x^y)^z.\n              --     Ada asks for parenthesization.\n              n1 := n;\n              n := new Formula_Rec (puiss);\n              i := i + 1;\n              n.left := n1;\n              n.right := Factor;\n            when '(' | '[' | '{' =>\n              if n = null then\n                n := new Formula_Rec (conv_symb (c));\n                i := i + 1;\n                n.left := Expression;\n                Check_brackets (c, str (i));\n                i := i + 1;\n              end if;\n            when others =>\n              null;  -- [P2Ada]: no otherwise / else in Pascal\n          end case;\n          if n = null then\n            Raise_Exception (Parse_Error'Identity, \"Unexpected end in factor\");\n          end if;\n          return n;\n        end Factor;\n\n        --  Term\n        n, left_factor : p_Formula_Rec;\n        c : Character;\n      begin\n        left_factor := Factor;\n        c := str (i);\n        if c = times_char or c = '/' then\n          i := i + 1;\n          n := new Formula_Rec (conv_symb (c));\n          n.left := left_factor;\n          n.right := Term;\n          return n;\n        else\n          return left_factor;\n        end if;\n      end Term;\n\n      --  Expression\n      n, left_term : p_Formula_Rec;\n      c : Character;\n    begin\n      left_term := Term;\n      c := str (i);\n      if c = plus_char or c = minus_char then\n        i := i + 1;\n        n := new Formula_Rec (conv_symb (c));\n        n.left  := left_term;\n        n.right := Expression;\n        return n;\n      else\n        return left_term;\n      end if;\n    end Expression;\n\n    generic\n      oper : S_Form;  --  - or / : these operators are left-associative only !\n      ivrs : S_Form;  --  + or *\n    procedure Left_Assoc (n : in out p_Formula_Rec);\n\n    procedure Left_Assoc (n : in out p_Formula_Rec) is\n      left_part : p_Formula_Rec;\n    begin\n      if n = null then  --  Should not happen, but who knows...\n        return;\n      end if;\n      --\n      --  Recursion\n      --\n      case n.s is\n        when Leaf =>\n          null;\n        when Unary =>\n          Left_Assoc (n.left);\n        when Binary =>\n          Left_Assoc (n.left);\n          Left_Assoc (n.right);\n      end case;\n      if n.s = oper then\n        if n.right /= null and then (n.right.s = oper or n.right.s = ivrs) then\n          --  This has been parsed as X - {Y + Z} or  X - {Y - Z},\n          --  should be {X - Y} + Z or {X - Y} - Z.\n          left_part := n.right.left;  --  Remember Y\n          n.right.left := n;\n          n := n.right;\n          n.left.right := left_part;\n          --\n          --  Redo on children. See 9-4-3-2 example...\n          --\n          Left_Assoc (n.left);\n          Left_Assoc (n.right);\n        end if;\n      end if;\n    end Left_Assoc;\n\n    procedure Left_Assoc_Plus is new Left_Assoc (plus, moins);  --  !!!\n    procedure Left_Assoc_Minus is new Left_Assoc (moins, plus);\n    procedure Left_Assoc_Divide is new Left_Assoc (sur, fois);\n\n  begin\n    i := 1;\n    Deep_delete (f.root);\n    f.root := Expression;\n    Left_Assoc_Plus (f.root);\n    Left_Assoc_Minus (f.root);\n    Left_Assoc_Divide (f.root);\n    if str (i) /= c_fin then\n      Deep_delete (f.root);\n      Raise_Exception (Parse_Error'Identity, \"Unexpected end in formula (extra symbols)\");\n    end if;\n  exception\n    when E : Parse_Error =>\n      Deep_delete (f.root);\n      Raise_Exception (Parse_Error'Identity, Exception_Message (E));\n  end Parse;\n\n  function Parse (s : String) return Formula is\n    f : Formula;\n  begin\n    Parse (f, s);\n    return f;\n  end Parse;\n\n  procedure Parse (f : out Formula; u : Unbounded_String) is\n  begin\n    Parse (f, To_String (u));\n  end Parse;\n\n  function Parse (u : Unbounded_String) return Formula is\n    f : Formula;\n  begin\n    Parse (f, u);\n    return f;\n  end Parse;\n\n  ---------------------------------- Evaluate ---------------------------------\n\n  function Sign (x : Real) return Real is\n  begin\n    if x < 0.0 then\n      return -1.0;\n    elsif x > 0.0 then\n      return +1.0;\n    else\n      return 0.0;\n    end if;\n  end Sign;\n\n  function Step (x : Real) return Real is\n  begin\n    if x < 0.0 then\n      return 0.0;\n    else\n      return 1.0;\n    end if;\n  end Step;\n\n  function Evaluate (f : p_Formula_Rec) return Real is\n    aux : Real;\n    use REF;\n  begin\n    if f = null then\n      return 0.0;\n    end if;\n    case f.s is\n      when nb =>\n        return f.n;\n      when pi =>\n        return Ada.Numerics.Pi;\n      when var =>\n        return 0.0;  --  Hacked.\n      when moins_una =>\n        return -Evaluate (f.left);\n      when plus_una |\n           par |\n           croch |\n           accol =>\n        return Evaluate (f.left);\n      when plus =>\n        return Plus (Evaluate (f.left), Evaluate (f.right));\n      when moins =>\n        return Minus (Evaluate (f.left), Evaluate (f.right));\n      when fois =>\n        return Times (Evaluate (f.left), Evaluate (f.right));\n      when sur =>\n        aux := Evaluate (f.right);\n        if Almost_zero (aux) then\n          raise Div_By_0;\n        elsif Almost_zero (aux - 1.0) then    --  X/1 -> X\n          return Evaluate (f.left);\n        else\n          return Evaluate (f.left) / aux;\n        end if;\n      when puiss =>\n        aux := Evaluate (f.right);\n        if Almost_zero (aux - Real'Floor (aux)) then\n          return Evaluate (f.left) ** Integer (aux);\n          --  Negative arguments are possible in this case\n        else\n          return Evaluate (f.left) ** aux;\n        end if;\n      when abso =>\n        return abs Evaluate (f.left);\n      when sign =>\n        return Sign (Evaluate (f.left));\n      when step =>\n        return Step (Evaluate (f.left));\n      when round =>\n        return Real'Rounding (Evaluate (f.left));\n      when trunc =>\n        return Real'Truncation (Evaluate (f.left));\n      when floor =>\n        return Real'Floor (Evaluate (f.left));\n      when ceiling =>\n        return Real'Ceiling (Evaluate (f.left));\n      when logn =>\n        return Log (Evaluate (f.left));\n      when expn =>\n        return Exp (Evaluate (f.left));\n      when sqrt =>\n        return Sqrt (Evaluate (f.left));\n      when sinus =>\n        return Sin (Evaluate (f.left));\n      when arcsin =>\n        return Arcsin (Evaluate (f.left));\n      when cosinus =>\n        return Cos (Evaluate (f.left));\n      when arccos =>\n        return Arccos (Evaluate (f.left));\n      when tg =>\n        return Tan (Evaluate (f.left));\n      when arctg =>\n        return Arctan (Evaluate (f.left));\n      when sh =>\n        return Sinh (Evaluate (f.left));\n      when arcsinh =>\n        return Arcsinh (Evaluate (f.left));\n      when ch =>\n        return Cosh (Evaluate (f.left));\n      when arccosh =>\n        return Arccosh (Evaluate (f.left));\n      when th =>\n        return Tanh (Evaluate (f.left));\n      when arctanh =>\n        return Arctanh (Evaluate (f.left));\n      when min =>\n        return Real'Min (Evaluate (f.left), Evaluate (f.right));\n      when max =>\n        return Real'Max (Evaluate (f.left), Evaluate (f.right));\n    end case;\n  end Evaluate;\n\n  function Evaluate (f : Formula) return Real is\n  begin\n    return Evaluate (f.root);\n  end Evaluate;\n\n  ------------------------------- Compare -----------------------------------\n\n  function Equivalent (fa, fb : p_Formula_Rec) return Boolean;\n\n  --  Special cases.\n  --    We check these equivalences because the concerned formula\n  --    parts are unlikely to be changed by the Simplify procedure.\n  --    E.g. we don't want to change x/2 into x*0.5; then, we check\n  --    the equivalence.\n\n  --  X * cst, or cst * X, equivalent to X / (1/cst)\n  function Equivalent_Times_Div (fa, fb : p_Formula_Rec) return Boolean is\n  begin\n    return\n      fa /= null and then fb /= null and then\n      (fa.s = fois and fb.s = sur) and then\n      fb.right /= null and then fb.right.s = nb and then\n      (\n        ( --  check X * cst\n          Equivalent (fa.left, fb.left) and then\n          fa.right /= null and then fa.right.s = nb and then\n          Almost_zero (fa.right.n * fb.right.n - 1.0)\n        )\n        or else\n        ( --  check cst * X\n          Equivalent (fa.right, fb.left) and then\n          fa.left /= null and then fa.left.s = nb and then\n          Almost_zero (fa.left.n * fb.right.n - 1.0)\n        )\n      );\n  end Equivalent_Times_Div;\n\n  --  General case:\n  function Equivalent (fa, fb : p_Formula_Rec) return Boolean is\n    ga, gb : S_Form;\n  begin\n    if fa = null then\n      return fb = null;\n    end if;\n    if fb = null then\n      return False;\n    end if;\n    --  fa and fb are not null, at this point\n    ga := fa.s;\n    gb := fb.s;\n    if ga in Neutral then\n      return Equivalent (fa.left, fb); -- +A, (A), [A], {A}  -> A\n    elsif gb in Neutral then\n      return Equivalent (fa, fb.left); -- +B, (B), [B], {B}  -> B\n    elsif ga = gb then\n      --  Formulas' nodes a and b are of the same kind\n      case ga is\n        when nb =>\n          return Almost_zero (fa.n - fb.n);\n        when pi =>\n          return True;\n        when var =>\n          return fa.v = fb.v;  --  same names\n        when Unary =>\n          return Equivalent (fa.left, fb.left);\n        when Binary =>\n          return\n              (Equivalent (fa.left, fb.left) and then\n               Equivalent (fa.right, fb.right))\n            or else\n              --  Detect that X * Y is equivalent to Y * X\n              (symmetric (ga) and then\n               Equivalent (fa.left, fb.right) and then\n               Equivalent (fa.right, fb.left));\n      end case;\n    else\n      --  Formulas' nodes a and b are not of the same kind, but...\n      return\n        Equivalent_Times_Div (fa, fb) or else\n        Equivalent_Times_Div (fa => fb, fb => fa);\n    end if;\n  end Equivalent;\n\n  function Equivalent (fa, fb : Formula) return Boolean is\n  begin\n    return Equivalent (fa.root, fb.root);\n  end Equivalent;\n\n  function Identical (fa, fb : p_Formula_Rec) return Boolean is\n  begin\n    if fa = null then\n      return fb = null;\n    end if;\n    if fb = null then\n      return False;\n    end if;\n    --  fa and fb are not null, at this point\n    if fa.s /= fb.s then\n      return False;\n    end if;\n    --  Formulas' nodes a and b are of the same kind\n    case fa.s is\n      when nb =>\n        return Almost_zero (fa.n - fb.n);\n      when pi =>\n        return True;\n      when var =>\n        return fa.v = fb.v;  --  same names\n      when Unary =>\n        return Identical (fa.left, fb.left);\n      when Binary =>\n        return Identical (fa.left, fb.left) and then Identical (fa.right, fb.right);\n    end case;\n  end Identical;\n\n  function Identical (fa, fb : Formula) return Boolean is\n  begin\n    return Identical (fa.root, fb.root);\n  end Identical;\n\n  ------------------------------- Simplify ----------------------------------\n\n  function Is_constant (a : p_Formula_Rec; cst : Real) return Boolean is\n  begin\n    return a /= null and then a.s = nb and then a.n = cst;\n  end Is_constant;\n\n  function Is_constant_pair (a : p_Formula_Rec) return Boolean is\n  begin\n    return\n      a.s in Binary and then\n      a.left /= null and then\n      a.right /= null and then\n      a.left.s = nb and then\n      a.right.s = nb;\n  end Is_constant_pair;\n\n  function Build_2X (X : p_Formula_Rec) return p_Formula_Rec is  --  returns 2*X\n    aux : constant p_Formula_Rec := new Formula_Rec (fois);\n  begin\n    aux.left := new Formula_Rec (nb);\n    aux.left.n := 2.0;\n    aux.right := X;\n    return aux;\n  end Build_2X;\n\n  function Build_X_pow_2 (X : p_Formula_Rec) return p_Formula_Rec is  --  returns X^2\n    aux : constant p_Formula_Rec := new Formula_Rec (puiss);\n  begin\n    aux.left := X;\n    aux.right := new Formula_Rec (nb);\n    aux.right.n := 2.0;\n    return aux;\n  end Build_X_pow_2;\n\n  procedure Simplify (f : in out p_Formula_Rec) is\n    aux,\n    nexp : p_Formula_Rec;\n\n    procedure left_replaces_f is\n    begin\n      aux := f.left;\n      f.left := null; --  empeche destruction\n      Deep_delete (f);\n      f := aux;\n    end left_replaces_f;\n\n    procedure right_replaces_f is\n    begin\n      aux := f.right;\n      f.right := null; --  empeche destruction\n      Deep_delete (f);\n      f := aux;\n    end right_replaces_f;\n\n    procedure cst_replaces_f (cst : Real) is\n    begin\n      Deep_delete (f);\n      f := new Formula_Rec (nb);\n      f.n := cst;\n    end cst_replaces_f;\n\n    use REF;\n\n    procedure Simplify_functions is\n      x, y : Real;\n      --  Assumes: f.s in Built_in_function\n    begin\n      if f.left = null then\n        return;\n      end if;\n      if f.s in Binary then\n        if f.right = null then\n          return;\n        end if;\n        if f.right.s = nb then\n          y := f.right.n;\n        end if;\n      end if;\n      --\n      --  Arguments are constants, we can evaluate the function and put the result as constant.\n      --  Actually we could use the \"Evaluate\" function (for operators as well), but we then would\n      --  need a fake payload. We also choose not to simplify cases where evaluation would fail.\n      --\n      if f.left.s = nb then        --  Evaluate \"f(cst)\" into f(cst)\n        x := f.left.n;\n        case Built_in_function (f.s) is\n          when abso =>\n            cst_replaces_f (abs x);\n          when sign =>\n            cst_replaces_f (Sign (x));\n          when step =>\n            cst_replaces_f (Step (x));\n          when round =>\n            cst_replaces_f (Real'Rounding (x));\n          when trunc =>\n            cst_replaces_f (Real'Truncation (x));\n          when floor =>\n            cst_replaces_f (Real'Floor (x));\n          when ceiling =>\n            cst_replaces_f (Real'Ceiling (x));\n          when sinus =>\n            cst_replaces_f (Sin (x));\n          when arcsin =>\n            cst_replaces_f (Arcsin (x));\n          when cosinus =>\n            cst_replaces_f (Cos (x));\n          when arccos =>\n            cst_replaces_f (Arccos (x));\n          when expn =>\n            cst_replaces_f (Exp (x));\n          when logn =>\n            if x > 0.0 then\n              cst_replaces_f (Log (x));\n            end if;\n          when sqrt =>\n            cst_replaces_f (Sqrt (x));\n          when tg =>\n            cst_replaces_f (Tan (x));\n          when arctg =>\n            cst_replaces_f (Arctan (x));\n          when sh =>\n            cst_replaces_f (Sinh (x));\n          when arcsinh =>\n            cst_replaces_f (Arcsinh (x));\n          when ch =>\n            cst_replaces_f (Cosh (x));\n          when arccosh =>\n            cst_replaces_f (Arccosh (x));\n          when th =>\n            cst_replaces_f (Tanh (x));\n          when arctanh =>\n            cst_replaces_f (Arctanh (x));\n          when min =>\n            if f.right.s = nb then\n              cst_replaces_f (Real'Min (x, y));\n            end if;\n          when max =>\n            if f.right.s = nb then\n              cst_replaces_f (Real'Max (x, y));\n            end if;\n        end case;\n      end if;\n      if f.s = cosinus and then f.left /= null and then f.left.s = moins_una then\n        aux := f.left.left;                              --  Cos(-X)  ->  Cos(X)\n        Dispose (f.left);\n        f.left := aux;\n      end if;\n    end Simplify_functions;\n\n  begin\n    if f = null then\n      return;\n    end if;\n    --  Simplify arguments first, before the formula itself\n    case f.s is\n      when Unary =>\n        Simplify (f.left);\n      when Binary =>\n        Simplify (f.left);\n        Simplify (f.right);\n      when others =>\n        null;\n    end case;\n    if f = null or else\n      (f.s in Unary and then f.left = null) or else\n      (f.s in Binary and then (f.left = null or else f.right = null))\n    then\n      return;\n    end if;\n\n    case f.s is\n\n      when moins_una =>\n        if f.left.s = moins_una then\n          aux := f.left.left;                           --  --X  ->  X\n          Dispose (f.left);\n          Dispose (f);\n          f := aux;\n        elsif f.left.s = nb then\n          cst_replaces_f (-f.left.n);                   --  -cst  ->  cst\n        end if;\n\n      when plus_una =>\n        left_replaces_f;                                --  +X  ->  X\n\n      when par | croch | accol =>\n        if par_or_terminal (f.left.s) then\n          left_replaces_f;     --  ((...)) -> (...), (c) -> c, (v) -> v\n        end if;\n\n      when plus =>\n        if f.right.s = moins_una then\n          aux := new Formula_Rec (moins);               --  X + -Y  ->  X - Y\n          aux.left := f.left;\n          aux.right := f.right.left;\n          Dispose (f.right);\n          Dispose (f);\n          f := aux;\n        elsif Equivalent (f.left, f.right) then\n          aux := Build_2X (f.left);                     --  X + X  ->  2*X\n          Deep_delete (f.right);\n          Dispose (f);\n          f := aux;\n        elsif f.right.s = plus and then Equivalent (f.left, f.right.left) then\n          f.left := Build_2X (f.left);                  --  X + {X + Y}  ->  2*X + Y\n          Deep_delete (f.right.left);   -- destroy 2nd occurence of X\n          aux := f.right.right;         -- keep Y\n          Dispose (f.right);\n          f.right := aux;\n        elsif f.right.s = plus and then Equivalent (f.left, f.right.right) then\n          f.left := Build_2X (f.left);                  --  X + {Y + X}  ->  2*X + Y\n          Deep_delete (f.right.right);  -- destroy 2nd occurence of X\n          aux := f.right.left;          -- keep Y\n          Dispose (f.right);\n          f.right := aux;\n        elsif f.left.s = nb and then f.right.s = plus and then f.right.left.s = nb then\n          aux := f.right.right;                         --  cst + {cst + X} -> cst + X\n          f.left.n := f.left.n + f.right.left.n;\n          Dispose (f.right);\n          f.right := aux;\n        elsif f.right.s = nb and then f.right.n < 0.0 then\n          aux := new Formula_Rec (moins);               --  X + neg_cst  ->  X - {abs neg_cst}\n          aux.left := f.left;\n          aux.right := f.right;\n          aux.right.n := abs aux.right.n;\n          Dispose (f);\n          f := aux;\n        elsif Is_constant_pair (f) then\n          cst_replaces_f (f.left.n + f.right.n);      --  cst + cst  ->  cst\n        elsif Is_constant (f.left, 0.0) then\n          right_replaces_f;                             --  0 + X  ->  X\n        elsif Is_constant (f.right, 0.0) then\n          left_replaces_f;                              --  X + 0  ->  X\n        end if;\n\n      when moins =>\n        if f.right.s = moins_una then\n          aux := new Formula_Rec (plus);                --  X - -Y  ->  X + Y\n          aux.left := f.left;\n          aux.right := f.right.left;\n          Dispose (f.right);\n          Dispose (f);\n          f := aux;\n        elsif Equivalent (f.left, f.right) then\n          cst_replaces_f (0.0);                         --  X - X   ->    0\n        elsif f.right.s = nb and then f.right.n < 0.0 then\n          aux := new Formula_Rec (plus);                --  X - neg_cst  ->  X + {abs neg_cst}\n          aux.left := f.left;\n          aux.right := f.right;\n          aux.right.n := abs aux.right.n;\n          Dispose (f);\n          f := aux;\n        elsif Is_constant_pair (f) then\n          cst_replaces_f (f.left.n - f.right.n);      --  cst - cst  ->  cst\n        elsif Is_constant (f.left, 0.0) then\n          aux := new Formula_Rec (moins_una);           --  0 - X   ->   -X\n          aux.left := f.right;\n          Deep_delete (f.left);\n          Dispose (f);\n          f := aux;\n        elsif Is_constant (f.right, 0.0) then\n          left_replaces_f;                              --  X - 0   ->   X\n        end if;\n\n      when fois =>\n        if Equivalent (f.left, f.right) then            --  X*X -> X^2\n          aux := Build_X_pow_2 (f.left);\n          Deep_delete (f.right);        -- destroy 2nd occurence of X\n          Dispose (f);\n          f := aux;\n        elsif f.right.s = fois and then Equivalent (f.left, f.right.left) then\n          f.left := Build_X_pow_2 (f.left);              --  X * {X * Y}  ->  X^2 * Y\n          Deep_delete (f.right.left);   -- destroy 2nd occurence of X\n          aux := f.right.right;         -- keep Y\n          Dispose (f.right);\n          f.right := aux;\n        elsif f.right.s = fois and then Equivalent (f.left, f.right.right) then\n          f.left := Build_X_pow_2 (f.left);              --  X * {Y * X}  ->  X^2 * Y\n          Deep_delete (f.right.right);  -- destroy 2nd occurence of X\n          aux := f.right.left;          -- keep Y\n          Dispose (f.right);\n          f.right := aux;\n        elsif Is_constant_pair (f) then\n          cst_replaces_f (f.left.n * f.right.n);       --  cst*cst  ->  cst\n        elsif f.left.s  = puiss and then\n              f.right.s = puiss and then\n          Equivalent (f.left.left, f.right.left)\n        then\n          aux := new Formula_Rec (par);                  --  X^m * X^n   ->   X^(m+n)\n          aux.left := new Formula_Rec (plus);\n          aux.left.left := f.left.right;\n          aux.left.right := f.right.right;        --  aux= \"(m+n)\"\n          nexp := new Formula_Rec (puiss);\n          nexp.left := f.left.left;\n          nexp.right := aux;                 --  nexp= \"X^(m+n)\"\n          Deep_delete (f.right.left);\n          Dispose (f.left);\n          Dispose (f.right);\n          Dispose (f);                --  dissoudre ancienne expr\n          f := nexp;\n        elsif f.right.s = puiss and then Equivalent (f.left, f.right.left) then\n          aux := f.right;                                --  X * X^n   ->   X^(n+1)\n          Deep_delete (f.left);\n          Dispose (f);\n          f := aux;            --  got rid of *\n          aux := new Formula_Rec (par);\n          aux.left := new Formula_Rec (plus);\n          aux.left.left := f.right;\n          aux.left.right := new Formula_Rec (nb);\n          aux.left.right.n := 1.0;     --  (n+1) prepared\n          f.right := aux;\n        elsif f.left.s = puiss and then Equivalent (f.left.left, f.right) then\n          aux := f.left;                                --  X^n * X   ->   X^(n+1)\n          Deep_delete (f.right);\n          Dispose (f);\n          f := aux;            --  got rid of *\n          aux := new Formula_Rec (par);\n          aux.left := new Formula_Rec (plus);\n          aux.left.left := f.right;\n          aux.left.right := new Formula_Rec (nb);\n          aux.left.right.n := 1.0;     --  (n+1) prepared\n          f.right := aux;\n        elsif Is_constant (f.left, 0.0) or else Is_constant (f.right, 0.0) then\n          cst_replaces_f (0.0);                         --  0*X or X*0  ->  0\n        elsif Is_constant (f.left, 1.0) then\n          right_replaces_f;                             --  1*X  ->  X\n        elsif Is_constant (f.right, 1.0) then\n          left_replaces_f;                              --  X*1  ->  X\n        end if;\n\n      when sur =>\n        if Is_constant (f.right, 1.0) then\n          left_replaces_f;                              --  X/1  ->  X\n        elsif Equivalent (f.left, f.right) then\n          cst_replaces_f (1.0);                         --  X/X  ->  1\n        elsif Is_constant_pair (f) and then not Almost_zero (f.right.n) then\n          cst_replaces_f (f.left.n / f.right.n);      --  cst/cst -> cst\n        end if;\n\n      when puiss =>\n        if Is_constant (f.right, 0.0) then\n          cst_replaces_f (1.0);                         --  X^0  ->  1\n        elsif Is_constant (f.right, 1.0) then\n          left_replaces_f;                              --  X^1  ->  X\n        elsif f.left.s = nb and f.right.s = nb then     --  cst^cst  ->  cst\n          cst_replaces_f (Exp (Log (f.left.n) * f.right.n));\n        end if;\n\n      when Built_in_function =>\n        Simplify_functions;\n\n      when pi =>\n        cst_replaces_f (Ada.Numerics.Pi);\n\n      when nb | var =>\n        null;\n    end case;\n  end Simplify;\n\n  procedure Simplify (f : in out Formula) is\n  begin\n    Simplify (f.root);\n  end Simplify;\n\n  procedure Enumerate_custom (f : Formula; lp : List_proc) is\n    procedure EC (f : p_Formula_Rec) is\n    begin\n      if f /= null then\n        case f.s is\n          when var =>\n            lp (To_String (f.v), 0);\n          when Unary =>\n            EC (f.left);\n          when Binary =>\n            EC (f.left);\n            EC (f.right);\n          when others =>\n            null;\n        end case;\n      end if;\n    end EC;\n    --\n  begin\n    if lp /= null then\n      EC (f.root);\n    end if;\n  end Enumerate_custom;\n\n  overriding procedure Adjust (f : in out Formula) is\n  begin\n    f.root := Deep_copy (f.root);\n  end Adjust;\n\n  overriding procedure Finalize (f : in out Formula) is\n  begin\n    Deep_delete (f.root);\n  end Finalize;\n\nend AoC_2020_18_Weird_Formulas;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_18_weird_formulas.ads",
    "content": "--  Variant of the Formulas package (see the open-source MathPaqs project),\n--  with \"alternative\" arithmetics...\n\nwith Ada.Finalization;\nwith Ada.Strings.Unbounded;             use Ada.Strings.Unbounded;\nwith Ada.Text_IO;\n\ngeneric\n\n  type Real is digits <>;\n\n  with function Plus (a, b : Real) return Real;\n  with function Minus (a, b : Real) return Real;\n  with function Times (a, b : Real) return Real;\n\n  plus_char  : Character;\n  minus_char : Character;\n  times_char : Character;\n\npackage AoC_2020_18_Weird_Formulas is\n\n  type Formula is tagged private;\n\n  ---------------------------------------------------\n  --  The parsing of the formula is done once      --\n  --  The evaluation is quick and done many times  --\n  ---------------------------------------------------\n\n  procedure Parse (f : out Formula; s : String);\n  function Parse (s : String) return Formula;  --  NB: a bit slower than the procedure\n  procedure Parse (f : out Formula; u : Unbounded_String);\n  function Parse (u : Unbounded_String) return Formula;  --  NB: a bit slower than the procedure\n\n  function Evaluate (f : Formula) return Real;\n\n  Parse_Error, Div_By_0 : exception;\n\n  -----------------------------------\n  --  Comparison / simplification  --\n  -----------------------------------\n\n  function Equivalent (fa, fb : Formula) return Boolean;\n  --  Strict form of formula equivalence:\n  function Identical (fa, fb : Formula) return Boolean;\n  procedure Simplify (f : in out Formula);\n\n  --  Deep_copy and Deep_delete are no more needed and\n  --  were removed, it is done now automatically.\n\n  ----------------------------------------------------------------\n  --  Display. Caution: the displayed constants may be rounded  --\n  ----------------------------------------------------------------\n\n  type Output_style is (\n    normal,     --  Normal is infix, should be the closest to the parsed formula\n    bracketed   --  Like normal, but displays a {} around every parse tree node\n  );\n\n  procedure Put (f : Formula; style : Output_style := normal);\n  procedure Put (t : in Ada.Text_IO.File_Type; f : Formula; style : Output_style := normal);\n  function Image (f : Formula; style : Output_style := normal) return String;\n\n  -----------------\n  --  Utilities  --\n  -----------------\n\n  type List_proc is access procedure (name : String; parameters : Natural);\n\n  procedure Enumerate_custom (f : Formula; lp : List_proc);\n  --  This will find all custom variables or functions appearing\n  --  in a formula and list it through List_proc.\n  --  A name will be listed as many times as it appears in the formula.\n\n  ---------------------------------------------------\n  --  Character set used for defining identifiers  --\n  ---------------------------------------------------\n\n  type Character_Set is array (Character) of Boolean;\n\n  --  Custom variables or functions always begin with a letter:\n  letters  : constant Character_Set :=\n    ('a' .. 'z' | 'A' .. 'Z' => True, others => False);\n\n  --  Set of following characters in custom variables or functions names is defined here:\n  following_character  : constant Character_Set :=\n    ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '$' | '.' => True, others => False);\n\nprivate\n\n  type S_Form is\n                (                                    --  0 argument (leaf, terminal nodes):\n                 nb, pi, var,\n                 --                                      1 argument:\n                 moins_una, plus_una,\n                 par, croch, accol,\n                 --  vvv begin of built-in functions\n                 abso, sign, step,\n                 round, trunc, floor, ceiling,\n                 expn, logn,\n                 sqrt,\n                 sinus, arcsin, cosinus, arccos, tg, arctg,\n                 sh, arcsinh, ch, arccosh, th, arctanh,\n                 --                                      2 arguments:\n                 min, max,\n                 --  ^^^ end of built-in functions\n                 moins, plus, sur, fois, puiss);\n\n  subtype Unary is S_Form range moins_una .. arctanh;\n  subtype Binary is S_Form range min .. puiss;\n\n  type Formula_Rec (s :  S_Form);\n  type p_Formula_Rec is access Formula_Rec;\n\n  type Formula_Rec (s :  S_Form) is record\n    case s is\n      when nb  =>  n : Real;\n      when pi  =>  null;\n      when var =>  v : Unbounded_String;\n      when Unary | Binary => left, right : p_Formula_Rec;\n    end case;\n  end record;\n\n  type Formula is new Ada.Finalization.Controlled with record\n    root : p_Formula_Rec := null;\n  end record;\n\n  overriding procedure Adjust (f : in out Formula);\n  overriding procedure Finalize (f : in out Formula);\n\nend AoC_2020_18_Weird_Formulas;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_19.txt",
    "content": "108: 117 50 | 63 64\n124: 50 64 | 64 64\n123: 64 119 | 50 85\n45: 60 64\n32: 20 50 | 79 64\n36: 97 64 | 70 50\n97: 50 64 | 64 50\n21: 50 104 | 64 83\n59: 50 124 | 64 83\n10: 115 64 | 34 50\n118: 50 124 | 64 4\n60: 12 50 | 4 64\n84: 29 64 | 99 50\n111: 64 27 | 50 14\n18: 64 101 | 50 29\n13: 64 45 | 50 1\n62: 64 97 | 50 83\n117: 124 64 | 70 50\n98: 50 4 | 64 124\n15: 64 114 | 50 12\n7: 100 64 | 56 50\n78: 99 50 | 52 64\n82: 114 64 | 97 50\n22: 6 64 | 4 50\n63: 12 50 | 114 64\n16: 64 52 | 50 70\n76: 50 46 | 64 13\n31: 64 69 | 50 67\n37: 21 50 | 128 64\n95: 68 64 | 16 50\n12: 64 50 | 50 30\n26: 50 12 | 64 83\n112: 113 50 | 72 64\n33: 104 64 | 52 50\n25: 70 64 | 114 50\n96: 51 64 | 105 50\n51: 50 47 | 64 26\n91: 103 50 | 9 64\n65: 66 64 | 23 50\n116: 64 114 | 50 97\n42: 64 54 | 50 40\n4: 50 64\n79: 50 97 | 64 29\n110: 64 116 | 50 118\n0: 8 11\n73: 50 12 | 64 101\n70: 50 50 | 64 50\n74: 61 50 | 65 64\n27: 50 107 | 64 90\n101: 30 30\n105: 17 50 | 24 64\n61: 58 64 | 102 50\n17: 50 83 | 64 29\n72: 30 97\n88: 64 38 | 50 2\n14: 50 36 | 64 2\n125: 64 50 | 64 64\n127: 95 64 | 28 50\n83: 64 64\n80: 64 107 | 50 81\n106: 50 101 | 64 29\n56: 88 64 | 49 50\n52: 50 50 | 64 64\n46: 80 50 | 120 64\n94: 68 64 | 33 50\n47: 50 114 | 64 6\n69: 44 64 | 57 50\n54: 74 64 | 3 50\n89: 50 83\n48: 106 64 | 59 50\n87: 86 50 | 37 64\n35: 64 73 | 50 55\n115: 50 99 | 64 70\n44: 111 50 | 109 64\n75: 78 50 | 22 64\n20: 64 101 | 50 6\n41: 50 4 | 64 101\n6: 64 50\n66: 50 93 | 64 115\n90: 64 101 | 50 124\n23: 50 82 | 64 77\n81: 50 114 | 64 101\n30: 50 | 64\n100: 122 50 | 75 64\n86: 50 73 | 64 18\n92: 64 48 | 50 71\n68: 6 50 | 114 64\n121: 50 70\n8: 42\n85: 64 112 | 50 110\n38: 64 104 | 50 4\n120: 84 50 | 55 64\n67: 64 7 | 50 53\n64: \"a\"\n55: 50 52 | 64 125\n28: 89 50 | 84 64\n71: 50 39 | 64 16\n109: 43 64 | 94 50\n99: 50 50\n43: 41 64 | 77 50\n119: 64 108 | 50 35\n57: 87 50 | 96 64\n39: 64 97 | 50 6\n104: 50 64 | 64 30\n29: 50 64 | 50 50\n34: 83 50 | 125 64\n2: 99 64 | 124 50\n11: 42 31\n114: 64 64 | 30 50\n93: 50 97 | 64 101\n58: 50 33 | 64 121\n113: 64 99 | 50 70\n128: 64 4 | 50 125\n40: 123 64 | 76 50\n107: 50 52 | 64 83\n102: 126 50 | 25 64\n126: 50 125 | 64 97\n19: 50 124 | 64 114\n24: 114 64 | 29 50\n49: 20 30\n1: 64 19 | 50 15\n103: 26 50 | 18 64\n9: 64 117 | 50 62\n50: \"b\"\n53: 91 64 | 5 50\n77: 6 64 | 99 50\n5: 32 64 | 10 50\n3: 64 92 | 50 127\n122: 115 64 | 98 50\n\nbbabbaaabbabbaaaabbbbbbb\nbbaabaaaaabbbaaaabaaabba\nbaabababbbbaaaaabbabaaba\nbaaabbbabaabbaaababaabbaaaaabbbb\nbbbbaabbbabaabbabaabaaaa\naabaaaabaababbbbababaabb\nbbabbbaaabbbbabbbbabbabbbbbbbbabaabaaaabaabaabbabbabbbbbaabaaaba\nbaaaaaaabaabbbaaaaaababb\naaabbabaaabbabbbabaaabba\nabbbbbabbababaabbaaabbbaababbbbaababbabb\nbababbaabbbbbbaababaaabaaabababbabababba\nbabbaabbbabaabbbbbaaabba\nabbbbbabbbbaababbababaaa\naaabaaababbaaabbbbbabbaaaabbbbba\nbbaabaaaabbbaaaabbabbbab\nbaabaabababbaaababbababa\nabbbbbabababaaabbbbbbbba\naababbbababbababaaababababbbbbbabaaabaaa\nbbbbabaabbabaabbbbabbbaa\naabaabbbbbbababbbabbbaba\nabbababaabbbaabbbabaaaababbbaabababbaaaaababbaabbbaabbabbbabaaabbaabaabbbbaaabaa\nbaababaaabababaabaaabbabbbaaaabbabbabaab\nbbbaaaaabaababaaaaabbaaabbbababbaaabaaba\nbbababbabbbbbbabbbbabbbbbaabbbabaabbbbababbabaab\nabbbbbabbbabaabbbabbaabaaababaab\nbbbbabbbbaababaaaaabbbbabbabbbbbbabbbbaaabaabbabaabbabbb\nabbaabbabaaabaaaaabbbbaaaaabbbbb\naabaababababbbabbbabbbaabaaaabaaaaabbbbbaabbbabbaaabbbab\nabaabaaabababbaababbabab\naabaaaabbbaababbbbabaaab\nbbbababbabbbbabaaaabababbbabbbabbbbaaaabaaabbbbbaabababbbbababbbbbabaabb\naabbaababaabaaaaabbbbbabbbaaabaaaabaabab\nbaabbaaaaaaabbabbbababab\nabbbabaabaabbbabbabaaaabaabaaaababaabbbb\naabbbabaaabababaabbababb\nabababbbabaaabbaaaaaaababbabaabbbabbaaaabbbbbaab\nabbabbaabbbaabbbabbaabaa\nbaabababbaabbaaabaaababb\naababaabbbabbababbaabababaaaabbabaabbaab\nbbaaaabbbbbbababaabbbaaaabaabaaabbbbbbba\nabbaabbbbaababaaaabaabaa\naaaaaabbabbaabbbbaabbabb\nbababababababaabaaabbaabbababaababaabaabababbaba\nababbbbabbbbabaaabbbbbba\nbabaaabaaabbababbabbbbaa\nbbabbbbabbbbbbabaaababbbaaabbabbbabbabbababbabbbbaabbbaabbababaa\nbbaabaaaaabbbabaabbabbba\nbabababababbaabaaabbbbbb\nbaabbbabaabaabbabaabbbbb\nbabbbbababbaaabbbaaabbaabababbaabababaabbbbbaaabaaaaaaaa\naabbbabbababbbbaaaaaabaa\nbbbababbababbbbabbaaabba\naabbabbaababaabbbbaababa\nabbabaaabbbaaaaabbbababaaabbababbabbbaab\nbabaaaaaaababababbbabbbbbbbbbbaa\nabaaababbabbbbbabaabaabb\nbabbbabbabbbbbabababbbbaaababbab\naaabbbbabababaabababbbbaabababab\nbaaabaabbabaaaabbababbaabbbabbbaabbbabbb\nbabaaabbabbabbabbabbbaba\nbbaabbbababbbbabaaaabaaaaabbabababaabaab\nabaaabaaabaabababbaaaabbbabbabab\nbbbaaaababbabbabaaaaabab\nbbbbababbaaabbaaabaabbbb\nabbbbabbbaaaaababbbbbbba\nbababbabaababbbbbababaaa\nbbababbabbbbabbbbbababaabbbbbbbbabbbbabbbbaababa\nbaaaaababaabababaabaaabb\nbaabaababaaabbaaabababab\nbaaaaaaabbbababbbbbaabbbaababaaa\nababaaabbabaabbbabababba\nbaaabbbaabbabaaabbaaaaabaaaabbabbabbbbbbbbbaabaa\nbbbababbabbbaaabaababaab\naaaaaabbaabbbaaabaaaaabb\nbabaaabbbbabbaaabbabbaab\naaabbaabbbababaaabaabaababababab\naaabaabbbabbaaaaababaaabababaabb\nbbaaaabbbaaabbbaaababaaa\nbbabbbbabbbaababbabbabba\nbaabababaaababaababaaaaaaababbab\nbaabbaaaaaabaaabbbbbaaaa\nbabbaaababaabaaaaaaabbbb\nbabaaaaaaaaabbabaabbababaabbabbaababaaabbbaabbaaaaabbbbb\nabababaabbabaabbbaabbaaabbaaaaaa\nbbbbbbaaaaabbabbbabbaaaabaabbbaababbbbbbbaabbbbaabbbababaabbaaababaababbabbbbaaaaabaaaaaaabaabab\nbbababaabbbbaabbbbaabbbbbbbbbbbabbbaabbabbbbbabbabaaabaaaaabaaaa\nabbbaabbbbbaabbbbabaabaabababbbbabaabbab\nbabaababaaababaabbaabbbbaaabaaabaaababbbabbbaaaabbabbbbbbbaababaabaabbbbbbbbbaaaaaababaa\nbabaabaababaabaabbaabbbb\nbbbbbaaabbababaaabaabbaaaaaaabbbabbabaabbaaaabba\nbabbbbbbaaabbbabbbbabaaa\nabaabaaababbbbabaababbab\nbbaaabaabaaaaaaaaaabbbabaabbbbbb\naaabbbabaaaaaabbaabbaabbbaabaabaaabbababaaabaaababbbabab\naaabbaabaabbabaabbbbabbabaaabaabbaabbabb\nbabababaabaabaaababbaaba\nbabbbbbbabababaabaabbaba\nbaabbbabbbaaaaabababbaabaabbbbaaababaabaabbaabaaaaaabbaabbaaabba\nabbbabaaabbbaabbbbaaabba\nbaabbbabaabbbbaaaabbbbbb\nbababbabaaaabaaaaabbbbaaababaaaaaaababbaaaabbbbbabaabbab\nabbaabbbbbabbbbbaabbbaab\nababbbabababbbaaaabbbabbbbaabaabbbbaaabbbaababbaaaaabbbbbaabbabb\naaababaaabbaabbbabbbbaaa\nbbbababbbabbbaaaaabbbbaabaaabbaabbabababaaaaabaa\nbabaabaaabbaabbbbbbbabaaabbaaabbbaababbaabbbbbbbbaabaaaa\nbababaabaabaaaabbaaaabba\nbaabbbbabaabababbaaabbabbbaabbbaabbbbabaababaaaaababbabaaabaabaaaaaababb\naabbbabbbbabbaaaaaaaabba\nbbbaaabbaabbababbaabaaaa\nabbbbbababbaabbbbaaabaaabbbbbabbbaaababaaabbaaababaabaaabbbabbaabbbbbbababaababb\nbabbbbbbababbbaabbabbbab\nabbaabbaaababbbabbaababa\naaabbbabbabaabaaabbaabbbabbaabbbaaaaaaaa\nabbbbabbbbbbabababbaabab\nbbbbababaaabababbbbbbbba\nbbbabaabababbbabbaaaabbbbababbabbabababa\naababababbbababbbbaabaaaababbababbbbaaaaabbbbabaabaababbabbbaaabbabbaaaabbbbababbabaabab\naabbaaabababbbaaabbaabaabababaaaaaaabababbabaaab\nbbaaaaabbabbbbbabbabbbab\nbabbaababbbbabbbbbabaaab\naabababaaabbababbbbbaaba\nbabbaaaabbbaabbbbbbbabaaabbbbbba\nbbaabaabbbabbbbaabaaababbaabababaabaaaaa\nabaaababbababbaaabbbbbbb\nbbaaaabbabbabaaaababbabb\naaabababaababababaaabbbb\nababbaaaabbbaabbbaabababbaaabbababbabbbabbaaabbb\naababbbaabababbabbabbbabbbaabababbbaababbabaabbabaababaa\nbaaabbbababbbabbbbaabaababbbbabbbabababbaabbbbba\naabababbaababbbbabbbaaaababbbbabbbbaaabbbabbbabaabaababb\nbaaabbabababbaaabaaaabab\naababbbaaabaabbaababbabb\naaabbaaaaababbbbbaabbbbbbaaaabaa\nbbbbbaaababaabaaabbaabbbbbabbbabaaaaabab\naababbbbaabaabbabbabbaab\nbbbaaaabaaaabaababbbbbbb\nabbabaaaaaaabaaababaaabaaaababbbabaaabbb\nabbbaaabbabababaabbbbbaa\nbaababaaaaababababababaabaaabbbaabaabaaa\nbbbbbbbbababbbbabbabbaab\nababbaabaabaabbbabbbbbbb\nbabaaababaabbaaaabbabbaaababbababbabbbaaababbbabbbabbbabbabbbabb\nbabaabbabbbaaababbaaaaaa\nbababbbaabababaabababaabaaaaaabbbbbababa\nbbbbaabbababaababaaaaaab\nababbabbbabbbbaabaabbbbb\naabababbabababbaababaabbbbbaabaaabbbbbababbbbbabbbbbabbbbababbabbaababaa\nababbbababbabbaabaaaaabb\nbabaabbbbabbabbbaaabbaabbaabbbababbbabba\nabbbaaabbaababaabbabaaba\nbbbabaabbabaabbbaabaabab\nababbaaaaabaaaabbbaaabab\nbaababababbabbaabbababab\nabbbbbabbbbbaabbaaaaaaab\nbaaaabbbaababaaaaabaaabbababbababaaaaabbbaaaabaa\nbbbaaabbabbbaaaababaaaaa\nbbbbaabbbbabbaaabbaaaaba\naaaabbabaaabbabbaaaabbba\nabaabaaabbbaaaababbaaabaabbbaaabbbababaaaabbaabbabbabaababbabbbb\naaabaabbbbaabaababbbaaababbbaaba\nbaaabbbbbabbababbabaabab\nbabbbabbabbabaaaaaaaaabbbbaaaaaa\nababbaaaabaababaaaabbbbb\nbbbaaabbbaabaababaaabbaabbbbbbaaabbbbbaa\nababaaaabbbbbbbbabaabbaa\nbababaababbbabaaaabbabaa\nbabbabaababbaaabbabbbbaababaababbbbaaaaaaaabaabaaaaaababbbabbbbaaaabbbaa\nbaaabaaaabbbabbabaababbb\nbabaaaaabababababaabbaabbaabbbbabbabbabbbbaaaabababbabbbaabbbaaa\nbaabaababbaabbbaaababbab\naabaabababaabbbabbbabaaaabaaabaababbabbbaaabbbbbbaabbbaabaaabbbbaababbbbaabbaabb\naabbbabbbbaabaaabbbbbabb\naaabbaabaabbabbabaaaabba\nbaaabbbaaaabbaaababbabba\nabaabbbababbbbababbaaaaa\nbbaaabaaabbbbababbbaababbbbbbaaaabbaababaaabbbbb\nababaaaabbbbbaabbababaabbbabbaaabbbbaaba\naabbabaaaabbbabbbaabbbbaababaababbbabbbbabaaabaabbaaaabbaabaaaaa\nbbbabbababbaaabbbaabbaaabaabbbaaaabbbbaabbababaaaabababb\nbabaaababbbbbaaaaabaaabb\nabbbabbabbbbaabbbbabbbaa\nbbbbabbbababbaabbbabaaaa\nabbbaabbbbbbbaaaabbababa\nbababaabbbbbbbbbaaaaabbb\nbabaaaababaabababbaabbaa\nabbbaabbabaababaabaaabaaabbbabaabbaababa\nbababbababbabbaabbaaaaaa\nbabbaaaababbaaabbbabaaaa\nbbbbbaaaaabbababaaaaabaa\nabaababaabaaabaaabaababb\nbaabbbbababbaabbbbbbbaba\nbbabbbbbbbaaaaabbbaaaaabbaabbbaabbbbaaabaaaabbaa\naaabbbaaaaaaabbbaaabaabbaaaaaaaabbbaaabbbbbbbaba\naabbbababbababbaaaaaabbb\nbbaabaaaabbaaabbabbabbababaaabbabbaaabba\nbabbaabbabbbbabbbabbbaaabbbaabbbbabbbaababaabbabbabbbbaa\nbbbaabbbaababababaaaaaab\nbbaaabaababaaabbaabbabbb\naaabaabbbbabbbbbababaabb\nbabaabbbbbbaababaabbbabbabbbabaabbabbaaababbabba\nbabbbbbabaaabbbaaaaaabab\naaabbbbabbababaaababbbbb\nabbbaaaabaaaaababbabbaba\nbaabaaabbbbabbbbaabbbbaababaaabbabaaabba\nababaababaababaaaaabbbaa\nbaaabbabaaabbaabbbbbabaaaaaabbaaaaaabaaabaabaabaabaaabbaaabbababaaabbababbaaaaba\nbaabaabaaaaaaabbabbabaaabbabaabbbbabbbbabbabbaabbbabbbabbaabaabb\naabbbaaabbbabbbbbbbbbbba\naaabaabbaababbbabbabaaaa\naaabbabbabbbbbbaaabbbbbbabbbbaaa\naabbbbaaaabababaaababbbaaaabaaaa\nbbaabaabbbbbbabababaababbbbbabaabbbbabaaabbabaab\naaabaabbaabbabbabaaaaaab\nbaaaaabaababbbabbbbaaaaa\nababbaabaaabaabbabaaaaba\nbaabaabaabababaababaaabbbbabbabb\nbaabbbabbbababbaaababaaa\naabaaaabaabaaaabbabababb\nbabbaababaabaaabaaaabbba\nabbaabbbaabbbaaabaaababa\naabbbabbaababbbbbbaababbbbbbbbaaabaaaabb\nbabbabbaababababbaaaabbbbaaaaaabbaaabbbbababbbabaabababa\nbaabaaabbababbabbbaababa\nbabbbabbbbabbbbbabbababa\naabbababbbbbbbbbabbaabab\nbbbbbaabaabbabbaabaaaabb\nbabbbbbbbabaaaabaabbbabbbabaabbbbbababaabbbbaabbabaaabbb\nbbabbbbaaaababbabaaaaaab\nabaaaabababaabbaababaabb\naaabbbabababbaaaaabaabbaababbbaabaaabbab\naaaabbabbababbbabaabbaab\nbbaaaaabbbaabaababbabbba\nbaaabaaabaabbbbaaabaaabb\naababbbbbbbababbbaaabbbbbbaaabba\naaaabaaabbbbbbbaabaabbab\naabaabbabbbaabbbaabbabbababaabbababbaaabaabaabaaabaaabba\nbaababaabababababbbbbaba\nbbaabaaabaaabbababbababa\nabbbaaaaaaababaabaaabbaabaaabbaaaabbaaba\nabbabbabbbbaaabaabaababb\nbabbabbbaabbbaaaaaaababb\nbbbabababbaabaabaaabaaaa\nbbbabaaabaababbabbaaabbaabaabbaa\nbaaaaababbbbbaabbbabbabb\nbaabababbaaabbbabababbaaababbabbabbbbbbb\nabbbaabbabaaaaaaabaaaaaaaaabbbbababbaaaaababbababaabbbbbbabbbaababbbbaaa\naaabbabbbaaaaaaabababaababaaaaab\nbabaaaaaaabbbababbbbabbbabbaabbbaaabbaaaaaaaaaab\naabbbabbbababbaabbbababaabbaabbabaaaaabb\nbabbaaabbaabbbaabaabbabb\nabbaabbaaabababbababbaba\nabbbbbabbbbbbbbbbaabbabb\nbbbaabbbbabaabaababaababbabbbabaaabaaabb\nbaabbbbabbbbbbbbbbbbaabbababbabb\naaabbbbaabbabbaaaaaababa\naabaabbabbbaaabababbbbbaaaaaaababaabbaba\nabbabbabbaabbbabaaaabbaabaabbabbababbbbbbbaaaaaaaaaababbbbbaaabaaabaaaaabaaaabaa\naaababaaaabbababbaabbbaabaababaaaabaaabaaaaabbaa\nbaabaaabaaaaaaaaaabaaabbbbbbaaab\nabaaabaaaaaaaabbbbaaaaba\nbabbaaabbbaaabaababbbaba\nbabbbbbabbaabaababbababbbabbabbabbbbbaba\naaaaaabbbaaaaaaaabaaaabaabbaabbaabbabbbbbbababbbaaaabbbb\nbbbaababababbaabbbbabaaa\naaaaabbabbaaaaabaaabbaabbbabbabaababaabbababbaaababbabaabbbaaabbabbbbabb\nbabaabaaaabbbaaaaabbaaab\nbbbbabbbbaaabbbabbbaababaaabbaabbabbbaba\naabaabaaabaaaabbabbabababaaabbabbbaaaabbbbbbaaaaababbaabaaabaabaabbababb\nababbaaaababbaabbaaaabbabababaababbaaabb\nabababababbbabbbaabbbaababbabaab\nbabbbbabbbbababbbbbbbbabbbababbb\naababbbbabaaaabaaabaabab\nbbbaaababababbababaababb\nbbbabbbbbabbbabbaabaabab\nbaaababbaaabbbaaabbbabaaabaabaaaaaaabaaaabaababa\nbbbbbbbbbbabbbbbbbbbbbabaaabbbaaabbbbaab\nbabbabbbbbbbabbbbbaaabba\nbabaaababbbbabaaaaabaaabaababababbabaaab\nabaababaababbaaabbabbbbbabbabbab\nbbbabbbbaabaaaabbbabaabbaaababbaaababbbbabaaaabbbbbabbbabaaaabab\nbabbbbbbaaabaabbbbbabbbbbabaabaaabaaabaabaaababa\nabbabbababbbbababbabaaab\nababbaaaabaaabaabbaababb\naabaaaabababaaaabbbbaabbabbbaaaaabbaaaab\nbabaaaaaabbbaaaabababaababbbabbababaabaababbbbaaaabaabab\nabaaaaaababbaabaabbaaaaababbaabbbabbbbbbbaaaabbbabaabbabbbabababaaababba\naabbbabababbaabbababbabb\naaabbaaaabaabbbaababaabb\nbbaabbbabbbbababaaabbbabbbbbabbabaaaaaabaabbbbaaaaabbaabbaaaaaaa\nbabaaaabaaabbabbaaabbaba\naabbbbaabbbabbaabbbbbbba\nbbaaaaaaabaabbaaaabaaaba\nabbbaaabbabbbbbbbbbbabaababaaabbbbaabaaaabbbbbbaabaabbaaabbbababbbbabbba\nabbaabbbaabbabababaaaabaabbababbabbbabbb\nabbaaabbbbaabaaabbbbabbbbabbbbbbbaababbb\nbbabbbbaabbbaaaabbbaababbbababbababbabba\nabaaabaaabaabaaabbabbbaa\naaabbbabbbbbababaaabaaba\naabaabbabbbaaaabbabbabba\nabbaaabbbbaabaabbababaaa\naabbabababbaaaaaaaaaabbbabababaabbbaaabbbbbaaaaa\naaaabbabbaababaabaaabaab\nbababbaaaaabbaaaabbabbbb\nabbaabbbabaaababbbbaababbabbaaaaabbbaaababbaaabaabbbbbba\naabbbabaaaabaaabbaaaabaa\nbababbaabababbaabaabbaba\nbbaabbbbbbbbaaaaabaabbbb\nbbbbbbabbabbbbbaabbbbaaa\nbababbbabaaabaaabbbabaab\nbaaaabaaaabbbbabbabbabbaaaaabbaa\nbbbbbbabbaabbbabaabbbaab\nbaabaabaabbbaabbaababbab\naaabbaaabbbbababaabbababbabaabbaabaabbbabbbabaab\nbaaaaaababbbbbbabbabababbbaaabbbaabaaaababbbabbbaababaabbbaaaaabbaabbbbbabbababb\nabbbabbabbaaabaabaaabaab\nabaabbbabababbabababaabaabbabbabaabbaaaabbbbaaaa\nbbabbabbbbbbaaabaabaababababaabbabababba\nabaabbabbababaaabbabbababbabaaaababaaaaaaaaaabaabbbbaabbbbbbabaaaaaababbbbabaabaaababbba\nbbaabbaabbbbbbabbabaaaabababaabbabbabbabbabaaabb\nabbbaabbbbbaabbaabbbabab\nbbbbbaabaaaabaabbaaababbabaaaabbabababbb\naabbbbbabaabaababaaabbaaaabaabbaabababbbaaabbbbb\naaaabaaabbbabababaaabbaaaabbabababbaababaababbaaabaaabba\nbbbbabaaababbaaabbabaabbbabbaaaaaaaaaaab\nbabbaaaababbbbbabbbabababaabaabb\nbaabababbbbbabbbabbabbba\nbabaabaaaaabbaaaaaaaaaaa\nbbbaaaabbabbaabbbabbbaba\nabbaaabababbbaaabbaababb\naaababaabbabaabbbababaaa\nbaaabbaaababbabbbabaaaaaabaabbbbaaabaabaababbbbbbbaaaabbaabbbaabababbabbababbaaa\nbbaabaabbbbababaaabbaabbaaabababbbbabaaaaaaaaaabbaaaaabbababbbbb\naaababbaabababaabbbaaabbbbabbaab\naabbbabaabbbabaabaabaaaa\nababbaaababbaababbabbaba\nbabbabaabbaaabbbabbbaaaaaabaabababaabaaaabaaabbbabbaabbbbabbabbbabbbaaab\nababbaaaababbaaabbbbaaba\nbababbaabaabaaababbaabab\nbabaabbaaabaabbaabbbbabbaababbbabaaaabaaaababaab\nbabbbaaaabbbbbabaabaaaabbbabaaaa\nabaabaaabababbabbbabaaab\nbabaabbabbbbabaaabaaaabaabbabbabaaaabbab\naaabaabbaabbbababbabbbbbaaabaaaa\nababaababbbaabababbaaaaabababbbbaabbaaba\naabbbabbabbabaaaabaabbab\nbbabbaaabababbaabbababbb\nbaabbababbababbaaaaabbbbaabbbabaabaabbbbbabaabaabbbbbaaa\naababbbabaaaaaabbaaabaab\nbbbbabbbaaaabaaaababaaaabbaaaaaaababbabb\nbaababbbaabaababbbababbbbbbaababbbbbaaabaaabbababbabaaaaababaaabaaaaabbabbbababb\nbaababaabbbabbbbbaaaabab\nabbaaababbbaaabbbabababb\nbbaaaaabbabbaabbababbabb\naabaabbaababaabaaaabbaba\nbbbaababaaabbbbaabbaabbbbaaabababbbbbaba\nbbaabbbabbaabaabaaaaabaa\naabaaaabbaaabbababaabbbabbbaaabbaabaaabaaaaabbba\nbabbaaabbaaabbaabbabbabb\nbbbaababaaabbbabbabaabab\naaababaabbaaabaaaabaabbaabaabbab\naaababbaabaabaabbaaaaabbbbabbaaaaaaabbababbbaaaabaabbaabaabbaabbbbbabbab\naaaaaaaaabbaabaababbbbbababaababbabbaabbababbbabaaaaaabaabbbabab\nbaaaaabbabaaaabbaaababbabaabbaababbbbbabaaababbbbbbbbaaaabaaabababbababbabbabaababababab\nabaaaaabbaabababbabaaaababbbaaaabbaaaaaa\nababaaaabbbbbaaaababaababaabbabbbbaaabab\nbbaaaabbaabbbabbabbaabab\nbaabaabaababaabaaaabaaba\nbaabbbabbbaabbaabbababaabbbaaabbbaaaabaabaabbbbbaabbabaaabbababbbbbbbaabbabbaaabababaabb\naaaabaaaabbaaababbabbaba\naabababbaaabbbababaababb\nababaaabababbbabbbabbbab\nabbbabbaaaababaabaaabbaaababbbbaaabbabbaaaaaabaabaaabbbbbbaaabbaaaaaabba\nbaaaabbbbaabbababbabbbabbabaaaba\nbaabaabaaaaabbabaabaabbbbaaaabbaabaaabbb\nabbaabbbababbaaababaaababbbaaababaaaaaabbbababab\naabbbbaaaaaabaababbaaaababaaabbbaabbbaaaabbbbbababbbaabaaaaabbabaaaaaaaa\nbaaaaaaabababaabababbaba\nbababbbaaabbababbbaaaaba\naaababbaaabbabbaababbbbb\naabababbabbbbabaabbabaaaabaabbbabbababbabababbabaaaaabba\nabbababbbaabaabbbaabbaaaabaaabbaababbbbbbbbbbabbaababbaabaabaababbbabbabaabbabbbbbaaaabbbbbababb\naabbabbaabaababaaaaaabba\naabbababaaababbaabaabbab\nabbbbbaababbaababbababaabbaaaaaabaaabababaaaabbbbbaaabbb\naaaaabbabaababbaaabaabaa\nbabbbaaabaabbbbababaabbaabaaaaabbbabbbaaabbbabbbbabbbbaa\naaaabaabbabaaaababababba\nabbbabbbaaaaabbbbbaabbaa\nbbbaaaabbbaabbbababaaabbbbababaabbaaaaaa\naaaabaabbbbaaaabbbbabbab\naababbbbbaabababbbaaabba\nbaabbbbababbbabbaabbabbabbbababbaaaaabab\nbbabbbbabaabbaaabaabbbbb\nababbaabbbababbabbababab\naaabababbbbababbabaaababbbabaaba\naaabababbaaabbbabbabbabb\nbbbbbbabaabaaaabbbaaabab\nabbabbaabbbabbaaabbaabbbaabaababaababbab\nabbaabbababbaaaaabbaabbaaabaabbaaabbaaba\nababbbabbaababbbbabbbbaaaabbaaabaaaaaaab\nbaabbbbaaaababbbaabbbbbaaabaaaaa\nbbbababababbaabaaaaaabaa\nbaabababbbbaabbababbbbbaaaababbaabaabbbaaabbabaabbaabbbb\naabbbaaabbbbbaabaaabbaba\nbabbbabbaabbaabbbaabbaab\nbbbabaabbbbaabbaaaabbabbaaabababbbabbaaaabbbaabbbaaabaaababababb\nbbbaaaabbbabbbbabbbabbba\naabbbabababaaaaabbbabbaaaabaaaba\nbababbaababababaabaaaabb\nbbbaaabbbbbaabbabbbbbbaabbaabbbb\nabbbaabbbababaabbbaaaaba\nabababaabaaabbbabaaabbabbabaaaabbbaaabab\nbbbabbbbbbbaaaaabbbbababbbabaaabababbbbb\nabaaaaaaababbaababbaaabaabbaaaab\nbababaababbbabbabbabaaba\nbabbaababababaabbbbbbbbbabbababbbababbbb\nbbbaaabbbbababaababbbaba\naaabbbbaabbbababbababaaaaaabbbbaababbbbbabaaababbbabbbaaaaaaaabaaaaaabaa\nbbaabbbabbbbbbaaaaaaaaab\nbaaabbbabbbaaaaaaabbaaaa\naaaabaaaaabaabbaabbabbbb\nabbbbabbbaababaaabababbbbaaabaabaaaaabaabbbbabbaabbabbbb\naaaabaabbbababbababbaabbbbabaabbbbbbaaab\nbbbbbaaabbbaababbbbababbbbabaabbaabbbbba\naaabbbbababbbabbbbbaababbbbbbbbbbbabaabbaaaaabaa\naabbbabaababaaabbabbbaba\nbbbaababbbbbbbbbabaabbaa\nababaaababbbbbabaaaaabab\nbbbababbbababbbaabbababa\nbababbbaabbbabbababbabaa\nbbbababaabaaaabaaaaabbbb\nababaaabbbbaaaabbbabaaba\naaababaabbbaaabbbbbaaaababbabbbb\nbabbbbabbababbaaababaaaaabaababbabbbabbb\nbababbabbabbabbbaabbababbaabbaaaaabbbaabaabbaabbbbaaabbaabbabbbabbbbbaab\nbabbaababaaabbaaababaaaabbbaabaa\nbbabbbbabaabababbaaabaab\nabbbaaabaaababbaabaabbab\nbbbababbbbbabbbbbbabbabb\nbbbbbaababaaaabaababaabb\nabbabaaaabbbaaaababbbbab\nababbbabaaabbbabaabbbbaaaaabbbbbaabaaaba\nbbaaabaaaaababaaabaabbbb\nabaaabaababaaabbbaaabbaabbbbabaabbabbaab\nbbbbbababbabaababaababbbaabbaabaaabaaaaaaabbbbba\naabbbabbabbaaababbababaabbbabababaaaaaaaaabaabaabaababba\nabaaaababbbbbbababaabbbabbbaaaaaababbabb\nbabbbbbaaaaabbabbaaaaabb\naaabaababbaabbaaabbbbbabbbbababbaabbbbbababbbaab\nabbabaaabbbabbaababbaabbaabbbbba\nbabaaabaabbbabbaaaaabbaa\nbaabbbbabaaaaababbbaabbbaaaabbbb\naabbaabbbbbaaaabbbbabbaaabbabbababbbbaababaababb\nabaaaabbbbaaababbbbbbabb\nabaaaabaababbbabaabaaabb\nabaababbaabaababbaaabbbb\nbbabbabbabababbaaaabbabaabababab\naaaaaabbbabaaaabbbbbbbaabaaaaabbaababbabbabbbababaaaabba\nbbababbabaaababbababbbbbbabbabab\nbbabbaaababbbbaababbaaab\nbaaaaaaaaabababbaabaabaa\nabbaaabbabbbaaaababaaabaababaabaababaabb\nabaaaaabaaababbaaaabaaab\nabaaaaaabbaabaaaaaabbaabababbbaaabbbabbbbaabbaab\nabbaaabbbbaabbaaaabbbaaabaabaaaa\naabaaaabbbbaaaabaaababbb\nabbaabaabbbbababbabbaaababaaabbaaabaaaabbabababababababb\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_19_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 19\n-------------------------------------------\n--  Monster Messages\n--\n--  https://adventofcode.com/2020/day/19\n--\n\nwith Ada.Text_IO;\n\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_19_full_Ada is\n  --  n : constant := 6; fn : constant String := \"mini.txt\";\n  n   : constant := 129;\n  fn  : constant String := \"aoc_2020_19.txt\";\n\n  type Rule_Index_List is array (Positive range <>) of Integer;\n  submax : constant := 5;\n\n  subtype Rule_Index_List_Fixed is Rule_Index_List (1 .. submax);\n\n  type Rule_Type (is_terminal : Boolean := False) is record\n    case is_terminal is\n      when True  =>\n        leaf : Character;\n      when False =>\n        max : Integer;\n        sub : Rule_Index_List_Fixed;\n        alt : Natural;  --  alternative subrule list starts at `alt`\n    end case;\n  end record;\n\n  max_rule_id : constant := 500;\n  rule : array (0 .. max_rule_id) of Rule_Type;\n  verbose : constant Boolean := False;\n  --\n  function Is_Valid (s : String) return Boolean is\n    --\n    --  We verify the string (s) against the rules (list),\n    --  in a LISP-esque fashion ( https://en.wikipedia.org/wiki/CAR_and_CDR ).\n    --  The nice thing in this problem is the tail recursion\n    --  on the string AND on the rule list.\n    --\n    function Verify (s : String; list : Rule_Index_List) return Boolean is\n      --\n      function Verify_First_Rule return Boolean is\n        rule_1 : Rule_Type renames rule (list (list'First));\n        tail_rule_list : Rule_Index_List renames list (list'First + 1 .. list'Last);\n      begin\n        if rule_1.is_terminal then\n          return\n              s (s'First) = rule_1.leaf\n            and then\n              --  Test the rest of the string against the other rules.\n              Verify (s (s'First + 1 .. s'Last), tail_rule_list);\n        elsif rule_1.alt = 0 then\n          --  Test the sub-rules, appended with the tail of the rules, and\n          --  verify all that on the local string.\n          return Verify (s, rule_1.sub (1 .. rule_1.max) & tail_rule_list);\n        else\n          --  Test separately both subrule lists:\n          return\n            Verify (s, rule_1.sub (1 .. rule_1.alt - 1) & tail_rule_list)\n               or else\n            Verify (s, rule_1.sub (rule_1.alt .. rule_1.max) & tail_rule_list);\n        end if;\n      end Verify_First_Rule;\n      --\n    begin\n      if list'Length = 0 then\n        --  Rule list is empty. OK if the string is empty as well.\n        return s'Length = 0;\n      end if;\n      if s'Length = 0 then\n        --  String is too short: there are unprocessed rules.\n        return False;\n      end if;\n      return Verify_First_Rule;\n    end Verify;\n    --\n    --  Test rule 0 (and all the rest...):\n    is_test_ok : constant Boolean := Verify (s, (1 => 0));\n  begin\n    if verbose then\n      Put_Line (\"Tested:  \" & s & \"   : \" & (if is_test_ok then \"OK\" else \"invald\"));\n    end if;\n    return is_test_ok;\n  end Is_Valid;\n  --\n  procedure Parse_Rules (f : in out File_Type) is\n    procedure Get_Nat (n : out Natural) is\n      c : Character;\n    begin\n      n := 0;\n      Get (f, c);\n      while c = ' ' loop  --  Skip heading blanks.\n        Get (f, c);\n      end loop;\n      loop\n        exit when (c < '0') or (c > '9');\n        n := n * 10 + Ord (c) - Ord ('0');\n        Get (f, c);\n      end loop;\n    end Get_Nat;\n    --\n    c, sep : Character;\n    i, j, k : Integer;\n  begin\n    for count in 1 .. n loop\n      Get_Nat (i);\n      Get (f, sep);\n      Get (f, c);\n      if c = '\"' then\n        Get (f, c);\n        rule (i) := (is_terminal => True, leaf => c);\n        Get (f, sep);\n        if verbose then\n          Put_Line (+\"Terminal \" & i & \" -> \" & rule (i).leaf);\n        end if;\n      else\n        k := 0;\n        rule (i).alt := 0;\n        loop\n          if (c >= '0') and (c <= '9') then\n            j := Ord (c) - Ord ('0');\n          else\n            j := 0;\n          end if;\n          k := k + 1;\n          while not End_Of_Line (f) loop\n            Get (f, c);\n            exit when (c < '0') or (c > '9');\n            j := j * 10 + Ord (c) - Ord ('0');\n          end loop;\n          rule (i).sub (k) := j;\n          exit when End_Of_Line (f);\n          Get (f, c);\n          if c = '|' then\n            rule (i).alt := k + 1;\n            Get (f, c);\n          end if;\n        end loop;\n        rule (i).max := k;\n        if verbose then\n          Put (+\"  List \" & i & \": \");\n          for l in 1 .. k loop\n            if rule (i).alt = l then Put (\"| \"); end if;\n            Put (+\"\" & rule (i).sub (l) & \" \");\n          end loop;\n          New_Line;\n        end if;\n      end if;\n    end loop;\n  end Parse_Rules;\n  --\n  total : Natural;\n  f : File_Type;\nbegin\n  for part in 1 .. 2 loop\n    total := 0;\n    Open (f, fn);\n    Parse_Rules (f);\n    if part = 2 then\n      rule (8)  := (is_terminal => False, max => 3, alt => 2, sub => (42, 42,  8, -1, -1));\n      rule (11) := (is_terminal => False, max => 5, alt => 3, sub => (42, 31, 42, 11, 31));\n    end if;\n    Ada.Text_IO.Skip_Line (f, 2);\n    while not End_Of_File (f) loop\n      if Is_Valid (Ada.Text_IO.Get_Line (f)) then\n        total := total + 1;\n      end if;\n    end loop;\n    Close (f);\n    Put_Line (total);\n    --  Part 1: Validated by AoC: 226\n    --  Part 2: Validated by AoC: 355\n  end loop;\nend AoC_2020_19_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_20.adb",
    "content": "--  Solution to Advent of Code 2020, Day 20\n-------------------------------------------\n--  Jurassic Jigsaw\n--\n--  https://adventofcode.com/2020/day/20\n--\n--  Part 1 only\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2020_20 is\n  use HAT, Interfaces;\n  size : constant := 144;\n  name : constant VString := +\"aoc_2020_20.txt\";\n\n  type Side is (up, down, swup, swdown, left, right, swleft, swright);\n\n  subtype Tile_Range is Positive range 1 .. size;\n  label : array (Tile_Range) of Natural;\n  side_code : array (Side, Tile_Range) of Natural;\n\n  --\n  subtype Edge_Value_Range is Natural range 0 .. 1023;\n  edge_count : array (Edge_Value_Range) of Natural;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  --\n  procedure Get_Nat (f : in out File_Type; n : out Natural) is\n    c : Character;\n  begin\n    n := 0;\n    Get (f, c);\n    while c = ' ' loop  --  Skip heading blanks.\n      Get (f, c);\n    end loop;\n    loop\n      exit when c < '0' or c > '9';\n      n := n * 10 + Ord (c) - Ord ('0');\n      Get (f, c);\n    end loop;\n  end Get_Nat;\n  --\n  procedure Read_Data is\n    t_s : String (1 .. 5);  --  \"Tile \"\n    f : File_Type;\n    c : Character;\n    bit : Integer;\n  begin\n    Open (f, name);\n    for n in Tile_Range loop\n      Get (f, t_s);\n      Get_Nat (f, label (n));\n      for s in Side loop\n        side_code (s, n) := 0;\n      end loop;\n      for i in 0 .. 9 loop\n        for j in 0 .. 9 loop\n          Get (f, c);\n          if c = '#' then\n            bit := 1;\n          else\n            bit := 0;\n          end if;\n          if i = 0 then  --  top-down (0 = top)\n            side_code (up, n)   := side_code (up, n)   + bit * (2 ** j);\n            side_code (swup, n) := side_code (swup, n) + bit * (2 ** (9 - j));\n          end if;\n          if i = 9 then\n            side_code (down, n)   := side_code (down, n)   + bit * (2 ** j);\n            side_code (swdown, n) := side_code (swdown, n) + bit * (2 ** (9 - j));\n          end if;\n          if j = 0 then\n            side_code (left, n)   := side_code (left, n)   + bit * (2 ** i);\n            side_code (swleft, n) := side_code (swleft, n) + bit * (2 ** (9 - i));\n          end if;\n          if j = 9 then\n            side_code (right, n)   := side_code (right, n)   + bit * (2 ** i);\n            side_code (swright, n) := side_code (swright, n) + bit * (2 ** (9 - i));\n          end if;\n        end loop;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n  --\n  procedure Count_Edges is\n    procedure Increment (value : Natural) is\n    begin\n      edge_count (value) := edge_count (value) + 1;\n    end Increment;\n  begin\n    for i in Edge_Value_Range loop\n      edge_count (i) := 0;\n    end loop;\n    for m in Tile_Range loop\n      for s in Side loop\n        Increment (side_code (s, m));\n      end loop;\n    end loop;\n    for i in Edge_Value_Range loop\n      if edge_count (i) > 2 then\n        Put_Line (\"Though puzzle case (luckily, our data isn't)\");\n        Put_Line (+\"\" & i & \"  : \" & edge_count (i));\n      end if;\n    end loop;\n  end Count_Edges;\n  --\n  function Is_Corner (n : Positive) return Boolean is\n  begin\n    return\n      (edge_count (side_code (left, n))  = 1 and edge_count (side_code (up, n))   = 1) or\n      (edge_count (side_code (right, n)) = 1 and edge_count (side_code (up, n))   = 1) or\n      (edge_count (side_code (left, n))  = 1 and edge_count (side_code (down, n)) = 1) or\n      (edge_count (side_code (right, n)) = 1 and edge_count (side_code (down, n)) = 1);\n  end Is_Corner;\n  --\n  function Spot_Corners return Integer_64 is\n    prod : Integer_64 := 1;\n  begin\n    for n in Tile_Range loop\n      if Is_Corner (n) then\n        prod := prod * Integer_64 (label (n));\n      end if;\n    end loop;\n    return prod;\n  end Spot_Corners;\n  --\nbegin\n  Read_Data;\n  Count_Edges;\n  if compiler_test_mode then\n    if Spot_Corners /= Integer_64'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (\"Product of corner labels:\" & Integer_64'Image (Spot_Corners));\n  end if;\n  --  20899048083289 (example)\n  --  83775126454273 (input)\nend AoC_2020_20;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_20.txt",
    "content": "Tile 2647:\n#....#####\n.##......#\n##......##\n.....#..#.\n.........#\n.....#..##\n#.#....#..\n#......#.#\n#....##..#\n...##.....\n\nTile 1283:\n######..#.\n#.#..#.#..\n..#..#...#\n.#.##..#..\n#......#..\n#.#....##.\n.#.....#.#\n#.#..#.#.#\n.#......##\n...##.....\n\nTile 3547:\n#.#.#.###.\n#.........\n#....##...\n#.....#..#\n#.....#.#.\n##..##...#\n#...##....\n......#..#\n#...##....\n.....###.#\n\nTile 1451:\n##..#.#...\n#.#.......\n##.#.....#\n....#.....\n...#...##.\n......#.#.\n#...##.##.\n........#.\n.#.##.#...\n..##..#...\n\nTile 3137:\n....#.##.#\n#....#...#\n..#.#.....\n...####..#\n.#.###...#\n.......#..\n##.##.#..#\n.#.##....#\n#...#....#\n..##.##..#\n\nTile 2897:\n###..#.##.\n..#......#\n.....#....\n###.#....#\n#.#..#...#\n.#...##..#\n##..##.##.\n#.....#..#\n.#......##\n#.#.#.##.#\n\nTile 1093:\n..#.#.#.#.\n#.#.......\n..##....#.\n.#.....#.#\n#........#\n.#....#..#\n##....#..#\n#.##..#..#\n..###...##\n.######.##\n\nTile 1217:\n#..#....##\n#.....#...\n##...##..#\n#.....#...\n..#.#..#..\n#..#....##\n.##.#.....\n......#...\n.#........\n.#..###.#.\n\nTile 2801:\n###..##.#.\n.........#\n##.#...###\n#......#..\n#........#\n......#...\n##.####...\n.....##...\n..#..#.##.\n...###.##.\n\nTile 1361:\n...#.##..#\n....#.....\n###.......\n#......#..\n.......##.\n#...#..#..\n#.....##.#\n##........\n#.#.......\n###.#..###\n\nTile 2063:\n...#....##\n##...#..##\n#........#\n........##\n#.......##\n#.........\n##.....##.\n.....##..#\n.#.##.#...\n.#..#####.\n\nTile 3797:\n##..#...#.\n.###.#.##.\n.....#.##.\n..#.......\n...#.#....\n........##\n#.#.#.##.#\n#.....#.##\n#.......#.\n.....#.##.\n\nTile 1289:\n####.##.#.\n.....#....\n#..#.#....\n####...#..\n#.#..#..#.\n.#.##..#..\n#........#\n....#..#..\n........#.\n###.#.####\n\nTile 1427:\n##.##..##.\n###..#.##.\n#..##...#.\n#..#.#...#\n#........#\n#...##....\n#........#\n.....#..#.\n.####....#\n##.#.##.#.\n\nTile 1951:\n....##.#.#\n.........#\n#........#\n.#..#...#.\n.....#####\n#......#.#\n...##....#\n......#...\n..#...#..#\n....####.#\n\nTile 1483:\n....####..\n.......#.#\n###..#..##\n...#.#...#\n#..##...##\n##.#......\n#...#..#..\n..#...#.##\n.........#\n.#...#....\n\nTile 1789:\n##..#####.\n....#....#\n........#.\n..#.#..#.#\n..##.#..##\n.........#\n.........#\n#..#.#..##\n....##....\n#.#.......\n\nTile 2129:\n#.###.#..#\n....##...#\n.#..#..##.\n...###.##.\n..#..#...#\n....##...#\n#.........\n#...#..###\n#...#.....\n...#....##\n\nTile 2137:\n..#.####.#\n##...#.#..\n.......###\n.#.....#.#\n.#....##.#\n#.......#.\n#....#...#\n#.....####\n......##.#\n..#####.##\n\nTile 3761:\n.####.#...\n####..#..#\n#...##..##\n.#.....#.#\n....#....#\n#.......#.\n...#..#..#\n#.##...##.\n...###...#\n...##.#..#\n\nTile 1327:\n..####.#.#\n#..#......\n......#.##\n#..##.....\n..##.##..#\n#.#.#.....\n####.....#\n..#.......\n#.#...##..\n#.##....#.\n\nTile 2741:\n.#..#...#.\n#....#..#.\n......##.#\n....#.#..#\n........##\n...#..#...\n......##..\n#...#..#.#\n......##..\n..#..#..#.\n\nTile 1699:\n.###..####\n##.....#.#\n.....##.##\n#.#...##..\n.#........\n.#....#..#\n#..#....#.\n.#...#...#\n#.......#.\n##.#..#..#\n\nTile 1151:\n..#.##....\n##....#...\n###.#..#.#\n#.......##\n....#.#..#\n#...###...\n.#..#.#..#\n#.#..##..#\n.#.#.#.#..\n.###..####\n\nTile 2273:\n#.#.#.#.##\n..........\n#......#..\n#.....#...\n#.#...#...\n##....##..\n##..##.#..\n#.#####.##\n##.##...##\n#...##..##\n\nTile 1999:\n##.##...##\n#......#..\n##..#.....\n#........#\n#.#...####\n..#....#.#\n#..#...#..\n.........#\n#...##....\n##.##.##..\n\nTile 1721:\n....##...#\n###.#....#\n.##..#....\n.#.#.#....\n...##....#\n##..#....#\n#....#.###\n#.....##..\n....#...##\n..#.#.#..#\n\nTile 2521:\n..#######.\n#.#..##.#.\n.#....##.#\n..#...####\n.......##.\n##...###..\n...##....#\n.##.#.....\n###..##..#\n####.##.#.\n\nTile 2111:\n..#.#..#..\n...#.....#\n..####...#\n.#.#..##.#\n.##..#.##.\n........##\n........##\n#..#.#....\n...#.###..\n.#.#...#..\n\nTile 2767:\n.#######..\n##.......#\n#...#.##..\n....#...##\n#........#\n..#.###...\n....#..#.#\n##....#.##\n..##....##\n.#####.#..\n\nTile 2141:\n####.#....\n#..#.#...#\n...#..#..#\n.......#..\n.....###.#\n#....#....\n.......#.#\n.#...#..##\n...#......\n.###.####.\n\nTile 2557:\n.#.##..#..\n..##.....#\n#.#.#....#\n..##...#..\n...#..##.#\n..........\n##......##\n#..#......\n#.#..#...#\n##.#####..\n\nTile 2269:\n.#.#...##.\n#.......##\n#.....##..\n##.#......\n#.##..###.\n.#.....##.\n....#....#\n....#...##\n#..##.....\n#.#.#.#.##\n\nTile 3511:\n.#.#.##...\n.#.....##.\n.#....#..#\n#.#......#\n#.#.#.....\n#........#\n..#.......\n.##.#.....\n##.#.....#\n..####..##\n\nTile 2789:\n#......#..\n#...#.....\n#.........\n.......#.#\n...#....##\n#.##..###.\n#...##...#\n.........#\n.........#\n.###..##..\n\nTile 2971:\n#.##.#....\n...#.....#\n.#....#...\n#.#..##...\n#.....#...\n####.....#\n#..###..##\n#....#....\n#..#.##...\n#.#..###..\n\nTile 3719:\n#.###.....\n...#.....#\n...##...##\n.#..#.#..#\n#..#.#..#.\n#.#..#..##\n#...###..#\n.#.#..#.##\n........#.\n#....###..\n\nTile 1901:\n.#...##.##\n#.........\n.#.#.....#\n#.##.....#\n#........#\n#....#...#\n.....##.##\n##.###..##\n....#....#\n....##..##\n\nTile 3191:\n#.#..###.#\n#...#..##.\n#.....#...\n.#.#.#....\n.#..##....\n#.....#.#.\n.##.......\n....#....#\n#..##.#...\n####....##\n\nTile 3709:\n..#......#\n#..#...#.#\n#.##....#.\n.#..#.##..\n..#......#\n#....##...\n##........\n....#....#\n.........#\n.#.#..###.\n\nTile 1613:\n...##..##.\n#......#..\n..##.#..##\n......##..\n.#..#..##.\n.......##.\n.......#.#\n...#.#....\n#......#.#\n###..#....\n\nTile 2441:\n..#.######\n#.#.......\n#..#.#....\n....#...##\n#...#...##\n#.##...#.#\n........##\n#.#...#...\n#..####.##\n#.##.####.\n\nTile 1409:\n..####.#.#\n..##....#.\n..#.#...#.\n..##.##...\n.#.##....#\n#.....##.#\n####.....#\n###....#..\n####..#.#.\n#..##.##.#\n\nTile 1523:\n.#.##..##.\n#..#.#....\n##.#.#...#\n....#.##.#\n#........#\n#.#.......\n#...##...#\n...#..##.#\n#.##...#..\n.####..#..\n\nTile 1367:\n#..#...#.#\n#.#.......\n..#..#....\n.###..###.\n###..#.##.\n##...#..#.\n#..#...#.#\n......##..\n##.....#.#\n.#####..##\n\nTile 1783:\n...#.####.\n.####..#..\n#....#.###\n#.#..#.#.#\n#.#.#.#..#\n#.......##\n#.##.#.#..\n.#.#....#.\n#..#.#...#\n.###..##.#\n\nTile 1871:\n.##..#.##.\n#........#\n#...#....#\n##.#..##..\n##.....##.\n#.....#.##\n........##\n....#....#\n#.........\n....#.#..#\n\nTile 3217:\n#.#...#.##\n.........#\n.........#\n#...#.....\n#....#.#.#\n.........#\n...#.##.##\n#...#.....\n.#..#....#\n#..###.#.#\n\nTile 3163:\n...##.#.##\n#.#......#\n....#...##\n#.......##\n###..#.#..\n.#....####\n##....#.##\n#.......#.\n.....#..#.\n.##.#.#.##\n\nTile 3271:\n##.#.#.##.\n##....##.#\n#.#.##..##\n#.#...##.#\n.##......#\n#.....#.#.\n#........#\n##..##....\n#.#..##..#\n#..#.####.\n\nTile 2707:\n..###.#...\n#...#.....\n#.#..#....\n#..##...##\n.###......\n.#..##...#\n#...#.....\n....#.....\n#..#.#....\n.##....#.#\n\nTile 3083:\n##..#.#.##\n#..#....##\n.........#\n..#.#...##\n..#.......\n.#.#.....#\n..#..#.#..\n#...#.#..#\n#..#.#....\n#.###..##.\n\nTile 1051:\n####...##.\n...#.#...#\n..........\n..#.......\n#......#..\n.#.##.##..\n#....#.#.#\n#..#.#...#\n#.#..##..#\n......###.\n\nTile 3767:\n.#..##.###\n...#.#....\n..#.....#.\n#.#.......\n.#.....#.#\n##..#....#\n#...#..#.#\n........##\n#........#\n..#....##.\n\nTile 2267:\n.#..#..#..\n.#.#.#....\n.#......#.\n#...#....#\n.###..#...\n.##.#...##\n..#.##.##.\n...#.#.##.\n##.#.##..#\n.#.##.....\n\nTile 1973:\n#.#####..#\n.#.......#\n#..#.#..#.\n#.#.#.#.#.\n.##.......\n#.#.....#.\n.#.......#\n#...##.#.#\n##.......#\n.##...####\n\nTile 3671:\n#..##.#.##\n....##...#\n.###.##...\n.........#\n#..#.....#\n..##...#..\n......#...\n..#..#..##\n..#.......\n##..###..#\n\nTile 3221:\n#.#..###.#\n#..#....##\n#..#......\n#...#...##\n..#..#..#.\n#..##...#.\n...#....#.\n.....#..#.\n##..#..#..\n.....#...#\n\nTile 1549:\n.###.##..#\n#.#.##...#\n#....#....\n..........\n#.#......#\n##.#.#..##\n...#.#..##\n........#.\n#.#....###\n#....#...#\n\nTile 3461:\n.######..#\n#.......##\n.......#..\n.#...#....\n..##....#.\n#.....##..\n##.#.#..#.\n.........#\n##.##.#...\n....#...##\n\nTile 2459:\n..##.##.#.\n...#..#...\n.........#\n#.#..#..##\n#.###.#...\n##.#......\n.......#..\n.........#\n........##\n#.##...#..\n\nTile 3203:\n.#...####.\n..##..#.#.\n#..#..##..\n#.#....##.\n...#.#....\n.......###\n#.....##..\n....#....#\n#......#..\n###.......\n\nTile 2203:\n#.#..##.##\n.......#..\n......#.##\n#.......##\n#..##.##.#\n..#.....##\n#.##.....#\n#.#....#..\n.##.....##\n......#...\n\nTile 3637:\n#...###.#.\n#.........\n..#.......\n...#.....#\n#..##....#\n#........#\n.......#..\n#....#.#..\n#.#..##..#\n..#.#..##.\n\nTile 2467:\n..##.##...\n##....####\n...#.#.#.#\n#.##...#.#\n...##.##..\n#.....#...\n##........\n..#...#.#.\n#...####.#\n#......###\n\nTile 2411:\n...##....#\n...##..###\n...##.####\n#.#..##.#.\n..##.#.###\n.#..#.###.\n....####.#\n.....##.#.\n#.........\n.#..#..###\n\nTile 2221:\n####.....#\n#.#.....##\n.#....#...\n.#.#......\n.##..#..#.\n....#.....\n.........#\n##.......#\n#....#....\n.##.######\n\nTile 1487:\n..#..##...\n.........#\n#..#...###\n....#...#.\n.#...##.#.\n.....#.#.#\n.....##...\n#.##......\n#.#.......\n#.#####.#.\n\nTile 1481:\n#.###.##..\n....##...#\n....#.....\n...#......\n##.###.#.#\n#.##..####\n..#......#\n.#....##.#\n..##.##.#.\n.#####.#.#\n\nTile 1669:\n#...##.##.\n...#..#...\n.##..#.#.#\n#..#..#..#\n#......#.#\n.#......##\n........#.\n......#..#\n.##..#.#.#\n##.##....#\n\nTile 3167:\n.#.####...\n.........#\n#......##.\n.....#....\n..#.#...##\n#.#.####.#\n...#....#.\n.........#\n#...#.#..#\n#.#.#.#.#.\n\nTile 3347:\n###...##..\n#.#......#\n...#.....#\n..........\n#.#.....#.\n..####..##\n..#.#.#..#\n##...#..#.\n..##.....#\n#..#....#.\n\nTile 2213:\n#..#####.#\n..........\n#..#.##.#.\n...###.#.#\n......##..\n......#..#\n.##.....##\n..#....###\n...####..#\n.####.#.##\n\nTile 3329:\n..##...#..\n#.#....#.#\n#...#..#..\n......#.##\n#...####.#\n..........\n##....##.#\n#......##.\n....##...#\n..####.##.\n\nTile 3851:\n#.#....##.\n.........#\n#.....#...\n##.##.....\n...#.###..\n#....##...\n.....#.##.\n.#........\n#......#.#\n...#..#..#\n\nTile 2659:\n#.#...#.#.\n.....#.##.\n#..##.####\n#.#.##....\n#....#..#.\n...#...#..\n...#....#.\n#....#.#..\n.##.#....#\n.....#..#.\n\nTile 1933:\n.####.##..\n#..####...\n.#..####..\n.#.#.##...\n......#.#.\n##........\n.#.#.....#\n#..#......\n....#.....\n...#...##.\n\nTile 3299:\n###.##..#.\n.......#..\n...#...##.\n###...#.##\n......##..\n....#.#..#\n.###......\n.#.#####..\n#..#.#..#.\n.....#.#.#\n\nTile 3691:\n...###...#\n#.........\n#.#.....##\n#.#....#..\n#..#...#..\n..........\n##...##..#\n.#...#...#\n#.....#.##\n.###..#...\n\nTile 3733:\n#..#.#####\n.....#....\n....###..#\n#..#.#....\n#.#..#.###\n..###...##\n......#.##\n...###....\n...#....#.\n..##......\n\nTile 2131:\n##.#..#.#.\n.#...#..##\n#.......#.\n....##...#\n.###..#...\n...#####..\n.....#...#\n##..#..##.\n..##....#.\n.#...####.\n\nTile 1723:\n.....#####\n.#.#..#...\n##......#.\n#.......##\n.###...#..\n#..#......\n#.........\n......#..#\n.........#\n.###.##.##\n\nTile 3463:\n##.#....##\n#....##..#\n..#.#.....\n#.#...#..#\n#....#....\n..#....#.#\n#...#..###\n##....#.##\n..#.#.....\n.#..#.##..\n\nTile 2549:\n#.####.#..\n...##....#\n##..#.##.#\n..###.#..#\n#.#......#\n#........#\n....#.....\n#......#.#\n#....####.\n...##.#.##\n\nTile 1031:\n#..#.#.#.#\n......##..\n#........#\n.###......\n..#..#..#.\n##....##..\n......#...\n...#...###\n.###...#..\n.##.#.###.\n\nTile 1979:\n#.######..\n.#.#.....#\n#........#\n#..##.....\n##........\n##.....#..\n......#...\n.........#\n.#........\n..#.#####.\n\nTile 2939:\n#.#...#.##\n.#..#....#\n.#.....#.#\n##......##\n...#..##..\n#....#.##.\n#...##.#.#\n..#...#...\n##.....#..\n.....##.#.\n\nTile 2381:\n..##.###.#\n..##...#..\n.#...#....\n#......#.#\n##.......#\n#..####...\n...#.#.#.#\n#.##.....#\n..#......#\n#..#.##...\n\nTile 3943:\n#.#.###..#\n.......###\n#.#...###.\n#..##.#..#\n#......#..\n#.##...#.#\n#.........\n##....##.#\n....#.#...\n.###.#....\n\nTile 1553:\n#####.####\n#...#.....\n#.#.....#.\n##......#.\n#....#.#..\n.#.....#.#\n##....#.#.\n#........#\n.........#\n.#.....##.\n\nTile 2351:\n.###.###..\n#.....#...\n##.##....#\n..#..##.#.\n#.#.......\n#....#....\n......##.#\n##...##..#\n.#.....#..\n.#.###..#.\n\nTile 2311:\n#.#.#..##.\n#..###.#..\n...##..#.#\n###.......\n##........\n#.#.......\n..##.....#\n.#.####...\n..#.#.#...\n###..##.#.\n\nTile 1567:\n..###.#.##\n.#.....###\n#...#..##.\n#.......#.\n.......#..\n#....#....\n...#.##.#.\n....#...##\n....#....#\n#.#...##..\n\nTile 2579:\n#.##..##..\n#......#..\n#..#..#..#\n##.......#\n....##.#.#\n#.####..#.\n#..#..#.##\n#...#..#.#\n...##...#.\n#..#.###..\n\nTile 3593:\n.#.##.#.##\n#...#....#\n..........\n##....#..#\n##......##\n#.........\n......#..#\n...#.....#\n....#....#\n##..###..#\n\nTile 2281:\n##....###.\n...#......\n#......#.#\n##.#..#..#\n###.#..##.\n.#...#...#\n..........\n.#.###.#..\n#..#......\n#..#.##.#.\n\nTile 1193:\n.......###\n##..#..#..\n.###...###\n....#.###.\n..#...#..#\n#.#....#..\n...####..#\n#....#..##\n.#.......#\n.#.#...##.\n\nTile 3833:\n...#####..\n#..####...\n#.#....###\n...##.#.##\n..#...#..#\n.##.#####.\n#..#..#..#\n#...##....\n.....#.#..\n.##.##.#.#\n\nTile 2003:\n.#.###.#..\n.........#\n..#..#....\n#.........\n#..##....#\n.......#.#\n......#...\n#....##..#\n.#......##\n..#..##.#.\n\nTile 2731:\n#.#..#..##\n....#..#.#\n..#...#...\n..#..#....\n#.#..#...#\n#....##...\n#.........\n#..##..#.#\n#.........\n.###.#....\n\nTile 3881:\n..##......\n#...#..#.#\n##...#....\n....#.....\n##.......#\n.....#####\n...#....##\n.........#\n..........\n#..##.####\n\nTile 3673:\n##..###.#.\n...##....#\n###.....##\n#..#...#.#\n#.##......\n..#.#.....\n..#.#....#\n.###.....#\n.###.##...\n###.#..#.#\n\nTile 1021:\n#..###.#..\n###..##.#.\n#..##....#\n.....###..\n....##...#\n....#.....\n#.##..#..#\n..........\n.......#.#\n..#.##..#.\n\nTile 2423:\n#.....####\n.##.#....#\n.#........\n##.....#..\n#.....###.\n#...#...#.\n#...#..#.#\n.#..#..##.\n##.......#\n.#####.###\n\nTile 3923:\n..#....###\n#.....#..#\n#...#.#.#.\n.#.......#\n#..#.#....\n.......#.#\n##....##.#\n.#..#...#.\n#...##..#.\n..#.#.#..#\n\nTile 2753:\n..####..#.\n#.......#.\n#.##.#..##\n#.#.#.....\n#..#......\n....#.#...\n.#.#..#..#\n#.....#..#\n##.#..#...\n#####....#\n\nTile 3929:\n....#####.\n##..#.##..\n##.#.#.##.\n##...#.#..\n#........#\n.##.#..#..\n#..#.##...\n##..#...#.\n.....#...#\n###..####.\n\nTile 3041:\n.##.#..#.#\n#..#...#..\n###..#..#.\n.#.#....##\n...##.....\n#....#..##\n#........#\n##.#...#..\n##....#..#\n...#..#..#\n\nTile 3433:\n..#.#.#...\n#.#.......\n.....#....\n..#......#\n#..#.....#\n........##\n##..##.##.\n##........\n#.#.##..##\n###.###..#\n\nTile 2719:\n..##..#..#\n#.##..##..\n#......#..\n#...##..##\n..#..#.#.#\n#......###\n..###..#..\n....#.#..#\n....##...#\n##..#..###\n\nTile 1201:\n.#...##.##\n#........#\n##...##...\n..........\n.....#.#..\n#.##.....#\n...#.##..#\n.........#\n.#.#.....#\n.##...#...\n\nTile 1129:\n...####..#\n......##..\n#.....##..\n#.......#.\n#......#..\n...##....#\n........##\n##.#.#.#..\n...#..##.#\n...##....#\n\nTile 3019:\n..#...###.\n.....#.##.\n#.##.....#\n.#.##..#..\n.#..###..#\n..#.####.#\n#..#.#...#\n.......#.#\n#..##.#..#\n#.##....##\n\nTile 1747:\n##.###.#..\n#.......#.\n#...#..#.#\n##...##.#.\n..###.#..#\n#..#..##..\n#...#.....\n..#.......\n...#..#.#.\n.##..##.##\n\nTile 1741:\n.##.#..#.#\n#...##..##\n#....#.#.#\n##...##..#\n##.......#\n#...#..##.\n...#.##.##\n...#..#.#.\n.......#.#\n.#####.###\n\nTile 1867:\n#..##.....\n.......###\n#..##....#\n##...#....\n...###....\n##..#.....\n.##.......\n#.....###.\n#...#..#.#\n...###....\n\nTile 2803:\n.#.##....#\n#.####..#.\n#.........\n#.#......#\n.......#.#\n........#.\n..#..#.#.#\n....###...\n#...##....\n...###....\n\nTile 3643:\n#..#..#.##\n####.#..#.\n#.#...#.##\n.#..#.....\n##....#..#\n.##.......\n.......#.#\n...##.#...\n.....#.##.\n#...####.#\n\nTile 2437:\n..###..###\n....#.....\n..........\n#.#..#.###\n##...####.\n....##....\n...##.....\n##..#.##..\n#......#..\n#.#.....#.\n\nTile 1069:\n..####....\n##..##...#\n.#..#..##.\n.#....##.#\n###.#.#.##\n...##..#.#\n##....#...\n#.#....#.#\n.#.....#.#\n#.#.#.....\n\nTile 1381:\n.###.#.##.\n....#..#..\n#.......##\n#...#.....\n.#...#..##\n...#....##\n#..#.###..\n..######.#\n#....#...#\n#######.#.\n\nTile 2617:\n..##..#.#.\n#.....##.#\n..#.#..#..\n.##.#..#..\n###...#.#.\n.###.##...\n#.#.......\n#..##.#..#\n##.....#..\n.##..#..##\n\nTile 2393:\n.##..#.#.#\n..#.#..###\n..##..#.##\n....#.....\n#...#.....\n##.#.....#\n.#.#..#.#.\n##.....#..\n.......#.#\n####..#...\n\nTile 3529:\n#.#...##.#\n......#..#\n.........#\n#.....#...\n.......#..\n.....#.#.#\n.....#....\n#....#.#.#\n....#.##.#\n.####.#..#\n\nTile 2953:\n...##...#.\n##.#.#..##\n#...#.....\n##.#...###\n...#......\n#.#.#..#.#\n.#...#...#\n##....#.##\n.......#..\n.#.#..#...\n\nTile 3617:\n#..##...##\n......#...\n#....#....\n..........\n.######.##\n##..#.#.##\n#.#...#...\n........#.\n.######.##\n##...###.#\n\nTile 3863:\n.##.#...##\n#...#.....\n..#.#....#\n#....#..##\n.....###..\n#.#......#\n#.......#.\n...#.....#\n#.........\n..###....#\n\nTile 3727:\n#.###.##.#\n..........\n...##.....\n..#..#..##\n#......###\n#....##...\n###.##....\n.....#....\n##.####.#.\n#..#.#.###\n\nTile 3803:\n###..#.##.\n.##......#\n.........#\n###.....##\n....###..#\n.......#.#\n........##\n#..#......\n##......##\n#.###..#..\n\nTile 1579:\n#...##.###\n.....#.###\n.##...#...\n#.#..#..#.\n..##.....#\n.........#\n..........\n#.....#.##\n.....#....\n.###..#...\n\nTile 1049:\n#..#.##.##\n##......##\n..#.##...#\n#.......#.\n###.....#.\n.....#.#.#\n...#......\n..##......\n#.#....#..\n##..#.#...\n\nTile 2687:\n##..#.##..\n.#........\n##..#...#.\n.#.#.....#\n.#..#.#..#\n#.###..#..\n..#......#\n#.......##\n#..#.....#\n#.##.#..##\n\nTile 1637:\n#..##...##\n##..#....#\n...#....#.\n#....#....\n.....#...#\n#...#...##\n.#....#...\n#.........\n..#....#..\n.#.####...\n\nTile 3527:\n.#....#.#.\n#.......#.\n..#....#.#\n####.#.#.#\n...#..#...\n###..#.###\n##..#....#\n#.##....##\n..#......#\n.....#.#..\n\nTile 2963:\n#.#.#.#.#.\n#.....#...\n##.#.....#\n..##......\n..#.......\n.#...#.##.\n###......#\n##....#..#\n.#...#..##\n..##..##.#\n\nTile 2287:\n##.######.\n.#.##.##..\n#..#....##\n##.#.#...#\n.......##.\n#...##...#\n...##..#..\n##....#.#.\n....#.##..\n..#.#..###\n\nTile 3677:\n###.....##\n#..#.#..#.\n#.#.......\n.....#..##\n..........\n......#.##\n.....#..#.\n#..#...#..\n.##......#\n#...##.##.\n\nTile 3559:\n..#..#.##.\n###......#\n..#.##....\n#.#..#....\n##..##..##\n..#...#.#.\n#.....#.##\n....#....#\n...#.#...#\n...#.###..\n\nTile 2837:\n..#...#...\n.....##...\n#.#..#...#\n....#....#\n...####.##\n#.........\n...#...##.\n.#..###.#.\n....#.....\n.###.##.#.\n\nTile 3539:\n..##....#.\n........#.\n......#..#\n...#..#...\n###....###\n#...#.....\n.#........\n#.....#...\n..##.#..#.\n..###..#.#\n\nTile 1667:\n.#..####..\n.....#....\n......#...\n#.#...##.#\n#...#.#..#\n##.#.#...#\n##..#..#..\n#...##...#\n.#..###...\n..#..####.\n\nTile 2791:\n#.##.###.#\n...#..#...\n##.....###\n...#.#..##\n.........#\n.###...#..\n...#.....#\n##.....##.\n###.......\n#..#.#....\n\nTile 2609:\n..##.#....\n##.#.#...#\n#.#..#....\n#.........\n...#..#..#\n#...#.#...\n##.##....#\n.###......\n##.....##.\n#.#...#.#.\n\nTile 3061:\n####..#.##\n#.....##..\n..........\n......#...\n..#.#..###\n.#.#..#..#\n.#...#...#\n#........#\n.....#.#..\n#..#....##\n\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_21.txt",
    "content": "mxc ssdszsn phc llj nhnd fqqcnm njrcfg mrczqmj zfnttf tqkfx zvq rftbr jgbk kmlkx tzdks czvphx qpbl fzlrf zmsdzh qfslcb psqc rfx vnjxs lkgln sqhvzg qzjrtl hfzqf qhtvsr zdthsvl cgflg nggbtk mxq rdkrtr djdhrn nkzqj lcrs mhrlx hpbnj blvfz djhj ssrgt lpvfv fslqkg rzcps njdb jbtlfv cncpbssj lsgqf hbdv gbhjv drtdz flndv gpjr xqgb xvjk zjbgp rjc bfnnnrn gcptp prksl xdcp pdt xtgjslz fgptl kdm njqrhcc nqvnn lxldx spnd nlqhlsn tcclbr gpqgkt jfrlp hddd bmqzgvr rfxgl fgsr hjvzcp mxzb hqd (contains eggs, fish, peanuts)\nzcphr pcslhrg strpjp hbbgk nqvnn rtq jqzklv fnlk mhrlx fgsr bvlb gpqgkt fqqcnm dhsssf pdhlzg dchvb njdb rms zppxp pdt nfgr th jbz tktj rtpff xvjk fqtc ldrgj jbtlfv hzmk tqkfx nppxr qzjrtl nlqhlsn qfslcb xbvrx jhv ssrgt xqgb nbgv kmlkx chgjqc nthsf vhjgg mcl fzlrf lzvh pmhhqrk hjzkg lpvfv jgbk xsk blvfz thtlt nfck lftqn mxq flndv lsgqf njqrhcc mrczqmj nnskqnmn rjc zfnttf sqhvzg rfxgl zmsdzh rxd zbxj phc rtmfg bfnnnrn kdm dfcgd (contains peanuts)\nvhjpjdr nxrgp pdj njdb fgsr zmsdzh fctmvrs dfcgd nnskqnmn cvbc rxd th fgptl fqqcnm xqgb nkzqj dkg phc qpbl dgxnc fnlk llj tktj nlqhlsn bkzbrm lzvh rfgf fgcd nppxr vxmrk mhrlx pcslhrg czvphx hfzqf dxrsgs jbz dxdrk chgjqc tqkfx nfgr snzxr frxmq hjzkg mgv lsgqf jhbnm rjc xtgjslz sxsxm gvdstsc pdt lpvfv zbxj (contains wheat, dairy)\nxdcp njrcfg blvfz kdbxxzv tcclbr jhbnm rlgr njqrhcc nggbtk rntk phc zmsdzh lxldx qfslcb psqc mzrx ggrc hqd mrczqmj jp mxq sqhvzg bggmsj mcl gcptp jgbk tzdks hbbgk llj smdlg tqkfx pdt jqgm jhv vnjxs gcpks cqqcd hrnvd rjc rfgf jlrt bvlb njdb rdkrtr dxrsgs czvphx flndv nppxr gvdstsc nlqhlsn hdtr gpqgkt fgcd lzvh bvcxfp dchvb spnd jsh gbhjv vhjgg bjcvpc prbk rng zvq nthsf kjjst pdj zdthsvl pdhlzg lsgqf mgv vbkb ssrgt jxvx (contains nuts, dairy)\njqgm prksl psqc lftqn jlrt jqzklv fppgp ldrgj cgflg xsk gpqgkt rjc sfkcp zmsdzh njqrhcc nppxr tcclbr snzxr hbdv npftghk phc hbmvpmt bjcvpc czmml bkzbrm ggrc pdt blvfz spnd smdlg mbmtz gcptp hpbnj jbz lsgqf czkfv gqnxlr nhnd chgjqc rzcps jhv fnlk gcpks nlqhlsn fslqkg rsr hjvzcp cvbc rdkrtr zdthsvl nxrgp hjzkg vbkb nfgr fgcd tktj czvphx qhtvsr hcjkd qfslcb hqd fqqcnm nhzthvn sxsxm (contains fish, sesame, soy)\nzmsdzh dxrsgs qrpzt tzdks bggmsj chgjqc cgflg sxsxm zppxp jbtlfv bvcxfp pdj hbmvpmt fzlrf lxldx llj dgxnc hfzqf hqzcncv gbhjv spnd phc hjzkg dhsssf fqtc xtgjslz nfck thtlt tcclbr xdcp djdhrn zjbgp nhnd kdm ksrjn mxq rng pdt dxdrk rtpff sqhvzg ldrgj kjjst rjc jp lsgqf flndv ggrc njqrhcc gpqgkt mrczqmj mxc rftbr psqc lzvh nmps (contains soy)\njfrlp hqd mxq fnlk cncpbssj nnskqnmn rzcps hbmvpmt pdt zmsdzh pfrqf zfnttf zjbgp dchvb jp mzbgp phc qpbl qdkk nqvnn rsr xbvrx sfkcp cqqcd cgflg dhsssf rlgr vnbfvkp hrnvd lsgqf ldrgj nxrgp qzjrtl czmml nthsf fqqcnm kmlkx lpm xvjk nbgv rfx fctmvrs qjhq njdb pdhlzg xsk rbjmdn tzdks spnd chgjqc bvlb jqzklv lzvh jxvx rxd kjjst jvhsj vxmrk (contains dairy, peanuts)\nnjqrhcc mxc mgv phc fzlrf spnd jvhsj kmlkx cldgd fgsr vnjxs ksrjn fqtc qjhq nfgr bmqzgvr pdhlzg frxmq gcptp rdjdq vbkb fgptl npftghk dxrsgs fgcd qdkk qzjrtl lpvfv hfzqf fqqcnm lzvh hpbnj hzmk jqzklv ktnlk tktj vhjpjdr llj fppgp zmsdzh hjzkg jbz cqqcd rtq hbdv njrcfg fslqkg jfrlp smdlg dhsssf qhtvsr rjc lsgqf jhv rftbr xgpdnz (contains wheat, dairy, eggs)\nzmsdzh sjpzc tkhzz kdbxxzv tqkfx fslqkg rtpff nbgv prksl nxrgp pdt zfnttf qdkk rjc vnbfvkp nppxr fppgp spnd bkzbrm rftbr mzbgp llj nfgr xtgjslz lpvfv zjbgp fctmvrs zgvtn xfn nvmm rntk jhbnm frxmq strpjp cqqcd phc dfcgd nggbtk kdm sxsxm gbhjv cldgd qjhq th jlrt rdjdq mzrx hqd jsh vhjgg nlqhlsn vxmrk zcphr lzvh mcl dhsssf bggmsj kjjst fqqcnm (contains nuts, dairy)\nzbxj jlrt lxldx jqgm zfnttf rdkrtr smdlg mcl fctmvrs vhjgg vbkb fqtc nlqhlsn czmml bxqpgx hpbnj fzlrf spnd pdj flndv phc pdt rzcps mzbgp gcpks ldrgj rtmfg zjbgp lzvh hjvzcp rfxgl czkfv gpqgkt bkzbrm jhbnm dxrsgs xdcp hbdv xvjk lpm lkgln gqnxlr kmlkx nfgr jbtlfv fgsr prksl jfrlp nthsf drtdz dfcgd dgxnc dhsssf rjc tkhzz tktj xgpdnz zmsdzh nhzthvn fslqkg bmqzgvr hrnvd lsgqf bjcvpc mbmtz mxc nbgv th bggmsj nqvnn nnskqnmn mxq rlgr rtpff kjjst pfrqf (contains nuts, soy)\ntktj jbz rbjmdn zcphr fqqcnm djdhrn smdlg nkzqj qdkk vnbfvkp rtmfg fnlk jqgm tkhzz rdkrtr hpbnj nhzthvn rjc czkfv lftqn cldgd fgsr rfxgl lkgln bvpxc lsgqf kdm blvfz spnd nlqhlsn xvjk nmps lzvh nvmm snzxr psqc vnjxs sfkcp pdt rfgf gcptp zdthsvl mrczqmj hqzcncv pcslhrg djhj hqd bggmsj nfck hdtr bxqpgx jsh rtpff jqzklv qlkfvk phc jfrlp strpjp (contains dairy, wheat, peanuts)\nhbmvpmt psqc pfrqf gvdstsc chgjqc cgflg pdhlzg gcptp nmps tktj frxmq mzbgp pdt mcl fppgp jqzklv mhrlx ssrgt tcclbr rzcps nhzthvn rjc rfxgl fqqcnm gqnxlr gpqgkt fgsr hqzcncv spnd nbgv nhnd mxc xtgjslz nfgr vbkb zjbgp jgbk nppxr rfgf dxrsgs nqvnn hfzqf gcpks jlrt rdkrtr rntk rlgr rxd kjjst flndv lxldx phc jqgm zmsdzh hrnvd zdthsvl drtdz rfx qpbl lzvh xbvrx gpjr hbdv tzdks blvfz smdlg gbhjv pmhhqrk nnskqnmn rtq prksl qfslcb ggrc nthsf bggmsj zppxp (contains eggs, fish)\nnthsf pmhhqrk gpjr zmsdzh jhv zfnttf vhjpjdr rtmfg cvbc nvmm vbkb bmqzgvr lftqn prksl rjc bfnnnrn qzjrtl pdj hrnvd jbtlfv mgv kdm xtgjslz nkzqj mhrlx fgcd kmlkx qrpzt xfn rntk fppgp fqqcnm dgxnc nggbtk bjcvpc nppxr qfslcb fctmvrs pdt njqrhcc rdkrtr ldrgj rfxgl jgbk spnd phc rfx lkgln rtq xdcp jhbnm prbk jqhn hfzqf mxc rms mxzb rtpff tqkfx fslqkg jbz hbmvpmt hbdv rfgf lzvh (contains fish)\ngcpks mrczqmj rtq gpjr npftghk hbbgk lxldx xtgjslz njrcfg hjvzcp kdm jp sfkcp bvcxfp xdcp nqvnn tkhzz czvphx ssdszsn xvjk zmsdzh chgjqc rdkrtr hqd qrpzt mbmtz frxmq pdt zppxp nmps hdtr dfcgd nbgv gbhjv th rsr lsgqf fqqcnm rjc cldgd flndv bjcvpc zfnttf zgvtn rms fslqkg phc rtpff hjzkg rlgr dxrsgs nvmm zcphr rxd nxrgp zdthsvl jhbnm jqhn qfslcb lftqn psqc czkfv pcslhrg fqtc xsk nnskqnmn mxq qdkk spnd lcrs ksrjn kmlkx ldrgj nfgr nlqhlsn cvbc djhj thtlt bmqzgvr lpvfv qpbl xqgb (contains dairy, soy, peanuts)\nprbk thtlt fqqcnm rjc tkhzz hcjkd blvfz xvjk njrcfg nnskqnmn xfn xdcp czkxlg hzmk bvlb ssdszsn xsk mbmtz spnd zjbgp lzvh lsgqf rtq kjjst xgpdnz bxqpgx czmml gpjr ggrc ktnlk jbtlfv pmhhqrk nkzqj phc zbxj fzlrf dgxnc lcrs xbvrx rdkrtr rfxgl hqd gbhjv vbkb pdt nfck qdkk jlrt (contains soy, nuts)\nqhtvsr mxc prksl jhv cvbc dkg drtdz gpqgkt jbtlfv rdkrtr qfslcb phc ssdszsn dchvb fppgp djdhrn tktj tkhzz jbz njqrhcc dhsssf lftqn mrczqmj jgbk lcrs hrnvd fqqcnm jqzklv rfx hjvzcp czkxlg pcslhrg kdbxxzv zvq spnd qzjrtl lzvh vxmrk hbmvpmt bxqpgx zmsdzh qdkk pfrqf jsh strpjp th njdb pdt sjpzc bfnnnrn lxldx nbgv hbbgk rjc (contains fish)\nsfkcp njqrhcc xvjk lpm rfgf fctmvrs spnd djdhrn nhnd zmsdzh njrcfg gvdstsc zjbgp nthsf prbk njdb jqzklv hdtr dxrsgs phc thtlt nppxr mxc fqqcnm gbhjv lcrs mzrx pdhlzg frxmq hbmvpmt nggbtk rdkrtr zdthsvl smdlg nfck nhzthvn pdt dkg xqgb bmqzgvr sjpzc qfslcb hjzkg llj nqvnn rjc lzvh rtq kmlkx hzmk rfx xbvrx fgptl (contains nuts, fish, peanuts)\nxgpdnz hqzcncv tkhzz lpvfv hpbnj fgsr zbxj rjc rms rntk ssdszsn tktj bvlb snzxr hrnvd xbvrx rxd rfxgl spnd mrczqmj gcpks cgflg lzvh zjbgp hzmk rng lpm rdjdq hdtr fqqcnm zmsdzh fctmvrs qzjrtl gbhjv nvmm zdthsvl blvfz xvjk lsgqf jvhsj cvbc phc jqgm jqzklv gpjr nbgv gqnxlr xfn zcphr (contains fish, eggs, sesame)\npmhhqrk vhjpjdr rjc lcrs xvjk lpm dxdrk rtq vhjgg gbhjv lzvh vbkb pdt njdb fgcd bxqpgx npftghk ktnlk sqhvzg rlgr bvpxc ssrgt jbtlfv gpjr hfzqf fgsr xqgb bggmsj nmps lxldx djhj nppxr jhbnm pcslhrg mgv jgbk nlqhlsn fqtc qrpzt jfrlp mzbgp fnlk nvmm cgflg ggrc kdm zppxp nnskqnmn jqgm fctmvrs hrnvd vnbfvkp rtmfg nxrgp phc ssdszsn xbvrx rzcps rftbr ldrgj hdtr mrczqmj rtpff lkgln zgvtn hbdv czvphx spnd qpbl zvq zmsdzh rbjmdn tqkfx rdjdq tkhzz dchvb rfxgl fqqcnm (contains soy, nuts, eggs)\nbvpxc chgjqc bggmsj rfgf qpbl fgcd bmqzgvr frxmq tktj lsgqf mxzb mzbgp bxqpgx gvdstsc rzcps hbbgk drtdz vhjgg fqqcnm rntk mbmtz spnd vxmrk thtlt nhzthvn mgv jp cncpbssj sqhvzg lftqn nmps lpm nggbtk hdtr xvjk pdt kdbxxzv qlkfvk zmsdzh fzlrf cldgd jqhn ktnlk npftghk prbk qhtvsr smdlg hqzcncv gqnxlr nthsf nvmm zvq nnskqnmn mhrlx rtq phc xtgjslz qrpzt gcptp rfx mxq hjvzcp rjc lkgln zgvtn xqgb (contains nuts)\nmcl xvjk xsk sjpzc rsr zmsdzh zjbgp drtdz zcphr zvq jhv qfslcb fzlrf lcrs tqkfx rfgf prbk xqgb rjc spnd dchvb tcclbr strpjp flndv njqrhcc hfzqf pdt dkg lzvh gcpks hjvzcp lsgqf fgptl mzbgp sxsxm nvmm phc rng frxmq dxrsgs nnskqnmn nhnd bvcxfp (contains nuts, eggs)\nrtq jfrlp dchvb fppgp jp xtgjslz sfkcp zppxp rzcps spnd mbmtz llj rbjmdn rsr nbgv lsgqf jqzklv mxc lxldx hdtr njrcfg phc gbhjv nthsf dkg nhnd lcrs fqqcnm hcjkd fgptl dfcgd dxdrk pdt nlqhlsn zmsdzh hbbgk pmhhqrk rjc pdhlzg dgxnc zfnttf jbtlfv nmps bmqzgvr fgcd jhbnm flndv hzmk chgjqc dhsssf nnskqnmn cldgd (contains nuts, peanuts)\nsjpzc cvbc zcphr gpqgkt lsgqf ggrc rtmfg hrnvd cldgd ssdszsn tktj chgjqc zjbgp spnd njqrhcc hjvzcp mkxbf dgxnc ldrgj dxdrk nqvnn mzbgp ssrgt mbmtz nfgr jp pdhlzg hbdv gcpks xtgjslz sqhvzg ksrjn mcl zmsdzh fppgp dxrsgs blvfz lftqn jhv czvphx jlrt lpm bjcvpc jvhsj pdt zppxp bvlb zvq djdhrn nggbtk phc qfslcb tqkfx nmps nppxr jxvx rzcps vhjpjdr bvpxc snzxr lzvh fqqcnm qrpzt sxsxm (contains wheat, fish)\nstrpjp dxrsgs qlkfvk cgflg sxsxm hpbnj lsgqf mgv prbk prksl zmsdzh rtpff xfn czkfv dgxnc nfck ldrgj cncpbssj pfrqf zppxp bggmsj qzjrtl xvjk kjjst mbmtz sjpzc lftqn lkgln mxc rtmfg rdjdq hqzcncv jqgm psqc nxrgp hzmk rntk rms th kdm nthsf hjzkg dkg sqhvzg zvq gpqgkt qrpzt pdt zcphr rfxgl mrczqmj jbtlfv ssdszsn blvfz bvlb dfcgd nmps thtlt fqqcnm jp zfnttf fnlk frxmq rlgr hbbgk vbkb xgpdnz vhjgg czvphx vxmrk fgptl cldgd lpvfv lcrs pdhlzg hddd spnd phc pcslhrg rjc (contains eggs, peanuts, dairy)\nzfnttf spnd rfx vbkb sfkcp tkhzz zmsdzh rfxgl dgxnc lsgqf sqhvzg phc bvpxc rlgr dxrsgs pdt vnbfvkp lftqn rfgf hcjkd fgsr nkzqj xgpdnz pmhhqrk tqkfx dfcgd cncpbssj rdkrtr qlkfvk blvfz xsk nfgr rsr czmml rtq bvcxfp kmlkx zdthsvl hzmk rjc xvjk gcpks tktj xfn prbk kdbxxzv fqqcnm mxc hjvzcp jp (contains peanuts)\nnfck nnskqnmn rtpff sqhvzg lsgqf dfcgd hcjkd cvbc fzlrf bvpxc rftbr dgxnc jlrt cncpbssj cgflg fslqkg pdt nbgv xdcp nqvnn rsr jxvx hqzcncv mrczqmj gpjr fqqcnm zmsdzh cldgd qfslcb czkfv bfnnnrn prbk fqtc zjbgp qhtvsr rdkrtr bvcxfp tkhzz rfx smdlg nggbtk mzbgp qpbl nvmm th snzxr gbhjv rng vxmrk mbmtz mhrlx blvfz rzcps qrpzt nhnd lxldx gcptp zgvtn njdb kjjst mcl npftghk rjc jqhn cqqcd prksl lzvh phc vnbfvkp psqc jgbk zvq hfzqf (contains nuts, fish)\nhcjkd rzcps fnlk fzlrf dgxnc cqqcd hbdv jvhsj lsgqf rxd bvcxfp lpvfv qpbl mrczqmj jqgm mxq jqhn hfzqf zmsdzh rjc lzvh nfgr vhjgg rntk rbjmdn ssdszsn tktj pdhlzg sqhvzg tqkfx czkxlg rfxgl gpqgkt njdb dkg strpjp zdthsvl nbgv lkgln vnbfvkp rfgf pcslhrg fppgp bmqzgvr hqzcncv rng dfcgd xbvrx qdkk hzmk vhjpjdr qlkfvk rms gqnxlr hdtr jlrt kdm sjpzc qhtvsr bvlb nppxr pdt vxmrk fqqcnm jxvx qrpzt thtlt zgvtn phc ksrjn fslqkg (contains soy, peanuts, fish)\nrsr hfzqf fctmvrs zjbgp qdkk qjhq rfx hqzcncv nfgr nhzthvn xbvrx jhbnm pdt rng rdjdq pdj nnskqnmn jhv bfnnnrn kdm cldgd nppxr nthsf lzvh czvphx vhjgg hdtr mbmtz mgv jbz mhrlx fppgp rlgr ssrgt jvhsj tktj fqqcnm zbxj nvmm qzjrtl czmml ggrc zmsdzh tkhzz dxdrk jp mrczqmj phc kmlkx jqzklv nhnd rftbr thtlt pcslhrg hbmvpmt jsh nmps nggbtk rtq nqvnn lkgln snzxr xdcp fqtc lsgqf spnd mxzb llj gbhjv (contains fish)\nspnd rng lsgqf nkzqj gbhjv mhrlx mcl hzmk sfkcp bfnnnrn qpbl dkg dxdrk nmps kdm djdhrn xbvrx rlgr tcclbr drtdz fqqcnm dhsssf gcptp kdbxxzv zcphr vnjxs mrczqmj rms kjjst bvlb fgsr bkzbrm jhv gpqgkt ssdszsn qjhq th zmsdzh kmlkx rjc hqzcncv rxd mxc jhbnm nggbtk bjcvpc njrcfg lftqn jbz jqhn jbtlfv hbmvpmt rsr nqvnn pdhlzg rzcps hdtr nnskqnmn rntk ssrgt qrpzt llj thtlt mbmtz mxzb pdt hfzqf nxrgp zdthsvl lxldx lzvh (contains peanuts)\nrfgf hddd rng ssrgt tzdks zjbgp blvfz spnd lzvh ldrgj fqqcnm fnlk bvcxfp gcptp dkg bfnnnrn zfnttf kdbxxzv gpjr rntk jsh nxrgp njdb xtgjslz dhsssf dxdrk lpm nnskqnmn lcrs mzrx nvmm jp prksl rzcps xgpdnz czmml rbjmdn mxq qhtvsr dgxnc bxqpgx mbmtz nmps bmqzgvr dfcgd pdt xbvrx njrcfg rfx fppgp fgptl fzlrf qrpzt zmsdzh cncpbssj tkhzz phc mkxbf rjc njqrhcc cqqcd tqkfx mxc nhzthvn hzmk pdj (contains fish)\nrms qrpzt hbbgk sxsxm dchvb jqhn gcptp xqgb psqc fctmvrs nlqhlsn tktj rntk qfslcb xdcp rfxgl fqqcnm jlrt zgvtn fgcd bvlb cvbc xbvrx rdkrtr rlgr prbk zmsdzh ssrgt phc tcclbr lpvfv djhj rsr rfx blvfz lzvh gpqgkt hpbnj bfnnnrn dxdrk nmps cncpbssj hjzkg hrnvd hbdv dgxnc hdtr rjc rdjdq jxvx qpbl zvq rtmfg jhbnm vhjpjdr nvmm lsgqf czkxlg pdt prksl xgpdnz rbjmdn gcpks fgsr zjbgp frxmq (contains soy, fish, peanuts)\ndrtdz nbgv hcjkd mxq sqhvzg xfn nfck phc gcptp hdtr nnskqnmn tqkfx rfxgl jqhn lpvfv blvfz czkxlg djhj lsgqf bggmsj flndv kmlkx mxzb czmml vnjxs spnd dchvb lzvh fzlrf bkzbrm xbvrx prbk ksrjn rxd fqqcnm xgpdnz pdt jfrlp bvpxc fgptl ktnlk njdb zmsdzh (contains nuts, wheat, fish)\nvxmrk fqqcnm rlgr prbk fgsr tktj gqnxlr ssrgt phc rng gcpks mzrx dxdrk njqrhcc czmml cgflg qjhq vnjxs prksl ktnlk tcclbr qhtvsr sjpzc bggmsj nhzthvn zmsdzh ggrc jp rfgf rtpff zcphr lsgqf spnd blvfz rjc tkhzz sxsxm xfn pdt xqgb mrczqmj zdthsvl jhbnm bvcxfp ssdszsn djhj npftghk (contains nuts, eggs, sesame)\nsfkcp bvpxc rfgf bjcvpc bggmsj jbz zppxp gpqgkt mgv lzvh qjhq hbbgk mrczqmj zmsdzh rlgr cvbc qzjrtl rbjmdn mxc czmml fqqcnm hfzqf jfrlp nhzthvn fctmvrs lftqn tcclbr djdhrn rjc cgflg spnd sjpzc phc pmhhqrk fslqkg flndv hzmk nvmm jp prksl dkg gcptp pdt (contains fish)\ndchvb nppxr njdb fqqcnm hbbgk strpjp bvcxfp nhnd rjc hpbnj tkhzz jqzklv spnd vbkb jqgm phc pdt bxqpgx kdbxxzv zmsdzh xgpdnz rfxgl kdm drtdz nhzthvn ldrgj rdkrtr thtlt cvbc mhrlx bggmsj hjvzcp sjpzc nbgv gcptp hqd lcrs hddd djhj ssdszsn tqkfx xtgjslz mzbgp rdjdq nnskqnmn hqzcncv hjzkg jfrlp mxq nmps pmhhqrk pdj th fgcd psqc lsgqf gcpks xfn fgptl nfck mkxbf mbmtz rxd blvfz ggrc zppxp mcl ksrjn zbxj nkzqj hbdv lpm dxdrk zcphr qhtvsr pcslhrg tktj (contains sesame)\nlzvh psqc rjc nhzthvn tqkfx lcrs pfrqf lkgln spnd nhnd pmhhqrk lxldx hqd dchvb zvq vnbfvkp mcl rsr rdkrtr hpbnj rfgf fzlrf ssrgt phc djdhrn fppgp rftbr xqgb hbdv vbkb tktj jqgm sfkcp pdt bggmsj bmqzgvr zfnttf jbtlfv nxrgp flndv sxsxm lsgqf zbxj dfcgd nmps mxc bvpxc rbjmdn gbhjv dxrsgs sjpzc jp fgcd zmsdzh jhbnm vxmrk bjcvpc zcphr gqnxlr njdb nvmm jqzklv kdbxxzv jsh xtgjslz gcpks rntk qpbl djhj lftqn ldrgj xfn hdtr tzdks tcclbr gcptp nnskqnmn (contains eggs, soy)\ngpqgkt lftqn frxmq dchvb hbdv gvdstsc djdhrn ssrgt drtdz rjc gpjr jvhsj rfxgl hqd spnd rtpff mzrx qfslcb cgflg jqhn strpjp zcphr xtgjslz lsgqf pcslhrg smdlg czmml nqvnn fqtc qpbl dkg phc xfn fgsr fppgp dgxnc cqqcd qzjrtl ggrc lkgln ksrjn nvmm qdkk rxd jlrt jhbnm nhnd lpm hjvzcp bfnnnrn pmhhqrk rdjdq hcjkd czvphx xbvrx zgvtn dxrsgs fqqcnm zmsdzh njqrhcc lzvh rzcps fzlrf (contains sesame, soy)\njgbk gvdstsc spnd rtmfg psqc njdb drtdz thtlt dxrsgs cldgd hjvzcp nggbtk dfcgd nppxr mbmtz gcpks rdjdq lzvh czvphx rjc vnbfvkp mhrlx frxmq bfnnnrn kmlkx qpbl lsgqf ldrgj qrpzt jp bvpxc phc zmsdzh jbtlfv nhzthvn rsr jxvx th rzcps kdbxxzv xgpdnz nqvnn rdkrtr pmhhqrk pdt prbk rbjmdn fgptl gpjr zbxj czmml tqkfx xdcp njqrhcc cncpbssj chgjqc fgcd (contains nuts, dairy, eggs)\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_21_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 21\n-------------------------------------------\n--  Allergen Assessment\n--\n--  https://adventofcode.com/2020/day/21\n--\n--  Full Ada version.\n--\n--  Main obstacles for using HAC:\n--    - lack of 'Value (or at least 'Image) attribute\n--    - lack of logical operators on arrays of Boolean\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nprocedure AoC_2020_21_full_Ada is\n\n  --  Enumerated types created by removing duplicates from data.\n  --  See: AoC_2020_21_full_Ada_Preproc.\n\n  type Ingredient is (bfnnnrn, bggmsj, bjcvpc, bkzbrm, blvfz, bmqzgvr,\n    bvcxfp, bvlb, bvpxc, bxqpgx, cgflg, chgjqc, cldgd, cncpbssj, cqqcd,\n    cvbc, czkfv, czkxlg, czmml, czvphx, dchvb, dfcgd, dgxnc, dhsssf, djdhrn,\n    djhj, dkg, drtdz, dxdrk, dxrsgs, fctmvrs, fgcd, fgptl, fgsr, flndv,\n    fnlk, fppgp, fqqcnm, fqtc, frxmq, fslqkg, fzlrf, gbhjv, gcpks, gcptp,\n    ggrc, gpjr, gpqgkt, gqnxlr, gvdstsc, hbbgk, hbdv, hbmvpmt, hcjkd, hddd,\n    hdtr, hfzqf, hjvzcp, hjzkg, hpbnj, hqd, hqzcncv, hrnvd, hzmk, jbtlfv,\n    jbz, jfrlp, jgbk, jhbnm, jhv, jlrt, jp, jqgm, jqhn, jqzklv, jsh, jvhsj,\n    jxvx, kdbxxzv, kdm, kjjst, kmlkx, ksrjn, ktnlk, lcrs, ldrgj, lftqn,\n    lkgln, llj, lpm, lpvfv, lsgqf, lxldx, lzvh, mbmtz, mcl, mgv, mhrlx,\n    mkxbf, mrczqmj, mxc, mxq, mxzb, mzbgp, mzrx, nbgv, nfck, nfgr, nggbtk,\n    nhnd, nhzthvn, njdb, njqrhcc, njrcfg, nkzqj, nlqhlsn, nmps, nnskqnmn,\n    npftghk, nppxr, nqvnn, nthsf, nvmm, nxrgp, pcslhrg, pdhlzg, pdj, pdt,\n    pfrqf, phc, pmhhqrk, prbk, prksl, psqc, qdkk, qfslcb, qhtvsr, qjhq,\n    qlkfvk, qpbl, qrpzt, qzjrtl, rbjmdn, rdjdq, rdkrtr, rfgf, rftbr, rfx,\n    rfxgl, rjc, rlgr, rms, rng, rntk, rsr, rtmfg, rtpff, rtq, rxd, rzcps,\n    sfkcp, sjpzc, smdlg, snzxr, spnd, sqhvzg, ssdszsn, ssrgt, strpjp, sxsxm,\n    tcclbr, th, thtlt, tkhzz, tktj, tqkfx, tzdks, vbkb, vhjgg, vhjpjdr,\n    vnbfvkp, vnjxs, vxmrk, xbvrx, xdcp, xfn, xgpdnz, xqgb, xsk, xtgjslz,\n    xvjk, zbxj, zcphr, zdthsvl, zfnttf, zgvtn, zjbgp, zmsdzh, zppxp, zvq);\n\n  type Allergen is (dairy, eggs, fish, nuts, peanuts, sesame, soy, wheat);\n\n  use HAT;\n\n  name : constant VString := +\"aoc_2020_21.txt\";\n\n  --  type Ingredient is (fvjkl, kfcds, mxmxvkd, nhms, sbzzf, sqjhc, trh);\n  --  type Allergen is (dairy, fish, soy);\n  --  name : constant VString := +\"mini.txt\";\n\n  type Ingredient_Set is array (Ingredient) of Boolean;\n  type Allergen_Set is array (Allergen) of Boolean;\n\n  type Food is record\n    ingr : Ingredient_Set;\n    allr : Allergen_Set;\n  end record;\n\n  food_list_max : constant := 100;\n  foods : Natural := 0;\n\n  type Food_List_Type is array (1 .. food_list_max) of Food;\n\n  food_list : Food_List_Type;\n\n  verbose : constant Boolean := True;\n\n  generic\n    type Enum is (<>);\n    type Enum_Set is array (Enum) of Boolean;\n  procedure Gen_Count (set : Enum_Set; total : out Natural; last : out Enum; verb : Boolean);\n\n  procedure Gen_Count (set : Enum_Set; total : out Natural; last : out Enum; verb : Boolean) is\n  begin\n    total := 0;\n    for e in set'Range loop\n      if set (e) then\n        if verb then Put (\" \" & e'Image); end if;\n        last := e;\n        total := total + 1;\n      end if;\n    end loop;\n    if verb then Put (total'Image & \" \"); end if;\n  end Gen_Count;\n\n  procedure Count is new Gen_Count (Ingredient, Ingredient_Set);\n\n  i_of_a : array (Allergen) of Ingredient;\n\n  procedure Find_Allergens_Ingredients (total_1 : out Natural) is\n    --  In a food ingrendient list, not all allergen are listed.\n    --  But when an allergen is listed, its associated ingredient IS listed, among others.\n    i_for_a : array (Allergen) of Ingredient_Set := (others => (others => True));\n    --  An allergen is done when the set of possible ingredients is reduced to 1.\n    done : array (Allergen) of Boolean := (others => False);\n    total : Natural;\n    i : Ingredient;\n    scrap : Food_List_Type := food_list;\n    to_solve : Natural := Allergen'Pos (Allergen'Last) + 1;\n  begin\n    loop\n      for f in 1 .. foods loop\n        for a in Allergen loop\n          if scrap (f).allr (a) then\n            --  Allergen a is in the food #f.\n            --  Then we can narrow the set of possible ingredients for a.\n            i_for_a (a) := i_for_a (a) and scrap (f).ingr;\n          end if;\n        end loop;\n      end loop;\n      --\n      for a in Allergen loop\n        if not done (a) then\n          if verbose then\n            Put (\"   \" & a'Image & \" can only be in ingredients: \");\n          end if;\n          Count (i_for_a (a), total, i, verbose);\n          if verbose then\n            New_Line;\n          end if;\n          if total = 1 then\n            --  Hurra, allergen a is ONLY in ONE ingredient, i.\n            --  We apply now the rule \"Each allergen is found in exactly ONE ingredient.\"\n            for f in 1 .. foods loop\n              --  Remove allergenic a and ingredient i everywhere.\n              scrap (f).allr (a) := False;\n              scrap (f).ingr (i) := False;\n            end loop;\n            if verbose then\n              Put_Line (\" -> allergen \" & a'Image & \" associated to ingredient \" & i'Image);\n            end if;\n            to_solve := to_solve - 1;\n            done (a) := True;\n            i_of_a (a) := i;\n          end if;\n        end if;\n      end loop;\n      exit when to_solve = 0;\n    end loop;\n    --\n    total_1 := 0;\n    for f in 1 .. foods loop\n      for i in Ingredient loop\n        if scrap (f).ingr (i) then  --  Unassociated ingredient.\n          total_1 := total_1 + 1;\n        end if;\n      end loop;\n    end loop;\n  end Find_Allergens_Ingredients;\n\n  procedure Read_Data is\n    f : File_Type;\n    s, s1, s2, key : VString;\n    i, paren : Integer;\n  begin\n    Open (f, name);\n    while not End_Of_File (f) loop\n      foods := foods + 1;\n      food_list (foods).ingr := (others => False);\n      food_list (foods).allr := (others => False);\n      Get_Line (f, s);\n      paren := Index (s, \"(contains \");\n      s1 := Slice (s, 1, paren - 1);\n      s2 := Slice (s, paren + 10, Length (s));\n      loop\n        i := Index (s1, \" \");\n        exit when i = 0;\n        key := Slice (s1, 1, i - 1);\n        food_list (foods).ingr (Ingredient'Value (VStr_Pkg.To_String (key))) := True;\n        s1 := Slice (s1, i + 1, Length (s1));\n      end loop;\n      loop\n        i := Index (s2, \", \");\n        exit when i = 0;\n        key := Slice (s2, 1, i - 1);\n        food_list (foods).allr (Allergen'Value (VStr_Pkg.To_String (key))) := True;\n        s2 := Slice (s2, i + 2, Length (s2));\n      end loop;\n      key := Slice (s2, 1, Length (s2) - 1);\n      food_list (foods).allr (Allergen'Value (VStr_Pkg.To_String (key))) := True;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  total_n : Natural;\n\nbegin\n  Read_Data;\n  Find_Allergens_Ingredients (total_n);\n  Put_Line (+\"Part 1: ingredients without known allergens: \" & total_n);\n  Put (\"Part 2: list of ingredients sorted by allergen's name: \");\n  for i of i_of_a loop Put (To_Lower (+i'Image) & ','); end loop;\n  New_Line;\nend AoC_2020_21_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_21_full_ada_preproc.adb",
    "content": "--  Preparation of Advent of Code 2020, Day 21\n----------------------------------------------\n--\n--  https://adventofcode.com/2020/day/21\n--\nwith Ada.Containers.Ordered_Maps, Ada.Text_IO;\n\nwith HAT;  --  in ../../../src\n\nprocedure AoC_2020_21_full_Ada_Preproc is\n  use HAT;\n\n  package Name_Mapping is new Ada.Containers.Ordered_Maps (VString, VString);\n\n  ingredient_map, allergen_map : Name_Mapping.Map;\n\n  i : Integer;\n  f : File_Type;\n  s, s1, s2, key : VString;\n  paren : Integer;\nbegin\n  Open (f, \"aoc_2020_21.txt\");\n  while not End_Of_File (f) loop\n    Get_Line (f, s);\n    paren := Index (s, \"(contains \");\n    s1 := Slice (s, 1, paren - 1);\n    s2 := Slice (s, paren + 10, Length (s));\n    loop\n      i := Index (s1, \" \");\n      exit when i = 0;\n      key := Slice (s1, 1, i - 1);\n      ingredient_map.Include (key, key);\n      s1 := Slice (s1, i + 1, Length (s1));\n    end loop;\n    loop\n      i := Index (s2, \", \");\n      exit when i = 0;\n      key := Slice (s2, 1, i - 1);\n      allergen_map.Include (key, key);\n      s2 := Slice (s2, i + 2, Length (s2));\n    end loop;\n    key := Slice (s2, 1, Length (s2) - 1);\n    allergen_map.Include (key, key);\n  end loop;\n  Close (f);\n  Put (\"  type Ingredient is (\");\n  for ingr of ingredient_map loop\n    Put (ingr & \", \");\n    if Integer (Ada.Text_IO.Col) > 70 then\n      New_Line;\n      Put (\"    \");\n    end if;\n  end loop;\n  New_Line;\n  Put (\"  type Allergen is (\");\n  for aller of allergen_map loop\n    Put (aller & \", \");\n  end loop;\n  New_Line;\nend AoC_2020_21_full_Ada_Preproc;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_22.adb",
    "content": "--  Solution to Advent of Code 2020, Day 22\n-------------------------------------------\n--  Crab Combat\n--\n--  https://adventofcode.com/2020/day/22\n--\n--  HAC 0.083 \"nice to have\"'s detected in this exercise:\n--\n--    *     comparison (equality operators) \"=\", \"/=\" of composite types (arrays and records)\n\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nprocedure AoC_2020_22 is\n  use HAT;\n\n  max_deck : constant := 50;\n\n  type Cards is array (1 .. max_deck) of Natural;\n\n  type Deck is record\n    top  : Natural;\n    card : Cards;\n  end record;\n\n  type Deck_Pair is array (1 .. 2) of Deck;\n\n  verbosity : constant := 0;\n\n  procedure Play (\n    g               : in out Deck_Pair;\n    winner          :    out Positive;\n    is_recursive    : in     Boolean;\n    recursion_level : in     Positive  --  For information only\n  )\n  is\n    --  \"The winner keeps both cards, placing them on the bottom\n    --   of their own deck so that the winner's card is above\n    --   the other card.\"\n    procedure Move_Top_Cards (winner, loser : in out Deck) is\n      top_card_winner, top_card_loser : Positive;\n    begin\n      top_card_winner := winner.card (winner.top);\n      top_card_loser  := loser.card (loser.top);\n      loser.top := loser.top - 1;\n      winner.top := winner.top + 1;\n      for i in reverse 3 .. winner.top loop\n        winner.card (i) := winner.card (i - 2);\n      end loop;\n      winner.card (1) := top_card_loser;\n      winner.card (2) := top_card_winner;\n    end Move_Top_Cards;\n    --\n    sub : Deck_Pair;\n    top_card : array (1 .. 2) of Positive;\n    round_win : Positive;\n    round : Natural := 0;\n    type Game_Mem is array (1 .. 1000) of Deck_Pair;\n    --  A size 100_000 is needed for the \"real\" data, otherwise\n    --  we would not be able to memorize enough the past decks.\n    --  But the needed stack for HAC would be huge and would\n    --  slow down the initialization part of the interpreter.\n    --  Better to switch to \"full Ada\" at this point.\n    --  See AoC_2020_22_full_Ada (file: aoc_2020_22_full_ada.adb).\n    mem : Game_Mem;\n    --\n    function Equal (g, h : Deck_Pair) return Boolean is\n    begin\n      for player in 1 .. 2 loop\n        if g (player).top /= h (player).top then\n          return False;\n        end if;\n        for i in 1 .. g (player).top loop\n          if g (player).card (i) /= h (player).card (i) then\n            return False;\n          end if;\n        end loop;\n      end loop;\n      return True;\n    end Equal;\n    --\n  begin\n    if verbosity > 1 and recursion_level > 6 then\n      Put_Line (+\"level=\" & recursion_level);\n    end if;\n    loop\n      round := round + 1;\n      mem (round) := g;\n      --\n      --  Recursion breaker (first rule of Recursive Combat).\n      --\n      if is_recursive then\n        for i in 1 .. round - 1 loop\n          if Equal (mem (i), g) then\n            winner := 1;\n            return;\n          end if;\n        end loop;\n      end if;\n      --\n      --  Draw cards.\n      --\n      for p in 1 .. 2 loop\n        top_card (p) := g (p).card (g (p).top);\n      end loop;\n      if is_recursive and\n         g (1).top - 1 >= top_card (1) and\n         g (2).top - 1 >= top_card (2)\n      then\n        --  Copy parts of the decks for the sub-game.\n        --\n        --  \"To play a sub-game of Recursive Combat, each player creates\n        --   a new deck by making a copy of the next cards in their deck\n        --   (the quantity of cards copied is equal to the number on the\n        --   card they drew to trigger the sub-game).\"\n        for p in 1 .. 2 loop\n          for i in 1 .. top_card (p) loop\n            sub (p).card (i) := g (p).card (g (p).top - 1 + i - top_card (p));\n          end loop;\n          sub (p).top := top_card (p);\n        end loop;\n        Play (sub, round_win, is_recursive, recursion_level + 1);\n      elsif top_card (1) > top_card (2) then\n        round_win := 1;\n      else\n        round_win := 2;\n      end if;\n      if round_win = 1 then\n        Move_Top_Cards (g (1), g (2));\n      else\n        Move_Top_Cards (g (2), g (1));\n      end if;\n      exit when g (1).top = 0 or g (2).top = 0;\n    end loop;\n    if g (1).top > 0 then\n      winner := 1;\n    else\n      winner := 2;\n    end if;\n  end Play;\n  --\n  procedure Show (a : Deck) is\n  begin\n    for i in 1 .. a.top loop\n      Put_Line (+\"    card \" & i & \":  \" & a.card (i));\n    end loop;\n  end Show;\n  --\n  function Score (a : Deck) return Natural is\n    res : Natural := 0;\n  begin\n    for i in 1 .. a.top loop\n      res := res + i * a.card (i);\n    end loop;\n    return res;\n  end Score;\n  --\n  procedure Read_Data (g : out Deck_Pair) is\n    data : Deck_Pair;\n    f : File_Type;\n    s : VString;\n    p : Natural := 0;\n  begin\n    Open (f, \"aoc_2020_22.txt\");\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      if Head (s, 6) = \"Player\" then\n        p := p + 1;\n        data (p).top := 0;\n      elsif s = \"\" then\n        null;\n      else\n        data (p).top := data (p).top + 1;\n        data (p).card (data (p).top) := Integer_Value (s);\n      end if;\n    end loop;\n    Close (f);\n    --  Invert the deck: top <-> bottom\n    for p in 1 .. 2 loop\n      g (p).top := data (p).top;\n      for i in 1 .. g (p).top loop\n        g (p).card (i) := data (p).card (1 + data (p).top - i);\n      end loop;\n    end loop;\n  end Read_Data;\n  --\n  winner : Positive;\n  g, g_start : Deck_Pair;\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\nbegin\n  Read_Data (g_start);\n  g := g_start;\n  Play (g, winner, False, 1);\n  if verbosity > 0 then\n    Put_Line (+\"Winner is: \" & winner);\n    Show (g (winner));\n  end if;\n  if compiler_test_mode then\n    if Score (g (winner)) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Score: \" & Score (g (winner)));\n  end if;\n  --  Part 1: validated by AoC: 31957\n  --  Part 2: validated by AoC: 33212. Part skipped (see remarks around Game_Mem).\nend AoC_2020_22;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_22.txt",
    "content": "Player 1:\n26\n16\n33\n8\n5\n46\n12\n47\n39\n27\n50\n10\n34\n20\n23\n11\n43\n14\n18\n1\n48\n28\n31\n38\n41\n\nPlayer 2:\n45\n7\n9\n4\n15\n19\n49\n3\n36\n25\n24\n2\n21\n37\n35\n44\n29\n13\n32\n22\n17\n30\n42\n40\n6\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_22_full_ada.adb",
    "content": "--  Solution to Advent of Code 2020, Day 22\n-------------------------------------------\n--  Crab Combat\n--\n--  https://adventofcode.com/2020/day/22\n--\n--  Full Ada version\n--\n--  Run-time with GNAT, AoC_Build_Mode = \"Fast\":\n--    *  4.45  seconds for a i5-9400 @ 2.9 GHz using a heap-allocated\n--               fixed (100,000) size array for memorizing the previous decks\n--    *  1.25  seconds for a i5-9400 @ 2.9 GHz using a vector\n--    *  0.36  seconds for a i5-9400 @ 2.9 GHz using a hashed set\n\nwith Ada.Containers.Hashed_Sets,\n     Ada.Containers.Vectors;\n\nwith HAT;\n--  ^ Files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nprocedure AoC_2020_22_full_Ada is\n\n  max_deck : constant := 50;\n\n  type Cards is array (1 .. max_deck) of Natural;\n\n  type Deck is record\n    top  : Natural;\n    card : Cards;\n  end record;\n\n  type Deck_Pair is array (1 .. 2) of Deck;\n\n  verbosity : constant := 0;\n\n  use HAT;\n\n  procedure Play (\n    g               : in out Deck_Pair;\n    winner          :    out Positive;\n    is_recursive    : in     Boolean;\n    recursion_level : in     Positive  --  For information only\n  )\n  is\n    --  \"The winner keeps both cards, placing them on the bottom\n    --   of their own deck so that the winner's card is above\n    --   the other card.\"\n    procedure Move_Top_Cards (winner, loser : in out Deck) is\n      top_card_winner, top_card_loser : Positive;\n    begin\n      top_card_winner := winner.card (winner.top);\n      top_card_loser  := loser.card (loser.top);\n      loser.top := loser.top - 1;\n      winner.top := winner.top + 1;\n      for i in reverse 3 .. winner.top loop\n        winner.card (i) := winner.card (i - 2);\n      end loop;\n      winner.card (1) := top_card_loser;\n      winner.card (2) := top_card_winner;\n    end Move_Top_Cards;\n    --\n    sub : Deck_Pair;\n    top_card : array (1 .. 2) of Positive;\n    round_win : Positive;\n    round : Natural := 0;\n    --\n    function Equal (g, h : Deck_Pair) return Boolean\n    with Inline\n    is\n    begin\n      for player in 1 .. 2 loop\n        if g (player).top /= h (player).top then\n          return False;\n        end if;\n        for i in 1 .. g (player).top loop\n          if g (player).card (i) /= h (player).card (i) then\n            return False;\n          end if;\n        end loop;\n      end loop;\n      return True;\n    end Equal;\n    --\n    function Hash (g : Deck_Pair) return Ada.Containers.Hash_Type\n    with Inline\n    is\n      use Ada.Containers;\n      knuth : constant := 2654435761;\n      res : Hash_Type := 1;\n    begin\n      for player in 1 .. 2 loop\n        res := knuth * res + Hash_Type (g (player).top);\n        for i in 1 .. g (player).top loop\n          res := knuth * res + Hash_Type (g (player).card (i));\n        end loop;\n      end loop;\n      return res;\n    end Hash;\n    --\n    --  We benchmark Vectors (linear search) vs. Hashed_Sets.\n    --\n    type Memory_Type is (use_vectors, use_sets);\n    mem_type_choice : constant Memory_Type := use_sets;\n    --\n    package Game_Mem_Vectors is new Ada.Containers.Vectors (Positive, Deck_Pair);\n    mem_vec : Game_Mem_Vectors.Vector;\n    --\n    package Game_Mem_Sets is new Ada.Containers.Hashed_Sets (Deck_Pair, Hash, Equal, Equal);\n    mem_set : Game_Mem_Sets.Set;\n    --\n  begin\n    if verbosity > 1 and recursion_level > 6 then\n      Put_Line (+\"level=\" & recursion_level);\n    end if;\n    loop\n      round := round + 1;\n      --\n      --  Recursion breaker (first rule of Recursive Combat).\n      --\n      if is_recursive then\n        case mem_type_choice is\n          when use_vectors =>\n            for mem of mem_vec loop\n              if Equal (mem, g) then\n                --  NB: the test `mem (i) = g` happens to work but is incorrect\n                --      (compares cards above top)\n                winner := 1;\n                return;\n              end if;\n            end loop;\n            mem_vec.Append (g);\n          when use_sets =>\n            if mem_set.Contains (g) then\n              winner := 1;\n              return;\n            end if;\n            mem_set.Include (g);\n        end case;\n      end if;\n      --\n      --  Draw cards.\n      --\n      for p in 1 .. 2 loop\n        top_card (p) := g (p).card (g (p).top);\n      end loop;\n      if is_recursive and\n         g (1).top - 1 >= top_card (1) and\n         g (2).top - 1 >= top_card (2)\n      then\n        --  Copy parts of the decks for the sub-game.\n        --\n        --  \"To play a sub-game of Recursive Combat, each player creates\n        --   a new deck by making a copy of the next cards in their deck\n        --   (the quantity of cards copied is equal to the number on the\n        --   card they drew to trigger the sub-game).\"\n        for p in 1 .. 2 loop\n          for i in 1 .. top_card (p) loop\n            sub (p).card (i) := g (p).card (g (p).top - 1 + i - top_card (p));\n          end loop;\n          sub (p).top := top_card (p);\n        end loop;\n        Play (sub, round_win, is_recursive, recursion_level + 1);\n      elsif top_card (1) > top_card (2) then\n        round_win := 1;\n      else\n        round_win := 2;\n      end if;\n      if round_win = 1 then\n        Move_Top_Cards (g (1), g (2));\n      else\n        Move_Top_Cards (g (2), g (1));\n      end if;\n      exit when g (1).top = 0 or g (2).top = 0;\n    end loop;\n    if g (1).top > 0 then\n      winner := 1;\n    else\n      winner := 2;\n    end if;\n  end Play;\n  --\n  procedure Show (a : Deck) is\n  begin\n    for i in 1 .. a.top loop\n      Put_Line (+\"    card \" & i & \":  \" & a.card (i));\n    end loop;\n  end Show;\n  --\n  function Score (a : Deck) return Natural is\n    res : Natural := 0;\n  begin\n    for i in 1 .. a.top loop\n      res := res + i * a.card (i);\n    end loop;\n    return res;\n  end Score;\n  --\n  procedure Read_Data (g : out Deck_Pair) is\n    data : Deck_Pair;\n    f : File_Type;\n    s : VString;\n    p : Natural := 0;\n  begin\n    Open (f, \"aoc_2020_22.txt\");\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      if Head (s, 6) = \"Player\" then\n        p := p + 1;\n        data (p).top := 0;\n      elsif s = \"\" then\n        null;\n      else\n        data (p).top := data (p).top + 1;\n        data (p).card (data (p).top) := Integer_Value (s);\n      end if;\n    end loop;\n    Close (f);\n    --  Invert the deck: top <-> bottom\n    for p in 1 .. 2 loop\n      g (p).top := data (p).top;\n      for i in 1 .. g (p).top loop\n        g (p).card (i) := data (p).card (1 + data (p).top - i);\n      end loop;\n    end loop;\n  end Read_Data;\n  --\n  winner : Positive;\n  g, g_start : Deck_Pair;\nbegin\n  Read_Data (g_start);\n  for is_recursive in Boolean loop\n    g := g_start;\n    Play (g, winner, is_recursive, 1);\n    if verbosity > 0 then\n      Put_Line (+\"Winner is: \" & winner);\n      Show (g (winner));\n    end if;\n    Put_Line (+\"Score: \" & Score (g (winner)));\n  end loop;\n  --  Part 1: Validated by AoC: 31957\n  --  Part 2: Validated by AoC: 33212\nend AoC_2020_22_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_23.adb",
    "content": "--  Solution to Advent of Code 2020, Day 23\n-------------------------------------------\n--  Crab Cups\n--\n--  https://adventofcode.com/2020/day/23\n--\n--  In this version, we don't move the cups at all.\n--  We redefine which one is the next.\n--\n--  Total run time for both parts, example & input:\n--      0.58 second (GNAT AoC_Build_Mode_Type = \"Fast\", i5-9400 @ 2.9 GHz).\n--    324.75 seconds (HAC, fastest build, same machine...).\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and GNAT (64-bit integer: Integer_64):\nwith Interfaces;\n\nprocedure AoC_2020_23 is\n  use HAT, Interfaces;\n\n  max_cup_pos : constant := 9;\n  subtype Cup_Range is Positive range 1 .. max_cup_pos;\n  type Cup_Array is array (Cup_Range) of Cup_Range;\n\n  function Play (c_init : Cup_Array; part : Positive) return Integer_64 is\n    big_max : constant := 1_000_000;\n\n    subtype Big_Cup_Range is Positive range 1 .. big_max;\n\n    type Cup_Info is record\n      label : Big_Cup_Range;\n      next  : Big_Cup_Range;\n    end record;\n\n    index_from_label : array (Cup_Range) of Big_Cup_Range;\n\n    c : array (Big_Cup_Range) of Cup_Info;\n\n    pick_label : array (1 .. 3) of Big_Cup_Range;\n    current_index, cursor,\n    pick_index, last_pick_index, after_pick_index,\n    dest_index, dest_next_index : Big_Cup_Range := 1;\n    --  ^ Initialization is just for removing a\n    --    warning issued by the ObjectAda compiler.\n    dest_label : Integer;\n    found : Boolean;\n    part_max, rounds : Positive;\n    res : Integer_64 := 0;\n  begin\n    if part = 1 then\n      part_max := max_cup_pos;\n      rounds   := 100;\n    else\n      part_max := big_max;\n      rounds   := 10_000_000;\n    end if;\n    for i in 1 .. part_max loop\n      if i <= max_cup_pos then\n        c (i).label := c_init (i);\n        index_from_label (c (i).label) := i;\n      else\n        c (i).label := i;\n      end if;\n      c (i).next  := 1 + i mod part_max;\n    end loop;\n    --\n    current_index := 1;\n    Game :\n    for round in 1 .. rounds loop\n      --  The crab picks up the three cups that are immediately\n      --  clockwise of the current cup.\n      pick_index := c (current_index).next;\n      cursor := pick_index;\n      for j in 1 .. 3 loop\n        pick_label (j) := c (cursor).label;\n        last_pick_index := cursor;\n        cursor := c (cursor).next;\n      end loop;\n      after_pick_index := cursor;\n      --  They are removed from the circle; cup spacing is adjusted as\n      --  necessary to maintain the circle.\n      c (current_index).next := after_pick_index;\n      --  The crab selects a destination cup: the cup with a label equal\n      --  to the current cup's label minus one.\n      dest_label := c (current_index).label - 1;\n      --\n      loop\n        --  If at any point in this process the value goes below the\n        --  lowest value on any cup's label, it wraps around to the\n        --  highest value on any cup's label instead.\n        if dest_label < 1 then\n          dest_label := part_max;\n        end if;\n        found := False;\n        for i in 1 .. 3 loop\n          if dest_label = pick_label (i) then\n            found := True;\n            exit;\n          end if;\n        end loop;\n        exit when not found;\n        --  If this would select one of the cups that was just picked up,\n        --  the crab will keep subtracting one until it finds a cup that\n        --  wasn't just picked up.\n        dest_label := dest_label - 1;\n      end loop;\n      --\n      if dest_label <= max_cup_pos then\n        dest_index := index_from_label (dest_label);\n      else\n        dest_index := dest_label;\n      end if;\n      --  The crab places the cups it just picked up so that they are\n      --  immediately clockwise of the destination cup. They keep the\n      --  same order as when they were picked up.\n      dest_next_index := c (dest_index).next;\n      c (dest_index).next := pick_index;\n      c (last_pick_index).next := dest_next_index;\n      --\n      current_index := c (current_index).next;\n    end loop Game;\n    --\n    if part = 1 then\n      for i in 1 .. max_cup_pos loop\n        if c (i).label = 1 then\n          cursor := i;\n          for count in 1 .. max_cup_pos - 1 loop\n            cursor := c (cursor).next;\n            res := 10 * res + Integer_64 (c (cursor).label);\n          end loop;\n        end if;\n      end loop;\n    else\n      for i in 1 .. big_max loop\n        if c (i).label = 1 then\n          cursor := i;\n          cursor := c (cursor).next;\n          res := Integer_64 (c (cursor).label);\n          Put (c (cursor).label, 0);\n          Put (\", \");\n          cursor := c (cursor).next;\n          Put (c (cursor).label, 0);\n          res := res * Integer_64 (c (cursor).label);\n          exit;\n        end if;\n      end loop;\n    end if;\n    return res;\n  end Play;\n\n  exm, inp : Cup_Array;\n  res : Integer_64;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n\nbegin\n  --  example 389125467\n  --  input   523764819\n  --\n  --  With full Ada we can write  ` exm := (3,8,9,1,2,5,4,6,7); `\n  --\n  exm (1) := 3;\n  exm (2) := 8;\n  exm (3) := 9;\n  exm (4) := 1;\n  exm (5) := 2;\n  exm (6) := 5;\n  exm (7) := 4;\n  exm (8) := 6;\n  exm (9) := 7;\n  --\n  inp (1) := 5;\n  inp (2) := 2;\n  inp (3) := 3;\n  inp (4) := 7;\n  inp (5) := 6;\n  inp (6) := 4;\n  inp (7) := 8;\n  inp (8) := 1;\n  inp (9) := 9;\n  --\n  for part in 1 .. 2 loop\n    if compiler_test_mode then\n      if Play (exm, part) /= Integer_64'Value (To_String (Argument (1))) or\n         Play (inp, part) /= Integer_64'Value (To_String (Argument (2)))\n      then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n      exit;\n      --  ^ This is for HAC & compiler testing: we skip part 2, takes too long.\n    else\n      Put (+\"Part: \" & part & \": labels on the \");\n      if part = 1 then\n        Put_Line (\"cups after cup 1\");\n      else\n        Put_Line (\"two cups that will end up immediately clockwise of cup 1\");\n      end if;\n      Put (\"  From example : \");\n      res := Play (exm, part);\n      if res > 0 then Put (Integer_64'Image (res)); end if;\n      New_Line;\n      --  Example, part 1: from AoC site:    67384529\n      --  Example, part 2: from AoC site:    149245887792 = 934001 * 159792\n      Put (\"  From input   : \");\n      res := Play (inp, part);\n      if res > 0 then Put (Integer_64'Image (res)); end if;\n      New_Line;\n      --  Input, part 1: validated by AoC: 49576328\n      --  Input, part 2: validated by AoC: 511780369955 = 760147 * 673265\n    end if;\n  end loop;\nend AoC_2020_23;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_23_simple_array.adb",
    "content": "--  Solution to Advent of Code 2020, Day 23\n-------------------------------------------\n--  Crab Cups\n--\n--  https://adventofcode.com/2020/day/23\n--\n--  Moving the cups to fill the gaps is very time-consuming\n--  on large sizes (part 2 of the game).\n--  See AoC_2020_23 for a much more efficient solution.\n--\n--  Total run time for both parts, example & input:\n--  169 minutes (almost 3 hours) with\n--  GNAT, AoC_Build_Mode_Type = \"Fast\", i5-9400 @ 2.9 GHz.\n--\n--  The linked list version takes 0.58 second on the same configuration.\n--  Then, the linked list version is more than 17,000 times faster!\n\nwith HAT; use HAT;  --  in ../../../src\n\nprocedure AoC_2020_23_Simple_Array is\n\n  max : constant := 9;\n  subtype Cup_Range is Positive range 1 .. max;\n  type Cup_Array is array (Cup_Range) of Cup_Range;\n\n  procedure Play (c_init : Cup_Array; part : Positive) is\n    big_max : constant := 1_000_000;\n    subtype Big_Cup_Range is Positive range 1 .. big_max;\n    c : array (Big_Cup_Range) of Big_Cup_Range;\n    c_cur : Big_Cup_Range;\n    pick : array (1 .. 3) of Big_Cup_Range;\n    dest, gap : Integer;\n    found : Boolean;\n    part_max, rounds : Positive;\n  begin\n    if part = 1 then\n      part_max := max;\n      rounds   := 100;\n    else\n      part_max := big_max;\n      rounds   := 10_000_000;\n    end if;\n    for i in 1 .. max loop\n      c (i) := c_init (i);\n    end loop;\n    for i in max + 1 .. part_max loop\n      c (i) := i;\n    end loop;\n    --\n    Game :\n    for round in 1 .. rounds loop\n      --  The crab picks up the three cups that are immediately\n      --  clockwise of the current cup.\n      for j in 1 .. 3 loop\n        pick (j) := c (j + 1);\n      end loop;\n      --  They are removed from the circle; cup spacing is adjusted as\n      --  necessary to maintain the circle.\n      null;\n      --  The crab selects a destination cup: the cup with a label equal\n      --  to the current cup's label minus one.\n      dest := c (1) - 1;\n      loop\n        --  If at any point in this process the value goes below the\n        --  lowest value on any cup's label, it wraps around to the\n        --  highest value on any cup's label instead.\n        if dest < 1 then\n          dest := part_max;\n        end if;\n        found := False;\n        for i in 1 .. 3 loop\n          if dest = pick (i) then\n            found := True;\n            exit;\n          end if;\n        end loop;\n        exit when not found;\n        --  If this would select one of the cups that was just picked up,\n        --  the crab will keep subtracting one until it finds a cup that\n        --  wasn't just picked up.\n        dest := dest - 1;\n      end loop;\n      --  Remove & shift current focus by one (current slot is always 1)\n      gap := 3;\n      c_cur := c (1);\n      for i in 1 .. part_max - 4 loop\n        c (i + 3 - gap) := c (i + 4);\n        if c (i) = dest then\n          --  The crab places the cups it just picked up so that they are\n          --  immediately clockwise of the destination cup. They keep the\n          --  same order as when they were picked up.\n          for j in 1 .. 3 loop\n            c (i + j) := pick (j);\n          end loop;\n          gap := 0;\n        end if;\n      end loop;\n      c (part_max) := c_cur;\n    end loop Game;\n    --\n    if part = 1 then\n      for i in 1 .. max loop\n        if c (i) = 1 then\n          for j in 1 .. max - 1 loop\n            Put (c (1 + (i + j - 1) mod max), 0);\n          end loop;\n        end if;\n      end loop;\n    else\n      for i in 1 .. big_max loop\n        if c (i) = 1 then\n          Put (c (1 + i mod big_max), 0);\n          Put (\", \");\n          Put (c (1 + (i + 1) mod big_max), 0);\n          exit;\n        end if;\n      end loop;\n    end if;\n    New_Line;\n  end Play;\n\n  exm, inp : Cup_Array;\n\nbegin\n  --  example 389125467\n  --  input   523764819\n  --\n  --  With full Ada we can write  ` exm := (3,8,9,1,2,5,4,6,7); `\n  --\n  exm (1) := 3;\n  exm (2) := 8;\n  exm (3) := 9;\n  exm (4) := 1;\n  exm (5) := 2;\n  exm (6) := 5;\n  exm (7) := 4;\n  exm (8) := 6;\n  exm (9) := 7;\n  --\n  inp (1) := 5;\n  inp (2) := 2;\n  inp (3) := 3;\n  inp (4) := 7;\n  inp (5) := 6;\n  inp (6) := 4;\n  inp (7) := 8;\n  inp (8) := 1;\n  inp (9) := 9;\n  --\n  for part in 1 .. 2 loop\n    Put_Line (+\"Part: \" & part);\n    Put (\"  From example : \"); Play (exm, part);\n    --  Part 1: from AoC site:    67384529\n    --  Part 2: from AoC site:    149245887792\n    Put (\"  From input   : \"); Play (inp, part);\n    --  Part 1: validated by AoC: 49576328\n    --  Part 2: validated by AoC: 511780369955\n  end loop;\nend AoC_2020_23_Simple_Array;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_24.adb",
    "content": "--  Solution to Advent of Code 2020, Day 24\n-------------------------------------------\n--  Lobby Layout\n--\n--  https://adventofcode.com/2020/day/24\n--\n--  NB: Was able to recycle parts from another \"Game of Life\"\n--      puzzle: Seating System (Day 11).\n--      As an hommage to John Conway, there are three\n--      \"Game of Life\" puzzles: Day 11, 17, 24.\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nprocedure AoC_2020_24 is\n\n  type Colour is (black, white);\n\n  function Flip (c : Colour) return Colour is\n  begin\n    if c = white then\n      return black;\n    else\n      return white;\n    end if;\n  end Flip;\n\n  type Direction is (e, se, sw, w, nw, ne);\n\n  type Position is record x, y : Integer; end record;\n\n  move : array (Direction) of Position;\n\n  --        (0, 1)    (1, 1)\n  --           nw      ne\n  --             \\    /\n  --  (-1, 0) w--(0, 0)--e (1, 0)\n  --             /    \\\n  --           sw      se\n  --       (-1,-1)    (0,-1)\n\n  --  Full Ada: we define `move` in a single expression:\n\n  --  move : constant array (Direction) of Position :=\n  --          (\n  --                nw =>  (0,  1),    ne =>  (1,  1),\n  --\n  --              w => (-1,  0),             e => (1,  0),\n  --\n  --                sw => (-1, -1),    se =>  (0, -1)\n  --          );\n\n  max : constant := 70;\n  subtype Tile_Range is Integer range -max .. max;\n  type Map_Type is array (Tile_Range, Tile_Range) of Colour;\n\n  procedure Change (current_map : in Map_Type; new_map : out Map_Type) is\n    function Count_Black (x, y : Tile_Range) return Natural is\n      occ : Natural := 0;\n      --\n      procedure Scan_Direction (dx, dy : Integer) is\n        xx : constant Integer := x + dx;\n        yy : constant Integer := y + dy;\n      begin\n        loop\n          exit when xx not in Tile_Range;\n          exit when yy not in Tile_Range;\n          case current_map (xx, yy) is\n            when black  => occ := occ + 1; exit;\n            when white  => exit;\n          end case;\n          --  Adjacent only in this problem.\n          --  xx := xx + dx;\n          --  yy := yy + dx;\n        end loop;\n      end Scan_Direction;\n    begin\n      for d in Direction loop\n        Scan_Direction (move (d).x, move (d).y);\n      end loop;\n      return occ;\n    end Count_Black;\n    --\n    count : Natural;\n  begin\n    for x in Tile_Range loop\n      for y in Tile_Range loop\n        new_map (x, y) := current_map (x, y);\n        count := Count_Black (x, y);\n        case current_map (x, y) is\n          when black =>\n            if count = 0 or else count > 2 then\n              new_map (x, y) := white;\n            end if;\n          when white =>\n            if count = 2 then\n              new_map (x, y) := black;\n            end if;\n        end case;\n      end loop;\n    end loop;\n  end Change;\n\n  function Is_large_enough (m : Map_Type) return Boolean is\n  begin\n    for y in Tile_Range loop\n      if m (-max, y) = black or else m (max, y) = black then\n        return False;\n      end if;\n    end loop;\n    for x in Tile_Range loop\n      if m (x, -max) = black or else m (x, max) = black then\n        return False;\n      end if;\n    end loop;\n    return True;\n  end Is_large_enough;\n\n  function Count (m : Map_Type) return Natural is\n    c : Natural := 0;\n  begin\n    for x in Tile_Range loop\n      for y in Tile_Range loop\n        if m (x, y) = black then\n          c := c + 1;\n        end if;\n      end loop;\n    end loop;\n    return c;\n  end Count;\n\n  procedure Init_Move is\n  --  This way of doing initialization is needed for HAC.\n  begin\n    move (e).x :=  1;\n    move (e).y :=  0;\n    move (se).x :=  0;\n    move (se).y := -1;\n    move (sw).x := -1;\n    move (sw).y := -1;\n    move (w).x := -1;\n    move (w).y :=  0;\n    move (nw).x :=  0;\n    move (nw).y :=  1;\n    move (ne).x :=  1;\n    move (ne).y :=  1;\n  end Init_Move;\n\n  use HAT;\n\n  procedure Read_Data (m : out Map_Type) is\n    --  Initializations are just for removing warnings\n    --  issued by the ObjectAda compiler.\n    c, c2 : Character := ' ';\n    i : Integer;\n    f : File_Type;\n    s : VString;\n    d : Direction := e;\n    p : Position;\n  begin\n    for x in Tile_Range loop\n      for y in Tile_Range loop\n        m (x, y) := white;\n      end loop;\n    end loop;\n    --\n    Open (f, \"aoc_2020_24.txt\");  --  \"input.txt\"\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      p.x := 0;\n      p.y := 0;\n      i := 1;\n      while i <= Length (s) loop\n        c := Element (s, i);\n        if c = 'n' or c = 's' then\n          i := i + 1;\n          c2 := Element (s, i);\n        end if;\n        i := i + 1;\n        case c is\n          when 'e' => d := e;\n          when 'w' => d := w;\n          when 'n' => if c2 = 'e' then d := ne; else d := nw; end if;\n          when 's' => if c2 = 'e' then d := se; else d := sw; end if;\n          when others => null;\n        end case;\n        p.x := p.x + move (d).x;\n        p.y := p.y + move (d).y;\n      end loop;\n      m (p.x, p.y) := Flip (m (p.x, p.y));\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  rounds, count_1, count_2 : Natural;\n  paving : array (Boolean) of Map_Type;\n  state : Boolean := False;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\n\nbegin\n  Init_Move;\n  Read_Data (paving (state));\n  --\n  --  Part 1, count black tiles\n  --\n  count_1 := Count (paving (state));\n  --\n  --  Part 2, hexagonal game of life\n  --\n  if compiler_test_mode then\n    rounds := 2;\n  else\n    rounds := 100;\n  end if;\n  --\n  for round in 1 .. rounds loop\n    if Is_large_enough (paving (state)) then\n      Change (paving (state), paving (not state));\n    else\n      Put (+\"  Too small! max=\" & max);\n      return;\n    end if;\n    state := not state;\n    if verbose then\n      Put_Line (+\"Round \" & round & \": \" & Count (paving (state)));\n    end if;\n  end loop;\n  --\n  count_2 := Count (paving (state));\n  --\n  if compiler_test_mode then\n    if count_1 /= Integer_Value (Argument (1)) or\n       count_2 /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1 : number of black tiles at startup: \" & count_1);\n    Put_Line (+\"Part 2 : number of black tiles after \" & rounds & \" rounds: \" & count_2);\n    --  Part 1: validated by AoC: 341\n    --  Part 2: validated by AoC: 3700\n  end if;\nend AoC_2020_24;\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_24.txt",
    "content": "nenwswenweswweenesweeenenwee\nnwnwnwnwswenenenwneswneenwnenenwnenwsw\nweweeeeneneseswesesweeesenwnw\nwnwwwwwnwwnewsewnwenwwnww\nenwnwsenwnenwnwseenwswnweseswenwswnwsw\nnwseseswsenwseswseseswsenweseeeenwnwsese\nsenwwwwnweeswewwwewwnenenwswse\nswnwneswnweneneneswneneeneswne\newsenwweneeeenwnwneneswnewwswesene\nsesenwsweseseswnenenwnweenwseenewee\nseswwwswwnwnwsewneenenenwnwneneseww\nnenenenenenenenenwsenewne\nswwnwswswswwswswswswswswswe\nnenwswnesesesesesesesesesesenwsenwsesesew\nwswwneswswswweeswswwwswnwswswseswnew\nwwwwwnwwewenwwwwswnwwew\nneenwnwnwnenenenenwenenwnwwwnwswswse\nswwneswswswswnwseswswswswswsw\nseseseenesewnwseseeswwseseeseneesesw\nnesenwswseswnwwseswwwseswwnenewswwwse\nwwwwwwswewww\nseenewewenwneswneneneneneneswnenee\nsesewnwsenwnwesesweneswseseseswnwsee\nnenwnenenwnwnwswnenwnwsenenwnenwwnwnwne\nseseswneeneeseeewwnwseesenwsenwsee\nseseeeeseseweesesesewnesesesenwsene\nswwswswseswwwswnewe\nswwswswswwseneswswseswswwnewswwwsw\nneeswneneneenenenene\nneeswseseswswnwwseswnwwswswseseseseseswne\newneneneenewewnenewseneenwneeesw\nenwnenwneeeeseeeeswenweeneseese\nnwwnwnwnwnwnwnenenenenenenenenwsenwsene\nnwseenwnwnwnenwnwwsenwnwne\nseseswsenwswseswswswseeseswse\nseswneswswswswswswswswwwswsw\nenesenenwesesweeweeswseseeseseew\nwwswnwweneswneenwsesesenwnwsenwwnw\nswnwwnwswwewsenewenwnewseswnwwww\nwswewnwwswwnwswswswswswwswsweswesww\nswesenwnweeneseseseswswwnwsewwenwswne\nwwwswwsewwwwswwwwwnw\nneeenwwwswnewnenwnwsenwsewwwww\nseneswswsewswneswswseswswseseseseewnwsese\nnenenenewneneneneneneneneeseneweese\nwswsweeswswwswswswswwswswwswwnwsw\nwwwseswnewswswswwwwwwsw\nwnwnwnwwnwnwnwnenwenenweneswsewenwnwnw\nwwweswewnewwnwswsewwwwwnwnenw\nnwnwsweneeeseeseeeseesesesenwseswese\nnwwswswswwswwswewwwwsenwswsenwsww\nsenwnenwnwnwnwnwnwnwnwnwnwnwsw\nneswnwseswswswswswswswswswsweswwswe\neeeeeeeseenwnweeseesweeeenw\nswseseseswswwnwneswewwnwnwseeswnwswwne\nneesenwseesesewwnwseeseseenwnesw\nneswswswwwswswsesweswswsw\neeneeewsenweseeeweeeneswee\nnwnenweneewnwnwnwwnwwwswnwsenwnwnwnw\nnewneeneseneneswnenwnenenesenewnwsw\nseseneeewsweneneeeneseneeeswwwene\nswswswswseswswwsesesesweswswswneneswsww\neeeeswneneeewseewneeseeee\nneeeneneneeeneneewneewwwnesenene\neneswnwnenwneeswwswneeeenenwenese\nseenwseseseeneeseseeseseseweseswsese\nseswnwswswenewnewnwswsw\nwwwwwwwwwwwneswswwwnewswse\nseeseswseseseswwsesese\nnenenewenenewesenesewesenwewnewne\nnwneseneeneseneswneneneewneewnee\nnenenwneneewewneeseneeneeneeese\neswnwswwswsewweswwnwneswwwswww\nneseswnweeeeseeeswee\nwwwwnwswwwswswswnwsese\nwseseswswwswswswnweswswsesweseesw\nnwneneneeewewwneneneeeeeswese\neesesesewnwseenweeeeesenweseswse\nneneneneenenwneswneneneneeeneee\nwswswsweeseswswswswwnwnwwsw\nwseewesenwnwneswnenweewneneswwnw\nnwneeswswseswwseseneswesenenwsenesww\nnwsewwwwswswwsenw\nswswswewswnwswwswswnwewswwseswww\nswswwwsewwnenesewwswswswwwwww\nnenwnwnwwnwnwnwnwnwnwenwswnwnwnwnwsenwnw\nneneneneneneneneneneneneneneswe\nnwwwswenwwneenwnwwswewnwwnwsww\neseswseswwnwneswneswsesewswnenesesw\nwwwwwnwnwwwe\nsenwenenewwnewswneewnesewsenenenesene\nsewewneewnwneenenenenweneese\nswswswewwwewneswswwswswswswwww\nswwnwneneenenenenwnwnenewnwseswnwsenenw\nswnenwneenenwnwnwnwsenwnwnwnwnwnwnwnwnw\nneswsesewswseeeneseswnwwswswsw\newwwwswwwswwneswwwewnwnewwsene\nnwnwnenwnwnwsewnweneswwswnwnwsenewnee\newneseeeeeeewenweseeeeeee\nnwseswwswseewwnwwwnwwnwwwseswene\nswswwswweswswewswswswsw\nnwnwneswnwneenwnwnwneswnenwnwnwnenenwne\neswweeeeswseenewenwsenwesesese\nseswnwneswnenenwnwnwesenesenwswnenenwnene\nnenwnenenwwnenwnwnenwnwsenwnwswse\nnewwwweswswswwswseenewwseseswnwsw\nnwwnwsesenwnwnesenwnwswnwewnwnenenwnwnw\nnwneneneneneneneeswnwnenenwne\nwnwnwsenwnesenenenenenwnenwne\nnenenwnenewnesenenewseneneeneneseenenesw\nwneneswnwnenwnwswneeseenwseswnesesenww\nswseswseseswseswneswseswsewseswsese\nweeesweeesenwseeee\nnenwswswnenwweswseseseewseneneseswe\nneweewneswneenweeneesweewnenene\nnesesweenenewneenenenewesenesenew\nswswswswseseswseswswswswswnw\nneneswwwwwwwwwwsewsenewwswww\nnenenenwnenenenewsenenesenenewnenwnwne\nneeneeswneeseeseenenwnwwseswewee\nswswswswnwseseswneseswseseswswswwnenesw\nneeswnenwneeeeweswswsweneneenwe\nwsenweswseenwsewsesenwsenesesesesesenesw\nseseswseseseswneswswse\nswnewswwwsesewswnewwwswwswswswww\nsenewneneneseneenenenwewenwwnwswsw\nweseneneseseseeeweeseswsweenesese\nswnewwswnwseswswswseswswwwswswswswne\nneneeenenweneneswenenesenwewneenesw\nseseseseneseswseseswswsewsenwseseesesese\nnenenwnwnwnenwnenenesenenwwneneneene\nnwnwnwsenenenwneswwnwnwnesenwnenenenew\nneeeeeweneseeweweeneeneenee\nwneneeneneenewneneeeeseeneneseeswe\neswwwnwwnwwnwwwwwwwenwswneswe\neseswwsweseeeneenewe\nsesesweseseswsesesenwseseseseweseswne\nsewseseseseseseseeseseseneseesenesw\nswwneewswwwnwwswswwenwewnwnwnww\neneneeeenwsenwnwesesweeeeswee\nwwwwwwswwswwnew\nswswwwswwnwewwnwneswwnwseneneww\nswnewnwnewnwwsweseeseswwswnenenwsee\nswewswswwswswswswseswswswswesweswswnw\nneswswseswswswswswswswneswswwnweswswe\nseeseseneseswswwsewseseenwsesenwseswsw\nesewneswnewwesewneswneneneneeenwe\nnesewnenesweneeeneneenenenenwnenenese\nnwnenwnwwnwnenwnenwnwneeeneswnwnwenww\neeeeeeswwwwnesenenwenwsenewsw\nnwswweswsweswsenwneswewswwswnesenwsw\nsesenwseseseseesesesesesesesesesesw\nnenesenenwnenwnwwnenwneneswnewesenene\nswnwwswswwwnenwwseswwwwnewewsee\nesesewswswsenwswswswnenewsw\nnwnwnwwnwnwnwnwnwse\neeneenenewsenenewwnenenenenenesenwe\nsweseswswseneseswswswnwswnwswswseswswse\neeseneeneneneeenenweeeeswnwee\nswswwewswwwnenwseswwswswswswswswsww\nneswswswnwwswnwseswweswswwswsww\nnwswnenwnewnweseneneeswswneswnwnwnesene\newnenwswwwnwnwnwnwnwwswwwwwwne\nwswseseseeseswnwwenenwneswsenesenwse\nnwnenenwseneswswsee\nnenenenenenwnewswnwnenwswnwnwenenwnwe\nneweweweswesenweesesenw\neenwneeeeenwwneeseseseseswwsese\nseeseneswseeseeeee\nnwneswswnwwweswnenewwnwneseseswwwse\nnewwwswwnwwnwnww\nneneeneseswnwenenesweneeneneweeew\nwswswnwneswenesenwnwnewnwsenenwnenesenenw\nwneneeneseswnweseseneewswenwnenwsese\nnwsweswswswwsweswswsenwwenweswneenw\nseneswswswswswseswswswswswswneswswswnwswse\nwswswneneneswswswswwsewswwnew\nenwsenwsenwswswewnewewnwweseww\nwswswseswsewwswwwwwswwwwnwnew\nswneswswswewswswswwwseswswswswswwswnw\nseeneweseeseeeswseeneseneswnwweswse\neeeseweswseweeeeeswsenwneewe\nswnweneneeneeeneeenenewneneeene\neeeeneseeeseneeswsenenweewnwnw\nswswswnewwseswseswswswseseneswewnwswe\nnwswswneeseswneswnwnwswsesw\nwwnwwswwwsewwswwwww\nsweeneeeneenwesweseeeneenweee\nnwwswsenwnwswnwnwnwswseeseseneenenwse\nnwwnenwnwnwswwwwwnwnwww\nwwwswnwnesenesewwseneesenwneseewsw\nnwnweenwnwnwswnwwnenwwsweswnweswene\nnenwnwnwnwneenenewwneswnenese\nnenenwnewnwsenwnewsweenene\nnwneenwneswsweswneseeswswsenenenenwnw\nswswseswseseneseseseseseswswswsenenweswse\nsenwswwsenwswsenwswswswswswswswswswww\nnwnwenwneswnwnwnwnwnenwnwnwnwnwnwnw\nnwnwwenewnwnwswswwe\nswsweseswseswnwnesesesenesewseswseswne\nswseneswswneswwswnenwwswseseswneswswseswsw\nswswseswswswswwwseswswneswswwnewswsw\nseswseswseneswseeswsenwswseswsesewswswse\nnenenenenewnenwnenenesenenesenenenenene\nwnwnwsenenwwnwnwnwwnwwnwswnwwwee\nnesesesesesesesenwsewseesesesewnesesese\nseesesesesenenwsesesesweesesesesese\nnwseeesweneswnenweswwwwnwnwnwnwswene\nwswwswnenwnenesweswneswswseswswswsesenenw\neesweeeeeeeenw\nwnwwwnwsewwnwnwwnwwsenwnenwwewnw\nnwswnwsewswnwnewswwneenwnenwsewnenwnw\nnenweenwneneneneswswneswsenwnenenenenenwse\nnwnenenenenwnenesenewnesenenenenenenwne\nseeeeeeseswnweeee\nswswwwnwwwwewswwwwwswwewnw\nwswwwswswnwwneseswseswwnewwswwnwse\nsesesenewseeeseseswe\nwswwsewwwwneswswwwwwnewswsew\neneeenweneneswnwneneeeneeeeese\nneenenwneeeneeeneneneneneeswnenesw\nnwswenwseeseesenenwneswseeesewesw\nsewwneswswwsewnwswnwswsewnenewwsww\nwseswwsenwnwnewsesenwwsenwneeswwnee\nnwswseeeseeesesew\nnwwsewnwnenwnwenwswswnwsewwesewe\newneeeeeeweeeeeesweeenwe\nneswswswwswswnwswnwseswswswwswseeseswsw\nseseneeseeseneseeeewseseswseseenwse\nnwnwnwnwsenwwnwnenwwnenwnwwnwnwswnww\nnwseweseseswnwweneseswseneswswswswswnw\nswwswwwswswnwwweswswwwewswww\nnwnwnwswsenenenwwwseswnwnwnwesenwnwwnww\neeeseeeeseswenwnwee\nenewneneeneseeeneeneeeeseeeew\nnwwnwnwswseswwnwnewnesewwneswnwesenw\nneeseswwwnwswwneeseswnewenwswswswsw\nseseswseswnwnwenwsesenwneewwneseee\nseseswswswesesenwseswnwswsene\nnenwewneswneeeneneneseeeneneneee\nsesesesesenwseseswseswsesesewnwsenesesw\nnwnwswneswnwseenwnwswneswnwesesenwnwe\nnwnwenewsweswnwsesenenewwnwnweswnw\nnenwneneswseenenewsenwnwswnwwnwnwnenenew\nsewseseseseswseswnesesesesesesese\nneweeneeneneeeesenenwswswneneneneee\neneneeswwseneneswnenweeweswnenwswnw\nsenwswnenwnwnenenenwnewnwnenwsenwwnwnene\nneswneswsenwswsewseenweseeeewsesese\nseseseswseesewnweseeesenwseseswseenwse\nsewwsesewwwwwwwnewwwnwwnwnw\nnweneswnenwenwnenenenwnwnenwneswwnwnw\nneneeneneneswenwneswnwnenwnwnwnwwswnene\nnwwnwnwnwnenwnwnwnwnwswnwnwnwsenw\nswwnwewwwsewswsww\neeseeseeeeseseseseswnwwseesesese\nenwsenwseswwnwnwnenwnwwnwnwnwsenwnenew\newneeneseneeseneneenwneneeneenenesw\nseseseswnwsenenwseese\nwswswwwwwneseww\nneewneeswsenwnwnwnenenwnenwswnwnenwnw\nneneseseswneswnwnwesenwnweenwnwnwswsenww\nwwwnwnwwseenwsewwwwewwnenwnwsw\nnwnenwnwwwwnwnwenwnwwnwswwnwenw\nswseswwneesesesewseseseesesesenwswsese\nswswseeseseseseswswswswswwswswseneswnwsw\nsenenesweewnweesewweneneseneeene\nwwwwnewwwwwsewwsewswwwwnew\newsesesesesesesenwswsese\nswswwswswneeswnwswwseswswsee\nsewnwwnewnwnewwwwwnenwsesewwnwww\nnenwneneneneneneneneseneeneneneswnw\nnwneseseeeswweee\nswwnwswwewswwseeswenwswswswswswsw\nswswneseswswswswnwswswswseeswswswswnwne\nwnwnewneenenesesenesweswneeswenene\nnwseseseseseswnwwseeseseeseseseesese\neswnwswwnwwewwwnwnwsewenenwwse\newwswwwnenwewewwesewewww\nswseneseswswswswwswswswnwswswswsweswswnw\nswwwswnwwweewnwsew\neeeeseseewnweewsweeeeeee\nnwnwnwnwnenwsenwnenwewnenwewnwsewnwnwnw\nnwsewnwnwnwneswnenwnenwnenwnwnenwswesw\nswnwnwwwewwnwwewwwewwswnwnw\neneeeesweewnenwnenesewewnee\nnwnwnwswwnwnwnwwwsenwwwne\neeeseeeseeweseeseseweeesenwse\neswsewswswswswswswswwswswnwswsw\nseseeeseeeeeeesenwsw\nesweeswsesewseeneseseseneeswnwsenesew\nswswswswnweneseeseswseswwswswswswswsw\nwwwwswwswwneswswwwsww\nswswwsweswnwswswswsw\nnenenwsewsenewnenewnenwnwswneseneseswe\nseseswseseswswswswswswneswwswsenenwsesw\nswsewsenesesenwseseseseenwseesenesesw\nenwwwswwnwesweswsenesewwswswwnw\nnwswnwnwnwnwnenwnwnwnwnwnwnwnesenweneswnww\nswswswewwswseseswswwnwnwnwswneeswnww\nwswneenwewnweneswneneneesw\nseeeseswwseeneseweeswnenweswsenew\nnwnwnewnewnwwwwwsewwnwwswnwwese\neeswnenwswswswswwswswswsw\nnwnenwneneneneneswneenenenwnwnwnenwnwsw\nseseseeeeseeseseseeswswnenwwe\nswwnewnwsewnwwnenenwwnwwsesewwnwnew\nnwnwsewnwneenwnwnwnwnenwnwneswsenenwnw\nwwwwwswwewwwwewnewwweww\nwnwsenwwsewnwwwnwnwnesenewnwswnew\nswsenesesenesesesesesesesewswesesesese\nseseneswswwseseseseseswneswseswseseesese\nenesenenwseneseseswweseeseneswwwsese\nsesesesenesewseseesesesewwswneseseesw\neeeseeeeweesenenweeseseswese\nswnwnwswnweswenesenwsenwseewneneswsesw\nsewswseenesesesenwnwsenenwseesesewnesw\nswswswswswsweswnewswswsesenenwswswnwsw\nenesweeeneseeseswwseeeenweese\nesenwwnwswseneneseswneseesenesewse\nswswsesewswnesewsewneseneseswswnesese\neseweeswseeeeseesenenee\nnewneswswwwswswwwwwwswnewwwwsesw\nnenenewswnwswnesenwnwnenenenwnwnwnenwne\nwseswnewsewswwnwswnewwwwwswwww\nwwwswwwnwwwwenwwnwwnww\nweeeeeesweenweswwneeeeeeee\nwneswswswnwswswsewswwsewsw\nseenwewseseseseseeseeesesesenweesw\nneswnenenwwnwenwnwnwnwwenenene\nwnewwseeswwnewneswnenwswwwwsww\nswswnwneswnweswseswswswswwwwsweswwsw\nwswsenwwswswwswwweneswswwswswswnew\nnwnwwwenwesenwseswnwnw\nseneneeeneenewe\nnwwnweenenwwnwnwsenwswnwnweswnenwswnwne\nnwnwnwnwsenwnwnwnenenwnwsenwnenwnwenwnww\nseswnwseswswseeneswwseseswseswswswseswsw\nswswneswwswswnewswwwnweswswnesesenw\nseswswseseswswsesenesw\nseseneswseseseseseesenesesesewsenenwsw\nneneneenenwswnwnwneneswnewnwnewnenwee\nseseswsewswnwseseswsesweseseeseswnesesw\nwwnenenwswsenwnwneneeswseeswew\nswwswnwnwseseseswnwseenenwseswnweswenw\nnwswwswswswswswswsweswnewsweseswswnesw\nsewwswwwnwwenwwnesenewnwswwswsene\nswseswsesesesenwseweseswseseswswsenwseese\nseseeseseesesenweeesweweesee\nwewswnwnwswenwnwswewseneneswsewwne\nesesenwseseenwswnewswenwseseseswnwswnw\nneswswseseseseseswseswswwnenwseseseswese\nseeeesesesesenwsenesewseesenwsesww\nswswseswsweswwswswswseswseswswnwswsw\nneeneeeneseeenwsweeeseeenwwne\nswwesesesenesenenewsesenewseesewsese\nnenwnwnwwwnwswnwnwsenwwwwnewwnwnw\neweneeenweewsweeeeeeseneese\nnewneswneneneeeseswneneswneneneswnwsw\nnweeeeeeeeweweeeeeesese\nsewnwwwwwewenwnwnwwwwwwwww\nnenewneenenenenwwnenwnenenenenenwe\neswswnesesewneseseswnwwswne\neeseesweeewseseeeneeese\nwneswsewwseesesenwneeseseswneswnwsesw\nswwswseswsesesweseswseswsw\nswswswwswswswsenwswswswswwswseswnenwswsw\nseneswweeneswnwneeneeeseweeew\nswswsweswnewnenesenwseseswswseseswsww\nnwnesewsweswwwsenewwnewwwwww\newneseseeeenewnenenweeneeswnene\nwwwwwwnwwwewseewnenwwwnwwsw\nwwwseswwsewswneswwneswwwwwwnw\nnenwnesenwnenwneenwnwnwnwnwnenwnwnwwsesw\nswneenwwswenwenweseeweeese\nnwwnwenwnweseswneewnwenwswnwwnwswnw\nnwwnwsenenwnwseneswnwneswnwnwnenwnenenenw\nnenenwnwsenenenenenenenwnenwnwnw\nnenwwseeneneswwsesenesenwnenenwsenenee\nnwwswswenwwnwsenwweneenwnenwnwwwww\nwnwswnewwwwwswnwnwwwnewwnwwswne\nnwsenwnwswnwnwswnenwnenenwnenwnwnwnwnenw\newnenenewneneneneenenenenwnenene\nnwsesesenwnwseeseseseseeseseesweesesw\nseeswnenesewnenwnenenwnenwneneneswenene\nseeeswenwseswneeese\nswenwenwswswseneswsenw\nwnwnwwnwnwsewnwnwnwnenwnwnwnwsewnenw\nnwwsenwnwsenenwnwnwnwnwnwnwwnwnenenwnenw\nsesesesenenwseeseseswseseseseswe\nswwwneseswswnewswwwswswswwnewswswww\nwwnwwnwnewnwnwswwnwwnwnw\nwsenwswesenwneswswseswswswewsweswswnw\neeseneeeeesweeewwneeseeneesw\newnenwnwnwswnwnwwsewwwnwnwewsenwnww\nnwesewsesesweeseesenenesesewseseesese\nseesweewneseseseenwseswneswenwsesenwse\nweeneswnesweswenwwnwnewswsenwene\nnwnwnwwwnwwwsenwneweswswwenwnwsene\nnwnwnwnwwnwnwwnwnwwwswwwnwsewnwe\nswneneeswseenwseneswnweenewnweenenw\neweeneswenweneenwsweeeene\nnwnwnenwewseseneseneswwnenwnenwnwnwsenew\n"
  },
  {
    "path": "exm/aoc/2020/aoc_2020_25.adb",
    "content": "--  Solution to Advent of Code 2020, Day 25\n-------------------------------------------\n--  Combo Breaker\n--\n--  https://adventofcode.com/2020/day/25\n--\nwith HAT;\n--  ^ For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2020.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2020_25 is\n\n  N : constant := 20201227;  --  A prime number.\n\n  use HAT, Interfaces;\n\n  function Transform (subjet_number : Integer_64; loop_size : Positive) return Integer_64 is\n    value : Integer_64 := 1;\n  begin\n    for i in 1 .. loop_size loop\n      value := value * subjet_number;\n      value := value rem N;\n    end loop;\n    return value;\n  end Transform;\n\n  procedure Solve (seed, card_public_key, door_public_key : Integer_64) is\n\n    function Find_Loop_Size (key : Integer_64) return Natural is\n      value : Integer_64 := 1;\n      max_loop_size : constant := 10_000_000;\n    begin\n      for i in 1 .. max_loop_size loop\n        value := value * seed;\n        value := value rem N;\n        if key = value then\n          return i;\n        end if;\n      end loop;\n      return 0;\n    end Find_Loop_Size;\n\n    card_loop_size : constant Natural := Find_Loop_Size (card_public_key);\n  begin\n    Put_Line (+\"  Card's reverse-engineered loop size : \" & card_loop_size);\n    Put_Line (+\"  Door's reverse-engineered loop size : \" & Find_Loop_Size (door_public_key));\n    --\n    Put_Line (\"  Encryption key :\" & Integer_64'Image (Transform (door_public_key, card_loop_size)));\n    --\n    --  NB:\n    --\n    --   card_public_key ** door_loop_size         =\n    --  (seed ** card_loop_size) ** door_loop_size =\n    --   seed ** (card_loop_size * door_loop_size) =\n    --  (seed ** door_loop_size) ** card_loop_size =\n    --   door_public_key ** card_loop_size\n    --\n  end Solve;\n\n  procedure Test_Example is\n    card_public_key : constant Integer_64 := Transform (7, 8);\n    door_public_key : constant Integer_64 := Transform (7, 11);\n  begin\n    Put_Line (\"Example\");\n    Put_Line (\"  Card's public key :\" & Integer_64'Image (card_public_key));\n    Put_Line (\"  Door's public key :\" & Integer_64'Image (door_public_key));\n    --\n    Solve (7, card_public_key, door_public_key);\n  end Test_Example;\n\n  procedure Input is\n  begin\n    Put_Line (\"Input\");\n    Solve (7, 18356117, 5909654);\n    --  Officially validated by AoC: 16902792\n  end Input;\n\nbegin\n  Test_Example;\n  Input;\nend AoC_2020_25;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Advent of Code 2021 examples.\n--  Some work with both HAC and \"full Ada\" compilers,\n--  some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject AoC_2021 is\n\n   for Source_Dirs use (\n     \".\",\n     \"../../../src\"   --  GNAT's access to the HAT package.\n   );\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\"\n      );\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   for Main use (\n     \"aoc_2021_22.adb\",\n     \"aoc_2021_21.adb\",\n     \"aoc_2021_20.adb\",\n     \"aoc_2021_19.adb\",\n     \"aoc_2021_18_full_ada.adb\",\n     \"aoc_2021_17.adb\",\n     \"aoc_2021_16.adb\",\n     \"aoc_2021_15.adb\",\n     \"aoc_2021_14.adb\",\n     \"aoc_2021_13.adb\",\n     \"aoc_2021_12.adb\",\n     \"aoc_2021_11.adb\",\n     \"aoc_2021_10.adb\",\n     \"aoc_2021_09.adb\",\n     \"aoc_2021_08.adb\",\n     \"aoc_2021_07.adb\",\n     \"aoc_2021_06.adb\",\n     \"aoc_2021_05.adb\",\n     \"aoc_2021_04.adb\",\n     \"aoc_2021_03.adb\",\n     \"aoc_2021_02.adb\",\n     \"aoc_2021_01.adb\"\n   );\n   \n   case AoC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n   end case;\n\n   Common_Options :=\n     (\"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n      \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n      \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n      \"-gnatf\",  --  Full errors. Verbose details, all undefined references\n      \"-gnatq\",  --  Don't quit, try semantics, even if parse errors\n      \"-gnatQ\",  --  Don't quit, write ali/tree file even if compile errors\n      --\n      \"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",       --  Style: check x:no extra parens\n      \"-gnatye\",       --  Style: check e:end/exit labels present\n      \"-gnaty2\",       --  Style: check indentation\n      \"-gnatytc\");     --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   Fast_Options := (\n     \"-O3\",\n     \"-funroll-loops\", \"-fpeel-loops\", \"-funswitch-loops\",\n     \"-ftracer\", \"-fweb\", \"-frename-registers\",\n     \"-ftree-vectorize\", \"-fipa-cp-clone\", \"-fgcse-after-reload\"\n   );\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Options & Debug_Options ;\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Options & Fast_Options & (\"-gnatpn\", \"-ffunction-sections\");\n      end case;\n   end Compiler;\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-g\");\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use (\"-g\", \"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend AoC_2021;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_01.adb",
    "content": "--  Solution to Advent of Code 2021, Day 1\n------------------------------------------\n--  Sonar Sweep\n--\n--  https://adventofcode.com/2021/day/1\n--  Copy of questions in: aoc_2021_01_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_01 is\n  use HAT;\n  f : File_Type;\n  depth, depth_p1, depth_p2, inc_a, inc_b, row, sum, sum_p1 : Integer;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  Open (f, \"aoc_2021_01.txt\");\n  depth_p1 := -1;\n  depth_p2 := -1;\n  inc_a := 0;\n  inc_b := 0;\n  row := 0;\n  sum := -1;\n  while not End_Of_File (f) loop\n    Get (f, depth);\n    row := row + 1;\n    if row > 1 and then depth > depth_p1 then\n      inc_a := inc_a + 1;\n    end if;\n    sum_p1 := sum;\n    sum := depth + depth_p1 + depth_p2;\n    if row > 3 and then sum > sum_p1 then\n      inc_b := inc_b + 1;\n    end if;\n    depth_p2 := depth_p1;\n    depth_p1 := depth;\n  end loop;\n  Close (f);\n  if compiler_test_mode then\n    if inc_a /= Integer_Value (Argument (1)) or\n       inc_b /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: Depth increases: \" & inc_a);\n    Put_Line (+\"Part 2: Depth increases: \" & inc_b);\n    --  Part 1: validated by AoC: 1154\n    --  Part 2: validated by AoC: 1127\n  end if;\nend AoC_2021_01;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_01.txt",
    "content": "199\n203\n200\n201\n196\n195\n196\n214\n227\n225\n229\n260\n246\n253\n271\n281\n280\n295\n310\n293\n295\n297\n298\n297\n306\n299\n290\n292\n289\n287\n291\n296\n294\n287\n286\n287\n289\n290\n281\n283\n282\n275\n256\n265\n242\n231\n226\n216\n227\n226\n249\n238\n237\n247\n245\n250\n264\n267\n259\n258\n264\n261\n249\n246\n239\n240\n259\n258\n280\n279\n278\n281\n272\n256\n255\n271\n286\n290\n286\n288\n290\n294\n292\n294\n292\n293\n294\n291\n298\n303\n301\n330\n331\n336\n362\n371\n374\n368\n367\n368\n366\n364\n371\n377\n378\n384\n386\n388\n393\n409\n423\n422\n411\n412\n426\n430\n441\n460\n462\n464\n469\n461\n483\n452\n455\n457\n468\n506\n509\n514\n525\n512\n524\n523\n522\n531\n549\n548\n549\n548\n524\n525\n528\n526\n537\n544\n549\n546\n525\n532\n535\n543\n544\n545\n525\n536\n538\n541\n524\n534\n542\n538\n539\n544\n543\n539\n538\n527\n553\n552\n562\n560\n561\n573\n574\n570\n571\n568\n569\n571\n573\n566\n567\n584\n591\n607\n605\n604\n605\n617\n615\n617\n606\n608\n609\n613\n616\n635\n634\n637\n635\n634\n655\n639\n646\n637\n628\n622\n648\n645\n640\n652\n653\n659\n661\n658\n650\n667\n670\n668\n680\n682\n673\n668\n678\n677\n675\n676\n677\n675\n688\n681\n676\n684\n675\n664\n665\n654\n660\n664\n663\n667\n658\n661\n676\n675\n680\n681\n690\n693\n697\n721\n733\n739\n740\n739\n751\n765\n766\n752\n748\n763\n772\n771\n782\n784\n797\n799\n817\n812\n811\n795\n783\n785\n790\n785\n784\n782\n771\n756\n759\n783\n772\n774\n779\n783\n786\n780\n783\n779\n777\n778\n777\n762\n778\n777\n770\n773\n769\n770\n771\n764\n765\n761\n745\n754\n758\n759\n746\n738\n740\n742\n767\n765\n754\n755\n758\n762\n760\n761\n757\n761\n770\n773\n777\n776\n777\n769\n767\n793\n805\n798\n793\n803\n809\n808\n817\n804\n809\n805\n804\n806\n808\n812\n830\n831\n832\n831\n819\n820\n823\n822\n812\n814\n812\n842\n858\n855\n856\n862\n860\n855\n839\n840\n841\n840\n846\n850\n859\n861\n852\n846\n848\n845\n833\n843\n846\n849\n889\n890\n894\n904\n907\n904\n905\n906\n907\n910\n902\n906\n900\n907\n906\n899\n887\n867\n866\n873\n878\n885\n880\n890\n863\n860\n859\n885\n856\n853\n854\n852\n864\n855\n874\n875\n874\n875\n871\n872\n867\n870\n873\n874\n860\n862\n879\n878\n879\n880\n881\n882\n878\n882\n885\n890\n902\n903\n905\n906\n909\n917\n916\n934\n932\n935\n937\n935\n910\n911\n907\n902\n904\n910\n917\n918\n943\n945\n959\n973\n972\n969\n973\n972\n958\n957\n959\n963\n968\n961\n960\n973\n971\n970\n977\n1002\n1012\n1011\n1007\n1017\n1024\n1014\n1013\n1019\n1005\n984\n983\n980\n993\n999\n982\n988\n989\n990\n992\n988\n989\n988\n981\n958\n973\n966\n965\n942\n926\n933\n928\n932\n940\n927\n930\n920\n930\n897\n905\n907\n889\n882\n888\n889\n872\n873\n885\n884\n886\n887\n898\n901\n902\n895\n880\n894\n886\n882\n885\n890\n896\n880\n881\n866\n872\n875\n903\n901\n907\n899\n920\n921\n934\n935\n937\n928\n929\n927\n928\n935\n906\n908\n906\n882\n883\n887\n891\n892\n898\n903\n907\n909\n916\n917\n945\n935\n937\n928\n918\n927\n916\n929\n919\n931\n954\n953\n954\n956\n953\n947\n937\n941\n960\n968\n951\n955\n954\n938\n939\n946\n945\n947\n948\n951\n943\n949\n946\n954\n952\n949\n943\n936\n944\n941\n950\n952\n948\n947\n971\n970\n969\n974\n971\n1000\n1005\n1007\n1009\n1008\n1000\n998\n999\n1001\n1008\n1001\n1024\n1005\n998\n1016\n1018\n1019\n1020\n1021\n1057\n1056\n1052\n1044\n1045\n1057\n1058\n1074\n1075\n1069\n1056\n1055\n1056\n1052\n1059\n1070\n1043\n1039\n1035\n1025\n1015\n1018\n1029\n1033\n1042\n1038\n1031\n1033\n1023\n1016\n1019\n1018\n1016\n1018\n1020\n1009\n1008\n997\n973\n983\n990\n996\n1002\n1001\n1000\n1002\n1001\n1015\n1016\n1015\n1019\n1020\n1016\n1010\n1009\n1008\n1016\n1018\n1015\n1011\n1004\n999\n1000\n1027\n1035\n1050\n1051\n1068\n1058\n1072\n1086\n1089\n1060\n1043\n1028\n1026\n1028\n1052\n1050\n1042\n1040\n1036\n1055\n1050\n1051\n1049\n1053\n1054\n1059\n1058\n1066\n1059\n1061\n1070\n1071\n1068\n1059\n1060\n1065\n1066\n1068\n1060\n1059\n1070\n1069\n1068\n1067\n1068\n1070\n1069\n1066\n1073\n1065\n1066\n1050\n1052\n1050\n1056\n1055\n1063\n1062\n1057\n1054\n1048\n1047\n1051\n1049\n1043\n1017\n1016\n1002\n1005\n992\n994\n999\n1001\n1017\n1026\n1024\n1028\n1040\n1039\n1046\n1022\n1023\n992\n995\n1019\n1022\n1023\n1011\n1004\n1005\n993\n991\n992\n995\n996\n997\n1009\n1011\n1012\n1017\n1030\n1029\n1031\n1024\n1033\n1008\n1006\n1018\n1020\n1015\n1020\n1031\n1029\n1026\n1030\n1042\n1039\n1029\n1027\n1008\n1003\n1019\n1000\n1001\n995\n996\n994\n988\n989\n988\n987\n994\n997\n1000\n994\n997\n989\n991\n985\n975\n982\n981\n986\n980\n979\n973\n984\n985\n983\n981\n956\n925\n924\n919\n913\n915\n917\n914\n916\n895\n910\n924\n919\n914\n928\n935\n927\n930\n932\n936\n939\n944\n948\n947\n946\n945\n948\n944\n942\n944\n958\n956\n947\n955\n990\n995\n996\n1007\n1009\n1013\n1012\n1011\n1020\n1019\n1021\n1016\n1038\n1050\n1043\n1046\n1047\n1043\n1040\n1039\n1045\n1046\n1030\n1031\n1034\n1035\n1045\n1066\n1085\n1092\n1101\n1100\n1101\n1099\n1084\n1085\n1086\n1090\n1091\n1087\n1100\n1099\n1092\n1095\n1101\n1102\n1118\n1117\n1138\n1139\n1132\n1127\n1131\n1132\n1130\n1128\n1130\n1150\n1149\n1157\n1158\n1156\n1157\n1155\n1170\n1175\n1167\n1166\n1177\n1174\n1186\n1187\n1186\n1185\n1189\n1193\n1204\n1191\n1196\n1198\n1186\n1198\n1215\n1210\n1211\n1212\n1211\n1207\n1206\n1198\n1202\n1190\n1185\n1190\n1199\n1222\n1225\n1222\n1234\n1236\n1260\n1261\n1262\n1272\n1289\n1286\n1290\n1297\n1295\n1270\n1291\n1299\n1303\n1318\n1342\n1356\n1361\n1362\n1326\n1325\n1333\n1329\n1349\n1353\n1367\n1368\n1371\n1369\n1353\n1351\n1349\n1352\n1354\n1353\n1356\n1355\n1362\n1366\n1368\n1370\n1349\n1354\n1357\n1356\n1360\n1357\n1361\n1363\n1364\n1345\n1338\n1335\n1334\n1322\n1329\n1333\n1334\n1331\n1330\n1337\n1348\n1347\n1348\n1317\n1307\n1313\n1330\n1323\n1324\n1327\n1334\n1336\n1334\n1332\n1338\n1341\n1342\n1373\n1375\n1374\n1372\n1373\n1371\n1370\n1375\n1363\n1361\n1366\n1389\n1390\n1366\n1380\n1381\n1379\n1383\n1400\n1402\n1404\n1409\n1410\n1434\n1439\n1443\n1448\n1434\n1462\n1463\n1462\n1464\n1465\n1471\n1465\n1464\n1469\n1473\n1480\n1486\n1488\n1492\n1494\n1495\n1496\n1504\n1496\n1495\n1472\n1469\n1465\n1466\n1455\n1464\n1465\n1474\n1475\n1490\n1499\n1490\n1492\n1489\n1500\n1504\n1500\n1499\n1500\n1510\n1511\n1516\n1511\n1515\n1512\n1499\n1506\n1509\n1493\n1495\n1496\n1485\n1486\n1476\n1475\n1484\n1485\n1469\n1477\n1478\n1467\n1468\n1469\n1477\n1478\n1475\n1473\n1461\n1468\n1470\n1496\n1491\n1506\n1505\n1526\n1530\n1528\n1529\n1533\n1555\n1558\n1557\n1554\n1557\n1559\n1560\n1562\n1561\n1563\n1564\n1550\n1559\n1558\n1559\n1554\n1535\n1538\n1541\n1540\n1529\n1528\n1519\n1527\n1535\n1518\n1523\n1519\n1536\n1562\n1561\n1566\n1568\n1583\n1584\n1599\n1585\n1581\n1588\n1559\n1561\n1574\n1587\n1574\n1576\n1589\n1588\n1582\n1581\n1584\n1604\n1563\n1555\n1561\n1564\n1548\n1541\n1542\n1546\n1548\n1550\n1566\n1544\n1523\n1525\n1521\n1541\n1550\n1551\n1548\n1558\n1561\n1560\n1550\n1563\n1578\n1582\n1563\n1557\n1558\n1557\n1559\n1574\n1569\n1577\n1576\n1577\n1571\n1573\n1572\n1574\n1577\n1581\n1566\n1535\n1539\n1540\n1536\n1545\n1544\n1513\n1511\n1509\n1502\n1489\n1490\n1495\n1488\n1492\n1513\n1519\n1520\n1521\n1530\n1512\n1514\n1512\n1517\n1518\n1520\n1519\n1527\n1526\n1527\n1528\n1529\n1522\n1525\n1529\n1525\n1524\n1525\n1527\n1529\n1524\n1523\n1525\n1533\n1535\n1536\n1555\n1557\n1573\n1572\n1571\n1590\n1593\n1594\n1593\n1565\n1566\n1554\n1572\n1567\n1569\n1566\n1597\n1616\n1630\n1641\n1638\n1634\n1647\n1651\n1649\n1652\n1659\n1660\n1651\n1656\n1653\n1654\n1653\n1658\n1643\n1642\n1641\n1654\n1655\n1656\n1666\n1673\n1682\n1665\n1663\n1670\n1654\n1668\n1667\n1656\n1646\n1655\n1662\n1680\n1683\n1682\n1683\n1684\n1722\n1702\n1710\n1711\n1715\n1728\n1730\n1735\n1736\n1750\n1755\n1756\n1755\n1752\n1761\n1768\n1767\n1760\n1751\n1747\n1764\n1763\n1762\n1748\n1753\n1745\n1752\n1754\n1746\n1747\n1748\n1756\n1761\n1756\n1734\n1711\n1712\n1721\n1727\n1726\n1731\n1729\n1715\n1716\n1733\n1738\n1740\n1756\n1755\n1748\n1744\n1751\n1756\n1774\n1775\n1755\n1746\n1754\n1758\n1767\n1785\n1786\n1787\n1788\n1766\n1787\n1786\n1788\n1762\n1757\n1752\n1760\n1781\n1750\n1757\n1762\n1767\n1770\n1744\n1743\n1747\n1756\n1763\n1775\n1769\n1760\n1759\n1766\n1768\n1764\n1759\n1761\n1792\n1798\n1800\n1802\n1813\n1810\n1822\n1824\n1816\n1842\n1843\n1835\n1833\n1834\n1837\n1826\n1830\n1850\n1855\n1857\n1862\n1856\n1877\n1878\n1875\n1850\n1847\n1846\n1847\n1846\n1826\n1829\n1825\n1817\n1818\n1815\n1834\n1833\n1822\n1825\n1815\n1817\n1815\n1816\n1810\n1822\n1815\n1817\n1821\n1820\n1814\n1802\n1799\n1814\n1834\n1830\n1842\n1828\n1836\n1849\n1851\n1849\n1848\n1849\n1865\n1885\n1895\n1904\n1910\n1921\n1937\n1941\n1970\n1968\n1975\n1982\n2003\n2012\n2011\n2008\n2006\n1997\n1994\n1991\n1989\n1988\n1995\n1976\n2006\n2018\n2015\n2023\n2022\n2023\n2048\n2038\n2039\n2041\n2057\n2058\n2059\n2060\n2059\n2061\n2031\n2032\n2033\n2020\n2019\n2023\n2032\n2034\n2027\n2029\n2027\n2018\n2028\n2055\n2054\n2043\n2047\n2046\n2055\n2047\n2056\n2037\n2032\n2003\n2002\n1999\n2001\n1996\n2000\n2002\n2004\n1988\n1990\n1999\n1986\n1988\n1986\n1985\n1977\n1978\n1977\n1973\n1977\n1978\n1985\n1988\n1964\n1967\n1989\n1984\n1980\n1979\n1980\n1999\n2006\n2004\n2018\n2051\n2024\n2023\n2025\n2026\n2012\n2000\n2017\n2018\n2017\n2019\n2017\n2025\n2030\n2038\n2016\n2001\n2020\n2018\n2010\n2013\n2028\n2031\n2018\n2019\n2009\n2015\n2011\n2012\n2024\n2027\n2028\n2018\n2007\n2009\n2011\n2009\n2008\n2006\n2008\n2013\n2017\n2027\n2030\n2031\n2029\n2045\n2064\n2065\n2064\n2077\n2075\n2066\n2037\n2038\n2043\n2047\n2049\n2055\n2090\n2092\n2101\n2115\n2117\n2130\n2131\n2130\n2136\n2141\n2145\n2151\n2150\n2149\n2150\n2143\n2150\n2139\n2142\n2140\n2146\n2147\n2148\n2146\n2141\n2158\n2176\n2195\n2194\n2190\n2187\n2188\n2205\n2206\n2208\n2207\n2208\n2200\n2199\n2193\n2169\n2188\n2189\n2183\n2202\n2170\n2164\n2165\n2166\n2177\n2181\n2198\n2197\n2207\n2201\n2206\n2203\n2209\n2213\n2214\n2216\n2218\n2219\n2214\n2235\n2239\n2235\n2253\n2246\n2247\n2246\n2247\n2246\n2251\n2249\n2275\n2285\n2293\n2294\n2295\n2299\n2303\n2302\n2303\n2276\n2282\n2287\n2294\n2299\n2301\n2300\n2306\n2294\n2301\n2296\n2289\n2291\n2300\n2301\n2287\n2286\n2307\n2305\n2315\n2305\n2309\n2334\n2337\n2348\n2349\n2350\n2332\n2342\n2341\n2338\n2310\n2316\n2333\n2335\n2330\n2342\n2349\n2341\n2363\n2368\n2374\n2360\n2359\n2350\n2348\n2359\n2365\n2364\n2355\n2341\n2339\n2345\n2338\n2335\n2323\n2324\n2318\n2294\n2296\n2297\n2286\n2282\n2278\n2276\n2272\n2267\n2269\n2270\n2269\n2266\n2268\n2264\n2268\n2260\n2263\n2297\n2311\n2319\n2301\n2292\n2302\n2309\n2307\n2303\n2306\n2311\n2293\n2278\n2284\n2288\n2271\n2273\n2275\n2278\n2279\n2283\n2318\n2315\n2312\n2325\n2346\n2339\n2314\n2303\n2304\n2279\n2278\n2269\n2267\n2270\n2277\n2287\n2285\n2288\n2289\n2288\n2284\n2283\n2281\n2289\n2288\n2275\n2278\n2265\n2267\n2262\n2259\n2260\n2261\n2251\n2250\n2254\n2253\n2242\n2240\n2241\n2226\n2232\n2236\n2201\n2182\n2183\n2191\n2185\n2192\n2197\n2211\n2210\n2208\n2218\n2219\n2228\n2227\n2225\n2226\n2225\n2226\n2229\n2233\n2237\n2236\n2211\n2215\n2216\n2236\n2227\n2228\n2227\n2226\n2244\n2260\n2258\n2257\n2258\n2250\n2248\n2229\n2225\n2223\n2222\n2221\n2220\n2219\n2213\n2214\n2212\n2216\n2217\n2220\n2216\n2217\n2223\n2227\n2231\n2225\n2228\n2230\n2233\n2226\n2224\n2241\n2221\n2220\n2224\n2221\n2220\n2223\n2221\n2246\n2247\n2246\n2222\n2226\n2237\n2250\n2251\n2276\n2288\n2309\n2304\n2330\n2323\n2327\n2350\n2349\n2348\n2346\n2354\n2350\n2323\n2320\n2313\n2315\n2314\n2316\n2332\n2338\n2341\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_01_questions.txt",
    "content": "--- Day 1: Sonar Sweep ---\n\nYou're minding your own business on a ship at sea when the overboard alarm goes off! You rush to see if you can help. Apparently, one of the Elves tripped and accidentally sent the sleigh keys flying into the ocean!\n\nBefore you know it, you're inside a submarine the Elves keep ready for situations like this. It's covered in Christmas lights (because of course it is), and it even has an experimental antenna that should be able to track the keys if you can boost its signal strength high enough; there's a little meter that indicates the antenna's signal strength by displaying 0-50 stars.\n\nYour instincts tell you that in order to save Christmas, you'll need to get all fifty stars by December 25th.\n\nCollect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!\n\nAs the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine.\n\nFor example, suppose you had the following report:\n\n199\n200\n208\n210\n200\n207\n240\n269\n260\n263\n\nThis report indicates that, scanning outward from the submarine, the sonar sweep found depths of 199, 200, 208, 210, and so on.\n\nThe first order of business is to figure out how quickly the depth increases, just so you know what you're dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something.\n\nTo do this, count the number of times a depth measurement increases from the previous measurement. (There is no measurement before the first measurement.) In the example above, the changes are as follows:\n\n199 (N/A - no previous measurement)\n200 (increased)\n208 (increased)\n210 (increased)\n200 (decreased)\n207 (increased)\n240 (increased)\n269 (increased)\n260 (decreased)\n263 (increased)\n\nIn this example, there are 7 measurements that are larger than the previous measurement.\n\nHow many measurements are larger than the previous measurement?\n\n--- Part Two ---\n\nConsidering every single measurement isn't as useful as you expected: there's just too much noise in the data.\n\nInstead, consider sums of a three-measurement sliding window. Again considering the above example:\n\n199  A      \n200  A B    \n208  A B C  \n210    B C D\n200  E   C D\n207  E F   D\n240  E F G  \n269    F G H\n260      G H\n263        H\n\nStart by comparing the first and second three-measurement windows. The measurements in the first window are marked A (199, 200, 208); their sum is 199 + 200 + 208 = 607. The second window is marked B (200, 208, 210); its sum is 618. The sum of measurements in the second window is larger than the sum of the first, so this first comparison increased.\n\nYour goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum. So, compare A with B, then compare B with C, then C with D, and so on. Stop when there aren't enough measurements left to create a new three-measurement sum.\n\nIn the above example, the sum of each three-measurement window is as follows:\n\nA: 607 (N/A - no previous sum)\nB: 618 (increased)\nC: 618 (no change)\nD: 617 (decreased)\nE: 647 (increased)\nF: 716 (increased)\nG: 769 (increased)\nH: 792 (increased)\n\nIn this example, there are 5 sums that are larger than the previous sum.\n\nConsider sums of a three-measurement sliding window. How many sums are larger than the previous sum?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_02.adb",
    "content": "--  Solution to Advent of Code 2021, Day 2\n------------------------------------------\n--  Dive!\n--\n--  https://adventofcode.com/2021/day/2\n--  Copy of questions in: aoc_2021_02_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_02 is\n  use HAT;\n  c, sep : Character;\n  i, x, d, aim : Integer;\n  f : File_Type;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  for part in 1 .. 2 loop\n    x := 0;\n    d := 0;\n    aim := 0;\n    Open (f, \"aoc_2021_02.txt\");\n    while not End_Of_File (f) loop\n      Get (f, c);\n      loop\n        Get (f, sep);\n        exit when sep = ' ';\n      end loop;\n      Get (f, i);\n      case part is\n        when 1 =>\n          case c is\n            when 'f' => x := x + i;  --  Forward\n            when 'u' => d := d - i;  --  Up\n            when 'd' => d := d + i;  --  Down\n            when others => null;\n          end case;\n        when 2 =>\n          case c is\n            when 'f' => x := x + i;        --  Forward\n                        d := d + i * aim;\n            when 'u' => aim := aim - i;    --  Up\n            when 'd' => aim := aim + i;    --  Down\n            when others => null;\n          end case;\n      end case;\n    end loop;\n    Close (f);\n    if compiler_test_mode then\n      if x * d /= Integer_Value (Argument (part)) then\n        Set_Exit_Status (1);  --  Compiler test failed.\n      end if;\n    else\n      Put_Line (+\"Part \" & part & \": x = \" & x & \", d = \" & d & \", solution = x * d = \" & x * d);\n      --  Part 1: validated by AoC: 2187380\n      --  Part 2: validated by AoC: 2086357770\n    end if;\n  end loop;\nend AoC_2021_02;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_02.txt",
    "content": "forward 1\ndown 6\ndown 6\nforward 2\nforward 2\ndown 2\ndown 1\ndown 5\ndown 7\ndown 3\nforward 1\nforward 6\nup 2\nforward 2\nforward 7\nforward 4\ndown 2\nforward 6\nforward 6\ndown 3\nup 7\ndown 6\nforward 2\nup 5\ndown 7\nforward 8\ndown 8\nforward 8\ndown 5\ndown 5\ndown 8\nforward 9\ndown 7\nforward 9\nforward 9\nforward 8\ndown 6\ndown 9\ndown 1\nforward 8\ndown 6\ndown 7\nup 3\nforward 5\ndown 1\ndown 7\nup 8\nforward 6\ndown 2\ndown 9\ndown 9\nforward 1\ndown 2\ndown 9\nforward 1\nforward 3\ndown 6\nup 7\ndown 7\nforward 3\ndown 4\ndown 3\nup 7\nup 7\nforward 2\ndown 7\nforward 2\ndown 3\nup 7\ndown 7\nforward 6\ndown 2\ndown 7\nforward 5\ndown 9\ndown 2\nup 7\ndown 1\nforward 5\ndown 5\nforward 9\ndown 6\ndown 3\ndown 7\ndown 8\ndown 3\nup 4\ndown 6\nforward 6\nup 7\nup 2\nforward 3\nup 1\ndown 5\nforward 9\nup 3\nforward 8\nup 4\ndown 7\ndown 8\ndown 3\ndown 7\nforward 5\nup 6\ndown 4\ndown 8\ndown 8\nforward 7\ndown 5\nforward 3\nforward 1\ndown 1\nforward 1\nup 1\nforward 4\nforward 9\nup 8\ndown 7\ndown 9\ndown 1\ndown 2\ndown 1\ndown 4\nforward 4\nforward 8\nforward 6\nforward 1\nforward 6\nforward 9\ndown 1\nup 9\ndown 9\nforward 2\ndown 6\ndown 8\ndown 6\nup 7\nforward 2\nup 2\nforward 5\ndown 2\nup 2\nup 9\nforward 7\ndown 6\nforward 3\ndown 5\nup 4\ndown 1\ndown 5\ndown 6\nup 7\ndown 3\ndown 9\nup 8\ndown 2\nup 8\ndown 1\ndown 2\ndown 4\nforward 6\nup 7\nup 3\nforward 8\ndown 9\ndown 8\nforward 3\nup 5\nforward 1\ndown 5\nup 2\ndown 5\nup 4\ndown 6\nforward 9\ndown 1\ndown 1\nforward 1\ndown 2\nforward 9\nup 5\ndown 7\nforward 7\ndown 9\ndown 5\ndown 3\nforward 4\ndown 2\nforward 7\nforward 3\nup 4\ndown 9\nforward 9\nforward 3\nforward 1\nforward 6\ndown 1\ndown 5\ndown 3\nforward 9\ndown 2\nforward 9\nup 7\nforward 7\nforward 7\nforward 8\nforward 6\nforward 5\ndown 7\nup 4\nforward 7\nup 2\nforward 6\ndown 2\ndown 9\ndown 3\nforward 5\ndown 3\ndown 9\nforward 2\nup 4\nforward 7\nforward 3\nforward 8\ndown 4\nforward 4\ndown 3\nup 7\nup 1\nup 4\ndown 3\ndown 5\ndown 3\ndown 7\ndown 3\ndown 7\ndown 5\ndown 1\nforward 5\nforward 6\ndown 1\nforward 9\ndown 4\nup 1\nforward 5\nup 6\ndown 4\nup 7\ndown 4\ndown 9\nforward 7\nup 8\nforward 3\nforward 5\ndown 9\ndown 1\ndown 7\nforward 9\ndown 9\ndown 5\nforward 6\nforward 4\nforward 3\ndown 1\ndown 2\nup 4\nup 7\ndown 8\nforward 4\nforward 1\nforward 8\ndown 8\ndown 8\nforward 1\nforward 5\nup 8\nforward 2\ndown 6\nforward 6\ndown 6\nforward 7\ndown 9\ndown 4\nup 4\nup 5\ndown 7\nforward 4\ndown 7\ndown 5\nforward 7\ndown 3\ndown 2\nforward 5\nforward 1\ndown 5\ndown 4\ndown 8\nup 8\nforward 3\ndown 7\ndown 8\ndown 5\nforward 1\ndown 6\nforward 8\nforward 2\nforward 3\ndown 4\nup 3\ndown 4\nforward 3\nforward 9\nup 5\nup 9\ndown 3\nup 4\nforward 4\ndown 9\nforward 8\ndown 2\ndown 2\nforward 9\ndown 5\ndown 2\nup 1\nforward 6\nforward 4\nup 5\nup 3\nup 8\ndown 7\nforward 5\nup 7\nforward 9\ndown 6\ndown 7\nforward 4\ndown 9\nup 2\nforward 8\ndown 1\nforward 6\nforward 1\nforward 4\ndown 9\ndown 6\nup 1\nforward 1\ndown 5\nup 1\nforward 3\ndown 1\ndown 4\nforward 3\ndown 4\nup 9\ndown 6\nup 6\nforward 1\nforward 8\nup 1\ndown 7\nup 8\nup 3\nup 7\ndown 9\nforward 8\ndown 3\nup 2\nforward 3\nup 4\nup 3\ndown 5\nforward 3\nforward 2\ndown 3\nforward 5\nup 4\ndown 9\ndown 8\ndown 3\ndown 5\ndown 7\nforward 2\nforward 8\nup 9\nforward 9\ndown 4\ndown 8\nforward 5\ndown 2\nup 4\ndown 7\nforward 6\nup 9\nforward 6\ndown 9\ndown 5\nforward 9\ndown 5\ndown 3\nup 6\nup 6\ndown 7\nup 1\nforward 7\nforward 4\ndown 5\nforward 8\ndown 5\ndown 8\nforward 4\nforward 8\nforward 1\ndown 7\nforward 4\ndown 6\ndown 4\nup 8\ndown 4\nup 5\nup 7\nup 2\ndown 5\ndown 9\nforward 6\ndown 7\ndown 9\ndown 3\nup 4\ndown 8\nforward 3\nforward 5\nforward 8\ndown 9\nforward 9\ndown 1\nup 1\ndown 9\nforward 3\nup 9\nforward 5\nforward 2\ndown 1\ndown 5\ndown 6\nforward 5\nforward 4\nup 5\nforward 5\nup 4\nup 9\nup 4\nforward 8\ndown 7\ndown 6\ndown 9\ndown 3\ndown 2\ndown 6\nup 6\nforward 6\nup 3\ndown 3\nforward 3\ndown 2\ndown 9\ndown 3\nforward 1\nforward 8\ndown 2\ndown 9\ndown 6\nup 3\ndown 6\nforward 1\nforward 1\nforward 2\ndown 9\ndown 8\nforward 9\ndown 2\nup 3\nforward 2\nup 5\nup 8\ndown 4\nup 3\nforward 3\nforward 5\nforward 1\ndown 5\nup 4\nforward 4\ndown 7\nforward 8\nup 7\nforward 5\ndown 2\nforward 4\nforward 6\ndown 7\ndown 9\nforward 2\nforward 2\ndown 4\ndown 5\nup 5\nforward 5\nforward 2\ndown 8\nforward 6\ndown 1\ndown 6\nforward 1\ndown 8\nup 6\ndown 8\nforward 4\ndown 4\ndown 4\nforward 3\nup 8\ndown 1\nforward 7\ndown 5\nforward 1\ndown 9\ndown 9\ndown 5\nforward 1\ndown 4\nup 6\nforward 4\nforward 5\nforward 1\ndown 4\ndown 2\ndown 5\nforward 6\nforward 1\nforward 6\ndown 2\ndown 6\nforward 3\ndown 9\nup 6\nforward 2\nup 7\nforward 8\ndown 7\nup 1\nforward 1\ndown 8\nforward 8\ndown 9\nforward 4\ndown 4\ndown 5\ndown 8\nup 3\nforward 1\nforward 9\ndown 9\nup 2\ndown 1\ndown 8\ndown 6\nforward 3\ndown 8\ndown 3\nforward 5\nforward 2\nforward 5\nforward 5\nforward 2\nforward 4\ndown 9\ndown 3\nforward 7\nforward 3\nup 3\nup 1\nforward 2\ndown 5\nforward 3\nup 3\nforward 2\nforward 9\nforward 5\ndown 3\nforward 9\nup 2\nforward 7\nup 3\ndown 8\nforward 7\nup 5\nforward 3\nforward 4\nup 5\ndown 6\nup 2\nforward 8\nup 3\ndown 5\ndown 4\nforward 9\nup 2\ndown 5\nforward 4\nup 7\ndown 9\nup 8\ndown 4\nup 5\nforward 4\ndown 8\nforward 3\ndown 5\ndown 5\ndown 8\nup 9\nforward 3\nforward 9\ndown 2\nforward 4\ndown 1\nup 3\ndown 9\nup 6\ndown 1\ndown 1\ndown 5\ndown 1\ndown 7\nforward 4\ndown 4\ndown 9\nup 1\nup 7\nup 2\ndown 8\nup 5\ndown 6\nforward 6\nforward 6\ndown 4\nforward 9\nforward 4\nforward 9\nforward 4\nup 5\nforward 9\nup 7\nup 1\nforward 5\nforward 9\ndown 7\nforward 7\nforward 6\ndown 5\nforward 9\nup 9\ndown 4\ndown 9\ndown 2\nforward 3\ndown 3\ndown 3\nforward 9\ndown 8\ndown 4\ndown 8\ndown 6\ndown 6\ndown 9\nup 5\ndown 3\ndown 4\nup 6\nup 2\nforward 1\nup 9\nup 9\nforward 9\nforward 7\ndown 3\nforward 2\nup 5\ndown 2\nforward 2\nforward 8\ndown 8\nforward 4\nforward 2\nup 3\nup 8\ndown 5\nforward 5\nforward 8\ndown 1\ndown 8\nforward 3\nforward 9\ndown 7\nforward 5\nforward 8\nforward 1\nup 6\nforward 9\nup 5\nforward 8\nforward 3\ndown 2\nup 9\nup 7\nforward 5\ndown 8\ndown 3\nforward 8\ndown 3\ndown 9\ndown 9\nforward 7\ndown 9\nforward 5\nforward 1\nforward 5\ndown 2\ndown 7\nforward 4\ndown 4\nup 8\ndown 2\nup 1\ndown 1\nup 5\nup 6\ndown 5\nup 9\nup 6\ndown 6\ndown 4\ndown 3\nforward 9\nforward 2\nforward 2\nup 6\nforward 9\ndown 3\nforward 4\nforward 6\nforward 8\nforward 2\nforward 8\nforward 4\ndown 1\nforward 3\nup 1\nup 9\nforward 9\nup 6\nup 5\nforward 2\ndown 6\nup 8\nup 9\nforward 3\nforward 9\ndown 7\ndown 6\nforward 2\ndown 7\nforward 4\ndown 5\ndown 2\ndown 6\ndown 2\ndown 5\ndown 3\nforward 3\ndown 7\ndown 6\ndown 5\nup 2\nforward 4\nup 9\nforward 2\nforward 4\ndown 5\nup 9\nup 2\nforward 9\nforward 6\ndown 6\ndown 3\ndown 5\ndown 1\nup 4\nup 1\ndown 4\ndown 1\nforward 5\nforward 3\ndown 7\ndown 9\nforward 2\ndown 3\nup 7\ndown 2\ndown 6\nforward 3\nforward 3\ndown 3\nup 1\nforward 6\nforward 3\ndown 6\ndown 2\nup 4\nup 3\ndown 5\ndown 9\ndown 3\nforward 7\nforward 2\nforward 9\ndown 6\nforward 4\nup 9\nforward 1\ndown 4\ndown 6\ndown 2\nforward 3\ndown 2\nup 8\nforward 1\nforward 9\ndown 9\nup 7\nforward 6\nup 8\ndown 9\ndown 4\nforward 8\ndown 6\ndown 1\ndown 9\ndown 1\nup 7\nforward 9\nup 3\nforward 7\nup 7\ndown 2\nforward 1\ndown 4\ndown 7\nforward 7\nforward 9\ndown 6\ndown 5\ndown 8\ndown 9\nup 3\ndown 7\nup 3\ndown 1\nforward 1\nforward 6\nforward 2\ndown 6\nforward 9\nforward 1\nup 2\nforward 1\nforward 3\nforward 4\nforward 7\nforward 4\ndown 3\nup 8\nforward 9\ndown 7\nforward 6\nforward 3\ndown 6\nforward 4\nup 1\nforward 3\ndown 3\nforward 9\nforward 2\nforward 1\nforward 4\nup 6\nforward 3\ndown 6\ndown 8\nup 4\nforward 8\nforward 4\ndown 8\nup 4\nup 3\nforward 9\nforward 3\ndown 5\nforward 7\nforward 1\nup 8\nup 4\ndown 1\ndown 3\ndown 9\ndown 7\nup 5\nforward 6\ndown 1\nforward 3\ndown 2\ndown 2\ndown 6\nforward 2\ndown 5\nforward 2\nforward 1\nup 9\ndown 1\nforward 3\ndown 3\nforward 6\ndown 1\nforward 5\nforward 7\ndown 6\nforward 7\ndown 4\nup 7\nforward 1\ndown 7\ndown 8\ndown 9\ndown 6\ndown 1\nforward 6\ndown 7\nforward 2\ndown 2\nup 1\nup 2\ndown 3\ndown 4\nup 2\nforward 3\ndown 5\ndown 4\ndown 9\ndown 6\ndown 9\ndown 7\ndown 2\nforward 7\nforward 3\nup 3\ndown 1\ndown 5\ndown 1\ndown 3\ndown 3\nforward 9\ndown 1\ndown 7\nup 4\ndown 1\ndown 6\nup 9\ndown 9\nforward 6\ndown 9\nforward 3\nforward 8\nup 1\nforward 3\ndown 8\nforward 2\ndown 6\ndown 1\nup 7\ndown 1\nforward 3\ndown 2\nforward 1\nup 8\nforward 8\nforward 7\ndown 9\nforward 3\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_02_questions.txt",
    "content": "--- Day 2: Dive! ---\n\nNow, you need to figure out how to pilot this thing.\n\nIt seems like the submarine can take a series of commands like forward 1, down 2, or up 3:\n\n    forward X increases the horizontal position by X units.\n    down X increases the depth by X units.\n    up X decreases the depth by X units.\n\nNote that since you're on a submarine, down and up affect your depth, and so they have the opposite result of what you might expect.\n\nThe submarine seems to already have a planned course (your puzzle input). You should probably figure out where it's going. For example:\n\nforward 5\ndown 5\nforward 8\nup 3\ndown 8\nforward 2\n\nYour horizontal position and depth both start at 0. The steps above would then modify them as follows:\n\n    forward 5 adds 5 to your horizontal position, a total of 5.\n    down 5 adds 5 to your depth, resulting in a value of 5.\n    forward 8 adds 8 to your horizontal position, a total of 13.\n    up 3 decreases your depth by 3, resulting in a value of 2.\n    down 8 adds 8 to your depth, resulting in a value of 10.\n    forward 2 adds 2 to your horizontal position, a total of 15.\n\nAfter following these instructions, you would have a horizontal position of 15 and a depth of 10. (Multiplying these together produces 150.)\n\nCalculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth?\n\n--- Part Two ---\n\nBased on your calculations, the planned course doesn't seem to make any sense. You find the submarine manual and discover that the process is actually slightly more complicated.\n\nIn addition to horizontal position and depth, you'll also need to track a third value, aim, which also starts at 0. The commands also mean something entirely different than you first thought:\n\n    down X increases your aim by X units.\n    up X decreases your aim by X units.\n    forward X does two things:\n        It increases your horizontal position by X units.\n        It increases your depth by your aim multiplied by X.\n\nAgain note that since you're on a submarine, down and up do the opposite of what you might expect: \"down\" means aiming in the positive direction.\n\nNow, the above example does something different:\n\n    forward 5 adds 5 to your horizontal position, a total of 5. Because your aim is 0, your depth does not change.\n    down 5 adds 5 to your aim, resulting in a value of 5.\n    forward 8 adds 8 to your horizontal position, a total of 13. Because your aim is 5, your depth increases by 8*5=40.\n    up 3 decreases your aim by 3, resulting in a value of 2.\n    down 8 adds 8 to your aim, resulting in a value of 10.\n    forward 2 adds 2 to your horizontal position, a total of 15. Because your aim is 10, your depth increases by 2*10=20 to a total of 60.\n\nAfter following these new instructions, you would have a horizontal position of 15 and a depth of 60. (Multiplying these produces 900.)\n\nUsing this new interpretation of the commands, calculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_03.adb",
    "content": "--  Solution to Advent of Code 2021, Day 3\n------------------------------------------\n--  Binary Diagnostic\n--\n--  https://adventofcode.com/2021/day/3\n--  Copy of questions in: aoc_2021_03_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_03 is\n  use HAT;\n  c : Character;\n  f : File_Type;\n  --\n  input : constant VString := +\"aoc_2021_03.txt\";\n  bits : constant := 12;\n  subtype Bit_Pos_Range is Integer range 1 .. bits;\n  stat_ones : array (Bit_Pos_Range) of Natural;\n  type Criterium is (most, least);\n  stat_ones_selected_pos : Natural;\n  --\n  subtype Bit_Type is Integer range 0 .. 1;\n  type Word is array (Bit_Pos_Range) of Bit_Type;\n  keep, bit_value, mem_valid : Word;\n  --\n  consider : Boolean;\n  rows, gamma, epsilon, res_1, res_2 : Natural;\n  gas : array (Criterium) of Natural;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\nbegin\n  for pos in Bit_Pos_Range loop\n    stat_ones (pos) := 0;\n  end loop;\n  rows := 0;\n  Open (f, input);\n  while not End_Of_File (f) loop\n    rows := rows + 1;\n    for pos in Bit_Pos_Range loop\n      Get (f, c);\n      if c = '1' then\n        stat_ones (pos) := stat_ones (pos) + 1;\n      end if;\n    end loop;\n  end loop;\n  Close (f);\n  gamma := 0;\n  for pos in Bit_Pos_Range loop\n    gamma := gamma * 2;\n    if stat_ones (pos) > rows / 2 then\n      gamma := gamma + 1;\n    end if;\n  end loop;\n  epsilon := 2 ** bits - 1 - gamma;\n  if verbose then\n    Put_Line (+\"Part 1: gamma: \" & gamma & \"; epsilon: \" & epsilon);\n  end if;\n  res_1 := gamma * epsilon;\n  --\n  --  Part Two\n  --\n  if verbose then Put_Line (+\"Part 2:\"); end if;\n  for pos in Bit_Pos_Range loop\n    keep (pos) := 0;  --  Just to remove a compiler warning.\n  end loop;\n  for crit in Criterium loop\n    for main_pos in Bit_Pos_Range loop\n      stat_ones_selected_pos  := 0;\n      rows := 0;\n      Open (f, input);\n      while not End_Of_File (f) loop\n        consider := True;\n        for pos in Bit_Pos_Range loop\n          Get (f, c);\n          bit_value (pos) := Ord (c) - Ord ('0');\n          if pos < main_pos then\n            consider := consider and keep (pos) = bit_value (pos);\n          elsif pos = main_pos then\n            if consider then\n              rows := rows + 1;\n              if bit_value (pos) = 1 then\n                stat_ones_selected_pos := stat_ones_selected_pos + 1;\n              end if;\n            end if;\n          end if;\n        end loop;\n        if consider then\n          mem_valid := bit_value;  --  Remember the number on the last considered row.\n        end if;\n      end loop;\n      Close (f);\n      if verbose then\n        Put (\"Bit pos: \"); Put (main_pos, 2); Put (+\"/\" & bits & \"; rows: \"); Put (rows, 5);\n      end if;\n      if rows = 1 then\n        keep := mem_valid;\n        if verbose then\n          Put_Line (\". Only one row left, stop!\");\n        end if;\n        exit;\n      else\n        case crit is\n          when most =>\n            if stat_ones_selected_pos >= rows - stat_ones_selected_pos then\n              keep (main_pos) := 1;\n            else\n              keep (main_pos) := 0;\n            end if;\n          when least =>\n            if stat_ones_selected_pos >= rows - stat_ones_selected_pos then\n              keep (main_pos) := 0;\n            else\n              keep (main_pos) := 1;\n            end if;\n        end case;\n        if verbose then\n          Put (\";  ones: \"); Put (stat_ones_selected_pos, 5); Put (keep (main_pos)); New_Line;\n        end if;\n      end if;\n    end loop;\n    if verbose then\n      for main_pos in Bit_Pos_Range loop\n        Put (keep (main_pos), 0);\n      end loop;\n      New_Line;\n    end if;\n    gas (crit) := 0;\n    for pos in Bit_Pos_Range loop\n      gas (crit) := gas (crit) * 2;\n      if keep (pos) = 1 then\n        gas (crit) := gas (crit) + 1;\n      end if;\n    end loop;\n  end loop;\n  if verbose then\n    Put_Line (+\"Oxygen: \" & gas (most));\n    Put_Line (+\"CO2: \" & gas (least));\n  end if;\n  res_2 := gas (most) * gas (least);\n  --\n  if compiler_test_mode then\n    if res_1 /= Integer_Value (Argument (1)) or\n       res_2 /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Result Part 1: \" & res_1);\n    Put_Line (+\"Result Part 2: \" & res_2);\n    --  Part 1: validated by AoC: 3549854\n    --  Part 2: validated by AoC: 3765399\n  end if;\nend AoC_2021_03;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_03.txt",
    "content": "000000011010\n011001111011\n100101011101\n000110000110\n101010001010\n010010000011\n011001111001\n100111000000\n011101011010\n000000110001\n101110111100\n111110100001\n000000001111\n001011111111\n101011001111\n101000101010\n110111010001\n000010011111\n000101001011\n101111001001\n100000000100\n010100010100\n100110001110\n101011101110\n111100101101\n000101000001\n001110000011\n111010110001\n101000101000\n011011000101\n000001100100\n101001011101\n001111111111\n101001001101\n100100100001\n101111000100\n000110101000\n001100011001\n101111101000\n101010110000\n110100010001\n101110101100\n010101100100\n011101100110\n101000011011\n101110101011\n110100001100\n100111000001\n010000100000\n111010110010\n111110100111\n001101110111\n001001100100\n000110100100\n011100110010\n100110001100\n011011110110\n110001011100\n101111001111\n110011011101\n111001100110\n110110011001\n111011000000\n000101101011\n111110101110\n000100011000\n000001000001\n010110000011\n000100011100\n011000110000\n101011010101\n100101110101\n110001010010\n101111001101\n101110011010\n101110000010\n010001111010\n100000111111\n000000010011\n100010111011\n000110100000\n101111000101\n001110011101\n100011010010\n100001011101\n011100101100\n111100010010\n111011011110\n010010000110\n010100001011\n011000100010\n100011001000\n011001101001\n110110010001\n111110001001\n000111101100\n100111000011\n111011110100\n101000000010\n011000110101\n101010110101\n110110000011\n111101000110\n010000100110\n000110101010\n111100110110\n111000011101\n010001011101\n101011011000\n101000101110\n110101010001\n000001110011\n110010001110\n110110000101\n110111111001\n110001000101\n001101010011\n010100011100\n111011100100\n101010001011\n001011101011\n101100010001\n010100000000\n110100000100\n010011111111\n101010010100\n111101000101\n000011000011\n001111100000\n010110101110\n001010110010\n000111100001\n101000101101\n111101110010\n000000101011\n110010000111\n001111100110\n000100001110\n110101101000\n000010100001\n000111010011\n010110001101\n111110011001\n011011111001\n000011010011\n001111000000\n011000010001\n000100011011\n110011111011\n001011101101\n010111011111\n001001110111\n100110100011\n000001110100\n000010011000\n110001101000\n000001100111\n011110100000\n110000001000\n110000001110\n000010001100\n000011100010\n101100111101\n101000000011\n110011001010\n110100110000\n100101001010\n111000111011\n100011001010\n111111111110\n111100000011\n011101110101\n010100001111\n010110010000\n000011010100\n011111010001\n111011000010\n111110000110\n101100101101\n010111011001\n001001111100\n001101010000\n011000100000\n001011111110\n100010101111\n001100010101\n001000001111\n110001010011\n000000011100\n011100010001\n000111100101\n010000010110\n000001111100\n010010110111\n110101001100\n001011001100\n111111011100\n111001100101\n001010010000\n101100101001\n101100110011\n011100111100\n110001110100\n101000101111\n110011111001\n011101000010\n100001111001\n010101111101\n101101010010\n110001011010\n110100100001\n011011110111\n101110110000\n110111001001\n000011110100\n101000110001\n011110110111\n011011101001\n101011101001\n100001111011\n101001010011\n110000010010\n001011110110\n110001011011\n101100100001\n001010000101\n101011000100\n000111110100\n011010000010\n110000011001\n010001011110\n001000100011\n010000111010\n011010111000\n000001110010\n010010011111\n100100010000\n001000000110\n100001110111\n000100010000\n000010110000\n010100111101\n100001100111\n100101101011\n000010111010\n010110111100\n100101010110\n001000101000\n011101101011\n000111101001\n001000010101\n101011010001\n001110101100\n010010100100\n101101101100\n000010111101\n000100111000\n100010110000\n001100101111\n111110000011\n001101101100\n110101001111\n110010101010\n011111000101\n111001111101\n000011001101\n000000011001\n010001110001\n001001010011\n110101110101\n011011110010\n111010110111\n011000011110\n111110011110\n110001001101\n010110100100\n011100000101\n000111110111\n101110100010\n000000011000\n011101010011\n001111100001\n110010010101\n101001001100\n000111100011\n101111100011\n001100010001\n110001100101\n011001101100\n000011000010\n000001111000\n110010001100\n110011010011\n010111100001\n101101101101\n010010100110\n010001101100\n111100100001\n001000001001\n110110101000\n000011000001\n001001001011\n001101100100\n100011111110\n100101110110\n001100010000\n100111100111\n010111100111\n110011101111\n010001101010\n011010011111\n001011000110\n010001100000\n111001010011\n010011100111\n101000111110\n110110110110\n000011111001\n101011100110\n000010011110\n010001111101\n100111010101\n100111001001\n100000010011\n000011111010\n110010100010\n101101000001\n111000001010\n011111101100\n001100001101\n000100010011\n010110011110\n001110001011\n101110011111\n011111000010\n110101001000\n000000110100\n110110101101\n010111110100\n110000000001\n100011100001\n100000010110\n010100100110\n100111111001\n000110111110\n000000110000\n110001110101\n101110110110\n101011110101\n110100110010\n010000001010\n110001111111\n000110101101\n111100010110\n110011100011\n110000000111\n110011011011\n111111001110\n111110111001\n110001110110\n001101000000\n001011111001\n110001001010\n001000010100\n001011110001\n000000010000\n111111000001\n110010000110\n111010011111\n100100100100\n000000000101\n100001010000\n110101110111\n001011111100\n100111101100\n100011110110\n110110111100\n001001010001\n011100111101\n110110001101\n111100001011\n000000100100\n111101101010\n111001111100\n010101110011\n101010100110\n100001000101\n100110011101\n101101000100\n100000011011\n001001101000\n001010011110\n100010011011\n011100010111\n011101000111\n111100101110\n100100000111\n100101110001\n100000011101\n001000011001\n010101100110\n101001101010\n100011110000\n101010100000\n111000101100\n111000101110\n101000100001\n100110000100\n010010110011\n111001101011\n011000000100\n010100001000\n010001101001\n001111101001\n010010110010\n101110010011\n011000101001\n111000111001\n110010011011\n110011010100\n100010110110\n110000011011\n111100100100\n101001111011\n110100010011\n101110100100\n000011111000\n001110101011\n101000001111\n111100000100\n010110001110\n010111011010\n100100101011\n110010111111\n011001011011\n000101100001\n010011001001\n000111111010\n000000011111\n011011000011\n111011110001\n110110010101\n111100010000\n011101100001\n001110000010\n110101011010\n000101011100\n011110000011\n100010010011\n011100100000\n001111111101\n000101000111\n001001011010\n101111111001\n110000111011\n000001100001\n101000100111\n111111101100\n110001100111\n101110010110\n100110000111\n000110000010\n100001110100\n101111011011\n110110000010\n111000001101\n110100010010\n100011010011\n110000111110\n110100000000\n101110000001\n001001011111\n101000000101\n000100110111\n111010000101\n010111100101\n010011100011\n100110100001\n110101011101\n100011000101\n001001111101\n100111000110\n001001110101\n111110010110\n011000000111\n010011101110\n111010011000\n001101100010\n111101100101\n101011100000\n101100100011\n100010101101\n010000101101\n111000000010\n000010001010\n000110101110\n000110110001\n111110111101\n001111110100\n101101110011\n011110011011\n100010110111\n001110000101\n101010001000\n110000110101\n000110000011\n101101111001\n101100001011\n010000001101\n101110110010\n101001111001\n000100110100\n111100001000\n101010100010\n010100011111\n011110001101\n001100100001\n110100011101\n000001001101\n000001001111\n110000010000\n110010111011\n100001111100\n110100000010\n010111100100\n111011001110\n100101000100\n111011010010\n011101000011\n011100010100\n010101000010\n010110100001\n010011001100\n011100100100\n100000111010\n011001000111\n011101011101\n100010101001\n011001111110\n011101110001\n001110100010\n011100010110\n100111110001\n000101001100\n001101110001\n110101110000\n000110011001\n100000111000\n111101010001\n000001110001\n110111001000\n110110110111\n110111101100\n001110010110\n100001111101\n110101101111\n000110010101\n100010001010\n001110110000\n111000110100\n010101111100\n001000101010\n011010111101\n110001110111\n000010001000\n100100011100\n001000100110\n100000100110\n101001110100\n100111001011\n000011010010\n010111001010\n111000000011\n110110110000\n010110101010\n110011010110\n101101001010\n011110110001\n100011011101\n001110010011\n011100000100\n111100100101\n111011110010\n010110011101\n111101000100\n000110111011\n000001011000\n101111110000\n101000100110\n100100100000\n001010001110\n000111011110\n101000100100\n011111110111\n111100011001\n101010010001\n101100011101\n011000011000\n011111100100\n001100101000\n110001100001\n000010010111\n110100001111\n010010011001\n010100100100\n110110101111\n001010110000\n110011010111\n000010010101\n100111001110\n001100101011\n001111111100\n010111111100\n101101000010\n000001001110\n011111111110\n001010000111\n111011010110\n110110100011\n010001101000\n010011010111\n000100001010\n010000100010\n000111100100\n011000010011\n001011000001\n001101001111\n100111010111\n100010100001\n010000110110\n111010101011\n010111011100\n011111011010\n001110100101\n010100110010\n100001000010\n011111110011\n100011011010\n110100011100\n011101111011\n101011011100\n111110001011\n101011010010\n111010101101\n011110010111\n011101100111\n000110100010\n110011100110\n100000010101\n111111100111\n101000110101\n110011001101\n100010011111\n111000011011\n101010000000\n111100110010\n001000011101\n001001100110\n101011001011\n010011111010\n110000110100\n100010000000\n100111111111\n101011100010\n011000100100\n111101010100\n100011111101\n010001110100\n100100101110\n111111000000\n001101111101\n011100101011\n111011110111\n001001101101\n110110000100\n101100111110\n000000001100\n110100011010\n001011010010\n111000110101\n011111100001\n000000101110\n110000010111\n100011111011\n111111000101\n110011101110\n000011000111\n001011101100\n100000000000\n011001010011\n111001010010\n000110101111\n111111111000\n000101110100\n111000010000\n100011011100\n111001111000\n101001011010\n011101111000\n111111110101\n100110101110\n100100010001\n100000101100\n001000001101\n000010110010\n110001000011\n111111011011\n010100010111\n101010001001\n000111011011\n001011111101\n110111110011\n011001100010\n011101111010\n001000000001\n101001100100\n110101110100\n111110011111\n111011111011\n111011111010\n101010000001\n001011010110\n111001011111\n100011110001\n011100101101\n010010010100\n001001100010\n110110000110\n011111011011\n001100100110\n011110111010\n010101011101\n110101100011\n001101110110\n011110101111\n001101110101\n001100001111\n100101111110\n101111001011\n001000110000\n001110000001\n100110101111\n111001000011\n101101111000\n000010000101\n010011001101\n111110000001\n001111101011\n111010001100\n101001101001\n001011101010\n101001100101\n011100001001\n000100011111\n101101001101\n111110111011\n000100011101\n100101101000\n101110011011\n001111100010\n101110011110\n110001000100\n110101010100\n011101000101\n011110001010\n110100011000\n001000100100\n111000011100\n000111110101\n011010101011\n000011110111\n100111110100\n100110100101\n011100100110\n000111111001\n010001110010\n001110111001\n010011111100\n100111011010\n001001000110\n111010010100\n110101000011\n100001111111\n111001001011\n001100100101\n110001001111\n011011010010\n110110000000\n010101111110\n011011010000\n110100101010\n100001100001\n010100110011\n101000011101\n111100000111\n010100111010\n101000001001\n101110010000\n010100010010\n100110011110\n010011111101\n011011000000\n101011100100\n101100110100\n111001101110\n001101101111\n101000010011\n000101001111\n001011101001\n001011111000\n001001010000\n111110101001\n110101100001\n011100001010\n100111010100\n010001001111\n001110100011\n100101111100\n010101011110\n000110111010\n111010101110\n001110001110\n011101001000\n010001000000\n011100110101\n111111001100\n011110101011\n010111011000\n100100111111\n110111111000\n001010100101\n001110011001\n010101001001\n101111101010\n011110001110\n100001000110\n110100001010\n000011001011\n101011000111\n000010001001\n011010100000\n011101011100\n110100000111\n101000111000\n011100011110\n111101110001\n001010010100\n011111110101\n111101000000\n111000010111\n001111010100\n000110000000\n001100010010\n010000111000\n111101101000\n101001011001\n010011100100\n111101111000\n101110001010\n101101110111\n010011000111\n100000011100\n100001100010\n100011011111\n010110001010\n100011111100\n110110011100\n011111101101\n111111101000\n100101110000\n100010100011\n100000010000\n100000100010\n001111011110\n000101111101\n111111111111\n111101100110\n010111110110\n101111100101\n000010110111\n010000011000\n000010111000\n010011111001\n010011001010\n101011101000\n001010111000\n010000110100\n100011011011\n100100000010\n001011000011\n001110011111\n010000110010\n010110110110\n110100110110\n000010101011\n010101000101\n001011010011\n100011001101\n001100000110\n101010100101\n111110011000\n101110111111\n111011101010\n010000010011\n101101110010\n010110110101\n000011111111\n111111001010\n000101000011\n000100000110\n111101110011\n000010101010\n100111011110\n101110001001\n100000000111\n111000011001\n101101101111\n101110010111\n111010011001\n011010110001\n010011101100\n110110010011\n010000001011\n001010100001\n110111011101\n111110111000\n110110101010\n100011000111\n101010111010\n101101111110\n100110101101\n101111101101\n111101100000\n010110000101\n101010001101\n011110101010\n000100001011\n001001011001\n000011000101\n011110000010\n111110001010\n111101010111\n011111000000\n010000000011\n101010100001\n011101101110\n110111110000\n111111101001\n100101111101\n011011011001\n101101000110\n000101101000\n110001011111\n011100010011\n111111111101\n001010000100\n111010001001\n101110110011\n111001010001\n110011100100\n000101100111\n011000001000\n011010101111\n000101000010\n111001000110\n101101100001\n101100010010\n101000010000\n001001111000\n001100101100\n100101010010\n101000010110\n111001100100\n111001110010\n100000010100\n011011111111\n100100001101\n011010100110\n101010010101\n011101110111\n110101011111\n010101010110\n011010000011\n000010000100\n011001100100\n101011011111\n110000100111\n001011001001\n000000101001\n011000111010\n100110001001\n111011100101\n000100101111\n100001001001\n101110000000\n100001001110\n111101100111\n111011111100\n000011011001\n000000100001\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_03_questions.txt",
    "content": "--- Day 3: Binary Diagnostic ---\n\nThe submarine has been making some odd creaking noises, so you ask it to produce a diagnostic report just in case.\n\nThe diagnostic report (your puzzle input) consists of a list of binary numbers which, when decoded properly, can tell you many useful things about the conditions of the submarine. The first parameter to check is the power consumption.\n\nYou need to use the binary numbers in the diagnostic report to generate two new binary numbers (called the gamma rate and the epsilon rate). The power consumption can then be found by multiplying the gamma rate by the epsilon rate.\n\nEach bit in the gamma rate can be determined by finding the most common bit in the corresponding position of all numbers in the diagnostic report. For example, given the following diagnostic report:\n\n00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010\n\nConsidering only the first bit of each number, there are five 0 bits and seven 1 bits. Since the most common bit is 1, the first bit of the gamma rate is 1.\n\nThe most common second bit of the numbers in the diagnostic report is 0, so the second bit of the gamma rate is 0.\n\nThe most common value of the third, fourth, and fifth bits are 1, 1, and 0, respectively, and so the final three bits of the gamma rate are 110.\n\nSo, the gamma rate is the binary number 10110, or 22 in decimal.\n\nThe epsilon rate is calculated in a similar way; rather than use the most common bit, the least common bit from each position is used. So, the epsilon rate is 01001, or 9 in decimal. Multiplying the gamma rate (22) by the epsilon rate (9) produces the power consumption, 198.\n\nUse the binary numbers in your diagnostic report to calculate the gamma rate and epsilon rate, then multiply them together. What is the power consumption of the submarine? (Be sure to represent your answer in decimal, not binary.)\n\n--- Part Two ---\n\nNext, you should verify the life support rating, which can be determined by multiplying the oxygen generator rating by the CO2 scrubber rating.\n\nBoth the oxygen generator rating and the CO2 scrubber rating are values that can be found in your diagnostic report - finding them is the tricky part. Both values are located using a similar process that involves filtering out values until only one remains. Before searching for either rating value, start with the full list of binary numbers from your diagnostic report and consider just the first bit of those numbers. Then:\n\n    Keep only numbers selected by the bit criteria for the type of rating value for which you are searching. Discard numbers which do not match the bit criteria.\n    If you only have one number left, stop; this is the rating value for which you are searching.\n    Otherwise, repeat the process, considering the next bit to the right.\n\nThe bit criteria depends on which type of rating value you want to find:\n\n    To find oxygen generator rating, determine the most common value (0 or 1) in the current bit position, and keep only numbers with that bit in that position. If 0 and 1 are equally common, keep values with a 1 in the position being considered.\n    To find CO2 scrubber rating, determine the least common value (0 or 1) in the current bit position, and keep only numbers with that bit in that position. If 0 and 1 are equally common, keep values with a 0 in the position being considered.\n\nFor example, to determine the oxygen generator rating value using the same example diagnostic report from above:\n\n    Start with all 12 numbers and consider only the first bit of each number. There are more 1 bits (7) than 0 bits (5), so keep only the 7 numbers with a 1 in the first position: 11110, 10110, 10111, 10101, 11100, 10000, and 11001.\n    Then, consider the second bit of the 7 remaining numbers: there are more 0 bits (4) than 1 bits (3), so keep only the 4 numbers with a 0 in the second position: 10110, 10111, 10101, and 10000.\n    In the third position, three of the four numbers have a 1, so keep those three: 10110, 10111, and 10101.\n    In the fourth position, two of the three numbers have a 1, so keep those two: 10110 and 10111.\n    In the fifth position, there are an equal number of 0 bits and 1 bits (one each). So, to find the oxygen generator rating, keep the number with a 1 in that position: 10111.\n    As there is only one number left, stop; the oxygen generator rating is 10111, or 23 in decimal.\n\nThen, to determine the CO2 scrubber rating value from the same example above:\n\n    Start again with all 12 numbers and consider only the first bit of each number. There are fewer 0 bits (5) than 1 bits (7), so keep only the 5 numbers with a 0 in the first position: 00100, 01111, 00111, 00010, and 01010.\n    Then, consider the second bit of the 5 remaining numbers: there are fewer 1 bits (2) than 0 bits (3), so keep only the 2 numbers with a 1 in the second position: 01111 and 01010.\n    In the third position, there are an equal number of 0 bits and 1 bits (one each). So, to find the CO2 scrubber rating, keep the number with a 0 in that position: 01010.\n    As there is only one number left, stop; the CO2 scrubber rating is 01010, or 10 in decimal.\n\nFinally, to find the life support rating, multiply the oxygen generator rating (23) by the CO2 scrubber rating (10) to get 230.\n\nUse the binary numbers in your diagnostic report to calculate the oxygen generator rating and CO2 scrubber rating, then multiply them together. What is the life support rating of the submarine? (Be sure to represent your answer in decimal, not binary.)\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_04.adb",
    "content": "--  Solution to Advent of Code 2021, Day 04\n-------------------------------------------\n--  Giant Squid\n--\n--  https://adventofcode.com/2021/day/4\n--  Copy of questions in: aoc_2021_04_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_04 is\n  use HAT;\n  res_1, res_2 : Integer;\n  sep : Character;\n  f : File_Type;\n  --\n  input : constant VString := +\"aoc_2021_04.txt\";\n  number_of_boards : constant := 100;\n  subtype Boards_Range is Integer range 1 .. number_of_boards;\n  first_winner, last_winner : Boards_Range;\n  any_winner_yet : Boolean := False;\n  --\n  list_max : constant := 2500;\n  list : array (1 .. list_max) of Natural;\n  top : Natural := 0;\n  number_last_bingo, number_first_winner : Natural;\n\n  board_size : constant := 5;\n  subtype Board_Side_Range is Integer range 1 .. board_size;\n\n  type Cell is record\n    value  : Natural;\n    marked : Boolean;\n  end record;\n\n  type Board_Type is array (Board_Side_Range, Board_Side_Range) of Cell;\n  board : array (Boards_Range) of Board_Type;\n  won : array (Boards_Range) of Boolean;\n  bingo : Boolean;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\nbegin\n  --\n  --  Get and prepare data.\n  --\n  Open (f, input);\n  loop\n    top := top + 1;\n    Get (f, list (top));\n    exit when End_Of_Line (f);\n    Get (f, sep);  --  Absorb the ',' separator\n  end loop;\n  for b in Boards_Range loop\n    won (b) := False;\n    for i in Board_Side_Range loop\n      for j in Board_Side_Range loop\n        Get (f, board (b)(i, j).value);\n        board (b)(i, j).marked := False;\n      end loop;\n    end loop;\n  end loop;\n  Close (f);\n  --\n  numbers_loop :\n  for n in 1 .. top loop\n    --  Mark all boards with the number in list (n).\n    boards_loop :\n    for b in 1 .. number_of_boards loop\n      if not won (b) then\n        --  Mark and check rows:\n        for i in Board_Side_Range loop\n          bingo := True;\n          for j in Board_Side_Range loop\n            if list (n) = board (b)(i, j).value then\n              board (b)(i, j).marked := True;\n            else\n              bingo := bingo and then board (b)(i, j).marked;\n            end if;\n          end loop;\n          exit when bingo;\n        end loop;\n        if not bingo then\n          --  Check columns:\n          for j in Board_Side_Range loop\n            bingo := True;\n            for i in Board_Side_Range loop\n              if not board (b)(i, j).marked then\n                bingo := False;\n                exit;\n              end if;\n            end loop;\n            exit when bingo;\n          end loop;\n        end if;\n        --  Process Bingo case:\n        if bingo then\n          won (b) := True;\n          last_winner := b;\n          number_last_bingo := list (n);\n          if not any_winner_yet then\n            any_winner_yet := True;\n            first_winner := b;\n            number_first_winner := number_last_bingo;\n          end if;\n        end if;\n      end if;\n    end loop boards_loop;\n  end loop numbers_loop;\n  --\n  if any_winner_yet then\n    res_1 := 0;\n    res_2 := 0;\n    for i in Board_Side_Range loop\n      for j in Board_Side_Range loop\n        if not board (first_winner)(i, j).marked then\n          res_1 := res_1 + board (first_winner)(i, j).value;\n        end if;\n        if not board (last_winner)(i, j).marked then\n          res_2 := res_2 + board (last_winner)(i, j).value;\n        end if;\n      end loop;\n    end loop;\n    if verbose then\n      Put_Line\n        (+\"First winner \" & first_winner &\n           \"; score 1: \" & res_1 & \" * \" & number_first_winner);\n      Put_Line\n        (+\"Last winner  \" & last_winner  &\n           \"; score 2: \" & res_2 & \" * \" & number_last_bingo);\n    end if;\n    res_1 := res_1 * number_first_winner;\n    res_2 := res_2 * number_last_bingo;\n  else\n    Put_Line (\"Uh? No Bingo?\");\n  end if;\n  --\n  if compiler_test_mode then\n    if res_1 /= Integer_Value (Argument (1)) or\n       res_2 /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: \" & res_1);\n    Put_Line (+\"Part 2: \" & res_2);\n    --  Part 1: validated by AoC: 39984\n    --  Part 2: validated by AoC: 8486\n  end if;\nend AoC_2021_04;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_04.txt",
    "content": "10,80,6,69,22,99,63,92,30,67,28,93,0,50,65,87,38,7,91,60,57,40,84,51,27,12,44,88,64,35,39,74,61,55,31,48,81,89,62,37,94,43,29,14,95,8,78,49,90,97,66,70,25,68,75,45,42,23,9,96,56,72,59,32,85,3,71,79,18,24,33,19,15,20,82,26,21,13,4,98,83,34,86,5,2,73,17,54,1,77,52,58,76,36,16,46,41,47,11,53\n\n 3 82 18 50 90\n16 37 52 67 28\n30 54 80 11 10\n60 79  7 65 58\n76 83 38 51  1\n\n83 63 60 88 98\n70 87  5 99 14\n85  3 11 16 33\n72 69 97 36 49\n26 17 58 13  2\n\n30 80 64 53 69\n36  0 32 46 70\n13 31 22 95 15\n12 35  5 84 21\n39 60 68 83 47\n\n77 93 26 62 88\n87 76 80 10 63\n32  7 28 82 44\n43 30 31 16 74\n33 86 42 45 47\n\n95 86 93 45 67\n20 58 63 35 97\n84 79 10 54 49\n48 66 75 23 61\n 5 30  6 56 71\n\n75  8 85 12 98\n37 51 91 24 23\n50 54 81 53 33\n72 57 52 25  6\n56 40 95 87 22\n\n52 19 53  9 32\n23 99 48 26 73\n10  8 54 20 79\n49 45 34 74 90\n27 72 30 13 57\n\n 1 60 72 85 64\n62 39 56 93 78\n90 17 87 48  7\n 9 13 45 23 69\n44 80 86 55 21\n\n86 57 25 98 18\n42 75 38  9 66\n54 19 99 87 49\n33 32 53  8  6\n17 68 24 58 95\n\n 2  5 80 10 61\n27 16 40 67 78\n66 13 24 42 75\n25  7 35 11 85\n93 38  4 31 77\n\n52 81 68 88 95\n82 50 46 87 20\n 3 54 59 75 51\n92 93 38 72  4\n 8 77 61 31 56\n\n45 16  8 44 62\n92 23 42 20 74\n73 83 65  9 84\n55 13 21 70 59\n34  2 98 47 37\n\n 3 54 85 79 76\n42 29 45 12 46\n60 59 24 67 80\n89 15 99 68 48\n40  7 95 44 70\n\n75 31 99 16 32\n80 56 43 30 36\n66 73 35 20 61\n67 28 89 23 54\n47 26 69 70 50\n\n35 91 81 13 15\n73  1 37 68 28\n98 29  9 22 56\n12 59 82 67 31\n77 47 32 79 52\n\n22 73 39 14 46\n99  0 27 34 40\n 4  5 38 23 18\n64 26 89 59 79\n71 76 53 49 62\n\n14 37 27 67 94\n76 16 79 61 83\n 8 43 36 28 75\n10  4 24 56 44\n26  1 88  9 86\n\n14 78 43 10 30\n56 29  1 61  9\n 7 95 39 35 25\n33 87 71 97 21\n72  0  4  2 24\n\n88  0 72 42  6\n53 79 58 80 20\n57 84 15 21 64\n98 17 43  8 95\n 2 22 59 63 78\n\n78 21 33 57 72\n10 69 85 73 16\n92 60 87 39 63\n40 15 77 80 56\n 6 62 99 50  3\n\n38 72 34 41 74\n90 29  9  6 91\n94 39 56 71 67\n53 21 22 32 10\n73 48 79 47 85\n\n 5 49 73 24  8\n75 12 11 47 69\n66 70 89 62 48\n99  3 29 88 30\n10 40 32 33 43\n\n61 93  2 58 84\n47 62 51 16 82\n80 22 50 31 65\n76 85 83  4 40\n86 59 68 14 69\n\n52  5 74  9 72\n84 69 38  1 27\n78 90 46 97 95\n57 21 32 93 29\n11 66 20 51 48\n\n 2  3 58 18 53\n11 96 63 33 13\n55 47 30  9 46\n98 85 79 19 65\n87 94 77 27 75\n\n54 97 46 33 90\n99 93 22  0 51\n83 53 34 29 38\n35 65 80 82  9\n56 30 19 49 15\n\n43 40 51 67 37\n 4 30 85 24 21\n83 94 69 91 99\n13 32 82 86 12\n66  9 60 65 97\n\n71 96 55 92  6\n83  8 63 56 18\n 4  0 74 70 34\n15 87 44 80 29\n68 33 99 14 47\n\n76 86 46  6  8\n90 80 77 30 62\n97 66 55 59 36\n 1 43 27 15 57\n54 70 38 21 89\n\n75 96 97 54 29\n62 43 69 57 88\n36 46 73 84 28\n18 98 38 63  4\n59 35 99 90 58\n\n66 29 60 25 95\n91  4 87 76 41\n26 19 45 96 74\n 7 82  3 81 31\n17 64 51 93 71\n\n41 51 14 70 26\n35 38 50 25 13\n95 60 88 36 24\n66 94 62 97 83\n21 10 37  1 96\n\n38 90 81 96 14\n40 82 71 18 83\n78 17 65 46 84\n 7 92 63 79 49\n55 21 89 95 72\n\n60 35 26 67 42\n59 77 15  6 75\n18 16 21 55  4\n98 49 38 43 30\n 0 85 69 96 19\n\n93 22 87 66 94\n 7 43 98 18 57\n29 20 91 60 21\n28 51 17 10 14\n96 12 15 25 37\n\n12 69 27 41 36\n58 11 42 44  9\n 8 56 33  7 30\n70 64 78 17 61\n22 28 94  0 99\n\n16 64 88 22 48\n65 42 23  7 26\n97 12 63 57 45\n29 94 91 21 54\n95 43  0 85 46\n\n 9 50 54 98 35\n45 37 84 87  5\n40 23 14 17 18\n73 43 86 41 59\n69 77 78 15 60\n\n79  9 45 59 85\n38 56 64 95 60\n39 22 14 57 66\n98 53 83 76 16\n62 94 72 54 82\n\n77 44  6 66 46\n 9 89 11 84 63\n81 94 87 83 21\n22 90  1 93 92\n24 65 34 45 99\n\n36 93 59  5 43\n76 49 51  0 68\n71 34 55  7 73\n14 10 45 63 95\n30 94 79 67 11\n\n93 98 82 96 91\n 3 79 55 70 24\n68 56 87 12 76\n19 31 67  1 54\n49 62 23 15 10\n\n10 74 98 15  6\n14 31 66 38 86\n68 84 60 80 26\n34 72 87 92 61\n81 56 73 12 53\n\n11 69  4  6 23\n38 47 16 99 96\n 7 13 40 41 78\n12  5  1 18 88\n20 42 10 82 73\n\n66 97 72 55 99\n26 59  6 79 53\n74 80 98 28 69\n25 95 17 29 34\n85 64 84 90 42\n\n95 50 58 51 66\n48 27 81 94  0\n35 82 57 71 16\n32 93 70 40 25\n31 73 46 12 90\n\n39 94 52  9 88\n 3 23 59 77 29\n 2 40 93 85 38\n74 97 12 50  1\n22 36 68 65 37\n\n70 15 44 90 55\n42 20 82  0 78\n10 49 62  3 22\n91 73 84 40 28\n72 13 11 60 19\n\n58 95 66 36 22\n91 99 77 94 44\n70 14 85 13 52\n49  6  2 50 35\n47 42 15 98 63\n\n35  1 99 21 68\n93 32 30 76  5\n79 96 10 85 16\n19 69 81 78 70\n66 36 26 94 39\n\n78 51 55  4 97\n21 36 53  1 26\n77 42 20 12 65\n17 52  6 40 16\n19 85  2 24 23\n\n95 68 76 14 30\n19 11 64 99 60\n63 55  8 40 65\n41 75 62 53 83\n26 34 46 72 79\n\n68  6 35 62 77\n43 14 88  7 11\n40 45 98 86 64\n 3 53 56 87 30\n28 37 48 10 72\n\n13 69 72 93 17\n 1 46  8 56 37\n78 27 49 64 59\n81 99 33 76 79\n84 98 51 82 31\n\n57 41 45 15 10\n65 72 79 17 29\n67  0 33 32 69\n56 96 92 46 53\n88  3 18 87 51\n\n97 52 58 67 17\n51 69 43 20 63\n 1 26 27 47 99\n53 23 14 90 86\n 4 56 13 36 11\n\n88 11 57 73 89\n43 34 91 15 58\n 9 39 18 12 14\n 1 98 29 77 52\n84 97 96 68 10\n\n99  5 69 53 45\n10 43 24 60 55\n64 57 30  3  0\n22 65 68 32 83\n52 38 74 97 20\n\n27 25 33 41 67\n54 42  3  1 55\n66 92 44 98 35\n14 82  5 10 39\n52 79 69 76 48\n\n64 58 60 91 42\n45 55 35  9 72\n36 74 99 33 26\n67  4 25 50 14\n15  2 96 82 11\n\n34 84 90 95 26\n 8 66 52 43 63\n79 98 36 85 41\n47 24 33 88 71\n86 91 83 40 18\n\n79 68 49 64 35\n23 57 27 77 71\n95 39 43 19 98\n78 62 65 58 60\n52 73 82  4 32\n\n22 54 57 45  3\n43 85 30 60 94\n35 46 28 55  6\n82 42 13 83 59\n76 70 41 61  1\n\n76 89 34 96  1\n95 60 55 23 88\n37 13 61 92 62\n98 77 32 82 31\n33 74 71 58 86\n\n73 91 92 49 44\n53  6 29  8 95\n 4 31 54 20 97\n98 57  2 65 75\n43 88  1 58  0\n\n49 91 70  1 79\n17 90 33 65 54\n56 47 63 83 52\n 8 45 72 84 39\n43 37 71 97 59\n\n90 93 20 31 96\n98 84  2 87 73\n97 16 19 24 38\n14 11 94 92 36\n 4 10 27 44 30\n\n20 77 81 80 28\n35 51 93 24 62\n54 56 41 68 79\n29 67 89 60 12\n63 91 18 90 99\n\n28 48 94 50 73\n20 27 34 59 43\n66 55 35 98 57\n40 53 21 99  4\n17 74 80  5 12\n\n76 22  6 61 23\n70 67 69 33  9\n87  2 12 68 27\n13 52 82 15 84\n24 51 89 53 38\n\n96 23 91 97 10\n50  8 68 67  0\n65  3 92  4 70\n53 77 59 86 66\n41 78 44 52 71\n\n62 19 17 63 75\n43 88 15 84 13\n41  7 47 16 23\n12 71  8 83 50\n36 31 22  5 79\n\n71 95 17 90 63\n64 52 32  3 93\n70 13 99 40  5\n22 18 83 11 55\n47 59 78 45 29\n\n 9 98 73 46 79\n 5 51 84 26 40\n64 62  0 66 18\n33 83 47  1 63\n89 31 99 54 36\n\n98 15 86  9 50\n67  7 75 85 17\n96 27 64 81 19\n80 30 29 54 52\n49 25 36  5 90\n\n39 29 40 16 69\n38 55 67 71 59\n42 72 51 10 45\n94 75 21 27  0\n84  6 22 33 30\n\n33 64 82 97 39\n79  7 62 49 99\n26  3 13 66 10\n37 98 15 80 47\n 1 35 30 50 43\n\n56 92 41 82 34\n68 79 11  0 65\n70 84 26 76 96\n 1 72 31 80  8\n 9 38 98 17  7\n\n12 19  6 29 89\n96 87 70 75 77\n84 74 64 54 13\n16 68 44 79 43\n61 47 69 26 50\n\n43 20 45 21 87\n80 50 83 26 49\n64 99 71 75  9\n18 96  6 94 88\n76 97 51 11 74\n\n85 47 25 72 93\n96 36 81 55 27\n63 18 57  1 29\n 9 35 83 88 98\n90 21  3 67 82\n\n58 94 55 10 98\n 2 24 71 93 57\n74 34 21 35 73\n89 88  6 16  8\n76 81 38 28 83\n\n36 53 63 67 18\n51 74 60 69 85\n32 22 80 58 98\n34 92 13 12 26\n46 61 31 96 47\n\n90  1  5 10 48\n12 76 95 83 17\n24 84 65 44 28\n81 80 41 79 15\n29 61 75 94 40\n\n65 22 40 75 86\n93 77 46 35 87\n88  5 91 48 74\n92 28 66 47 30\n69  2 29 67 94\n\n78 38  1 53 68\n84 70 26  7 72\n92 87 55 47  6\n51 82 36 73 28\n75 58 35 49 56\n\n61 85 60 19 24\n16 23 71 74 33\n42  7 57 82 70\n14 97 59 99 49\n46 30 89 79 41\n\n 5 24 92 19 65\n 0 80 33 78 23\n 4 37 31 16 41\n79 73 88 36 67\n86 29 62 61 71\n\n40 51 27 57 85\n53 68 31 60 83\n48 69 24 17 96\n54 89 22 77 64\n95 26 21 65 41\n\n48  7 20 68 21\n31 22  1 99 96\n82 63 78  2 70\n18 83 58 92 51\n81 64 98 44 89\n\n23 74 99 75  6\n81 14 37  8 85\n12 36 55 20 47\n88  7 90 87 43\n 3 44 83 15  2\n\n97 15 69 76 95\n13 44 31 10 14\n40 83 49 11 65\n43 98 55 92 89\n90 33 73 32 53\n\n25 79 77 83 68\n 5 10 23 15 19\n18  4 92 51 76\n17 90 70 49 39\n74 63 75 42 67\n\n46 66 18 17 28\n75 76 78 72 44\n57 39 97 27 99\n36 58 62 90 82\n14 45 48 64  1\n\n51 90 58  6 37\n28 30 57 54 10\n45 80 39  4  0\n29 17 66 18 55\n96 44 36 76 34\n\n94 50  0 71 99\n11 67 96 87 64\n48 30 31 68 40\n89 55 23 92 42\n16 62 37 83 33\n\n66 42 91 70 72\n28 69 96 17 71\n99  5  2 26 19\n60 87 51 83 76\n77 33 64 61 54\n\n61 93 90 82 88\n80 11 25 40 28\n60 29 34 39 21\n24 13 72 77  2\n19 95 47 17  0\n\n86 97 50 42 87\n 7 18 80 23 30\n41  6 96 92 98\n36 45 77 71 38\n19 40 47 39 53\n\n83  7 80 86 65\n37 22 19 84 92\n29 17 76  4 33\n97 50  1 12 21\n15 58 39 38 74\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_04_questions.txt",
    "content": "--- Day 4: Giant Squid ---\n\nYou're already almost 1.5km (almost a mile) below the surface of the ocean, already so deep that you can't see any sunlight. What you can see, however, is a giant squid that has attached itself to the outside of your submarine.\n\nMaybe it wants to play bingo?\n\nBingo is played on a set of boards each consisting of a 5x5 grid of numbers. Numbers are chosen at random, and the chosen number is marked on all boards on which it appears. (Numbers may not appear on all boards.) If all numbers in any row or any column of a board are marked, that board wins. (Diagonals don't count.)\n\nThe submarine has a bingo subsystem to help passengers (currently, you and the giant squid) pass the time. It automatically generates a random order in which to draw numbers and a random set of boards (your puzzle input). For example:\n\n7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1\n\n22 13 17 11  0\n 8  2 23  4 24\n21  9 14 16  7\n 6 10  3 18  5\n 1 12 20 15 19\n\n 3 15  0  2 22\n 9 18 13 17  5\n19  8  7 25 23\n20 11 10 24  4\n14 21 16 12  6\n\n14 21 17 24  4\n10 16 15  9 19\n18  8 23 26 20\n22 11 13  6  5\n 2  0 12  3  7\n\nAfter the first five numbers are drawn (7, 4, 9, 5, and 11), there are no winners, but the boards are marked as follows (shown here adjacent to each other to save space):\n\n22 13 17 11  0         3 15  0  2 22        14 21 17 24  4\n 8  2 23  4 24         9 18 13 17  5        10 16 15  9 19\n21  9 14 16  7        19  8  7 25 23        18  8 23 26 20\n 6 10  3 18  5        20 11 10 24  4        22 11 13  6  5\n 1 12 20 15 19        14 21 16 12  6         2  0 12  3  7\n\nAfter the next six numbers are drawn (17, 23, 2, 0, 14, and 21), there are still no winners:\n\n22 13 17 11  0         3 15  0  2 22        14 21 17 24  4\n 8  2 23  4 24         9 18 13 17  5        10 16 15  9 19\n21  9 14 16  7        19  8  7 25 23        18  8 23 26 20\n 6 10  3 18  5        20 11 10 24  4        22 11 13  6  5\n 1 12 20 15 19        14 21 16 12  6         2  0 12  3  7\n\nFinally, 24 is drawn:\n\n22 13 17 11  0         3 15  0  2 22        14 21 17 24  4\n 8  2 23  4 24         9 18 13 17  5        10 16 15  9 19\n21  9 14 16  7        19  8  7 25 23        18  8 23 26 20\n 6 10  3 18  5        20 11 10 24  4        22 11 13  6  5\n 1 12 20 15 19        14 21 16 12  6         2  0 12  3  7\n\nAt this point, the third board wins because it has at least one complete row or column of marked numbers (in this case, the entire top row is marked: 14 21 17 24 4).\n\nThe score of the winning board can now be calculated. Start by finding the sum of all unmarked numbers on that board; in this case, the sum is 188. Then, multiply that sum by the number that was just called when the board won, 24, to get the final score, 188 * 24 = 4512.\n\nTo guarantee victory against the giant squid, figure out which board will win first. What will your final score be if you choose that board?\n\n--- Part Two ---\n\nOn the other hand, it might be wise to try a different strategy: let the giant squid win.\n\nYou aren't sure how many bingo boards a giant squid could play at once, so rather than waste time counting its arms, the safe thing to do is to figure out which board will win last and choose that one. That way, no matter which boards it picks, it will win for sure.\n\nIn the above example, the second board is the last to win, which happens after 13 is eventually called and its middle column is completely marked. If you were to keep playing until this point, the second board would have a sum of unmarked numbers equal to 148 for a final score of 148 * 13 = 1924.\n\nFigure out which board will win last. Once it wins, what would its final score be?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_05.adb",
    "content": "--  Solution to Advent of Code 2021, Day 05\n-------------------------------------------\n--  Hydrothermal Venture\n--\n--  https://adventofcode.com/2021/day/5\n--  Copy of questions in: aoc_2021_05_questions.txt\n--\n--  HAC 0.098 \"nice to have\"'s detected in this exercise:\n--\n--    *     ` hits := (others => (others => 0)); `\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_05 is\n  use HAT;\n  sep_1, sep_3 : Character;\n  sep_2 : String (1 .. 3);\n  res : array (1 .. 2) of Integer;\n  f : File_Type;\n  --\n  input : constant VString := +\"aoc_2021_05.txt\";\n  subtype X_Range is Integer range 0 .. 1000;\n  subtype Y_Range is Integer range 0 .. 1000;\n  x1, x2, xx : X_Range;\n  y1, y2, yy : Y_Range;\n  len : Natural;\n  dx, dy : Integer;\n  hits : array (X_Range, Y_Range) of Natural;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n\nbegin\n  for x in X_Range loop\n    for y in Y_Range loop\n      hits (x, y) := 0;\n    end loop;\n  end loop;\n  --\n  for part in 1 .. 2 loop\n    Open (f, input);\n    while not End_Of_File (f) loop\n      Get (f, x1);\n      Get (f, sep_1);\n      Get (f, y1);\n      Get (f, sep_2);\n      Get (f, x2);\n      Get (f, sep_3);\n      Get (f, y2);\n      case part is\n        when 1 =>\n          if x1 = x2 then\n            for y in Min (y1, y2) .. Max (y1, y2) loop\n              hits (x1, y) := hits (x1, y) + 1;\n            end loop;\n          elsif y1 = y2 then\n            for x in Min (x1, x2) .. Max (x1, x2) loop\n              hits (x, y1) := hits (x, y1) + 1;\n            end loop;\n          end if;\n        when 2 =>\n          if x1 /= x2 and then y1 /= y2 then\n            --  The hydrothermal vent mapping systems assumes a diagonal.\n            xx := x1;\n            yy := y1;\n            dx := (x2 - x1) / abs (x2 - x1);\n            dy := (y2 - y1) / abs (y2 - y1);\n            len := abs (x2 - x1);\n            for draw in 0 .. len loop\n              hits (xx, yy) := hits (xx, yy) + 1;\n              if draw < len then\n                xx := xx + dx;\n                yy := yy + dy;\n              end if;\n            end loop;\n          end if;\n      end case;\n    end loop;\n    Close (f);\n    --\n    res (part) := 0;\n    for x in X_Range loop\n      for y in Y_Range loop\n        if hits (x, y) >= 2 then\n          res (part) := res (part) + 1;\n        end if;\n      end loop;\n    end loop;\n  end loop;\n  --\n  if compiler_test_mode then\n    if res (1) /= Integer_Value (Argument (1)) or\n       res (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: crossings of horizontal and vertical lines: \" & res (1));\n    Put_Line (+\"Part 2: crossings, including diagonals: \" & res (2));\n    --  Part 1: validated by AoC: 6225\n    --  Part 2: validated by AoC: 22116\n  end if;\nend AoC_2021_05;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_05.txt",
    "content": "955,125 -> 151,929\n830,251 -> 526,555\n182,185 -> 13,16\n73,871 -> 73,951\n169,968 -> 626,968\n471,180 -> 471,746\n725,478 -> 791,544\n577,413 -> 577,753\n636,937 -> 181,937\n46,601 -> 714,601\n400,905 -> 400,972\n911,773 -> 883,801\n818,684 -> 818,705\n71,846 -> 151,846\n737,489 -> 626,378\n634,800 -> 634,482\n401,209 -> 401,469\n676,688 -> 384,396\n247,819 -> 680,819\n944,343 -> 196,343\n57,689 -> 586,160\n13,54 -> 918,959\n736,490 -> 520,706\n331,20 -> 208,20\n639,865 -> 322,548\n914,227 -> 914,980\n163,411 -> 163,825\n344,58 -> 344,199\n274,153 -> 989,153\n15,14 -> 983,982\n784,269 -> 332,721\n206,921 -> 206,331\n219,944 -> 260,903\n81,92 -> 976,987\n325,633 -> 502,810\n887,850 -> 887,83\n203,756 -> 203,627\n447,33 -> 748,33\n87,245 -> 87,932\n817,324 -> 881,324\n922,227 -> 167,982\n626,867 -> 155,396\n743,689 -> 743,779\n516,433 -> 133,433\n444,407 -> 614,407\n42,140 -> 475,140\n311,422 -> 311,514\n526,59 -> 643,59\n709,69 -> 455,69\n136,46 -> 159,46\n300,113 -> 763,576\n979,977 -> 18,16\n380,490 -> 380,556\n134,726 -> 134,287\n317,717 -> 383,717\n726,712 -> 211,197\n703,952 -> 165,952\n806,575 -> 122,575\n589,691 -> 589,716\n965,337 -> 879,337\n938,23 -> 57,904\n186,141 -> 385,141\n864,744 -> 959,744\n276,957 -> 636,957\n98,846 -> 98,349\n559,261 -> 559,63\n564,808 -> 564,429\n491,362 -> 491,746\n513,250 -> 897,250\n939,442 -> 249,442\n366,678 -> 916,678\n325,79 -> 604,358\n513,890 -> 133,890\n360,88 -> 427,88\n777,266 -> 522,266\n371,859 -> 776,859\n111,600 -> 111,980\n366,471 -> 646,191\n849,407 -> 933,407\n867,681 -> 570,384\n467,707 -> 797,377\n624,304 -> 852,76\n341,149 -> 575,383\n34,499 -> 736,499\n13,312 -> 927,312\n897,188 -> 897,639\n372,665 -> 372,501\n651,22 -> 173,22\n450,394 -> 450,798\n140,584 -> 140,960\n223,919 -> 980,919\n893,645 -> 429,181\n284,488 -> 207,411\n823,868 -> 622,667\n426,881 -> 868,881\n49,63 -> 974,988\n921,475 -> 81,475\n166,653 -> 166,913\n40,191 -> 767,918\n911,499 -> 911,363\n966,960 -> 84,78\n193,522 -> 193,379\n208,255 -> 673,255\n684,837 -> 684,192\n921,758 -> 921,841\n756,244 -> 756,277\n866,533 -> 866,186\n97,747 -> 798,46\n415,287 -> 415,759\n570,824 -> 902,824\n341,792 -> 44,792\n849,787 -> 161,99\n501,621 -> 565,685\n409,62 -> 215,256\n591,780 -> 855,780\n901,67 -> 901,223\n662,212 -> 578,212\n196,924 -> 196,94\n404,492 -> 300,492\n10,984 -> 984,10\n722,739 -> 722,775\n805,637 -> 805,299\n848,722 -> 707,722\n444,597 -> 158,597\n402,57 -> 509,57\n490,353 -> 273,353\n868,208 -> 421,655\n102,930 -> 903,129\n557,877 -> 557,529\n27,69 -> 843,885\n549,695 -> 468,695\n767,701 -> 104,701\n415,141 -> 415,809\n205,767 -> 205,427\n264,723 -> 952,35\n357,279 -> 390,279\n529,436 -> 250,715\n390,472 -> 889,971\n983,11 -> 21,973\n732,307 -> 112,927\n412,801 -> 252,801\n738,338 -> 738,94\n80,135 -> 952,135\n623,269 -> 870,516\n216,507 -> 32,507\n927,10 -> 927,946\n389,955 -> 389,399\n683,825 -> 629,879\n163,450 -> 208,495\n303,217 -> 831,217\n827,632 -> 827,736\n629,880 -> 629,533\n368,67 -> 111,67\n625,268 -> 397,268\n737,335 -> 299,773\n666,767 -> 494,939\n144,238 -> 757,238\n511,211 -> 270,211\n312,901 -> 548,665\n550,763 -> 47,763\n942,403 -> 464,881\n969,18 -> 15,972\n963,831 -> 187,55\n933,831 -> 933,408\n733,658 -> 876,658\n599,392 -> 980,11\n44,406 -> 900,406\n645,169 -> 577,237\n731,41 -> 731,265\n574,397 -> 574,249\n316,279 -> 316,657\n826,116 -> 18,924\n611,892 -> 824,892\n607,168 -> 607,85\n371,914 -> 113,656\n145,201 -> 458,514\n813,952 -> 189,328\n633,15 -> 239,409\n832,278 -> 202,908\n234,698 -> 509,423\n635,27 -> 635,18\n701,147 -> 701,577\n777,722 -> 777,835\n519,298 -> 497,298\n80,71 -> 875,866\n872,350 -> 58,350\n128,711 -> 131,711\n591,709 -> 362,480\n129,647 -> 54,572\n980,731 -> 282,33\n245,813 -> 682,813\n867,238 -> 463,642\n511,888 -> 511,391\n727,38 -> 289,38\n311,888 -> 311,801\n261,915 -> 926,250\n855,835 -> 145,125\n78,688 -> 826,688\n989,40 -> 66,963\n956,30 -> 101,885\n665,826 -> 406,826\n97,981 -> 985,93\n971,847 -> 357,233\n725,531 -> 725,556\n63,570 -> 403,570\n41,430 -> 577,430\n40,54 -> 796,810\n417,232 -> 417,392\n214,800 -> 936,78\n542,955 -> 146,955\n76,263 -> 471,263\n784,507 -> 784,858\n443,222 -> 443,881\n317,157 -> 317,956\n245,599 -> 166,520\n307,649 -> 307,313\n399,782 -> 538,782\n483,731 -> 294,731\n950,903 -> 281,234\n283,522 -> 866,522\n472,505 -> 278,505\n435,693 -> 845,283\n881,751 -> 294,164\n40,840 -> 179,979\n481,398 -> 481,661\n509,687 -> 509,875\n976,866 -> 684,574\n133,130 -> 158,130\n268,81 -> 641,454\n613,754 -> 393,974\n980,984 -> 14,18\n55,909 -> 952,12\n865,132 -> 986,132\n147,773 -> 147,414\n135,62 -> 934,861\n298,293 -> 298,978\n583,990 -> 424,990\n760,189 -> 516,189\n286,292 -> 286,648\n60,352 -> 60,830\n335,241 -> 420,156\n360,571 -> 360,354\n361,233 -> 714,233\n21,78 -> 922,979\n35,748 -> 449,748\n859,26 -> 73,812\n277,827 -> 277,708\n160,633 -> 515,278\n673,422 -> 568,317\n620,235 -> 620,645\n538,698 -> 156,698\n47,543 -> 439,543\n65,975 -> 945,95\n259,644 -> 242,644\n777,216 -> 794,216\n100,191 -> 835,926\n450,581 -> 450,433\n475,784 -> 475,118\n840,584 -> 580,844\n191,283 -> 191,58\n170,650 -> 130,690\n478,269 -> 478,781\n44,981 -> 839,186\n270,744 -> 270,902\n941,960 -> 102,121\n303,690 -> 303,467\n150,18 -> 150,601\n470,523 -> 240,523\n166,575 -> 621,575\n197,765 -> 691,271\n164,798 -> 369,798\n544,319 -> 677,319\n31,212 -> 777,958\n894,774 -> 894,752\n567,225 -> 67,225\n884,201 -> 184,201\n675,961 -> 187,473\n203,78 -> 203,690\n52,945 -> 957,40\n987,214 -> 987,762\n792,975 -> 792,673\n358,782 -> 598,542\n105,716 -> 777,44\n736,643 -> 245,643\n507,940 -> 275,940\n231,936 -> 231,209\n204,545 -> 186,563\n881,426 -> 881,460\n315,867 -> 96,867\n793,324 -> 642,324\n276,709 -> 540,973\n834,401 -> 834,701\n616,874 -> 616,606\n892,596 -> 892,570\n255,919 -> 850,324\n764,62 -> 82,744\n682,374 -> 978,374\n218,353 -> 218,787\n140,289 -> 720,869\n811,20 -> 811,203\n165,291 -> 284,291\n137,382 -> 137,767\n15,14 -> 989,988\n947,682 -> 499,234\n751,356 -> 862,356\n398,362 -> 398,494\n260,32 -> 780,552\n839,484 -> 584,484\n198,865 -> 198,327\n600,461 -> 418,279\n346,439 -> 495,588\n854,661 -> 775,661\n119,575 -> 119,415\n349,849 -> 349,421\n13,401 -> 21,393\n169,511 -> 169,61\n848,678 -> 213,678\n42,25 -> 729,712\n903,740 -> 816,740\n398,862 -> 398,116\n443,624 -> 101,624\n135,158 -> 223,158\n440,742 -> 388,742\n903,963 -> 49,109\n131,198 -> 208,198\n147,289 -> 147,663\n684,307 -> 684,299\n453,864 -> 453,404\n361,982 -> 978,365\n840,64 -> 563,64\n377,301 -> 613,301\n32,366 -> 609,366\n867,240 -> 867,188\n798,714 -> 956,714\n617,792 -> 617,354\n309,357 -> 309,797\n824,888 -> 824,598\n947,958 -> 305,316\n505,934 -> 461,890\n45,685 -> 597,133\n875,170 -> 66,979\n239,959 -> 985,213\n769,423 -> 769,39\n62,750 -> 764,48\n749,798 -> 749,307\n110,646 -> 241,777\n93,804 -> 867,30\n361,663 -> 856,663\n494,788 -> 187,788\n696,379 -> 696,823\n664,935 -> 146,417\n895,804 -> 895,144\n200,240 -> 805,240\n347,794 -> 487,934\n978,920 -> 978,408\n730,480 -> 390,140\n933,810 -> 933,513\n429,864 -> 134,864\n476,339 -> 183,632\n677,878 -> 677,417\n980,261 -> 757,261\n452,569 -> 452,280\n535,223 -> 867,223\n159,466 -> 983,466\n332,155 -> 334,153\n887,478 -> 887,179\n173,245 -> 773,845\n441,274 -> 632,465\n987,389 -> 987,440\n830,806 -> 747,806\n103,82 -> 796,775\n945,14 -> 129,14\n110,873 -> 520,873\n393,391 -> 291,391\n598,125 -> 129,594\n378,546 -> 175,546\n302,558 -> 617,243\n943,752 -> 244,53\n972,943 -> 41,12\n16,164 -> 124,164\n270,815 -> 27,815\n146,729 -> 146,317\n153,255 -> 166,255\n511,505 -> 270,505\n404,568 -> 388,568\n485,751 -> 485,785\n752,686 -> 160,686\n523,676 -> 385,676\n854,437 -> 618,437\n578,212 -> 875,509\n800,115 -> 815,130\n439,554 -> 868,983\n225,803 -> 244,822\n494,735 -> 655,574\n932,191 -> 932,41\n842,325 -> 630,325\n201,288 -> 518,288\n255,332 -> 53,332\n385,959 -> 329,903\n757,447 -> 276,447\n884,957 -> 884,449\n686,354 -> 195,354\n384,677 -> 951,110\n173,77 -> 164,77\n767,840 -> 248,321\n81,180 -> 81,371\n517,838 -> 517,461\n950,559 -> 221,559\n934,826 -> 329,221\n311,329 -> 311,146\n140,459 -> 280,459\n200,195 -> 24,19\n517,270 -> 865,618\n43,54 -> 939,950\n853,339 -> 853,388\n297,795 -> 240,795\n358,890 -> 275,973\n26,70 -> 931,975\n781,141 -> 318,604\n17,794 -> 204,794\n87,534 -> 763,534\n590,968 -> 590,613\n358,836 -> 758,836\n598,635 -> 764,635\n313,670 -> 313,478\n832,330 -> 832,629\n973,36 -> 21,988\n131,814 -> 709,236\n261,163 -> 261,906\n720,48 -> 659,48\n988,152 -> 326,814\n937,761 -> 690,761\n988,784 -> 988,879\n807,445 -> 336,916\n933,978 -> 51,96\n305,966 -> 305,402\n184,687 -> 437,687\n256,172 -> 186,172\n508,162 -> 421,162\n689,52 -> 740,52\n545,807 -> 545,630\n676,924 -> 620,924\n976,68 -> 139,905\n322,96 -> 45,96\n663,407 -> 199,871\n562,636 -> 224,974\n172,439 -> 126,439\n740,628 -> 852,628\n252,28 -> 596,372\n129,850 -> 571,408\n75,446 -> 399,446\n67,460 -> 704,460\n932,531 -> 932,60\n520,229 -> 255,494\n462,756 -> 462,614\n158,117 -> 592,551\n203,722 -> 203,892\n93,822 -> 207,822\n634,172 -> 634,457\n272,365 -> 272,377\n989,23 -> 25,987\n739,776 -> 40,776\n843,708 -> 24,708\n665,10 -> 665,728\n271,858 -> 11,598\n947,642 -> 629,960\n230,760 -> 938,52\n291,552 -> 291,388\n689,400 -> 260,829\n610,194 -> 470,194\n628,824 -> 45,241\n935,940 -> 51,56\n90,871 -> 90,933\n973,934 -> 104,65\n435,245 -> 768,245\n43,666 -> 625,666\n770,563 -> 724,563\n363,816 -> 363,889\n25,725 -> 701,49\n784,846 -> 484,846\n989,293 -> 989,502\n572,135 -> 485,135\n683,807 -> 370,494\n982,182 -> 225,939\n838,522 -> 520,522\n253,942 -> 970,225\n442,963 -> 577,963\n867,193 -> 307,753\n269,204 -> 771,204\n941,925 -> 136,120\n329,488 -> 728,89\n37,424 -> 254,424\n179,864 -> 895,148\n359,473 -> 359,675\n976,933 -> 129,86\n220,101 -> 376,101\n988,667 -> 946,667\n667,22 -> 308,22\n831,782 -> 245,196\n759,813 -> 225,279\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_05_questions.txt",
    "content": "--- Day 5: Hydrothermal Venture ---\n\nYou come across a field of hydrothermal vents on the ocean floor! These vents constantly produce large, opaque clouds, so it would be best to avoid them if possible.\n\nThey tend to form in lines; the submarine helpfully produces a list of nearby lines of vents (your puzzle input) for you to review. For example:\n\n0,9 -> 5,9\n8,0 -> 0,8\n9,4 -> 3,4\n2,2 -> 2,1\n7,0 -> 7,4\n6,4 -> 2,0\n0,9 -> 2,9\n3,4 -> 1,4\n0,0 -> 8,8\n5,5 -> 8,2\n\nEach line of vents is given as a line segment in the format x1,y1 -> x2,y2 where x1,y1 are the coordinates of one end the line segment and x2,y2 are the coordinates of the other end. These line segments include the points at both ends. In other words:\n\n    An entry like 1,1 -> 1,3 covers points 1,1, 1,2, and 1,3.\n    An entry like 9,7 -> 7,7 covers points 9,7, 8,7, and 7,7.\n\nFor now, only consider horizontal and vertical lines: lines where either x1 = x2 or y1 = y2.\n\nSo, the horizontal and vertical lines from the above list would produce the following diagram:\n\n.......1..\n..1....1..\n..1....1..\n.......1..\n.112111211\n..........\n..........\n..........\n..........\n222111....\n\nIn this diagram, the top left corner is 0,0 and the bottom right corner is 9,9. Each position is shown as the number of lines which cover that point or . if no line covers that point. The top-left pair of 1s, for example, comes from 2,2 -> 2,1; the very bottom row is formed by the overlapping lines 0,9 -> 5,9 and 0,9 -> 2,9.\n\nTo avoid the most dangerous areas, you need to determine the number of points where at least two lines overlap. In the above example, this is anywhere in the diagram with a 2 or larger - a total of 5 points.\n\nConsider only horizontal and vertical lines. At how many points do at least two lines overlap?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_06.adb",
    "content": "--  Solution to Advent of Code 2021, Day 6\n------------------------------------------\n--  Lanternfish\n--\n--  https://adventofcode.com/2021/day/6\n--  Copy of questions in: aoc_2021_06_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_06 is\n  timer_max : constant := 8;\n  subtype Timer_Range is Integer range 0 .. timer_max;\n  use HAT, Interfaces;\n  type Lanternfish_Population is array (Timer_Range) of Integer_64;\n  pop_init, pop : Lanternfish_Population;\n  pop_0 : Integer_64;\n  days : array (1 .. 2) of Positive;\n  --\n  input : constant VString := +\"aoc_2021_06.txt\";\n  sep : Character;\n  i : Integer;\n  f : File_Type;\n  r : array (1 .. 2) of Integer_64;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  for j in Timer_Range loop\n    pop_init (j) := 0;\n  end loop;\n  Open (f, input);\n  loop\n    Get (f, i);\n    pop_init (i) := pop_init (i) + 1;\n    exit when End_Of_File (f);\n    Get (f, sep);\n  end loop;\n  Close (f);\n  --\n  days (1) := 80;\n  days (2) := 256;\n  for part in 1 .. 2 loop\n    pop := pop_init;\n    for d in 1 .. days (part) loop\n      pop_0 := pop (0);\n      for j in 0 .. timer_max - 1 loop\n        pop (j) := pop (j + 1);\n      end loop;\n      pop (6) := pop (6) + pop_0;  --  Life cycle\n      pop (timer_max) := pop_0;    --  New fishes\n    end loop;\n    r (part) := 0;\n    for j in Timer_Range loop\n      r (part) := r (part) + pop (j);\n    end loop;\n  end loop;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    for part in 1 .. 2 loop\n      Put_Line (\n        +\"Part \" & part & \": population after \" & days (part) &\n        \" days:\" & Integer_64'Image (r (part)));\n    end loop;\n    --  Part 1: validated by AoC: 388419\n    --  Part 2: validated by AoC: 1740449478328\n  end if;\nend AoC_2021_06;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_06.txt",
    "content": "1,1,1,1,3,1,4,1,4,1,1,2,5,2,5,1,1,1,4,3,1,4,1,1,1,1,1,1,1,2,1,2,4,1,1,1,1,1,1,1,3,1,1,5,1,1,2,1,5,1,1,1,1,1,1,1,1,4,3,1,1,1,2,1,1,5,2,1,1,1,1,4,5,1,1,2,4,1,1,1,5,1,1,1,1,5,1,3,1,1,4,2,1,5,1,2,1,1,1,1,1,3,3,1,5,1,1,1,1,3,1,1,1,4,1,1,1,4,1,4,3,1,1,1,4,1,2,1,1,1,2,1,1,1,1,5,1,1,3,5,1,1,5,2,1,1,1,1,1,4,4,1,1,2,1,1,1,4,1,1,1,1,5,3,1,1,1,5,1,1,1,4,1,4,1,1,1,5,1,1,3,2,2,1,1,1,4,1,3,1,1,1,2,1,3,1,1,1,1,4,1,1,1,1,2,1,4,1,1,1,1,1,4,1,1,2,4,2,1,2,3,1,3,1,1,2,1,1,1,3,1,1,3,1,1,4,1,3,1,1,2,1,1,1,4,1,1,3,1,1,5,1,1,3,1,1,1,1,5,1,1,1,1,1,2,3,4,1,1,1,1,1,2,1,1,1,1,1,1,1,3,2,2,1,3,5,1,1,4,4,1,3,4,1,2,4,1,1,3,1\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_06_questions.txt",
    "content": "--- Day 6: Lanternfish ---\n\nThe sea floor is getting steeper. Maybe the sleigh keys got carried this way?\n\nA massive school of glowing lanternfish swims past. They must spawn quickly to reach such large numbers - maybe exponentially quickly? You should model their growth rate to be sure.\n\nAlthough you know nothing about this specific species of lanternfish, you make some guesses about their attributes. Surely, each lanternfish creates a new lanternfish once every 7 days.\n\nHowever, this process isn't necessarily synchronized between every lanternfish - one lanternfish might have 2 days left until it creates another lanternfish, while another might have 4. So, you can model each fish as a single number that represents the number of days until it creates a new lanternfish.\n\nFurthermore, you reason, a new lanternfish would surely need slightly longer before it's capable of producing more lanternfish: two more days for its first cycle.\n\nSo, suppose you have a lanternfish with an internal timer value of 3:\n\n    After one day, its internal timer would become 2.\n    After another day, its internal timer would become 1.\n    After another day, its internal timer would become 0.\n    After another day, its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8.\n    After another day, the first lanternfish would have an internal timer of 5, and the second lanternfish would have an internal timer of 7.\n\nA lanternfish that creates a new fish resets its timer to 6, not 7 (because 0 is included as a valid timer value). The new lanternfish starts with an internal timer of 8 and does not start counting down until the next day.\n\nRealizing what you're trying to do, the submarine automatically produces a list of the ages of several hundred nearby lanternfish (your puzzle input). For example, suppose you were given the following list:\n\n3,4,3,1,2\n\nThis list means that the first fish has an internal timer of 3, the second fish has an internal timer of 4, and so on until the fifth fish, which has an internal timer of 2. Simulating these fish over several days would proceed as follows:\n\nInitial state: 3,4,3,1,2\nAfter  1 day:  2,3,2,0,1\nAfter  2 days: 1,2,1,6,0,8\nAfter  3 days: 0,1,0,5,6,7,8\nAfter  4 days: 6,0,6,4,5,6,7,8,8\nAfter  5 days: 5,6,5,3,4,5,6,7,7,8\nAfter  6 days: 4,5,4,2,3,4,5,6,6,7\nAfter  7 days: 3,4,3,1,2,3,4,5,5,6\nAfter  8 days: 2,3,2,0,1,2,3,4,4,5\nAfter  9 days: 1,2,1,6,0,1,2,3,3,4,8\nAfter 10 days: 0,1,0,5,6,0,1,2,2,3,7,8\nAfter 11 days: 6,0,6,4,5,6,0,1,1,2,6,7,8,8,8\nAfter 12 days: 5,6,5,3,4,5,6,0,0,1,5,6,7,7,7,8,8\nAfter 13 days: 4,5,4,2,3,4,5,6,6,0,4,5,6,6,6,7,7,8,8\nAfter 14 days: 3,4,3,1,2,3,4,5,5,6,3,4,5,5,5,6,6,7,7,8\nAfter 15 days: 2,3,2,0,1,2,3,4,4,5,2,3,4,4,4,5,5,6,6,7\nAfter 16 days: 1,2,1,6,0,1,2,3,3,4,1,2,3,3,3,4,4,5,5,6,8\nAfter 17 days: 0,1,0,5,6,0,1,2,2,3,0,1,2,2,2,3,3,4,4,5,7,8\nAfter 18 days: 6,0,6,4,5,6,0,1,1,2,6,0,1,1,1,2,2,3,3,4,6,7,8,8,8,8\n\nEach day, a 0 becomes a 6 and adds a new 8 to the end of the list, while each other number decreases by 1 if it was present at the start of the day.\n\nIn this example, after 18 days, there are a total of 26 fish. After 80 days, there would be a total of 5934.\n\nFind a way to simulate lanternfish. How many lanternfish would there be after 80 days?\n\n--- Part Two ---\n\nSuppose the lanternfish live forever and have unlimited food and space. Would they take over the entire ocean?\n\nAfter 256 days in the example above, there would be a total of 26984457539 lanternfish!\n\nHow many lanternfish would there be after 256 days?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_07.adb",
    "content": "--  Solution to Advent of Code 2021, Day 7\n------------------------------------------\n--  The Treachery of Whales\n--\n--  Interesting here: the `fast` mode is running in O(n)\n--      where n is the span of x positions (x_max - x_min + 1).\n--      The `slow` and straightforward way is running in O(n**2):\n--      one outer loop over all positions, one inner loop for\n--      computing the cost of moving all crabs to the position\n--      considered in the outer loop.\n--\n--  https://adventofcode.com/2021/day/7\n--  Copy of questions in: aoc_2021_07_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_07 is\n  use HAT, Interfaces;\n  --\n  input : constant VString := +\"aoc_2021_07.txt\";\n  --\n  sep : Character;\n  f : File_Type;\n  r : array (1 .. 2) of Integer;\n  x_min_min : constant := 0;\n  x_max_max : constant := 2000;\n  subtype Position_Range is Integer_64 range x_min_min .. x_max_max;\n  type Crab_Population is array (Position_Range) of Integer_64;\n  pop : Crab_Population;\n  xx_inp : Integer;\n  xx, x_min, x_max,\n  cost_1, cost, cost_min,\n  dist, x_cost_min,\n  s_px, s_x_px, total, total_x_px, total_x2_px : Integer_64;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\n  fast : constant Boolean := True;\n  T0 : constant Time := Clock;\nbegin\n  for j in Position_Range loop\n    pop (j) := 0;\n  end loop;\n  total := 0;\n  Open (f, input);\n  loop\n    Get (f, xx_inp);\n    xx := Integer_64 (xx_inp);\n    pop (xx) := pop (xx) + 1;\n    total := total + 1;\n    if total = 1 then\n      x_min := xx;\n      x_max := xx;\n    end if;\n    if xx < x_min then x_min := xx; end if;\n    if xx > x_max then x_max := xx; end if;\n    exit when End_Of_File (f);\n    Get (f, sep);\n  end loop;\n  Close (f);\n  if verbose then\n    Put_Line (+\"Pos min:\" & Integer_64'Image (x_min));\n    Put_Line (+\"Pos max:\" & Integer_64'Image (x_max));\n    Put_Line (+\"Total:\" & Integer_64'Image (total));\n  end if;\n  if fast then\n    total_x_px := 0;\n    total_x2_px := 0;\n    for x in x_min .. x_max loop\n      total_x_px  := total_x_px  + Integer_64 (x) * pop (x);\n      total_x2_px := total_x2_px + Integer_64 (x * x) * pop (x);\n    end loop;\n  end if;\n  --\n  cost_min := 0;  --  Just calm down a warning.\n  for part in 1 .. 2 loop\n    if fast then\n      s_px   := 0;\n      s_x_px := 0;\n    end if;\n    for y in x_min .. x_max loop\n      --  Compute the cost of moving all crabs to position y.\n      if fast then\n        --  Quick computation without inner loop:\n        s_px   := s_px   + pop (y);                   --  Partial sum: sum_{x <= y} pop_x\n        s_x_px := s_x_px + Integer_64 (y) * pop (y);  --  Partial sum: sum_{x <= y} x * pop_x\n        --\n        if part = 1 then\n          cost := y * (2 * s_px - total) - 2 * s_x_px + total_x_px;\n        else\n          cost :=      (2 * y *        s_px -           --\n                        2 *            s_x_px +         --   Maths,\n                                       total_x2_px +    --   pencil & paper\n                        (1 - 2 * y)  * total_x_px +     --\n                        (y ** 2 - y) * total)           --   --> 639x faster!\n                   / 2;                                 --\n        end if;\n      else\n        --  Slow, straightforward computation, with inner loop:\n        cost := 0;\n        for x in x_min .. x_max loop\n          dist := abs (x - y);\n          if part = 1 then\n            cost_1 := dist;\n          else\n            cost_1 := dist * (dist + 1) / 2;\n          end if;\n          cost := cost + cost_1 * pop (x);\n        end loop;\n      end if;\n      --  Did we find an optimum ?\n      if y = x_min or cost < cost_min then\n        cost_min := cost;\n        x_cost_min := y;\n      end if;\n    end loop;\n    if verbose then\n      Put_Line\n        (\"Minimal cost:\" & Integer_64'Image (cost_min) &\n         \" at x =\" & Integer_64'Image (x_cost_min));\n    end if;\n    r (part) := Integer (cost_min);\n  end loop;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: sum of linear costs: \" & r (1));\n    Put_Line (+\"Part 2: sum of quadratic costs: \" & r (2));\n    --  Part 1: validated by AoC: 340052\n    --  Part 2: validated by AoC: 92948968\n  end if;\nend AoC_2021_07;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_07.txt",
    "content": "1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,11,39,71,27,749,252,590,80,445,1125,1044,690,307,145,713,709,468,135,24,330,932,110,1732,1550,826,1,188,1585,388,977,205,351,550,1,782,111,225,523,325,188,134,954,139,448,903,1225,161,791,1539,918,113,15,234,377,2,22,52,1530,119,922,658,41,256,192,161,102,109,8,1492,765,1277,92,245,73,281,1579,485,645,962,287,207,609,109,203,1181,867,371,290,1582,201,16,298,626,329,756,466,433,384,871,84,1661,1177,28,169,263,527,18,619,823,961,41,211,142,842,175,421,202,440,201,104,814,1059,80,17,420,749,522,261,80,540,36,708,1166,357,639,45,224,852,1209,1400,303,13,255,959,83,85,339,184,616,192,688,1145,200,26,376,624,165,10,492,11,866,531,28,20,614,3,500,354,650,74,1156,743,350,8,1641,38,254,673,523,242,186,756,98,1352,425,165,1072,1072,441,487,489,408,685,1083,527,172,32,419,699,672,464,1986,312,941,991,639,260,70,4,490,386,1079,883,285,260,91,204,1724,555,547,468,140,372,94,6,1189,165,439,22,261,255,197,81,9,306,23,61,151,477,326,1393,69,1246,191,113,172,806,116,644,23,500,567,276,237,257,482,262,87,561,530,786,312,1130,251,1391,0,478,85,129,714,64,499,484,771,461,876,563,587,20,4,704,84,230,667,1099,187,491,25,382,1607,14,434,902,1424,263,58,13,394,21,199,885,1113,105,238,423,972,1270,131,103,21,1125,3,1032,122,111,551,122,127,103,1164,1038,688,98,468,547,464,766,1044,1758,718,1476,1057,49,1526,118,391,629,241,280,303,0,915,88,656,1113,100,458,364,1612,362,1090,391,112,722,538,38,54,218,279,893,128,947,336,100,99,1329,342,543,1061,626,40,164,639,640,525,1121,714,592,696,260,103,520,160,151,462,260,1153,1319,132,608,1469,261,1080,96,908,383,36,70,1082,393,99,1573,567,19,1238,391,39,58,334,732,193,79,124,538,1511,185,608,538,0,52,13,190,180,49,184,143,655,74,315,105,906,569,1037,110,224,68,840,1300,130,762,269,560,655,156,819,1137,1483,1037,238,854,91,329,25,677,317,58,563,39,456,919,485,512,37,217,281,1020,914,289,1196,1060,440,1402,85,1130,931,226,325,598,482,861,60,610,308,551,178,1121,436,155,89,1283,887,163,516,1011,26,493,371,538,688,11,1023,148,174,150,401,1115,111,500,84,585,1,307,863,11,1333,414,855,340,810,75,79,292,8,1296,50,17,638,941,260,1250,817,311,184,902,623,97,57,75,425,647,33,225,85,335,34,905,44,644,208,386,194,1427,204,9,226,1278,165,776,510,707,541,378,26,265,661,475,803,344,107,947,307,453,1305,1589,999,55,1364,130,745,545,650,1223,783,965,416,737,275,32,166,951,30,947,1208,159,257,648,214,94,710,386,923,772,910,688,322,312,818,361,77,1,828,280,582,153,428,42,68,1061,271,627,578,12,449,14,583,128,925,355,608,34,492,231,101,6,732,791,94,305,975,1023,201,184,580,591,1604,547,528,417,684,768,1095,925,1429,417,1014,367,1031,160,820,206,227,1045,828,8,170,235,222,483,479,106,182,121,231,282,646,1165,21,68,51,130,14,68,330,1087,76,782,593,85,203,949,164,21,73,14,1590,137,436,163,582,725,46,326,436,59,44,621,317,269,216,486,396,194,713,4,1072,327,186,225,701,320,726,1220,331,17,78,558,1213,1000,436,240,940,1658,19,553,1498,660,152,304,267,33,926,340,556,1098,1434,1813,111,245,1,132,224,782,209,1142,1412,40,716,1,91,184,218,3,484,252,71,263,468,624,12,924,147,687,330,342,746,607,17,709,16,431,232,444,9,1386,44,181,1128,876,74,637,549,213,476,18,320,387,106,61,319,785,165,735,73,806,718,188,327,453,1555,978,13,400,1025,670,698,610,171,97,644,963,1037,53,2,106,20,855,17,7,495,1508,41,205,467,1848,59,243,758,6,396,22,1558,198,227,495,1370,4,128,371,573,1130,591,190,118,1246,1049,122,15,1755,332,567,202,162,989,1061,232,591,308,1433,132,100,564,436,466,15,1229,280,49,1827,701,118,106,246,18,2,184,43,1496,1091,156,334,730,354,429,6,83,1185,1,229,229,16,207,419,1018,197,1492,1805,1334,246,1378,175,297,1362,470,599,263,656,390,119,692,22,859,22,60,1009,5,1310,161,461,157,247,309,195,5,663,402\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_07_questions.txt",
    "content": "--- Day 7: The Treachery of Whales ---\n\nA giant whale has decided your submarine is its next meal, and it's much faster than you are. There's nowhere to run!\n\nSuddenly, a swarm of crabs (each in its own tiny submarine - it's too deep for them otherwise) zooms in to rescue you! They seem to be preparing to blast a hole in the ocean floor; sensors indicate a massive underground cave system just beyond where they're aiming!\n\nThe crab submarines all need to be aligned before they'll have enough power to blast a large enough hole for your submarine to get through. However, it doesn't look like they'll be aligned before the whale catches you! Maybe you can help?\n\nThere's one major catch - crab submarines can only move horizontally.\n\nYou quickly make a list of the horizontal position of each crab (your puzzle input). Crab submarines have limited fuel, so you need to find a way to make all of their horizontal positions match while requiring them to spend as little fuel as possible.\n\nFor example, consider the following horizontal positions:\n\n16,1,2,0,4,2,7,1,2,14\n\nThis means there's a crab with horizontal position 16, a crab with horizontal position 1, and so on.\n\nEach change of 1 step in horizontal position of a single crab costs 1 fuel. You could choose any horizontal position to align them all on, but the one that costs the least fuel is horizontal position 2:\n\n    Move from 16 to 2: 14 fuel\n    Move from 1 to 2: 1 fuel\n    Move from 2 to 2: 0 fuel\n    Move from 0 to 2: 2 fuel\n    Move from 4 to 2: 2 fuel\n    Move from 2 to 2: 0 fuel\n    Move from 7 to 2: 5 fuel\n    Move from 1 to 2: 1 fuel\n    Move from 2 to 2: 0 fuel\n    Move from 14 to 2: 12 fuel\n\nThis costs a total of 37 fuel. This is the cheapest possible outcome; more expensive outcomes include aligning at position 1 (41 fuel), position 3 (39 fuel), or position 10 (71 fuel).\n\nDetermine the horizontal position that the crabs can align to using the least fuel possible. How much fuel must they spend to align to that position?\n\n--- Part Two ---\n\nThe crabs don't seem interested in your proposed solution. Perhaps you misunderstand crab engineering?\n\nAs it turns out, crab submarine engines don't burn fuel at a constant rate. Instead, each change of 1 step in horizontal position costs 1 more unit of fuel than the last: the first step costs 1, the second step costs 2, the third step costs 3, and so on.\n\nAs each crab moves, moving further becomes more expensive. This changes the best horizontal position to align them all on; in the example above, this becomes 5:\n\n    Move from 16 to 5: 66 fuel\n    Move from 1 to 5: 10 fuel\n    Move from 2 to 5: 6 fuel\n    Move from 0 to 5: 15 fuel\n    Move from 4 to 5: 1 fuel\n    Move from 2 to 5: 6 fuel\n    Move from 7 to 5: 3 fuel\n    Move from 1 to 5: 10 fuel\n    Move from 2 to 5: 6 fuel\n    Move from 14 to 5: 45 fuel\n\nThis costs a total of 168 fuel. This is the new cheapest possible outcome; the old alignment position (2) now costs 206 fuel instead.\n\nDetermine the horizontal position that the crabs can align to using the least fuel possible so they can make you an escape route! How much fuel must they spend to align to that position?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_08.adb",
    "content": "--  Solution to Advent of Code 2021, Day 8\n------------------------------------------\n--  Seven Segment Search\n--\n--  https://adventofcode.com/2021/day/8\n--  Copy of questions in: aoc_2021_08_questions.txt\n--\n--  HAC 0.098 \"nice to have\"'s detected in this exercise:\n--\n--    *     Comparison (equality operators) \"=\", \"/=\" of\n--            composite types (arrays and records)\n--    *     Logical operators on arrays of Boolean\n--\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_08 is\n  use HAT;\n  --\n  input : constant VString := +\"aoc_2021_08.txt\";\n  --\n  r : array (1 .. 2) of Integer;\n  --\n  procedure Part_1 is\n    c, sep : Character;\n    f : File_Type;\n    first_line : Boolean := True;\n    size : Integer;\n  begin\n    --\n    --  Part 1 : count unique patterns (2 segments for digit '1',\n    --           3 for '7', 4 for '4', 7 for '8')\n    --\n    r (1) := 0;\n    Open (f, input);\n    first_line := True;\n    while not End_Of_File (f) loop\n      if first_line or End_Of_Line (f) then\n        --  Skip the training message\n        for i in 1 .. 61 loop\n          Get (f, sep);\n        end loop;\n      end if;\n      first_line := False;\n      size := 0;\n      loop\n        Get (f, c);\n        exit when c = ' ';\n        size := size + 1;\n        exit when End_Of_Line (f);\n      end loop;\n      if size = 2 or size = 3 or size = 4 or size = 7 then\n        r (1) := r (1) + 1;\n      end if;\n    end loop;\n    Close (f);\n  end Part_1;\n  --\n  procedure Part_2 is\n    --\n    subtype Segment is Character range 'a' .. 'g';\n    type Segment_Set is array (Segment) of Boolean;\n    zero_set : Segment_Set;\n    --\n    f : File_Type;\n    c, bar, spc : Character;\n    --\n    procedure Get_Segment (s : out Segment_Set) is\n    begin\n      s := zero_set;\n      loop\n        Get (f, c);\n        exit when c = ' ';\n        s (c) := True;\n        exit when End_Of_Line (f);\n      end loop;\n    end Get_Segment;\n    --\n    function Count (s : Segment_Set) return Natural is\n      total : Natural := 0;\n    begin\n      for c in Segment loop\n        if s (c) then\n          total := total + 1;\n        end if;\n      end loop;\n      return total;\n    end Count;\n    --\n    procedure Intersect (s, t : Segment_Set; s_and_t : out Segment_Set) is\n    begin\n      for c in Segment loop\n        s_and_t (c) := s (c) and t (c);\n      end loop;\n    end Intersect;\n    --\n    function Equal (s, t : Segment_Set) return Boolean is\n      res : Boolean := True;\n    begin\n      for c in Segment loop\n        res := res and (s (c) = t (c));\n        exit when not res;\n      end loop;\n      return res;\n    end Equal;\n    --\n    subtype Digit_Range is Integer range 0 .. 9;\n    subtype Output_Range is Integer range 1 .. 4;\n    training : array (Digit_Range) of Segment_Set;\n    temp, output   : Segment_Set;\n    --  k = assoc (i) means: training (i) represents digit k.\n    assoc : array (Digit_Range) of Integer;\n    segs_to_index : array (1 .. 7) of Digit_Range;\n    index_to_segs : array (Digit_Range) of Positive;\n    first_line : Boolean := True;\n    size : Integer;\n    dig_it : Digit_Range;\n    num : Natural;\n  begin\n    --\n    --  Part 2 : decode the digits!\n    --\n    r (2) := 0;\n    for s in Segment loop\n      zero_set (s) := False;\n    end loop;\n    Open (f, input);\n    first_line := True;\n    while not End_Of_File (f) loop\n      if first_line or End_Of_Line (f) then\n        for i in Digit_Range loop\n          Get_Segment (training (i));\n          size := Count (training (i));\n          segs_to_index (size) := i;\n          index_to_segs (i) := size;\n          case size is\n            when 2 => assoc (i) := 1;\n            when 3 => assoc (i) := 7;\n            when 4 => assoc (i) := 4;\n            when 7 => assoc (i) := 8;\n            when 5 | 6 => assoc (i) := -1;\n            when others => Put (\"Error!\");\n          end case;\n        end loop;\n      end if;\n      first_line := False;\n      --\n      --  Determine the 5- and 6-segment digits:\n      --      _    _    _          _    _    _\n      --      _|   _|  |_         | |  |_   |_|\n      --     |_    _|   _|        |_|  |_|   _|\n      --\n      for i in Digit_Range loop\n        case index_to_segs (i) is\n          when 5 =>\n            --  Intersect with the \"4\" (4 segments), and count the remaining segments.\n            Intersect (training (i), training (segs_to_index (4)), temp);\n            if Count (temp) = 2 then\n              assoc (i) := 2;\n            else\n              --  Intersect with the \"1\" (2 segments), and count the remaining segments.\n              Intersect (training (i), training (segs_to_index (2)), temp);\n              if Count (temp) = 2 then\n                assoc (i) := 3;\n              else\n                assoc (i) := 5;\n              end if;\n            end if;\n          when 6 =>\n            --  Intersect with the \"4\" (4 segments), and count the remaining segments.\n            Intersect (training (i), training (segs_to_index (4)), temp);\n            if Count (temp) = 4 then\n              assoc (i) := 9;\n            else\n              --  Intersect with the \"1\" (2 segments), and count the remaining segments.\n              Intersect (training (i), training (segs_to_index (2)), temp);\n              if Count (temp) = 2 then\n                assoc (i) := 0;\n              else\n                assoc (i) := 6;\n              end if;\n            end if;\n          when others => null;\n        end case;\n      end loop;\n      --\n      Get (f, bar);  --  Absorb '|'\n      Get (f, spc);  --  Absorb ' '\n      num := 0;\n      for i in Output_Range loop\n        Get_Segment (output);\n        size := Count (output);\n        for i in Digit_Range loop\n          if Equal (output, training (i)) then\n            dig_it := assoc (i);\n            exit;\n          end if;\n        end loop;\n        num := num * 10 + dig_it;\n      end loop;\n      r (2) := r (2) + num;\n    end loop;\n    Close (f);\n  end Part_2;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Part_1;\n  Part_2;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: number of unique digit display patterns: \" & r (1));\n    Put_Line (+\"Part 2: sum of decoded display numbers: \" & r (2));\n    --  Part 1: validated by AoC: 440\n    --  Part 2: validated by AoC: 1046281\n  end if;\nend AoC_2021_08;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_08.txt",
    "content": "dfgabce cadfgb cefa ca aecbg dfcegb geabd ecbfg cab agcfbe | egbfadc dbgae gcfeb abgdfc\nfbcag eg dbge gcbfe acdgfe gec fdcegba efbdc fbedgc efabdc | ge fagbc dfebc eg\nda gdbcea gdcfbe acgbd dbfcgea ebad aecdfg afcbg adc ecdbg | afcegd dacebg ad cdbafeg\ngafeb ag acfbed ega ebadfg bfcge dgfa begcda edfba cfgedba | ag dafg dfcbgea feacdb\ncefdag gcea fag defca gbdaef afcdg dcbgf ga adfecbg fcbdea | geac cfedba cgea fadecg\nfcgaed abdecgf cfaed ceb febacd dbecf bc cbfa gecbad fbdeg | facde cfgade acdefb cbe\nbcgae cfedba efcbadg dafbc dfbe fcgbad ef aefgcd acfbe fea | abfcd cafbd fbde dcgbaf\ngeabdc fedga cafdbg cd aefcbg adcge dac bdegafc cegab dceb | dcfgba cad cad deabcg\ngdecab fde aecf adbgfe egdcaf dgaebcf decfg bcfdg ef ceadg | cefdabg fcea efac edf\ncbgaf edfa bfgecd fcdbae debca dfb bcdaf bdcaeg fecgadb fd | cafdgeb gabcf df afdebc\nfdebgc egdfb bfcdg cfedgab fdeagb egcb fcb cfdeba cb fagcd | gebfd afdbgec bc gdcafbe\ncb gcdefa cdb bacg eabfd ebdac gdabec gcbefd bgdecaf caedg | cgdeab ebfdgca edgbca cbefadg\nefbc aecgbd ebgdfa ecbag afb cfgeadb bf cadgf bgfca egcabf | bf agdbce fab bfcdeag\ncedafg aecdbg fcd cgeda cdfag efcg agfdb defcab fagcebd cf | adgcfe daecg abcged fgedbca\nbcgaed cfdgea caebd gdebc bega fbecadg ge fcdaeb gde gfbdc | gabe eg cadebf ecgadf\naefc abefg acfbge agedbf dbgce cab abgdfc ecbga ac bfdceag | beafgd ca ac ac\nafbde fedag becda dacegf baf gacdbfe fcabdg fgeb fgdabe fb | fb afbdge bcdea fedacbg\nbfd cdgbfa dgefca fabdeg cgebdfa cabd gfcda cbgef db dgfcb | bd badegcf acdb adegcf\nef cfbgd cdbfe bef ceadb bfcgead aedf edbagc abgcef aecbdf | bcfegad bef bef fe\ncbagef beadgc fae deacb fcagd cgdebfa dfeb bdecaf fe fcdae | dfaceb efdb beafcg bdef\ngdfeacb bca gfeacb gfeca egcb bc dgeacf fabgd fbcdae gcbfa | bfdeca bca adbgf abdgf\nfaedbc egcaf bdgaf agdebcf fagcb cab bcdgaf dbgc fbgead cb | bdgafc cb dgbfa bgcd\ndfabc bgacde ad dab edfa bdfec dbgefca facgb eacfbd fcgdeb | ecdbfag bedfc ebfcad bfcdge\ndfegbc cfagb ba gefbc abec bfcdega bfa egadbf fgbcea fgcda | eafbdg ebfgc fgbdcea ba\nfgdebca dgbcea adbce cfaedb acebf ef efc cfabg edgafc fedb | fdeb fce gcfab bafgc\ncfdg daefgcb caedgb aefbc cbdag fg fdbgac fbg beagdf fbcga | dgfc fecgabd fgcd gbf\ncbadef abgdef cfea ac gedbc dcbafg dca fdbecag dceab deafb | eafc ebfdga cefa abcde\nfcbged ebdca bde ceagb abcdfeg bd cdaef cgabed ecgfab bgda | baecd dgbcea ecafd dbag\nbfeag cdabf dbeacg dgbcefa eda fdabge bafde ed egfd ebcafg | ebfcadg defg fadbe cfbgea\nbfd dgbec gfcadb ecdf aefbg cfbgead fd gcbdfe debgf gcdeab | ecdbga aebgf abcfgde fd\necgfda bcafe dgbefca dagcb dfc acdfb cdabfe cebfag fbde fd | bgdefac cfd febgac df\ndcafb dgafcb dbeacf bdga degbcfa cgbaf ga fga efdgca cegfb | ag beagdfc abcfg gcdeaf\ncgbfd fegcba ecgfb cbe dafebg bdface gace ec fcgdeab eagfb | gcdfb acge ecb cebgf\nadbcgf ef fged feb dabfgce bdgfc becfgd dcabe febgac bdfec | cgdbf fdcgeb afcbge fbdgc\ncg dagfc dfagbc cgab dagbf gbdcfe dgc aefgdbc aecdf bafegd | cg gfacbed bfgad bgacfed\ncadfeg cfdegba edagcb fae faebc decfb fa aebcg fgba egafcb | baegc fa acfbe af\nfed bcdge fcbae gbfd gfabecd cdaegb df egdfac egcfbd becdf | cadegf edcgbf fcbde dbgf\nfadcg beafcd cedbag edabg abdfge bdagf fba dgcbaef fb fbge | deafcgb dfcaeb geadfb ecfgdba\nbec fbcea cgbf bfgcea cdefa cgadeb cb fdbeag bdaegcf fgabe | ebfacg bgcf cb bc\ngb agdbce efacgd cgdfbe agdec afcdb ebag gcb eadfgcb bdgac | efcbagd bedcag bgc baeg\nfbe dcbgae cedgfba bcgefa bfdge bf dafge edbgc fcdb bcfdeg | bdfc fdabgce ebgfd fegbd\nfb abfdge fgdca fedcag bafcgd bfg gdeabfc fbgac eagcb bcdf | gacfedb fb bf fcadg\nbg eadgf bcdea gbd gebda edgbac cagb dfecab fgcbead ecfbgd | gbedca adfebgc acgb bdg\nadgfce begafc gfeac cde cgabd ed becdfa gfed egfbcda egacd | ed cgeda dfeacb dec\nagefcb gadec gdbafe dg cebafdg dcfg ecagf edg gdeacf ceadb | dgaefc egcadbf cdfg faecg\nfdec gcbdaf bafedc cf dbegac ceabd gbadecf fca gbefa bacfe | fc fdce acf afc\nfdecg gdefcba cg dbcfe dfbeac gcfedb daefg facdgb gebc cfg | begafdc fcdebag dbcgaef gfc\nadcgef agbdfec dc ecad cgeabf edfbg bcdgaf fdgce ceagf cdg | cdgef ecda cade cd\nabdefc bdaecfg dgeacb fb gfade bacde bdagcf fdb becf adbef | fcbadg cefabd fdb edfga\nefcgab bead fcdeg ae cgdab dgcbae aeg edgca bcegdaf gdcfab | gdafceb ea eag aeg\ndceafb befac fca cf fdcb cadgef bedaf ebagc aedfbg acgdbef | beadfc cf cfeba gbeca\ngce eacgbd afcdbe eg dfcebga bedca gfbca agfedc gcaeb gebd | gdbe ge ge gbde\nbcgae bedgfca gde ed gdaec gbfcad cgbdef gdaecf edfa gfadc | cdbfeg bgdfac cfdeag adgfbc\ngebca dbacfeg dbfeag bagfe eadfb gf fdge fbg dfceba gafbdc | egfd fedg egafb gf\nbegfadc bdcae dgbca edbf acbfeg fcgead be eba afdce aedcbf | bfedac edcab eba fdbace\nfdbgc cegabf ac dfbage bgfae faec gac caedbg bfgedca bfagc | acef dfgcb face gbafed\ncdbfge bfceg dgacbe baegfd ecb dfceabg ebdfg cb acfge bdfc | cbe gcbefd egdcba eafbdg\nfecdb dgbcfae bedca edf ef cfebgd ecgf gfdbc fdbagc afbged | aedbgf ef fecg fagcbd\ngdecfb fbadge cabe adfcg efcbd ea gbeacfd fcedba dea fdeac | acbe acbe dea fcgedba\nbg dgfac gabdec dgcabef beafc gfceab cgb bafcde fegb cgafb | bcg bg fdgca faebcg\nadfgc dfcbge dgafbc gaf acfb dgcea gebcdaf fbgdea fbgdc af | fa agcdf fga gfebda\ndefag begdf fa becgda aef afcg dfaceg cgdae eacdfb acefbgd | cadfeb edgaf fa ecadbf\nfec edfbc fagecd cgdfb ef fcabdg cedba fbecdg bfge faegbcd | befdc dbfecga acgdbf gcbedfa\ned cedbfg bdfac fdeac baed fde eagcbdf abgfdc feadbc gaefc | fdbca de cgbdfe de\nfcbga ge cagbef acebfdg egbf acbge ceg egcdfa bagdcf adcbe | cgfab ecg ebcda afgcde\ndf fadcbeg gcfbde dcagb fbd afgdbc cbeagd dfcab cafbe adfg | eagdbcf fgda cgbda gbfced\nagef bgdcaef ade adcbf gdbace cefdg febgdc cgefda fedca ae | ae afdgec febgcd agcdeb\ngfbc fdg dbaef fg aefgdcb gefdac gebcd dbegac fegcbd fbedg | cfgb gdebc cbaefdg fgd\nebfgac gcf geabdfc cegbda fgade bcaeg fcba cf fdecgb ecafg | cfg fgc acfgdeb gdabfec\ngafeb ebdgac ed cgbfad cgeadfb bdecfa bfcda fabde aed ecdf | bgfdaec fedcbag de fedc\nage ebcdfg afcdeg dcfeg efadgbc fgad becad ag eacgd gabecf | ag gcdfbe agecd fdgce\naecfbd geb afbde fdgeab gfeba ebgcadf bg gdbf fgeac bceagd | eacdgfb bge edabcf ebdaf\ncgabe aefbcdg fagdce abcdfg dcbe aecgbd cge fbaeg ce dcbga | bgacfed gafcdb egc egc\nbdefa fagbd fabdce cdae fceagb deb fbdecg fcbea de agedbcf | fgdcabe afbde bde gfcbde\ndgfcea dcbea dabcf edcbga cedafb gfabc cgdabfe afd fd dbfe | debf egdacb dbef edabcg\nbfdea adfceb fgcbae feg fdebg bagfdce egcdb fedagb dgaf gf | bgdfea gef cdebfag edcbgaf\nade aefgdc ea feac gefdc eacbdfg eabfgd abcdg efbdgc geacd | eafgdc fgebad cbdefg cdefg\negfdab edfb agfec dbcage ade ed badcfg gfcdeba afedg fgadb | aedbcg bgfda aed dae\ncfdbge abgc afgbe cb bcf ebfdga adecf efbacdg agfbce bacfe | bfc fbc cfb bfc\ngd bgd gcafeb dfcbage ebfgcd egfbd decg gcafdb aedfb ebgfc | gdec gefbacd gdce dg\ngf dbegac becgadf dfge facbe gfa acdgfe ecgfa dcfbag gceda | gfed cefba cabfe acedfg\nfd cdbagef fdgbec daebcg dfba fbacdg cdf cfadg gabdc gfcae | agecf cfd cdf egcbad\ndfca adgefb fbced cfdbge fa egcabfd eabcf eabfcd cabeg afe | acfd dbecf af af\nagfdec dfcag edgacfb baegfd fd gfaecb dacgb ecfga dfec daf | gabcd ebcgadf fbegac fgace\nedafg gcfea cbaeg afcdgbe fcde fc acf cedagf begfda cdbfag | cf daecbfg bgace dcgabef\nbdefagc gcba bfacde adbce ga dgefc cagdeb dgeabf aegdc adg | faecdgb gda ag dga\nbecdag bceadf edcab dgacb bdgcaef gd dga cedg agbfc dafebg | gd gced gad cgabd\ngbfaed bdacf db fcabg ecfda edcb adcfge adb abcfed cgedfba | bad dba fdecgab edacf\nae cabe ecgafb dfgce afbdge gdacfb bdegfca afe agfcb cegfa | ae fgdeab gcfed cgdfabe\nad fdbcg cbfea fdabgec dca cgadfe fbdac dbag gbcfde bgcfad | dbagfc dac ad cbfdge\nfdgbaec ab dabe cabegd cgaed bcdag bgfdc gebcfa agb cadefg | efbgac dcgafe dagecb gba\ncafbge gdbfac aefcb adfcegb daefc bacge gcabed febg fb bfc | bfcgae gebf bfc abgcdf\ndfbgca bfcae ebc ebfdac eb eadfgcb dfeb edbagc fdcba gfcea | becadf ecb bce badcf\ncdefa adcgfe fdceb eacdfbg adf ad fcgea deag gacbfd aecfgb | da dega adcebfg acdbefg\ndace dcebg adbcfg abdcg de dceagb fcbeg fbacedg bdeafg deb | bed cabgd ed fecbg\nedabgc fdbaegc gcadfe afed fcd gecbf fd fgdcab fedcg dgace | gaecd bdgcaf gedfcab fead\ngfbae bgefdc cbfgdae dbgfea abgc bc aecbgf adfce bce afbce | aedgfbc bacgfe bcdefg gfbea\ncadeg cagdfb bdc bfcedga cgbafe facbe efbd edcba bafdec bd | dbc agdce efdacb bcd\nac fegacb bac afdc aedfbc defba dgefba gcdeb edacb dcbeagf | egdbc egcfbad decba adfc\nbcfdag cgfdbea dce gbcfd ed bgced dfbgec gcaeb fcbead dgfe | defg edc gecdb de\neb fbe afdec bfgda cdfbgae fbgcde aedbfc deafgc ecab efdba | aegcdf fedgcab edcfbag be\ncfabg aceg gba fcebda egabfc cbaef acfbdeg ga gcfdb adbfge | cgae abg gace dfabec\nfabe af fdaeg bdega fdceg adbfge fad gcedbfa dfgbac aedgbc | afdgceb aebf dfa cgbaed\necgdf bfcagd dcegb gafdc efac feadbgc agcdef eagbfd fge ef | ef egf dcgfa decgf\nag ecbga bga fdegab gbdcfe gbecf afbecg ebdac edacgfb cagf | gafc ecgbf bag eadgbf\ndafe fe cef agdebfc fecdg bedcg bdcafg beafcg dcegaf fdcag | dafe fcdag afdgce adef\ngefac dagcfe age facdegb acfbg edfa ea edfcg egdcab fcbgde | gcefa ea aebdgc ecfga\ncdfbea debgca adbec bgfadc cdg ceadg bgce gc gfaed fcdgeab | cg cgd afdcbg cdg\ngcbefda fdcga cfdebg fgdabc abgd fdbcg cabfde fda efagc ad | dgcfa bacfed cfbegd da\ncgbaed bcdefg ebdca dcabf feabcdg cgae deabg ced ec efgdba | bgdfce ceag cde dbegac\ndebgfa gbdce ecdgbf ag agdc bga acdgbfe bceag cbaef cebagd | bga ga gaceb abecgd\ndbgcef eafgb fcdeb bdfcae fadc ac degabc agbcefd abfce cba | fcedb cebdga dacf dafcbeg\nbag gceb cbafd bg bgfaec dfgcae cbagf gceaf dfageb bcafegd | agb gb gb fedbagc\ngadce gecdf cgf egbfd beagfc afdc dfcageb cf bcgdae dgefca | fc gfc eacfdg cgf\ndabcfg ebadf cf cebag fbc eagfcb bcegad fgce eabcf ebcgdaf | feacbdg ebadf adfbe fc\nad fgeac afd bfagcde afbcde gdca debgf adgfe fbagec cfaged | adcg adgefc ad adgcef\nfcdbeag fdbage cadf daecb bgecd bafce bda ad cdbaef eacbgf | ad caebdf gbcefa bcade\nefbgca cabdgef fabcd dafec bf afdgcb fab agcbd fgbd dgceab | fba fb dcagb dbfcag\nbea cbfag agefdc cdeb gbadcef aefgdb eagdc cgdeba egbac be | bgace eb be cbde\nacbdeg cefda fb cfbaeg ebf aefcb gbfc ceagb cegbfda gebafd | agcfbe afdec fbgc dfcegab\nbc cgdab gbfcad ecbdfa cbd fgdac edfacgb dgaeb afecdg bcgf | fcbg dbc dcafgb bcgf\naedf dga cgfbde fgbde cfbgad dabegf cfgabde geacb bdaeg da | dfea agd baecg gcaeb\ngc cefga dbefac bacedg afedg afcbe becgaf bcgf bdgfeac cag | cgbf bgcf dabceg gc\ndb cdegf gcbfd afgbc dgcfba cbgaef dgba fgebacd fadcbe fdb | fgebac bd fdegc db\ndebgafc dacbeg fdg cgdba fdagcb eacfg bdcf gafbde fd dcagf | fbcd bgcefda cafbged dfbc\nfcab gdbef begadc fdecga abdcefg bafgec cb cbe efbgc egacf | bce gcfeb cgbfade cbaf\naedg agfebcd abfge fge cdbefg eg dgcfba gdebfa acbef gafbd | agdfbc baefc efg gbfea\ncdgab cbfedga eacbgd cf dceafg cadgfb fdc efbdg bcfa fdbgc | dfc fc cdgbf gcbadf\ngce eg edcfagb eacgdb bfegdc cdgaf ecgad cebadf eagb cedab | dcbae cdafg gedacfb ge\ndbeagf gfbda fdebgc gabfdc afbgc cgbea fc cdaf ecadbgf fcb | cfgedb bdagf fc gbecfd\nbdcefg egcfab acedg fcdb fbgeda bec cebdg deacbgf cb ebdfg | bc decbg eacgd bdcf\ndfgeab cegba facbegd edg dfgceb gafcbd edbgc gfcbd dcfe de | bdceg fecd cedf defgcb\negfb dfgace cfgaebd befac adcgb aeg ge cebag bgface bdacfe | cgbea cgbae cbdgaef afebgc\nde efd efdbg efabdcg fgaceb bfgdc fgabe edgfab ebda degacf | fecagd ed adbe de\nfedbga gc gec gaefd ecagf gecbda bafce cgfead cgdf cadfbeg | gafed gcfd cgfd gcfd\nbedfgca ebfdc acgbfd cfb dfbeg decaf bc dabefc beac aedcgf | debgf efacd cb bc\nedgcba eg dbfga acfgeb cdbea bcfdaeg dcge gdeba dacefb egb | efgdacb cgeafbd gfadb gedc\nbacfde dgcefa eabdf acfebdg afgdbc dba aedfc aebgf db bdce | db afecd agcdfe agfedbc\ndga cgadb cdbge bfgca edab ad cbgade efbcdga afedgc ecfgbd | ad dgecb ad bdgac\nabfdec dacfegb faecg cbge acgfb fcgaeb bgfda bc bfc fgcdae | cgeb fgaecb cbeg gadbefc\nea ecgbfda eacb efa facegb bgfea ebfdg gfbac edcgaf gcdfba | gabfe bgfeca ae cabe\necf bfged cebfgd adfebg dfabec cgdf gbeca cf bdfcgea bgfce | cdfgeab gdbfe daebcf bcagdef\nebf efbdc bf bfcdge dgcfea bgfc cedab begdaf egcdf befdcag | ebgcfda gdfaeb bf ecfgd\negcdf ecafg afebdc df dgfa agfecd cfbdgea ecgafb gdceb cfd | cdf cgadef acfgbde defgc\ngbdeacf bfcdg cag acdgf efdbcg ac fagdcb gbfeac bcda edfga | agc gaedf abdc cag\ncfgd edbcfg gfebc begcdfa acebgf ged dbace faedbg gecbd gd | bagefc dgefabc defabg becgf\ngcbe ce ebdfa cae bdcagfe bgdac gdeacb cbdagf dbace caegfd | ec acedb gabcd bcagfed\nefdgba cgabfed ec caef ceagb fbega cbgda ebc afbgec ecbdgf | afegdb gacbd dgefab edafgb\necagd bfdec fabdce bda beadc gfeabd bdfeacg afbc gecbfd ba | becdf dcaeg gcdea adb\ncefb cfabdg dbf bfeacd baged bf baefd gaecfd cbfaedg fecda | bf fedac fdgecba bdf\ngce gdbcae fecd efcbgd fbdacg eafbg cefgb cbdfg ec fgdacbe | cge ec bgcfead ceg\ndeagfb af efca gfecad dfa bacdg cfdegb fecdg egdacfb dfcag | fdgce af edbgafc fdgce\nfagdce ebd abdegf defba cafebdg eb daefg dfbca ebga defcbg | afdeb eb bde egba\nbafed aecdb fbce cbd gdebafc cfbadg badegf bc ecdfab gecad | dbc dbc badgcfe fdgeba\nfgbec bfacde ge edgcfb cgdbfae fdecga cfbga efg dbge cdfeb | bedfcg eg ge afebdcg\ndcaef ag gcab aeg acedg edgcb efgdacb cgfbed dafgeb agdbec | bedagc bdegc dfcebg adecf\ndcfg abecg bgadc dg fcgbda gadebf cdabfe badcf agd fcdbega | abdfeg gd egbac cabgdf\ndfgebc eabcd efcdb dbecfa dac aegdb ca bcgafed fbac fcadge | ca egcdafb afcbdge eagdb\nebgdc cbgdfe dcbfae bfagcd gdef cebga bceagfd ecd dfbgc ed | de ed fdegcba edc\neb feb begdcf efgacb gdbe daecf dgcfb fbdcega cebfd gabcdf | efdbc be afdec efb\nbegac fbec bcdafg acb cb fgaebd afegbc gebadcf dagec beafg | adgce fceb cgdeafb cab\nca cdfagb ebfca ebdcgaf afebg dfbgae cega cebfd fbagce fac | bgedaf cgae gdaecfb egdabcf\ngabfd agfc ecdbfag aefcbd afd af gdabfc bgcfed abedg dcgfb | af bdgcef adgbf gcdafb\negfda fed dbfga adgefb de gacbdf aefgc aecbfd bdge fdbecga | ed de eacbgdf bdeg\ndbfag cdbfea gfdbec agfedbc gfb bg gabfcd fgeda dbfac acbg | dfbac gcba gb fbgda\ndbcgf gba gdcaeb dgbacfe edfba debgcf cbdgaf afcg ag abfdg | bgafecd edfcgb ag dgfba\nbdfcg acebfg egfbacd gfdcba fbg dagb bg cbdaf cgdfe edfcab | bagd gfebacd efbcda gfb\ncedbf fcabdge cge feagbc dfcge gedb adcgf bdcefg edacfb eg | cbdfe cge efbcad cfagdeb\ncga fgeda ceagd ebcg beadc bgfecad fgdcba gc cagebd dfeabc | cag daebgc cg fcdageb\nfgdc fda aebgd cabfde fd agbecf fdacgbe dbfga cfgba bdgacf | facbg fbdagec fdcg ebafcgd\ngbced efbgca gfebd bdc baecg fcabed dcbgeaf gbedac dc acdg | gfbace cdafbe cbaeg bcd\nafgdec ba dbcge daefg dabeg dfbcage afbd fgdaeb gab cfegab | bcfage bgead ba fgdbcea\nace dgcaef daegbc bfgeda ecbd degab cgabf ce eagbdfc bcgea | cdgeaf bdgea edcb cae\ncd cadf gfead gdefab dce adcfge degcf cgefb gdfbcae aebcgd | efgdc dce ecd dc\nafdbe ad fgdeb fda aebdcgf bcaefg acbfe fdceab bacd dcagef | afd begfd acfeb fda\ndfg afgedbc cbfga gbdace dbagf fdegab edgacf df befd edgba | dgeba df efbd cfadge\nbdcgaf aebg badfce efagc gdefc cabfeg abgcf ecafbdg afe ae | aegdbcf ageb eagb ebdfgca\ngdceab fb bfe cgbfea edbagfc cafed ebacg ebafc defgcb gbfa | efb efcba bf afgb\nbafcg cdfgb ac caf fcdabe adgc dbgefc bedafcg bgacdf bfaeg | bcfegad afegb gabfdce bgcfa\ndafgb gca fcab fcabgd dcfaebg gfcdae cgdba ac gbadef egcbd | bcedg aebgfcd gfeadb afbc\nadebg fcgaedb dagfe agfc fdbaec fgaecd feg acdfe gf becdgf | feg fge gfe egf\ngf gfda gfb gfcebd gefab afcbged eabdg adgbfe fbace bgcade | dbafgce fbdaeg dagf fcbae\nfbegcd ecg cefdbag fcgd ebdac gbecd cg bfcgea bafdeg edfgb | fcbegd acbde bcgaef cge\ngbcadf cf gfbc defbca acgfd bcaedg afegd cfbgeda caf gcdba | begcad cfa bagfedc gbcdeaf\nbegacdf dcafbg gb cgfbed gbcde cedfab dfcbe gbc cadge ebfg | gbfe gb ebcdfga bfeg\nfe bgadefc cbgdf gbfade cefgd ecdgaf efg afce eacgd dcgeab | gdebac fcae egbdfac fgdeab\nebfca fdac fdb bgdecaf dbcgef cedbfa bgcefa fd eadfb baegd | cgfaeb dgbecf dfb bagecf\nebda eagcf gcbea ba bfcegad acebgd gdecb cdafgb acb gfcdbe | fgcebd cedbgf gbfdac cefag\nedacf fed eacgd febadc ebafc bfcgea ecafgdb adbf fd gbfdec | fabce egfcbd deafgbc bafd\ngfbe fdbga ged ge aegdf baegcd afecd ebgcfda fgacbd gdeafb | cdfae fdaec ge aefdg\ngebaf afdbcg cfged dga fgead febdcga ad fbaedg bade gbfaec | cgbfdea gadfecb agfde gad\nfdg cfgdbe cfbeadg cgbf gedbc dcfage dfgeb fg agcbed adefb | gdf bdecg faedb gfd\nacdgbe cfabg gfbacd cbf dfbcea bcfegad cf gcdab efbag fdcg | dbfagc fgbdcea cbdga fc\nafbcg dgbfac dgaebf gcfea gbceadf afb fb abgcd abcdge fdcb | gbceda cgdabe bcgdae fbgdea\ncgbedf dbgfc cbef cf bgfda gcedb gadceb efdcag fdc bcfdaeg | fecb ebdcfg cf badgf\nfg cafdg fegadbc aefcdb bcagd degf gfecba adegfc cfg fdeac | gdcafe cgfdae gebfca dfcgae\nfdbecg fcagbd fgeabd cadbe bcdag dafgb facg gdc bdgeacf cg | cedab cbdga gcd gc\ngdeaf edbcag fbac fgecdba dfbcea afdce ac fbecd dbefcg cea | efcbd gdeaf dfceagb ace\nabgdc ebcgd ecgdf ebagcd dabe edgbcfa be cgeabf ceb cdfgba | fdacbg abegcd abdgc cabfdge\nfbgcd feacb ed eadf becfd bde fdabce cgdbea fadbcge gbefac | dcgbf fcebd ebcfd gbface\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_08_questions.txt",
    "content": "--- Day 8: Seven Segment Search ---\n\nYou barely reach the safety of the cave when the whale smashes into the cave mouth, collapsing it. Sensors indicate another exit to this cave at a much greater depth, so you have no choice but to press on.\n\nAs your submarine slowly makes its way through the cave system, you notice that the four-digit seven-segment displays in your submarine are malfunctioning; they must have been damaged during the escape. You'll be in a lot of trouble without them, so you'd better figure out what's wrong.\n\nEach digit of a seven-segment display is rendered by turning on or off any of seven segments named a through g:\n\n  0:      1:      2:      3:      4:\n aaaa    ....    aaaa    aaaa    ....\nb    c  .    c  .    c  .    c  b    c\nb    c  .    c  .    c  .    c  b    c\n ....    ....    dddd    dddd    dddd\ne    f  .    f  e    .  .    f  .    f\ne    f  .    f  e    .  .    f  .    f\n gggg    ....    gggg    gggg    ....\n\n  5:      6:      7:      8:      9:\n aaaa    aaaa    aaaa    aaaa    aaaa\nb    .  b    .  .    c  b    c  b    c\nb    .  b    .  .    c  b    c  b    c\n dddd    dddd    ....    dddd    dddd\n.    f  e    f  .    f  e    f  .    f\n.    f  e    f  .    f  e    f  .    f\n gggg    gggg    ....    gggg    gggg\n\nSo, to render a 1, only segments c and f would be turned on; the rest would be off. To render a 7, only segments a, c, and f would be turned on.\n\nThe problem is that the signals which control the segments have been mixed up on each display. The submarine is still trying to display numbers by producing output on signal wires a through g, but those wires are connected to segments randomly. Worse, the wire/segment connections are mixed up separately for each four-digit display! (All of the digits within a display use the same connections, though.)\n\nSo, you might know that only signal wires b and g are turned on, but that doesn't mean segments b and g are turned on: the only digit that uses two segments is 1, so it must mean segments c and f are meant to be on. With just that information, you still can't tell which wire (b/g) goes to which segment (c/f). For that, you'll need to collect more information.\n\nFor each display, you watch the changing signals for a while, make a note of all ten unique signal patterns you see, and then write down a single four digit output value (your puzzle input). Using the signal patterns, you should be able to work out which pattern corresponds to which digit.\n\nFor example, here is what you might see in a single entry in your notes:\n\nacedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |\ncdfeb fcadb cdfeb cdbaf\n\n(The entry is wrapped here to two lines so it fits; in your notes, it will all be on a single line.)\n\nEach entry consists of ten unique signal patterns, a | delimiter, and finally the four digit output value. Within an entry, the same wire/segment connections are used (but you don't know what the connections actually are). The unique signal patterns correspond to the ten different ways the submarine tries to render a digit using the current wire/segment connections. Because 7 is the only digit that uses three segments, dab in the above example means that to render a 7, signal lines d, a, and b are on. Because 4 is the only digit that uses four segments, eafb means that to render a 4, signal lines e, a, f, and b are on.\n\nUsing this information, you should be able to work out which combination of signal wires corresponds to each of the ten digits. Then, you can decode the four digit output value. Unfortunately, in the above example, all of the digits in the output value (cdfeb fcadb cdfeb cdbaf) use five segments and are more difficult to deduce.\n\nFor now, focus on the easy digits. Consider this larger example:\n\nbe cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb |\nfdgacbe cefdb cefbgd gcbe\nedbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec |\nfcgedb cgb dgebacf gc\nfgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef |\ncg cg fdcagb cbg\nfbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega |\nefabcd cedba gadfec cb\naecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga |\ngecf egdcabf bgf bfgea\nfgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf |\ngebdcfa ecba ca fadegcb\ndbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf |\ncefg dcbef fcge gbcadfe\nbdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd |\ned bcgafe cdgba cbgef\negadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg |\ngbdfcae bgc cg cgb\ngcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc |\nfgae cfgab fg bagce\n\nBecause the digits 1, 4, 7, and 8 each use a unique number of segments, you should be able to tell which combinations of signals correspond to those digits. Counting only digits in the output values (the part after | on each line), in the above example, there are 26 instances of digits that use a unique number of segments (highlighted above).\n\nIn the output values, how many times do digits 1, 4, 7, or 8 appear?\n\n--- Part Two ---\n\nThrough a little deduction, you should now be able to determine the remaining digits. Consider again the first example above:\n\nacedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |\ncdfeb fcadb cdfeb cdbaf\n\nAfter some careful analysis, the mapping between signal wires and segments only make sense in the following configuration:\n\n dddd\ne    a\ne    a\n ffff\ng    b\ng    b\n cccc\n\nSo, the unique signal patterns would correspond to the following digits:\n\n    acedgfb: 8\n    cdfbe: 5\n    gcdfa: 2\n    fbcad: 3\n    dab: 7\n    cefabd: 9\n    cdfgeb: 6\n    eafb: 4\n    cagedb: 0\n    ab: 1\n\nThen, the four digits of the output value can be decoded:\n\n    cdfeb: 5\n    fcadb: 3\n    cdfeb: 5\n    cdbaf: 3\n\nTherefore, the output value for this entry is 5353.\n\nFollowing this same process for each entry in the second, larger example above, the output value of each entry can be determined:\n\n    fdgacbe cefdb cefbgd gcbe: 8394\n    fcgedb cgb dgebacf gc: 9781\n    cg cg fdcagb cbg: 1197\n    efabcd cedba gadfec cb: 9361\n    gecf egdcabf bgf bfgea: 4873\n    gebdcfa ecba ca fadegcb: 8418\n    cefg dcbef fcge gbcadfe: 4548\n    ed bcgafe cdgba cbgef: 1625\n    gbdfcae bgc cg cgb: 8717\n    fgae cfgab fg bagce: 4315\n\nAdding all of the output values in this larger example produces 61229.\n\nFor each entry, determine all of the wire/segment connections and decode the four-digit output values. What do you get if you add up all of the output values?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_09.adb",
    "content": "--  Solution to Advent of Code 2021, Day 9\n------------------------------------------\n--  Smoke Basin\n--\n--  First 2021 puzzle with recursion :-)\n--\n--  https://adventofcode.com/2021/day/9\n--  Copy of questions in: aoc_2021_09_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_09 is\n  use HAT;\n  --\n  input : constant VString := +\"aoc_2021_09.txt\";\n  sx : constant := 100;\n  sy : constant := 100;\n  --\n  c : Character;\n  f : File_Type;\n  r : array (1 .. 2) of Integer;\n  map : array (1 .. sx, 1 .. sy) of Natural;\n  seen : array (1 .. sx, 1 .. sy) of Boolean;\n  size, la1, la2, la3 : Natural := 0;\n  --\n  --  `Visit` returns the size of the basin around point (x, y).\n  --  Side effect: it writes in `seen`.\n  --\n  function Visit (x, y : Integer) return Natural is\n  begin\n    if x < 1 or else x > sx or else y < 1 or else y > sy or else seen (x, y) then\n      return 0;\n    end if;\n    seen (x, y) := True;\n    if map (x, y) = 9 then\n      return 0;\n    end if;\n    return 1 + Visit (x - 1, y) + Visit (x + 1, y) + Visit (x, y - 1) + Visit (x, y + 1);\n  end Visit;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  Open (f, input);\n  for y in 1 .. sy loop\n    for x in 1 .. sx loop\n      Get (f, c);\n      map (x, y) := Ord (c) - Ord ('0');\n      seen (x, y) := False;\n    end loop;\n  end loop;\n  Close (f);\n  r (1) := 0;\n  for y in 1 .. sy loop\n    for x in 1 .. sx loop\n      if (x = 1  or else map (x - 1, y) > map (x, y)) and then\n         (y = 1  or else map (x, y - 1) > map (x, y)) and then\n         (x = sx or else map (x + 1, y) > map (x, y)) and then\n         (y = sy or else map (x, y + 1) > map (x, y))\n      then\n        --  We have found a low point - a location (x, y) that is\n        --  lower than any of its adjacent locations.\n        r (1) := r (1) + map (x, y) + 1;\n        size := Visit (x, y);\n        if size > la1 then\n          la3 := la2;\n          la2 := la1;\n          la1 := size;\n        elsif size > la2 then\n          la3 := la2;\n          la2 := size;\n        elsif size > la3 then\n          la3 := size;\n        end if;\n      end if;\n    end loop;\n  end loop;\n  r (2) := la1 * la2 * la3;\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: number of low points: \" & r (1));\n    Put_Line (+\"Part 2: product of the sizes of the 3 largest basins: \" & r (2));\n    --  Part 1: validated by AoC: 423\n    --  Part 2: validated by AoC: 1198704\n  end if;\nend AoC_2021_09;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_09.txt",
    "content": "9656799999432123456997667932987634348988901234569972123973212398999898743234578999878965345989412345\n8746789898543235689879457891396521236567892347698763299865101987898789652123459998767893239874323458\n7657896797654348798968346799987430123456943458987654987654219876747688943435698967656789098765434567\n8767945698967859987653235678976521234567894569998785698765345965434567894566987654345678999886548698\n9878936989898967998842123799988432345678965679989976789876459876123998999879876543234567999998657789\n9989759876789899987651012989999654676789896899877899893987898765017899997989977532123456789879767899\n9899898765698789998763123467898765699998789998766568932998989854146789876598765431012345678969878989\n9787987974545698999873234578989876987899678987653456949899876543235678995439876532123478989654989678\n7656896653432367897654348989678989876996589978321239898787987665366789989321987543234569996543294569\n6542985432101256789865457892569998765989439865430149764656798878457899878910197655345699965432123468\n7699876543232345699978767893478998654879921996521398943245679987678978567891298876758789899543234589\n9989989854345467789989898976569999743467892987432987852134789998789765456789469987899898798954387678\n8978998765676778990195999989678987654568909876549896721012878979999879345899878998963934567895698789\n7867999876789989321234989999889998987678912987898765432124568965345998976901989029652123458986789899\n6756889987899995435345678901999989598789329898969976543234567891299987899893499198743239567899899989\n5345678998969876568856789899539976439899498789458987654545678910988956789789598999874358678989999878\n3245588999654987678767898788998765323978987672387898765677989899877545695679987898765456789679878567\n2133457899865698789898987657897654312369876521256789898788996789765421234989996799976768994598765456\n1012345678976789897979998546789762101459985432345698969899345678973210199898765689989879323987654345\n2123456789998899976567899434998979299998976543456987654901236789894391985795454767898989212398943234\n3234567896789999875478996524567898987897897654567898783212345898765989674889323656987898901999892123\n4365788945678998983239987678978987645656789765799969999476556969879876563479312345896567899898789012\n5458899656789987899945699899989996534345679879893459878987768956989995412458923456789456998787678923\n6867898767999876767896789954399897621236989997992398768998878945999989325567894567992368987654589434\n9878939878999765456789899876998765432347895456789987657899999656789878934678985688954979998543678945\n8989921989998754345678912999879876749456954397990198845679998769898969895989876999769899876452345796\n7797890999989643234678993987764989898987895989891987932348999878987658789999987894998789985321234589\n6646789899878932123456789896653299987898939876799876541256896989876545678999898923987679876542345678\n5437898768967893236589898765432129876999329865789987652367955798767534567898769219876565987643456789\n6545698657657789345679989654321098765695409784679898783458944987654323456789954329765434598754767893\n8656798743245678956799878979434998654989598643566799854769432198765412577899895498979123799865698912\n9778999894657889767898767898749876543878969432345689965878945987654323989976789987898945678977899101\n9889899985769999878987656797657998652569654321298999876989656798768734896565699876787896789988956912\n3998769876778954989898545679769876543478998910187892987998969989899656789454598765576997895699349893\n2987645987889643498765434568978997655599987651456891098987898778949767895323459874445689934569298789\n1985432398995721239897655678989999876789299732345993129986889654339878944413569763234796545678997689\n9876543569954310398989767899199896989892196545456789298765678943210989432102698752125689698789976567\n0987654567899451987679878954398765496989987656769899987654567894321296563213987643014578999898965456\n1398875698998969876556989995459654345678998767898999874323476989432987674345987532123567899987894345\n2989976789997898765443293989598743233459899898997898765212345678943498789456896543234598909876743234\n9878989899876739874321012378987654102398799989875689654323466789994989898967997654345689412985432123\n8767899956965323965632323569876543212399678976554678995567587999989878987898998765467897329876741012\n7656789345953219876745456789987656323987567895443456789878678999876567896999019876569976535987899124\n2345698999894923987896567896798767434598978987321234998989789998765458345892123987698998976899998934\n1235987986789894998987878965439898765989989876510127897699898999854341237789239998987899989998987895\n0129876545656789879598989896910999879876599765431456789534967898765210125678998999876787899987656989\n9234995434345678965439196789891299989987678976542345678923456789874321434567897998765476799876545678\n8945986325234799654321015798789989996598789989753658789212369892986476545698956899656365689995434569\n7897995410125679965432123987678678965439894198764767994349498943996589656789346798743234578989323478\n6789894323234567897693939876584589896520943299875879765598967899898698767893234989654125689873212369\n5556789654356789998989899965423456789699954987976989876987656987769789978932129876543236798764201256\n4345679965678893459876799854312345678987899876598991987976549876549890989543234989654345899854342345\n1234567896789902398765689763201456899876798765439790999885434985432991299954345698769656789996456976\n0145698919893212398764568954342567979985459886545699898766323976421289989895456799898767996987567987\n1256789323994323459873487895656878967894398987676789797652109876534569876789567989989878945698878998\n2345678999689934598932456976789989656789997699887897679843212987675698765678979878878989234589989129\n3476789987567896987541237897895798787999896543999989498765323498789988654568998765767896545678999099\n4587899976434679876532698998954679898998798432365679339865454679899876543678999544254898656789998978\n7698999874323567998643459999543569999987654321234890123976565678989987654567898432123789767999987867\n8789998765213898989654589987656998798798943210126789234597698789678998775689987521035678978999976756\n9899987654345799879867678999899899677679854322287898949989989893459789987793298643146789989998865545\n7998998785956789769878789934987766543598765643398967898765678932545679999894389743287894393987654334\n5387899899897893456989897823496543432349876754679456987654567891234567894976569654398993212398710123\n4286789998789954567896945312987932101345989867989347898943498992345698943987698795456789101239853234\n3045789987698995778965432109899893232346899978993212349874679989456789932198999987567893234345954345\n2134569865567989899879844398786789345456789989654324498765899978987896891099998998678954545467977656\n3245698654456778999997656979645678959867898998995455569876998767898945692989987998789765656579998797\n9959987843345569998989869868734567893978987687789569699989998756789434989876576899890998767898989898\n7898765432123498987879998759823678991989876545678978789990987645678959878789445778921239898997778999\n6989887753012397976867897642102899989998765434567899999892998534589998764621234567899399999876567895\n5878999864129986545456789543234999878999543212678959898789876523569987653210123456998989998765456894\n4569459954298865434345897676349898767987654104588969765698765434678998767821234767897778999987567893\n3679598765987654321237898765498789656898983223467899878789897645678959898532345678976569896598678912\n2998999879876543210136789877897676545789765434689999989895998656789544999643658789785458789439789323\n9887891989987984334545678989987543235678978585693298793934569877894323498754769897654345678929899654\n5776790994098875455676789796798763124569987678789109652123488989994212349865878989643234589214978969\n4665689873129986566788997654569653023678998789893298743456567895789109456976989878510145679323469998\n3534999865434597679899679932398762124589209899984349654567789964899298967987898764321234578934678987\n2329898986597698789934567891987643236799919959875498765689891095998987998998949865986465678958789976\n1019767899989999892123458910399754568899898945986789898789999989987876989219439877896568789769899895\n2398756798978899975234567891239865678938767996797899999891298777896865878901921998989679899878998794\n4987645987659798764356789932445978789324456789898989899930987656985434767899890129878989999989987643\n9865434596545679875678899945566989893212345999999876789321986549876323457895791298967899998799875432\n8754322987634789986789999896678997932101969899898765895439997998765412568934942987856789897698764321\n7652101298945678997998988789789236893399898789799654976998998987654324569929899876545476789539875210\n8743212349896789999887875678990145994988789677678967899876799398767434567898789986434365689123986929\n9854529498789899898766434567891956789876643534567898998765989219976565678987678954321234678934999898\n8765698987678998789654323458999897899985432423458999989854978901987676789997569854210176789549898787\n9876987976589989698767454567898789989894321012567899876543467892398787899986498769321289998798766656\n3989876645459876569878765698923678976789463123478999965432456799459898979876359998434799999897655545\n2198765432398965456989876789434569765699954354589789654321347988998959567965219876545678988976543234\n1099876541987654367896987898765678954578895455696599796542459977796543459894323987957989477895432123\n2989987650199763212345698929987789543456789566789678989763598765689921298765434599768995356789921012\n9879998753298654523456999019898897652569899678899789979878689874577890349876545699879654247698892123\n8768999865349767684567899998769976543478998789979899869989789843456789456987656789989543123456789434\n7656899965459888785678999896658987654567899894567988758899899652345678987898767896798762012348996545\n4645788987567999898789998765347998765678987943459876546789998761234569999979898945679843234459987676\n3434567987678932949899987643246899876799986212345986323499869810123478934567999637789954345678998789\n2123456798889431234989998432143456989897695401234595434987654321234599123456798548898765456789239892\n3012348999995432345678999543012345699976543212345976545698975432346789245678987656789876797890123921\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_09_questions.txt",
    "content": "--- Day 9: Smoke Basin ---\n\nThese caves seem to be lava tubes. Parts are even still volcanically active; small hydrothermal vents release smoke into the caves that slowly settles like rain.\n\nIf you can model how the smoke flows through the caves, you might be able to avoid it and be that much safer. The submarine generates a heightmap of the floor of the nearby caves for you (your puzzle input).\n\nSmoke flows to the lowest point of the area it's in. For example, consider the following heightmap:\n\n2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n\nEach number corresponds to the height of a particular location, where 9 is the highest and 0 is the lowest a location can be.\n\nYour first goal is to find the low points - the locations that are lower than any of its adjacent locations. Most locations have four adjacent locations (up, down, left, and right); locations on the edge or corner of the map have three or two adjacent locations, respectively. (Diagonal locations do not count as adjacent.)\n\nIn the above example, there are four low points, all highlighted: two are in the first row (a 1 and a 0), one is in the third row (a 5), and one is in the bottom row (also a 5). All other locations on the heightmap have some lower adjacent location, and so are not low points.\n\nThe risk level of a low point is 1 plus its height. In the above example, the risk levels of the low points are 2, 1, 6, and 6. The sum of the risk levels of all low points in the heightmap is therefore 15.\n\nFind all of the low points on your heightmap. What is the sum of the risk levels of all low points on your heightmap?\n\n--- Part Two ---\n\nNext, you need to find the largest basins so you know what areas are most important to avoid.\n\nA basin is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height 9 do not count as being in any basin, and all other locations will always be part of exactly one basin.\n\nThe size of a basin is the number of locations within the basin, including the low point. The example above has four basins.\n\nThe top-left basin, size 3:\n\n2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n\nThe top-right basin, size 9:\n\n2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n\nThe middle basin, size 14:\n\n2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n\nThe bottom-right basin, size 9:\n\n2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n\nFind the three largest basins and multiply their sizes together. In the above example, this is 9 * 14 * 9 = 1134.\n\nWhat do you get if you multiply together the sizes of the three largest basins?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_10.adb",
    "content": "--  Solution to Advent of Code 2021, Day 10\n-------------------------------------------\n--  Syntax Scoring\n--\n--  https://adventofcode.com/2021/day/10\n--  Copy of questions in: aoc_2021_10_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_10 is\n  use HAT, Interfaces;\n  --\n  input : constant VString := +\"aoc_2021_10.txt\";\n  --\n  stack : String (1 .. 200);\n  top : Natural;\n  --\n  procedure Push (c : Character) is\n  begin\n    top := top + 1;\n    stack (top) := c;\n  end Push;\n  --\n  function Pop_OK (c : Character) return Boolean is\n  begin\n    if top = 0 then\n      return False;\n    end if;\n    top := top - 1;\n    return stack (top + 1) = c;\n  end Pop_OK;\n  --\n  scores : array (1 .. 100) of Integer_64;\n  top_score_array : Natural := 0;\n  ins : Natural;\n  line_score : Integer_64 := 0;\n  f : File_Type;\n  c : Character;\n  points : Integer_64;\n  r : array (1 .. 2) of Integer_64;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\nbegin\n  r (1) := 0;\n  r (2) := 0;\n  scores (1) := 1;  --  Just for calming down a GNAT warning.\n  Open (f, input);\n  while not End_Of_File (f) loop\n    --  Analyse a line's syntax:\n    top := 0;\n    loop\n      Get (f, c);\n      case c is\n        when '(' => Push (')');\n        when '[' => Push (']');\n        when '{' => Push ('}');\n        when '<' => Push ('>');\n        when ')' | ']' | '}' | '>' =>\n          if not Pop_OK (c) then  --  Incorrect closing character.\n            case c is\n              when ')' => points := 3;\n              when ']' => points := 57;\n              when '}' => points := 1197;\n              when '>' => points := 25137;\n              when others => null;\n            end case;\n            r (1) := r (1) + points;\n            Skip_Line (f);  --  We count only the first error of a line.\n            exit;\n          end if;\n        when others => null;\n      end case;\n      if End_Of_Line (f) then\n        if top > 0 then --  Incomplete line\n          line_score := 0;\n          for i in reverse 1 .. top loop\n            line_score := line_score * 5;\n            case stack (i) is\n              when ')' => points := 1;\n              when ']' => points := 2;\n              when '}' => points := 3;\n              when '>' => points := 4;\n              when others => null;\n            end case;\n            line_score := line_score + points;\n          end loop;\n          ins := 0;\n          for i in reverse 1 .. top_score_array loop\n            if line_score <= scores (i) then\n              ins := i;\n            end if;\n          end loop;\n          if ins = 0 then\n            scores (top_score_array + 1) := line_score;\n          else\n            for i in reverse ins .. top_score_array loop\n              scores (i + 1) := scores (i);\n            end loop;\n            scores (ins) := line_score;\n          end if;\n          top_score_array := top_score_array + 1;\n        end if;\n        exit;\n      end if;\n    end loop;\n  end loop;\n  r (2) := scores (top_score_array / 2 + 1);\n  --  ^ \"There will always be an odd number of scores to consider.\"\n  Close (f);\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: invalid closing delimiter points:\" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2: autocomplete points:             \" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 388713\n    --  Part 2: validated by AoC: 3539961434\n  end if;\nend AoC_2021_10;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_10.txt",
    "content": "(({(({{<{{(<{<{}()>(<>{})}{[(){}]{{}[]}}>)<[{{{}[]}{{}{}}}{{[]()}<[][]>}]>}}(<[{([()<>][[]<>])}(((\n([<[([<{(<[[[<()[]>[()()]]<[<>()]<[][]>>]](({({}{})}{<[]<>><[]()>})[<<[]<>>([]())>{<<>{}><<><>>}])><{<{(\n[([(([<<<{(<([()()]{{}{}}){({}[])[()[]]}>({(<>()){{}{}}}<<[]{}>[<>()]>)>}[([<({}[]){{}{}}>])[<<<\n([[{{([<<<<({(<>{}){[]{}}]<({}{})[[]()]>)((([]())(()[])){[()[]]{()<>}})>{[<(<>[])>{[()<>]{()[]}}]({(<><>)[[\n{<({[(({((({((<>())([]()))}[{{[]()}{()()}}(<<><>>(<>{}))])))}<<((([[<>{}][<><>]](<{}()>[{}}))<\n({{<({<{<{{[<{{}<>}[<>()]>[<()<>><[]()>]]}(([{{}<>}{(){}}][(()<>){<><>}])(({{}()})[{[]{}}]))}>}\n(<[[[<[<{{([{(()()){[]{})}{[[][]][<>[]]}][{({}[])}[<<>[]>]])}}({(<(<(){}>{()[]}){[()[]]{{}\n[<[[({([(<[{<({}())[[]()]>{<()<>>[(){}]}}]>)]<<{(<<<<>><{}>>([{}()][{}<>])>[[{<>}<{}()>][{()[]}]])}>>\n[{(<{{([(<[<{(<>[]){{}()}}>(<({}<>)[{}{}]>{{<><>}[<>{}]})]{[{{{}()}<()()>}]{([()[]])[(<>())<()[]\n<[[<<<{({[<{(<[][]><{}<>>)[([]<>)[[][]]]}[{[<>[]]}((<>()){()<>})]>{[(<()()>{{}()})<[{}[]]{\n{[{(([<([[{[(({}<>){<>[]})([[][]](<>[]))]{{[[]{}]}}}]<{(<[()<>]<{}()]>{<[]()>[()[]]})<(<()<>>[[][]]\n{<<<{<{({[[({<<>{}>[<>]})<[<<>[]><[]<>>][[<>{}]({}{})]>]][{[([[][]][[]()])]([[()()]{[]<>}])}<[({[]<>}\n([<(<<{<<((<<({}())[{}<>]>{<[][]>{{}()}}>(<<<>()>(()[])>))<<{[<>()](<>())}<([][])[()()]>>>\n<<(<[{[<{(<<{<[][]>[<>[]]}<(<>{})([][])>>>)<<[{[()()][[]{}]}<[()[]]<[][]>>]>{<{<[]<>>{<>()}}[<()()>[<>()\n<(({({{{(([({<<><>>{[]<>}}({()[]}([]{}))}[{<()[]><[][]>}<{[]{}}{[]()}>]]<<<[(){}]{(){}}>{{(\n[{[[{<<{<{<<([()()]{[]()})[[[][]]<[][]>]>>}>(<{(([[]()][[]()])[({}<>){<>}]){([{}[]]){[{}[]>[[]{}\n({[[{<[({[{({{{}[]}[<>[]]}{({}()){{}}})[({<>[]}{[]()}){{(){}}[[]{}]}]}](([[[()<>](<>[])]<<\n[(<{{[<{<{(<{({}[])<()>}><<<<><>><()()>>>)[{[{{}[]}({}[])]<(()[])({})>][{<<><>>}[({}[])<<>\n(<({[<<[<(<<<<()()><{}{}>>([{}<>]}>[({{}<>}[()<>])(({}[])[[]()])]>{{<{{}[]}(<>())>[[(){}]<\n<<{(<({{[{<[(([]<>)<[]{}>)(<<>{}><[]()>)]{{[{}[]]<(){}>}(<{}<>>(()()))}>(<<({})(<>[])>><{{[]<>}(<\n<(<({[<[[<({[[{}{}][[]<>]}[<<>{}>(()[])]}<{{()[]}}[[<>[]]<[]()>]>)<[(([][])<[]()>)(<()[]>)]\n({[<(({[{((((<<>[]>(<>()))<(()[])>)<<({}{})<<><>>>>)[[[<(){}>(<><>)]([(){}][{}()])]])[((<((\n({[{[([{[[<[((<>())[<>()])]({{(){}}{()()}}([(){}]<<>[]>))>]][[<[<[{}<>]<(){}>>({[]()}<{}[]>)]((<()()>(\n<{[{(<{<({[<<(<>{})((){})>(({}<>)[{}{}])><[[<>[]]<(){}>]<(<>[])<{}{}>>>]{{([{}[]])<<()[]>>}\n[{[[(([(<[[{<{()[]}([]<>)><<[]()>[<>()]>}]<([<()<>>{<>()}][(()<>){{}{}}])>]<{{[{[][]}(())]}(\n<<(<<[(([({<{(())}([{}[]](<>[]))]<<<()<>><[]{}>>[<[][]>{{}<>}]>}[[{[[]()]}({()()}{[]})]<(<\n({(<<<<[({{<<{<>{}}({}())>({()<>}[()<>])>{{{()<>}(()[])}(<[]<>>(()<>))}}(<<[{}]((){})><({}[\n({[(<<[<[(<[<(()<>)>{(()())({}[])}>[{{[]<>}[{}{}]}({[]()}[<>[]])]>)]({[<[{[]<>}[{}()]][[[]<>]<<>>]\n{(<{<{[({({[<[[]<>][()[]]>{({}()){<><>}}]{([[]()]({}{}))[<<><>>{{}{}}]}}){{(<([]{})>({<>[]}<[][]>))}\n<{([{{([{[[{{(()[])<{}[]>}}{{{()()}<<><>>}}][{{[[][]]{[][]}}}]]}])}{([[<(<<<<>[]>([]{})>>({<{}()>[[]()]>([[][\n[{(<{[[{((<{<[[][]][[]<>]>[(()())[(){}]]}{{{{}[]}[(){}]}(<()[]>{[]()})}>({((()()}){({}[])([]{})}})))\n{{((<({[({{{({<>{}}<[]{}>)[{{}()}{<>[]}]}<[({}[])<<>>]>}}(<<({[]<>}([][]))(<[]()><{}[]>)>{<({}[]){{}{\n[<(<[{<({[(([[[]][[]<>]][[<><>]{[]()}])[{({}{}){<>{}}}<{()<>}{{}{}}>])](<[({<>{}}([]()))][[<{}<>>([]())]((\n<([[<(({{([{[{<>}([]())][{()()}(<>()))}[([<><>]{<>[]})(([]{}){{}()})]](<(([]<>)([]{}))[(<>())]>))\n{{{[{[(<((<([{{}{}}[[][]]](([])))])){[<<[<[]()>[<><>]]>>{{<[[][]][{}<>]>[<[]<>>{[]()}]}[[([]()\n<<([({({{[{[<(()[])><([]<>){<>{}}>]<[(<>[])<{}()>]>}]}<<<[{([][])((){})}(<{}<>>{()[]})][({[][]}{[]{}})]><[(\n[[((([([[{<([(()()){{}<>}]<([]<>){[]{}}>)[(<{}{}>[{}<>])(<{}{}>[()[]])]><[({{}[]})[[<>()][{}[]]]]{<<()[]\n<<<{(([{[<({{({}{})(<><>)}({{}()})}{<<()><(){}>>[{<>{}][()<>]]}){(<<{}[]>[<><>]>({[]()}<{}{}>)){{{<>}{[]<\n([[{{<{<{[<{([()()]<<>[]>)[[()<>](()<>)]}>[<({()<>}(()))<{[]{}}{{}{}}>>(([(){}]<()()>)<<()()>(<><>)>)]](({\n((<<[<([{<([<<()()>{[]<>}>[<{}[]>([])]][([<>()]{()[]})])><((<<<><>>{<><>}}([{}()][()<>])){[{[]}]\n[<{(({{[{<[[{[<>()]}[[()()]({}[])]]<[({}<>)(<>{})]<(<>{})[{}<>]>>]<<(([]())<{}()>)(<[][]>(()[]))>>>((\n<[<[[([<(<({{[()]<<>>}([<>[]][{}()])}([<[]{}><{}()>][<<>{}){<>()}]))>[<[[<()[]><()[]>][[<>\n{[[[{<[{[{[[[(<>()){[]}]{[{}()]}]{[<()<>><<><>>]({<>()}{[]()})}]}]<[{(<<()()><[]()>>(<{}<>>{(){}}))([{{}}][[\n<([([([{<[[{{<{}()>{[]()}}}<((<><>){[]()}>>]{[[[{}[]]({}<>)]<((){})>]{(<()<>>(()<>))([<>]<{}<\n[({<[[{[({<{((<>{})<{}[]>)[<[]()>([]<>)]}>}<{<<<[][]>[{}{}]>>([<(){}><{}[]>])}<<<<<><>>{{}<>>>{[<>\n{<{{<([{([{<[(<>())<{}[]>]({<>[]})>[[(()()){<>{}}]{{<><>}(()[])}]}{([(<>)(()[])])(({<>{}}<[]<>))([\n[<{(<<<{{{([{[[][]]{()()}}<[[][]](()())>][(<{}[]>({}[]))]){({<(){}>(<>())}<{(){}}{[]{}}>){<(()())[(){}]>({{}(\n{<<[<[{([[<{<(<>){<>{}}>{({}())(<>{})}}<(([][]))>><{{[[]<>][[]()]}[<<>()><(){}>]}>]])}[{([((<((){\n([(({<[[((<([([]())[[][]]][{<>{}}<(){}>]]><<(<(){}>[[]()])([[][]][()()])><[{()()}<<>{}>]>>)){\n[{(<<<{((<<({[()[]]<{}()>}{<<>{}>{<>[]}})((<{}[]>[()<>])<<<>[]>[<>[]]>)><<<[(){}]>{<()[]>{(){}}}>([<<><>>{{\n{([({[[<({{([(<>{})<[]<>>])[[<{}><<>{}>]]}{([<[]()>[{}<>]]<([]{})>)})<({{[{}[]]{<><>}}{[[]{}]<<>{}>}}\n[[[((<[([({({<<>{}>[<><>]}){{(()<>)<[]()>}<{{}[]}({}())>}})[((({<><>})({[][]}(()())))<[{{}{}}{()\n<<[([(({<<[[[<[]<>>]]<((<><>)[{}[]])>][([<<>{}>{[][]}]{{()()}[[]()]>){(([]<>)([][])){(<><>)}}]>{[{\n<([[(<{{{{({<{{}{}}(()())>[[[]()]{()<>}]}[[{[]()}{()()}>])}}<[<{[(()<>)(()())][(()())]}({<()<>>(<>{}\n[{{[<(<{(<<<({{}()}<<>()>)([[]()]{()[]})>(({{}<>}[<>{}])([(){}]{()<>}))>[[(<[]{}>(<><>))[<[]\n{{{[{<{[<<{{{{()<>}{(){}}}}<([{}<>][{}{}])<<{}<>>{()[]}>>}{[<<<>>[()<>]>]([[{}()](<>{})]{{[][]}{(){}}})\n[[[{<({{(<([(<()()>({}()))])>)<<(<[(()())]{(<>())[<>[]]}><<{(){}}<{}<>>>[{[]()}(<>{})]>)([{([]<>)([][\n(({[(({{[{({[(())<(){}>]})<{<<{}{}](()<>)>({[]{}}((){}))}({<[]()>[[]<>]}{<{}[]>[[]{}]})>}][{<\n[<{<[[[<(({[[(<>())]<{<>[]}(<><>)>]}[<{<()<>>}><[{()[]}(<>[])]{{<>()}[{}<>]}]])<[<({{}[]}(<><\n[(<{{[{{([({{[{}()]<()()>}{[()()]{<>[]}}}(<<()>(<>{})>))]<([(<[]>[[]<>])([{}](<>()])])<{<<[]{}>(<>\n[[{{([<([{{([{[]{}}<()[]>]{<(){}>([][])})}<<{{<><>}[()]}{<<>{}>{<>}}>([(<>{})<<>[]>]{{<><>}{<>()}})>}\n<[{([<{<[<(<{{<><>}[{}<>]}<<{}[]><[][]>>>{({()()}{<>[]})<<[]{}>[{}[]]>})<<[({}<>)]>(({{}()})(((){}]))>>\n{[[<(([<[<<<<[[]()]{()<>>>{({}())<[]{}>}>[({<>{}}(<>[]))((()[])[()])]>>{[[[({})]{(()())[<>()]}]]{<{<()(\n<([({[[([[{{<[{}[]](<>)><{()()}[[]{}]>}<<({}{})({}{})><<(){}><<>[]>>>}[{{([][])(<>{})}[<<>[]><{}{}>]}[<[\n((<<<[<[(<<[[({}<>)<[]>][[(){}]<<>()>]]{<[()()]<()<>>>{{<>()}((){})}}>[({<<>[]>{()()}))(({[]()}{()[]}\n[(({{<[([{[[({(){}}{()[]}){([]{})([]{})}][{{<>()}<{}{}>}]]({{[<>[]]}(<{}[]><{}()>)}(({()()}((\n<[<<{<({<{<<[(()())[()[]]]]<({{}{}}[[]<>])>>[([<(){}><{}<>>]<<[]()>(<><>)>)[[(()[]){{}()}]{(\n<{[<({(<({<[[(()[])][<()()>({}())]](<{[]()}[{}[]]>({(){}}{()[]}))>}[<{<<<><>>[(){}]>{<()<>>{<>[]}}}>[<{\n{{{<({{(<({{[[<>()]<<>[]>]{<<><>>([]<>)}}}({<<<><>>{[]<>}><(<>()>([][])>}))>([<{[{{}()}[[][]]]<{<>[]}<[]<>>>\n{{(([{[[([([{<[]()>{[]{}}}(<()[]><[][]>>]({{(){}}[[][]]}[[<>]{<>()}]))])]]}])[[[([<[[[<[[]<>]<(\n[<(<{{<((([(([()[]]<{}>)<[<><>][{}()]>)<([[]()])>](<{((){})((){})}{([]<>)<<>[]>}){[([]())](({}[]){()\n<({[<(<(({[([<{}()><(){}>]([<>][()()]))(<[()[]]><[()[]]({}{})>)]{(<(<>{})[{}<>]><{{}{}}{[]()}>)\n{<<[<{[[[([<{{[][]}[[]()]}<[[][]][<>{}]>>]){{[<<()()>(()[])][[<>()]{<>()}]]((<<><>><{}()>)[{{\n{{<([{[[<(<{{{{}[]}{<><>}}}((<{}>))>[(<(()[]){<>{}}>((()())[<>]))])>]]}[{[{((([<(){}>({}[])][<(\n<[[((([{[[<<[{<>[])[{}[]]]>>(<[{[][]}<{}<>>][[()<>][[][]]]>([([]<>)({}())](<{}()>{()<>})))]<\n({<{<[{(((<(<(()[]){[][]}>[<()<>>[<>()]])(<{{}{}}(<>{})>)>[(({(){}}{()()])[{{}{}}[<>{}]])])\n({{((<([(({([[<>()][{}{}]]<(<>)(())>}}{<([<>()]{[]})([<>{}](<>[]))><({[]()}(<>[])){([][])[<>[]]}>})[{\n([{[<(({(<<<<<[]<>>{[]{}}><((){}){<>()}>>([[()[]][<>{}]]([[][]][()<>]))>><<[([()()]{<><>}){<{}<>>{<><\n[{({<{<{({(({[[]()]([][])}{{{}()}([][]>}){<({}<>)[<>()]>[[()<>]<<>>]})[(<<()()>{[][]}><[<>(\n{[[<({<<<<<{[[{}{}](()())]<([][]){<><>}>}>{<[[<>()]<[]>][{<>{}}({}[])]>}>[{{{[()<>][<>{}]}}}[[[({\n[<(<(<{<<{{{(<()[]>{{}})}}<[[{[]{}}([]{})][(<><>)[[]()]]]{<{<>[]}(<><>)>[({})(<>[])]}>}[(([[{}{}][\n(([([[<<[[(<({()<>}{()<>})<([]<>)(<>[])>>[{<{}[]>{[]()}}])[<<([][])<[]()>>[{{}()>{{}{}}]>]]][[<<(([]<>)\n[([[{([{[{{<(<<>()>)(<[]()><<>{}>)>><<(<[]()>([][])){<<><>><{}[]>}>([[<><>]{{}()}]<{[]()}>)>}<({([()\n([[([{<{([<<<(()())[{}()]>([{}<>](()[]))>({<{}[]><<>[]>}{([]<>)({}())})>[(<<{}()><<>()>>[[<><>]])({[[]()]<{}\n{[{{([(<<([([<[]()>])<{({}<>)({}())}<([]()){[]<>}>>]){((<{[]<>}({}{})>({{}[]}{{}<>}))[({[][\n{{[(<<<({<{[[([]<>){()()}]((<><>)[{}()])]{[(()<>)[{}()]]}}([<<[][]>)[{()<>}<{}{}>]]{{{{}{}}((){})}{[<>\n{(<<[(<<<<{([[[]<>]{(){}}]{{[]()}}){<<()<>>>[{{}{}}<{}<>>]}}>[[{[{<>()}<{}[]>]<{{}[]}>}<(({}[])(<><>)\n<<[(<{[({<<<<{[]{}}<{}[]>>>({{()[]}{()()}}<<{}{}>({}{})>)>>})]{(<((<([[]()][()<>]){((){})<[]\n[[[[{<<[[{<(([{}{}]([]<>))({[]()})}(<{()[]}<{}<>>>{[<>{}]})>({[<{}{}>][<<>{}>(<>)]}[<{[][]}{{}{}}\n{<<[(<((({{{[[<>[]]{<>{}}](({}())({}{}))}<{<(){}>([]<>)}{((){})}]}}{<{{([]())[()]}{<(){}>(<><>)}}[[<<>\n<([[[[[[{<(<[<<><>>{[][]}]>)([([()[]][()()])]([{()[]){()[]}][{[]()}(()<>)]))>[{[({<>()}[{}\n[(({<<<({<{[(<{}{}>{()<>}){{()[]}{[]{}}}]}>})([<<<({<>()}[[]()])>({[{}<>]<[]<>>}(((){})))>>{[[([<><>]([]<\n{{[[({{[({<{[{()<>}([][])]([(){}])}>(<(([]())<()<>>){[[]()]([]())}><<<<>[]>[()<>]>[<[]{}>[<><>]]\n<{({((<{[{[<(<[]{}>(<>{}))>][{{<{}<>}{()<>}}<(<>())<()()>>}[[({}()){[]()}](<<>[]>{[]()})]]}<<{(({}<>\n(<<{{{[{[{((<{()<>}({}<>)>[(()<>)(<><>)]))[[[(<>[])<{}<>>][[[]<>]<{}()>]]<[(<>{})[<>]]>]}]}][(\n((({([[<[([[[[()[]]<{}()>](({}())[()])]<[{(){}}({}())](([]()){{}()})>]<(({<>{}}[[]{}])<<()<>\n{{[(<<([({((([{}<>]{{}[]})([<><>](<>())))[{(()[])[()()]>[(()()){<>[]}]])}<([{[[]()][[]{}]}(\n[<<({{[<<[({((()<>)[<>()]){<{}>[[]<>]}}[<{[]()}(()<>)>])<([<<>{}>[<><>]]<{[]<>}[()<>]>){[{<><>}<<>[]>]{((\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_10_questions.txt",
    "content": "--- Day 10: Syntax Scoring ---\n\nYou ask the submarine to determine the best route out of the deep-sea cave, but it only replies:\n\nSyntax error in navigation subsystem on line: all of them\n\nAll of them?! The damage is worse than you thought. You bring up a copy of the navigation subsystem (your puzzle input).\n\nThe navigation subsystem syntax is made of several lines containing chunks. There are one or more chunks on each line, and chunks contain zero or more other chunks. Adjacent chunks are not separated by any delimiter; if one chunk stops, the next chunk (if any) can immediately start. Every chunk must open and close with one of four legal pairs of matching characters:\n\n    If a chunk opens with (, it must close with ).\n    If a chunk opens with [, it must close with ].\n    If a chunk opens with {, it must close with }.\n    If a chunk opens with <, it must close with >.\n\nSo, () is a legal chunk that contains no other chunks, as is []. More complex but valid chunks include ([]), {()()()}, <([{}])>, [<>({}){}[([])<>]], and even (((((((((()))))))))).\n\nSome lines are incomplete, but others are corrupted. Find and discard the corrupted lines first.\n\nA corrupted line is one where a chunk closes with the wrong character - that is, where the characters it opens and closes with do not form one of the four legal pairs listed above.\n\nExamples of corrupted chunks include (], {()()()>, (((()))}, and <([]){()}[{}]). Such a chunk can appear anywhere within a line, and its presence causes the whole line to be considered corrupted.\n\nFor example, consider the following navigation subsystem:\n\n[({(<(())[]>[[{[]{<()<>>\n[(()[<>])]({[<{<<[]>>(\n{([(<{}[<>[]}>{[]{[(<()>\n(((({<>}<{<{<>}{[]{[]{}\n[[<[([]))<([[{}[[()]]]\n[{[{({}]{}}([{[{{{}}([]\n{<[[]]>}<{[{[{[]{()[[[]\n[<(<(<(<{}))><([]([]()\n<{([([[(<>()){}]>(<<{{\n<{([{{}}[<[[[<>{}]]]>[]]\n\nSome of the lines aren't corrupted, just incomplete; you can ignore these lines for now. The remaining five lines are corrupted:\n\n    {([(<{}[<>[]}>{[]{[(<()> - Expected ], but found } instead.\n    [[<[([]))<([[{}[[()]]] - Expected ], but found ) instead.\n    [{[{({}]{}}([{[{{{}}([] - Expected ), but found ] instead.\n    [<(<(<(<{}))><([]([]() - Expected >, but found ) instead.\n    <{([([[(<>()){}]>(<<{{ - Expected ], but found > instead.\n\nStop at the first incorrect closing character on each corrupted line.\n\nDid you know that syntax checkers actually have contests to see who can get the high score for syntax errors in a file? It's true! To calculate the syntax error score for a line, take the first illegal character on the line and look it up in the following table:\n\n    ): 3 points.\n    ]: 57 points.\n    }: 1197 points.\n    >: 25137 points.\n\nIn the above example, an illegal ) was found twice (2*3 = 6 points), an illegal ] was found once (57 points), an illegal } was found once (1197 points), and an illegal > was found once (25137 points). So, the total syntax error score for this file is 6+57+1197+25137 = 26397 points!\n\nFind the first illegal character in each corrupted line of the navigation subsystem. What is the total syntax error score for those errors?\n\n--- Part Two ---\n\nNow, discard the corrupted lines. The remaining lines are incomplete.\n\nIncomplete lines don't have any incorrect characters - instead, they're missing some closing characters at the end of the line. To repair the navigation subsystem, you just need to figure out the sequence of closing characters that complete all open chunks in the line.\n\nYou can only use closing characters (), ], }, or >), and you must add them in the correct order so that only legal pairs are formed and all chunks end up closed.\n\nIn the example above, there are five incomplete lines:\n\n    [({(<(())[]>[[{[]{<()<>> - Complete by adding }}]])})].\n    [(()[<>])]({[<{<<[]>>( - Complete by adding )}>]}).\n    (((({<>}<{<{<>}{[]{[]{} - Complete by adding }}>}>)))).\n    {<[[]]>}<{[{[{[]{()[[[] - Complete by adding ]]}}]}]}>.\n    <{([{{}}[<[[[<>{}]]]>[]] - Complete by adding ])}>.\n\nDid you know that autocomplete tools also have contests? It's true! The score is determined by considering the completion string character-by-character. Start with a total score of 0. Then, for each character, multiply the total score by 5 and then increase the total score by the point value given for the character in the following table:\n\n    ): 1 point.\n    ]: 2 points.\n    }: 3 points.\n    >: 4 points.\n\nSo, the last completion string above - ])}> - would be scored as follows:\n\n    Start with a total score of 0.\n    Multiply the total score by 5 to get 0, then add the value of ] (2) to get a new total score of 2.\n    Multiply the total score by 5 to get 10, then add the value of ) (1) to get a new total score of 11.\n    Multiply the total score by 5 to get 55, then add the value of } (3) to get a new total score of 58.\n    Multiply the total score by 5 to get 290, then add the value of > (4) to get a new total score of 294.\n\nThe five lines' completion strings have total scores as follows:\n\n    }}]])})] - 288957 total points.\n    )}>]}) - 5566 total points.\n    }}>}>)))) - 1480781 total points.\n    ]]}}]}]}> - 995444 total points.\n    ])}> - 294 total points.\n\nAutocomplete tools are an odd bunch: the winner is found by sorting all of the scores and then taking the middle score. (There will always be an odd number of scores to consider.) In this example, the middle score is 288957 because there are the same number of scores smaller and larger than it.\n\nFind the completion string for each incomplete line, score the completion strings, and sort the scores. What is the middle score?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_11.adb",
    "content": "--  Solution to Advent of Code 2021, Day 11\n-------------------------------------------\n--  Dumbo Octopus\n--\n--  https://adventofcode.com/2021/day/11\n--  Copy of questions in: aoc_2021_11_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_11 is\n  use HAT;\n  input : constant VString := +\"aoc_2021_11.txt\";\n  sx : constant := 10;\n  sy : constant := 10;\n  map : array (1 .. sx, 1 .. sy) of Natural;\n  flashed : array (1 .. sx, 1 .. sy) of Boolean;\n  --\n  procedure Increase (x, y : Integer) is\n  begin\n    map (x, y) := map (x, y) + 1;\n    if map (x, y) > 9 and then not flashed (x, y) then\n      flashed (x, y) := True;\n      for yy in y - 1 .. y + 1 loop\n        for xx in x - 1 .. x + 1 loop\n          if xx in 1 .. sx and then yy in 1 .. sy and then map (xx, yy) <= 9 then\n            Increase (xx, yy);\n          end if;\n        end loop;\n      end loop;\n    end if;\n  end Increase;\n  --\n  c : Character;\n  step, count : Natural;\n  f : File_Type;\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Open (f, input);\n  for y in 1 .. sy loop\n    for x in 1 .. sx loop\n      Get (f, c);\n      map (x, y) := Ord (c) - Ord ('0');\n    end loop;\n  end loop;\n  Close (f);\n  r (1) := 0;\n  step := 0;\n  loop\n    step := step + 1;\n    for y in 1 .. sy loop\n      for x in 1 .. sx loop\n        flashed (x, y) := False;\n      end loop;\n    end loop;\n    for y in 1 .. sy loop\n      for x in 1 .. sx loop\n        Increase (x, y);\n      end loop;\n    end loop;\n    --\n    count := 0;\n    for y in 1 .. sy loop\n      for x in 1 .. sx loop\n        if map (x, y) > 9 then\n          map (x, y) := 0;\n          count := count + 1;\n        end if;\n      end loop;\n    end loop;\n    if step <= 100 then\n      r (1) := r (1) + count;\n    end if;\n    if count = sx * sy then\n      r (2) := step;\n      exit;\n    end if;\n  end loop;\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: Total flashes in the first 100 steps: \" & r (1));\n    Put_Line (+\"Part 2: First step during which all octopuses flash: \" & r (2));\n    --  Part 1: validated by AoC: 1679\n    --  Part 2: validated by AoC: 519\n  end if;\nend AoC_2021_11;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_11.txt",
    "content": "1553421288\n5255384882\n1224315732\n4258242274\n1658564216\n6872651182\n5775552238\n5622545172\n8766672318\n2178374835\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_11_questions.txt",
    "content": "--- Day 11: Dumbo Octopus ---\n\nYou enter a large cavern full of rare bioluminescent dumbo octopuses! They seem to not like the Christmas lights on your submarine, so you turn them off for now.\n\nThere are 100 octopuses arranged neatly in a 10 by 10 grid. Each octopus slowly gains energy over time and flashes brightly for a moment when its energy is full. Although your lights are off, maybe you could navigate through the cave without disturbing the octopuses if you could predict when the flashes of light will happen.\n\nEach octopus has an energy level - your submarine can remotely measure the energy level of each octopus (your puzzle input). For example:\n\n5483143223\n2745854711\n5264556173\n6141336146\n6357385478\n4167524645\n2176841721\n6882881134\n4846848554\n5283751526\n\nThe energy level of each octopus is a value between 0 and 9. Here, the top-left octopus has an energy level of 5, the bottom-right one has an energy level of 6, and so on.\n\nYou can model the energy levels and flashes of light in steps. During a single step, the following occurs:\n\n    First, the energy level of each octopus increases by 1.\n    Then, any octopus with an energy level greater than 9 flashes. This increases the energy level of all adjacent octopuses by 1, including octopuses that are diagonally adjacent. If this causes an octopus to have an energy level greater than 9, it also flashes. This process continues as long as new octopuses keep having their energy level increased beyond 9. (An octopus can only flash at most once per step.)\n    Finally, any octopus that flashed during this step has its energy level set to 0, as it used all of its energy to flash.\n\nAdjacent flashes can cause an octopus to flash on a step even if it begins that step with very little energy. Consider the middle octopus with 1 energy in this situation:\n\nBefore any steps:\n11111\n19991\n19191\n19991\n11111\n\nAfter step 1:\n34543\n40004\n50005\n40004\n34543\n\nAfter step 2:\n45654\n51115\n61116\n51115\n45654\n\nAn octopus is highlighted when it flashed during the given step.\n\nHere is how the larger example above progresses:\n\nBefore any steps:\n5483143223\n2745854711\n5264556173\n6141336146\n6357385478\n4167524645\n2176841721\n6882881134\n4846848554\n5283751526\n\nAfter step 1:\n6594254334\n3856965822\n6375667284\n7252447257\n7468496589\n5278635756\n3287952832\n7993992245\n5957959665\n6394862637\n\nAfter step 2:\n8807476555\n5089087054\n8597889608\n8485769600\n8700908800\n6600088989\n6800005943\n0000007456\n9000000876\n8700006848\n\nAfter step 3:\n0050900866\n8500800575\n9900000039\n9700000041\n9935080063\n7712300000\n7911250009\n2211130000\n0421125000\n0021119000\n\nAfter step 4:\n2263031977\n0923031697\n0032221150\n0041111163\n0076191174\n0053411122\n0042361120\n5532241122\n1532247211\n1132230211\n\nAfter step 5:\n4484144000\n2044144000\n2253333493\n1152333274\n1187303285\n1164633233\n1153472231\n6643352233\n2643358322\n2243341322\n\nAfter step 6:\n5595255111\n3155255222\n3364444605\n2263444496\n2298414396\n2275744344\n2264583342\n7754463344\n3754469433\n3354452433\n\nAfter step 7:\n6707366222\n4377366333\n4475555827\n3496655709\n3500625609\n3509955566\n3486694453\n8865585555\n4865580644\n4465574644\n\nAfter step 8:\n7818477333\n5488477444\n5697666949\n4608766830\n4734946730\n4740097688\n6900007564\n0000009666\n8000004755\n6800007755\n\nAfter step 9:\n9060000644\n7800000976\n6900000080\n5840000082\n5858000093\n6962400000\n8021250009\n2221130009\n9111128097\n7911119976\n\nAfter step 10:\n0481112976\n0031112009\n0041112504\n0081111406\n0099111306\n0093511233\n0442361130\n5532252350\n0532250600\n0032240000\n\nAfter step 10, there have been a total of 204 flashes. Fast forwarding, here is the same configuration every 10 steps:\n\nAfter step 20:\n3936556452\n5686556806\n4496555690\n4448655580\n4456865570\n5680086577\n7000009896\n0000000344\n6000000364\n4600009543\n\nAfter step 30:\n0643334118\n4253334611\n3374333458\n2225333337\n2229333338\n2276733333\n2754574565\n5544458511\n9444447111\n7944446119\n\nAfter step 40:\n6211111981\n0421111119\n0042111115\n0003111115\n0003111116\n0065611111\n0532351111\n3322234597\n2222222976\n2222222762\n\nAfter step 50:\n9655556447\n4865556805\n4486555690\n4458655580\n4574865570\n5700086566\n6000009887\n8000000533\n6800000633\n5680000538\n\nAfter step 60:\n2533334200\n2743334640\n2264333458\n2225333337\n2225333338\n2287833333\n3854573455\n1854458611\n1175447111\n1115446111\n\nAfter step 70:\n8211111164\n0421111166\n0042111114\n0004211115\n0000211116\n0065611111\n0532351111\n7322235117\n5722223475\n4572222754\n\nAfter step 80:\n1755555697\n5965555609\n4486555680\n4458655580\n4570865570\n5700086566\n7000008666\n0000000990\n0000000800\n0000000000\n\nAfter step 90:\n7433333522\n2643333522\n2264333458\n2226433337\n2222433338\n2287833333\n2854573333\n4854458333\n3387779333\n3333333333\n\nAfter step 100:\n0397666866\n0749766918\n0053976933\n0004297822\n0004229892\n0053222877\n0532222966\n9322228966\n7922286866\n6789998766\n\nAfter 100 steps, there have been a total of 1656 flashes.\n\nGiven the starting energy levels of the dumbo octopuses in your cavern, simulate 100 steps. How many total flashes are there after 100 steps?\n\n--- Part Two ---\n\nIt seems like the individual flashes aren't bright enough to navigate. However, you might have a better option: the flashes seem to be synchronizing!\n\nIn the example above, the first time all octopuses flash simultaneously is step 195:\n\nAfter step 193:\n5877777777\n8877777777\n7777777777\n7777777777\n7777777777\n7777777777\n7777777777\n7777777777\n7777777777\n7777777777\n\nAfter step 194:\n6988888888\n9988888888\n8888888888\n8888888888\n8888888888\n8888888888\n8888888888\n8888888888\n8888888888\n8888888888\n\nAfter step 195:\n0000000000\n0000000000\n0000000000\n0000000000\n0000000000\n0000000000\n0000000000\n0000000000\n0000000000\n0000000000\n\nIf you can calculate the exact moments when the octopuses will all flash simultaneously, you should be able to navigate through the cavern. What is the first step during which all octopuses flash?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_12.adb",
    "content": "--  Solution to Advent of Code 2021, Day 12\n-------------------------------------------\n--  Passage Pathing\n--\n--  https://adventofcode.com/2021/day/12\n--  Copy of questions in: aoc_2021_12_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_12 is\n  use HAT;\n  --\n  dic_max : constant := 30;\n  subtype Dic_Range is Integer range 1 .. dic_max;\n  subtype Segment_Range is Dic_Range;\n  top, segs : Natural := 0;\n  dic : array (Dic_Range) of VString;\n  start_idx, end_idx : Dic_Range;\n  --\n  type Segment is record\n    from : Dic_Range;\n    to   : Dic_Range;\n  end record;\n  --\n  seg : array (Segment_Range) of Segment;\n  small : array (Dic_Range) of Boolean;\n  seen : array (Dic_Range) of Natural;\n  --\n  procedure Read_Data is\n    procedure Check (word : VString; pos : out Dic_Range) is\n    begin\n      for i in 1 .. top loop\n        if dic (i) = word then\n          pos := i;\n          return;\n        end if;\n      end loop;\n      --  Word not yet in dictionary.\n      top := top + 1;\n      dic (top) := word;\n      small (top) := True;\n      seen (top) := 0;\n      for i in 1 .. Length (word) loop\n        small (top) := small (top) and then Element (word, i) in 'a' .. 'z';\n      end loop;\n      pos := top;\n    end Check;\n    --\n    input : constant VString := +\"aoc_2021_12.txt\";\n    --\n    c    : Character;\n    word : VString;\n    f    : File_Type;\n  begin\n    Check (+\"start\", start_idx);\n    Check (+\"end\", end_idx);\n    small (start_idx) := True;\n    seen (start_idx) := 2;  --  This prevents visiting again the \"start\" cave.\n    --\n    Open (f, input);\n    while not End_Of_File (f) loop\n      segs := segs + 1;\n      word := +\"\";\n      loop\n        Get (f, c);\n        exit when c = '-';\n        word := word & c;\n      end loop;\n      Check (word, seg (segs).from);\n      word := +\"\";\n      loop\n        Get (f, c);\n        word := word & c;\n        exit when End_Of_Line (f);\n      end loop;\n      Check (word, seg (segs).to);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  --\n  --  `Visit` has a side effect on `seen` array.\n  --\n  function Visit (cave : Dic_Range; joker : Boolean) return Natural is\n    result : Natural;  --  Number of paths from this cave reaching the end.\n    procedure Test (to : Dic_Range) is\n    begin\n      if small (to) then\n        case seen (to) is\n          when 0 =>\n            result := result + Visit (to, joker);\n          when 1 =>\n            if joker then\n              --  Continue the visit, but joker is discarded.\n              result := result + Visit (to, False);\n            end if;\n          when others =>\n            --  We cannot enter this `to` cave.\n            null;\n        end case;\n      else\n        --  Large cave: no limit!\n        result := result + Visit (to, joker);\n      end if;\n    end Test;\n  begin\n    if cave = end_idx then\n      return 1;\n    end if;\n    seen (cave) := seen (cave) + 1;\n    --  As long as we don't find a way to the end,\n    --  there is no interesting path from that cave:\n    result := 0;\n    for s in 1 .. segs loop\n      --  We can go through a segment many times,\n      --  But small caves have to be visited only once.\n      --  In all the data we've have got (3 examples & input),\n      --  there is no segment between two large caves.\n      --  Such a situation would lead to infinite recursion.\n      if cave = seg (s).from then\n        Test (seg (s).to);\n      elsif cave = seg (s).to then\n        Test (seg (s).from);\n      end if;\n    end loop;\n    seen (cave) := seen (cave) - 1;\n    return result;\n  end Visit;\n\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\nbegin\n  Read_Data;\n  r (1) := Visit (start_idx, False);\n  if not compiler_test_mode then\n    r (2) := Visit (start_idx, True);\n  end if;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: Number of paths (normal rules): \" & r (1));\n    Put_Line (+\"Part 2: Number of paths (special rule): \" & r (2));\n    --  Part 1: validated by AoC: 3497\n    --  Part 2: validated by AoC: 93686\n  end if;\nend AoC_2021_12;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_12.txt",
    "content": "um-end\npk-um\nFE-il\nay-FE\npk-start\nend-jt\num-FE\nRO-il\nxc-ay\nil-end\nstart-EZ\npk-FE\nxc-start\njt-FE\nEZ-um\npk-xc\nxc-EZ\npk-ay\nil-ay\njt-EZ\njt-om\npk-EZ\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_12_questions.txt",
    "content": "--- Day 12: Passage Pathing ---\r\n\r\nWith your submarine's subterranean subsystems subsisting suboptimally, the only way you're getting out of this cave anytime soon is by finding a path yourself. Not just a path - the only way to know if you've found the best path is to find all of them.\r\n\r\nFortunately, the sensors are still mostly working, and so you build a rough map of the remaining caves (your puzzle input). For example:\r\n\r\nstart-A\r\nstart-b\r\nA-c\r\nA-b\r\nb-d\r\nA-end\r\nb-end\r\n\r\nThis is a list of how all of the caves are connected. You start in the cave named start, and your destination is the cave named end. An entry like b-d means that cave b is connected to cave d - that is, you can move between them.\r\n\r\nSo, the above cave system looks roughly like this:\r\n\r\n    start\r\n    /   \\\r\nc--A-----b--d\r\n    \\   /\r\n     end\r\n\r\nYour goal is to find the number of distinct paths that start at start, end at end, and don't visit small caves more than once. There are two types of caves: big caves (written in uppercase, like A) and small caves (written in lowercase, like b). It would be a waste of time to visit any small cave more than once, but big caves are large enough that it might be worth visiting them multiple times. So, all paths you find should visit small caves at most once, and can visit big caves any number of times.\r\n\r\nGiven these rules, there are 10 paths through this example cave system:\r\n\r\nstart,A,b,A,c,A,end\r\nstart,A,b,A,end\r\nstart,A,b,end\r\nstart,A,c,A,b,A,end\r\nstart,A,c,A,b,end\r\nstart,A,c,A,end\r\nstart,A,end\r\nstart,b,A,c,A,end\r\nstart,b,A,end\r\nstart,b,end\r\n\r\n(Each line in the above list corresponds to a single path; the caves visited by that path are listed in the order they are visited and separated by commas.)\r\n\r\nNote that in this cave system, cave d is never visited by any path: to do so, cave b would need to be visited twice (once on the way to cave d and a second time when returning from cave d), and since cave b is small, this is not allowed.\r\n\r\nHere is a slightly larger example:\r\n\r\ndc-end\r\nHN-start\r\nstart-kj\r\ndc-start\r\ndc-HN\r\nLN-dc\r\nHN-end\r\nkj-sa\r\nkj-HN\r\nkj-dc\r\n\r\nThe 19 paths through it are as follows:\r\n\r\nstart,HN,dc,HN,end\r\nstart,HN,dc,HN,kj,HN,end\r\nstart,HN,dc,end\r\nstart,HN,dc,kj,HN,end\r\nstart,HN,end\r\nstart,HN,kj,HN,dc,HN,end\r\nstart,HN,kj,HN,dc,end\r\nstart,HN,kj,HN,end\r\nstart,HN,kj,dc,HN,end\r\nstart,HN,kj,dc,end\r\nstart,dc,HN,end\r\nstart,dc,HN,kj,HN,end\r\nstart,dc,end\r\nstart,dc,kj,HN,end\r\nstart,kj,HN,dc,HN,end\r\nstart,kj,HN,dc,end\r\nstart,kj,HN,end\r\nstart,kj,dc,HN,end\r\nstart,kj,dc,end\r\n\r\nFinally, this even larger example has 226 paths through it:\r\n\r\nfs-end\r\nhe-DX\r\nfs-he\r\nstart-DX\r\npj-DX\r\nend-zg\r\nzg-sl\r\nzg-pj\r\npj-he\r\nRW-he\r\nfs-DX\r\npj-RW\r\nzg-RW\r\nstart-pj\r\nhe-WI\r\nzg-he\r\npj-fs\r\nstart-RW\r\n\r\nHow many paths through this cave system are there that visit small caves at most once?\r\n\r\n--- Part Two ---\r\n\r\nAfter reviewing the available paths, you realize you might have time to visit a single small cave twice. Specifically, big caves can be visited any number of times, a single small cave can be visited at most twice, and the remaining small caves can be visited at most once. However, the caves named start and end can only be visited exactly once each: once you leave the start cave, you may not return to it, and once you reach the end cave, the path must end immediately.\r\n\r\nNow, the 36 possible paths through the first example above are:\r\n\r\nstart,A,b,A,b,A,c,A,end\r\nstart,A,b,A,b,A,end\r\nstart,A,b,A,b,end\r\nstart,A,b,A,c,A,b,A,end\r\nstart,A,b,A,c,A,b,end\r\nstart,A,b,A,c,A,c,A,end\r\nstart,A,b,A,c,A,end\r\nstart,A,b,A,end\r\nstart,A,b,d,b,A,c,A,end\r\nstart,A,b,d,b,A,end\r\nstart,A,b,d,b,end\r\nstart,A,b,end\r\nstart,A,c,A,b,A,b,A,end\r\nstart,A,c,A,b,A,b,end\r\nstart,A,c,A,b,A,c,A,end\r\nstart,A,c,A,b,A,end\r\nstart,A,c,A,b,d,b,A,end\r\nstart,A,c,A,b,d,b,end\r\nstart,A,c,A,b,end\r\nstart,A,c,A,c,A,b,A,end\r\nstart,A,c,A,c,A,b,end\r\nstart,A,c,A,c,A,end\r\nstart,A,c,A,end\r\nstart,A,end\r\nstart,b,A,b,A,c,A,end\r\nstart,b,A,b,A,end\r\nstart,b,A,b,end\r\nstart,b,A,c,A,b,A,end\r\nstart,b,A,c,A,b,end\r\nstart,b,A,c,A,c,A,end\r\nstart,b,A,c,A,end\r\nstart,b,A,end\r\nstart,b,d,b,A,c,A,end\r\nstart,b,d,b,A,end\r\nstart,b,d,b,end\r\nstart,b,end\r\n\r\nThe slightly larger example above now has 103 paths through it, and the even larger example now has 3509 paths through it.\r\n\r\nGiven these new rules, how many paths through this cave system are there?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_13.adb",
    "content": "--  Solution to Advent of Code 2021, Day 13\n-------------------------------------------\n--  Transparent Origami\n--\n--  https://adventofcode.com/2021/day/13\n--  Copy of questions in: aoc_2021_13_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_13 is\n  use HAT;\n  --\n  input : constant VString := +\"aoc_2021_13.txt\";\n  --\n  x_max : constant := 2000;\n  y_max : constant := 1000;\n  subtype X_Range is Integer range 0 .. x_max;\n  subtype Y_Range is Integer range 0 .. y_max;\n  x_last : X_Range := 0;\n  y_last : Y_Range := 0;\n  map : array (X_Range, Y_Range) of Boolean;\n  --\n  function Count return Natural is\n    total : Natural := 0;\n  begin\n    for x in 0 .. x_last loop\n      for y in 0 .. y_last loop\n        if map (x, y) then\n          total := total + 1;\n        end if;\n      end loop;\n    end loop;\n    return total;\n  end Count;\n  --\n  procedure Show is\n  begin\n    for y in 0 .. y_last loop\n      for x in 0 .. x_last loop\n        if map (x, y) then\n          Put ('#');\n        else\n          Put (' ');\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n  --\n  f_max : constant := 20;\n  subtype Fold_Range is Integer range 1 .. f_max;\n  f_last : Natural := 0;\n  type Fold_Instruction_Type is record\n    x_axis : Boolean;\n    line   : Natural;\n  end record;\n  fold_instruction : array (Fold_Range) of Fold_Instruction_Type;\n  --\n  procedure Read_Data is\n    f : File_Type;\n    c, sep : Character;\n    xd : X_Range;\n    yd : Y_Range;\n    skip : String (1 .. 11) := \"fold along \";\n  begin\n    for x in X_Range loop\n      for y in Y_Range loop\n        map (x, y) := False;\n      end loop;\n    end loop;\n    Open (f, input);\n    loop\n      Get (f, xd);\n      Get (f, sep);\n      Get (f, yd);\n      map (xd, yd) := True;\n      x_last := Max (x_last, xd);\n      y_last := Max (y_last, yd);\n      if End_Of_Line (f) then\n        Skip_Line (f);\n      end if;\n      exit when End_Of_Line (f);\n    end loop;\n    --  Folding instructions\n    while not End_Of_File (f) loop\n      f_last := f_last + 1;\n      Get (f, skip);\n      Get (f, c);\n      fold_instruction (f_last).x_axis := c = 'x';\n      Get (f, sep);\n      Get (f, fold_instruction (f_last).line);\n    end loop;\n    Close (f);\n  end Read_Data;\n  --\n  procedure Fold (f : Fold_Range) is\n    xf, xe : X_Range;\n    yf, ye : Y_Range;\n  begin\n    if fold_instruction (f).x_axis then\n      xf := fold_instruction (f).line;\n      xe := xf * 2;\n      for x in 0 .. xf - 1 loop\n        for y in 0 .. y_last loop\n          map (x, y) := map (x, y) or map (xe - x, y);\n        end loop;\n      end loop;\n      x_last := xf - 1;\n    else\n      yf := fold_instruction (f).line;\n      ye := yf * 2;\n      for x in 0 .. x_last loop\n        for y in 0 .. yf - 1 loop\n          map (x, y) := map (x, y) or map (x, ye - y);\n        end loop;\n      end loop;\n      y_last := yf - 1;\n    end if;\n  end Fold;\n  --\n  r : Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\nbegin\n  Read_Data;\n  for f in 1 .. f_last loop\n    Fold (f);\n    if f = 1 then\n      r := Count;\n      exit when compiler_test_mode;\n    end if;\n  end loop;\n  if compiler_test_mode then\n    if r /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: Number of dots after 1st fold: \" & r);\n    Put_Line (+\"Part 2: Height-letter code:\");\n    Show;\n    --  Part 1: validated by AoC: 602\n    --  Part 2: validated by AoC: CAFJHZCK\n  end if;\nend AoC_2021_13;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_13.txt",
    "content": "1284,359\n47,25\n699,764\n55,204\n552,247\n731,877\n765,12\n619,806\n437,864\n1202,152\n105,456\n159,165\n648,563\n701,143\n609,861\n972,414\n1195,379\n1097,439\n358,95\n1126,288\n773,332\n863,813\n1250,63\n1280,95\n1237,672\n224,343\n1222,488\n748,842\n554,208\n1086,215\n1136,479\n1308,826\n371,367\n972,722\n766,719\n80,366\n920,22\n765,882\n1208,354\n994,526\n512,430\n1007,507\n773,695\n909,672\n370,231\n38,812\n766,495\n1078,534\n633,408\n233,770\n251,429\n874,315\n649,666\n1140,868\n1138,75\n808,441\n864,150\n1066,814\n440,674\n477,238\n1290,739\n786,434\n263,42\n306,891\n1086,652\n248,621\n515,387\n378,730\n1255,189\n769,187\n70,473\n408,773\n1039,581\n373,312\n537,562\n1078,360\n1036,775\n925,565\n1022,530\n132,207\n1027,815\n869,7\n631,281\n725,404\n945,305\n1173,509\n678,338\n788,207\n447,753\n166,740\n745,199\n49,383\n1151,729\n1255,705\n351,507\n648,331\n1,208\n728,299\n174,479\n224,215\n179,372\n497,541\n445,84\n952,95\n1136,422\n1253,341\n251,877\n269,150\n227,154\n597,341\n72,343\n657,656\n900,473\n117,562\n990,474\n1096,326\n524,147\n1228,473\n990,420\n360,434\n493,47\n582,299\n843,266\n1220,850\n370,103\n176,26\n1192,430\n890,252\n1235,809\n1220,318\n666,332\n711,481\n1083,154\n825,2\n365,305\n566,854\n1278,658\n213,887\n26,7\n766,399\n448,47\n892,549\n349,38\n605,168\n303,42\n592,114\n433,219\n7,560\n10,526\n227,614\n186,836\n323,109\n32,658\n1061,802\n544,271\n289,589\n227,280\n713,553\n997,574\n577,221\n502,696\n497,801\n431,486\n42,250\n68,866\n1290,372\n736,773\n676,3\n1208,663\n1004,891\n202,775\n1116,655\n1057,670\n840,16\n160,320\n172,371\n480,32\n666,441\n83,880\n100,816\n813,821\n1265,868\n976,420\n372,822\n1284,7\n110,495\n348,451\n1210,526\n467,852\n170,474\n788,339\n390,872\n119,703\n940,663\n577,764\n316,646\n1,460\n1027,79\n137,509\n565,247\n838,395\n321,93\n763,712\n268,332\n355,42\n217,590\n410,473\n213,439\n433,456\n733,221\n1099,739\n1211,602\n221,438\n371,92\n579,205\n207,529\n487,813\n1124,58\n1097,455\n213,7\n1099,67\n1149,847\n208,744\n633,486\n1156,813\n239,735\n174,78\n370,663\n438,348\n599,690\n1061,92\n987,337\n333,93\n1126,291\n239,541\n1029,760\n1283,637\n78,273\n318,186\n441,103\n1036,119\n1074,793\n867,827\n75,17\n415,541\n488,154\n644,441\n64,91\n554,816\n976,474\n676,43\n239,353\n271,133\n92,842\n544,719\n1097,887\n157,801\n1309,131\n900,421\n731,689\n597,822\n388,175\n599,637\n385,296\n987,785\n57,374\n1158,889\n167,365\n731,205\n316,722\n830,530\n239,159\n905,92\n663,726\n927,581\n530,483\n107,522\n455,889\n1267,316\n502,866\n45,26\n842,58\n833,238\n70,638\n803,36\n211,515\n562,52\n20,851\n480,332\n1148,64\n679,281\n1248,200\n666,562\n385,744\n1093,864\n1260,164\n888,364\n547,74\n373,582\n480,479\n551,486\n1021,589\n120,476\n467,266\n1061,753\n1298,644\n728,103\n544,658\n561,44\n1149,47\n1233,316\n1195,827\n443,155\n124,35\n88,488\n1203,182\n1248,305\n266,787\n249,589\n110,770\n1019,341\n565,199\n863,753\n1267,255\n549,438\n612,616\n552,551\n1208,231\n577,130\n883,733\n43,578\n274,551\n766,623\n584,642\n1078,812\n410,80\n658,68\n627,369\n216,236\n775,540\n850,239\n366,530\n720,803\n1252,338\n869,551\n830,332\n1237,448\n274,882\n110,627\n60,130\n698,26\n758,23\n213,791\n92,52\n808,812\n445,114\n50,400\n758,540\n62,200\n1066,473\n683,628\n1097,103\n448,418\n1247,68\n770,789\n816,154\n1089,456\n817,47\n502,562\n927,294\n1267,764\n1275,33\n338,172\n541,187\n383,600\n539,155\n30,799\n749,850\n981,847\n1077,770\n808,5\n609,420\n354,175\n383,742\n950,434\n535,703\n1036,12\n415,353\n264,332\n594,588\n184,288\n415,735\n1086,231\n1241,490\n961,38\n974,156\n758,354\n591,826\n1222,406\n574,366\n502,620\n1211,733\n927,742\n38,530\n864,430\n644,696\n564,402\n577,578\n415,93\n612,644\n955,852\n1044,130\n864,296\n1248,835\n763,522\n1248,694\n1124,836\n410,814\n622,882\n662,563\n119,191\n769,775\n90,318\n895,541\n579,877\n822,154\n686,351\n349,856\n473,133\n390,22\n90,850\n418,148\n666,696\n1136,368\n701,644\n510,843\n1099,379\n733,764\n825,450\n427,733\n730,376\n883,280\n877,456\n867,67\n217,752\n830,252\n146,147\n1034,46\n714,338\n619,444\n771,620\n724,866\n403,429\n57,822\n27,369\n1039,152\n1129,133\n1195,739\n959,507\n207,753\n764,294\n564,598\n837,740\n1257,304\n661,271\n1208,652\n160,574\n1083,609\n1029,565\n274,119\n609,644\n443,827\n1011,42\n211,739\n580,518\n895,801\n401,672\n815,165\n502,396\n624,351\n445,536\n842,338\n766,658\n1123,266\n401,670\n113,119\n1036,460\n85,589\n661,623\n60,175\n249,802\n1097,791\n45,537\n224,802\n89,647\n236,793\n726,256\n211,67\n80,528\n1283,705\n537,332\n338,816\n385,150\n221,456\n227,609\n400,299\n248,173\n502,498\n649,623\n1303,560\n592,332\n316,248\n1086,92\n117,114\n622,658\n136,63\n748,52\n907,465\n1230,773\n579,689\n274,460\n107,182\n1077,124\n1237,446\n355,852\n174,422\n691,603\n1283,369\n653,656\n109,640\n433,675\n873,30\n1225,589\n698,616\n522,207\n540,789\n488,546\n1186,343\n102,231\n169,373\n354,719\n907,429\n217,864\n249,354\n713,822\n1059,429\n1293,56\n488,98\n1208,204\n60,63\n637,56\n448,847\n1236,152\n1161,880\n1267,130\n545,12\n584,252\n1191,533\n919,516\n268,338\n410,30\n274,12\n418,549\n634,43\n1044,175\n544,399\n383,294\n1193,88\n212,553\n527,677\n224,679\n937,312\n1066,25\n427,280\n1300,780\n895,735\n254,595\n706,282\n441,392\n813,73\n700,72\n415,159\n1171,628\n644,889\n900,80\n209,114\n837,133\n537,695\n716,271\n822,740\n1143,365\n599,413\n115,379\n1158,476\n769,119\n373,196\n60,287\n1022,364\n877,219\n1265,250\n1,763\n910,595\n937,751\n35,33\n1066,421\n26,359\n825,521\n1033,231\n880,802\n49,831\n830,642\n75,809\n80,773\n1178,351\n142,464\n1300,114\n2,68\n70,256\n354,215\n813,801\n867,739\n266,287\n480,562\n371,815\n1241,852\n539,620\n524,434\n1111,5\n85,305\n174,32\n800,395\n1046,562\n1134,418\n1136,78\n93,850\n107,372\n416,152\n925,329\n194,787\n1250,130\n705,511\n657,238\n1225,876\n274,775\n1129,761\n574,773\n1242,28\n937,143\n32,236\n758,551\n564,850\n174,368\n1220,150\n1101,114\n843,8\n594,306\n545,814\n118,38\n160,740\n1241,42\n378,220\n994,646\n698,278\n73,446\n552,343\n925,296\n174,498\n1089,438\n855,668\n609,117\n544,627\n1265,26\n1099,515\n100,368\n611,130\n23,556\n1056,708\n1250,831\n570,497\n544,684\n682,887\n1027,527\n43,130\n731,533\n1200,627\n248,684\n62,305\n740,497\n1092,315\n1240,638\n1086,343\n701,582\n989,93\n830,396\n124,411\n186,338\n1071,353\n1158,722\n284,663\n758,343\n152,190\n7,334\n266,607\n706,494\n691,88\n1261,63\n766,175\n610,72\n373,329\n1263,25\n174,480\n666,364\n446,744\n1211,161\n581,222\n790,600\n93,178\n1141,373\n120,215\n93,322\n597,789\n744,854\n1010,311\n761,149\n1019,441\n224,231\n900,30\n472,499\n706,730\n480,172\n688,658\n371,540\n174,396\n825,444\n830,172\n\nfold along x=655\nfold along y=447\nfold along x=327\nfold along y=223\nfold along x=163\nfold along y=111\nfold along x=81\nfold along y=55\nfold along x=40\nfold along y=27\nfold along y=13\nfold along y=6\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_13_questions.txt",
    "content": "--- Day 13: Transparent Origami ---\r\n\r\nYou reach another volcanically active part of the cave. It would be nice if you could do some kind of thermal imaging so you could tell ahead of time which caves are too hot to safely enter.\r\n\r\nFortunately, the submarine seems to be equipped with a thermal camera! When you activate it, you are greeted with:\r\n\r\nCongratulations on your purchase! To activate this infrared thermal imaging\r\ncamera system, please enter the code found on page 1 of the manual.\r\n\r\nApparently, the Elves have never used this feature. To your surprise, you manage to find the manual; as you go to open it, page 1 falls out. It's a large sheet of transparent paper! The transparent paper is marked with random dots and includes instructions on how to fold it up (your puzzle input). For example:\r\n\r\n6,10\r\n0,14\r\n9,10\r\n0,3\r\n10,4\r\n4,11\r\n6,0\r\n6,12\r\n4,1\r\n0,13\r\n10,12\r\n3,4\r\n3,0\r\n8,4\r\n1,10\r\n2,14\r\n8,10\r\n9,0\r\n\r\nfold along y=7\r\nfold along x=5\r\n\r\nThe first section is a list of dots on the transparent paper. 0,0 represents the top-left coordinate. The first value, x, increases to the right. The second value, y, increases downward. So, the coordinate 3,0 is to the right of 0,0, and the coordinate 0,7 is below 0,0. The coordinates in this example form the following pattern, where # is a dot on the paper and . is an empty, unmarked position:\r\n\r\n...#..#..#.\r\n....#......\r\n...........\r\n#..........\r\n...#....#.#\r\n...........\r\n...........\r\n...........\r\n...........\r\n...........\r\n.#....#.##.\r\n....#......\r\n......#...#\r\n#..........\r\n#.#........\r\n\r\nThen, there is a list of fold instructions. Each instruction indicates a line on the transparent paper and wants you to fold the paper up (for horizontal y=... lines) or left (for vertical x=... lines). In this example, the first fold instruction is fold along y=7, which designates the line formed by all of the positions where y is 7 (marked here with -):\r\n\r\n...#..#..#.\r\n....#......\r\n...........\r\n#..........\r\n...#....#.#\r\n...........\r\n...........\r\n-----------\r\n...........\r\n...........\r\n.#....#.##.\r\n....#......\r\n......#...#\r\n#..........\r\n#.#........\r\n\r\nBecause this is a horizontal line, fold the bottom half up. Some of the dots might end up overlapping after the fold is complete, but dots will never appear exactly on a fold line. The result of doing this fold looks like this:\r\n\r\n#.##..#..#.\r\n#...#......\r\n......#...#\r\n#...#......\r\n.#.#..#.###\r\n...........\r\n...........\r\n\r\nNow, only 17 dots are visible.\r\n\r\nNotice, for example, the two dots in the bottom left corner before the transparent paper is folded; after the fold is complete, those dots appear in the top left corner (at 0,0 and 0,1). Because the paper is transparent, the dot just below them in the result (at 0,3) remains visible, as it can be seen through the transparent paper.\r\n\r\nAlso notice that some dots can end up overlapping; in this case, the dots merge together and become a single dot.\r\n\r\nThe second fold instruction is fold along x=5, which indicates this line:\r\n\r\n#.##.|#..#.\r\n#...#|.....\r\n.....|#...#\r\n#...#|.....\r\n.#.#.|#.###\r\n.....|.....\r\n.....|.....\r\n\r\nBecause this is a vertical line, fold left:\r\n\r\n#####\r\n#...#\r\n#...#\r\n#...#\r\n#####\r\n.....\r\n.....\r\n\r\nThe instructions made a square!\r\n\r\nThe transparent paper is pretty big, so for now, focus on just completing the first fold. After the first fold in the example above, 17 dots are visible - dots that end up overlapping after the fold is completed count as a single dot.\r\n\r\nHow many dots are visible after completing just the first fold instruction on your transparent paper?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_14.adb",
    "content": "--  Solution to Advent of Code 2021, Day 14\n-------------------------------------------\n--  Extended Polymerization\n--\n--  https://adventofcode.com/2021/day/14\n--  Copy of questions in: aoc_2021_14_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_14 is\n  use HAT, Interfaces;\n  --\n  rule_max : constant := 200;\n  subtype Rule_Range is Integer range 1 .. rule_max;\n  --\n  subtype Alpha is Character range 'A' .. 'Z';\n  subtype Pair is String (1 .. 2);\n  --  Ideally: `array (1 .. 2) of Alpha` when HAC supports array comparisons.\n  --\n  type Rule_Type is record\n    from    : Pair;\n    to      : Alpha;\n    child_1 : Rule_Range;\n    child_2 : Rule_Range;\n  end record;\n  --\n  rule : array (Rule_Range) of Rule_Type;\n  rules : Natural := 0;\n  --\n  initial_polymer : VString;\n  type Pair_Population is array (Rule_Range) of Integer_64;\n  zero : Pair_Population;\n  gen_pop : array (1 .. 2) of Pair_Population;\n  --\n  procedure Read_Data is\n    sep : String (1 .. 4);\n    f : File_Type;\n    input : constant VString := +\"aoc_2021_14.txt\";\n  begin\n    Open (f, input);\n    Get_Line (f, initial_polymer);  --  Original sequence\n    Skip_Line (f);\n    while not End_Of_File (f) loop\n      rules := rules + 1;\n      Get (f, rule (rules).from (1));\n      Get (f, rule (rules).from (2));\n      Get (f, sep);\n      Get (f, rule (rules).to);\n    end loop;\n    Close (f);\n    --  Initial population as pairs\n    for i in Rule_Range loop\n      zero (i) := 0;\n    end loop;\n    gen_pop (1) := zero;\n    for i in 1 .. rules loop\n      for j in 1 .. Length (initial_polymer) - 1 loop\n        if +rule (i).from = Slice (initial_polymer, j, j + 1) then\n          gen_pop (1)(i) := gen_pop (1)(i) + 1;\n        end if;\n      end loop;\n    end loop;\n  end Read_Data;\n  --\n  procedure Prepare_Computation is\n    child_1, child_2 : Pair;\n  begin\n    --  Prepare shortcuts pair -> new pairs.\n    for i in 1 .. rules loop\n      child_1 (1) := rule (i).from (1);\n      child_1 (2) := rule (i).to;\n      child_2 (1) := rule (i).to;\n      child_2 (2) := rule (i).from (2);\n      for j in 1 .. rules loop\n        if +rule (j).from = +child_1 then\n          rule (i).child_1 := j;\n        end if;\n        if +rule (j).from = +child_2 then\n          rule (i).child_2 := j;\n        end if;\n      end loop;\n    end loop;\n  end Prepare_Computation;\n  --\n  gen : Positive := 1;\n  --\n  procedure Evolve is\n    parents : Integer_64;\n    new_gen : constant Positive := 3 - gen;\n    child_1_idx, child_2_idx : Positive;\n    procedure Increase (pop : in out Integer_64) is\n    begin\n      pop := pop + parents;\n    end Increase;\n  begin\n    gen_pop (new_gen) := zero;\n    for i in 1 .. rules loop\n      parents := gen_pop (gen) (i);\n      child_1_idx := rule (i).child_1;\n      child_2_idx := rule (i).child_2;\n      Increase (gen_pop (new_gen) (child_1_idx));\n      Increase (gen_pop (new_gen) (child_2_idx));\n    end loop;\n    gen := new_gen;\n  end Evolve;\n  --\n  r : array (1 .. 2) of Integer_64;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := not compiler_test_mode;\n  --\n  res : Integer_64;\n  --\n  procedure Atom_Counts is\n    stat : array (Alpha) of Integer_64;\n    total : Integer_64 := 0;\n    aa : Alpha;\n    stat_most_common_element  : Integer_64 := Integer_64'First;  --  \"- infinity\"\n    stat_least_common_element : Integer_64 := Integer_64'Last;   --  \"+ infinity\"\n  begin\n    for a in Alpha loop\n      stat (a) := 0;\n    end loop;\n    for r in 1 .. rules loop\n      aa := rule (r).from (1);\n      stat (aa) := stat (aa) + gen_pop (gen)(r);\n      aa := rule (r).from (2);\n      stat (aa) := stat (aa) + gen_pop (gen)(r);\n    end loop;\n    --  Ghost pair at the beginning of the polymer:\n    aa := Element (initial_polymer, 1);\n    stat (aa) := stat (aa) + 1;\n    --  Ghost pair at the end of the polymer:\n    aa := Element (initial_polymer, Length (initial_polymer));\n    stat (aa) := stat (aa) + 1;\n    --  Now all stats for all atomic symbols are exactly double counted.\n    for a in Alpha loop\n      stat (a) := stat (a) / 2;\n      total := total + stat (a);\n      if stat (a) > 0 and then verbose then\n        Put_Line (+\"  \" & a & \":\" & Integer_64'Image (stat (a)));\n      end if;\n    end loop;\n    if verbose then\n      Put_Line (+\"  Total:\" & Integer_64'Image (total));\n    end if;\n    for a in Alpha loop\n      if stat (a) > 0 then\n        if stat (a) < stat_least_common_element then\n          stat_least_common_element := stat (a);\n        end if;\n        if stat (a) > stat_most_common_element then\n          stat_most_common_element := stat (a);\n        end if;\n      end if;\n    end loop;\n    res := stat_most_common_element - stat_least_common_element;\n    --\n  end Atom_Counts;\n  --\nbegin\n  Read_Data;\n  Prepare_Computation;\n  if verbose then\n    Put_Line (+\"Initial: \");\n  end if;\n  Atom_Counts;\n  for gen_count in 1 .. 40 loop\n    Evolve;\n    if verbose then\n      Put_Line (+\"Generation \" & gen_count & ':');\n    end if;\n    Atom_Counts;\n    if gen_count = 10 then\n      r (1) := res;\n    end if;\n  end loop;\n  r (2) := res;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Part 1: count after 10 generations:\" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2: count after 40 generations:\" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 2345\n    --  Part 2: validated by AoC: 2432786807053\n  end if;\nend AoC_2021_14;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_14.txt",
    "content": "BNSOSBBKPCSCPKPOPNNK\n\nHH -> N\nCO -> F\nBC -> O\nHN -> V\nSV -> S\nFS -> F\nCV -> F\nKN -> F\nOP -> H\nVN -> P\nPF -> P\nHP -> H\nFK -> K\nBS -> F\nFP -> H\nFN -> V\nVV -> O\nPS -> S\nSK -> N\nFF -> K\nPK -> V\nOF -> N\nVP -> K\nKB -> H\nOV -> B\nCH -> F\nSF -> F\nNH -> O\nNC -> N\nSP -> N\nNN -> F\nOK -> S\nBB -> S\nNK -> S\nFH -> P\nFC -> S\nOB -> P\nVS -> P\nBF -> S\nHC -> V\nCK -> O\nNP -> K\nKV -> S\nOS -> V\nCF -> V\nFB -> C\nHO -> S\nBV -> V\nKS -> C\nHB -> S\nSO -> N\nPH -> C\nPN -> F\nOC -> F\nKO -> F\nVF -> V\nCS -> O\nVK -> O\nFV -> N\nOO -> K\nNS -> S\nKK -> C\nFO -> S\nPV -> S\nCN -> O\nVC -> P\nSS -> C\nPO -> P\nBN -> N\nPB -> N\nPC -> H\nSH -> K\nBH -> F\nHK -> O\nVB -> P\nNV -> O\nNB -> C\nCP -> H\nNO -> K\nPP -> N\nCC -> S\nCB -> K\nVH -> H\nSC -> C\nKC -> N\nSB -> B\nBP -> P\nKP -> K\nSN -> H\nKF -> K\nKH -> B\nHV -> V\nHS -> K\nNF -> B\nON -> H\nBO -> P\nVO -> K\nOH -> C\nHF -> O\nBK -> H\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_14_questions.txt",
    "content": "--- Day 14: Extended Polymerization ---\r\n\r\nThe incredible pressures at this depth are starting to put a strain on your submarine. The submarine has polymerization equipment that would produce suitable materials to reinforce the submarine, and the nearby volcanically-active caves should even have the necessary input elements in sufficient quantities.\r\n\r\nThe submarine manual contains instructions for finding the optimal polymer formula; specifically, it offers a polymer template and a list of pair insertion rules (your puzzle input). You just need to work out what polymer would result after repeating the pair insertion process a few times.\r\n\r\nFor example:\r\n\r\nNNCB\r\n\r\nCH -> B\r\nHH -> N\r\nCB -> H\r\nNH -> C\r\nHB -> C\r\nHC -> B\r\nHN -> C\r\nNN -> C\r\nBH -> H\r\nNC -> B\r\nNB -> B\r\nBN -> B\r\nBB -> N\r\nBC -> B\r\nCC -> N\r\nCN -> C\r\n\r\nThe first line is the polymer template - this is the starting point of the process.\r\n\r\nThe following section defines the pair insertion rules. A rule like AB -> C means that when elements A and B are immediately adjacent, element C should be inserted between them. These insertions all happen simultaneously.\r\n\r\nSo, starting with the polymer template NNCB, the first step simultaneously considers all three pairs:\r\n\r\n    The first pair (NN) matches the rule NN -> C, so element C is inserted between the first N and the second N.\r\n    The second pair (NC) matches the rule NC -> B, so element B is inserted between the N and the C.\r\n    The third pair (CB) matches the rule CB -> H, so element H is inserted between the C and the B.\r\n\r\nNote that these pairs overlap: the second element of one pair is the first element of the next pair. Also, because all pairs are considered simultaneously, inserted elements are not considered to be part of a pair until the next step.\r\n\r\nAfter the first step of this process, the polymer becomes NCNBCHB.\r\n\r\nHere are the results of a few steps using the above rules:\r\n\r\nTemplate:     NNCB\r\nAfter step 1: NCNBCHB\r\nAfter step 2: NBCCNBBBCBHCB\r\nAfter step 3: NBBBCNCCNBBNBNBBCHBHHBCHB\r\nAfter step 4: NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB\r\n\r\nThis polymer grows quickly. After step 5, it has length 97; After step 10, it has length 3073. After step 10, B occurs 1749 times, C occurs 298 times, H occurs 191 times, and N occurs 865 times; taking the quantity of the most common element (B, 1749) and subtracting the quantity of the least common element (H, 161) produces 1749 - 161 = 1588.\r\n\r\nApply 10 steps of pair insertion to the polymer template and find the most and least common elements in the result. What do you get if you take the quantity of the most common element and subtract the quantity of the least common element?\r\n\r\n--- Part Two ---\r\n\r\nThe resulting polymer isn't nearly strong enough to reinforce the submarine. You'll need to run more steps of the pair insertion process; a total of 40 steps should do it.\r\n\r\nIn the above example, the most common element is B (occurring 2192039569602 times) and the least common element is H (occurring 3849876073 times); subtracting these produces 2188189693529.\r\n\r\nApply 40 steps of pair insertion to the polymer template and find the most and least common elements in the result. What do you get if you take the quantity of the most common element and subtract the quantity of the least common element?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_15.adb",
    "content": "--  Solution to Advent of Code 2021, Day 15\n-------------------------------------------\n--  Chiton\n--\n--  https://adventofcode.com/2021/day/15\n--  Copy of questions in: aoc_2021_15_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_15 is\n  use HAT;\n  sx_max : constant := 500;\n  sy_max : constant := 500;\n  map : array (1 .. sx_max, 1 .. sy_max) of Natural;\n  --  Cumulative minimal risk from starting point to (x, y)\n  c_risk : array (1 .. sx_max, 1 .. sy_max) of Natural;\n  risk_max : constant Integer := Integer'Last;\n  sx, sy : Natural;\n  input : constant VString := +\"aoc_2021_15.txt\";\n  --\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n    x, y : Natural := 0;\n  begin\n    Open (f, input);\n    while not End_Of_File (f) loop\n      y := y + 1;\n      x := 0;\n      Get (f, c);\n      loop\n        x := x + 1;\n        map (x, y) := Ord (c) - Ord ('0');\n        c_risk (x, y) := risk_max;\n        exit when End_Of_Line (f);\n        Get (f, c);\n      end loop;\n    end loop;\n    sx := x;\n    sy := y;\n    Close (f);\n  end Read_Data;\n  --\n  r : array (1 .. 2) of Integer;\n  --\n  --  `Visit` explores adjacent cells (recursive algorithm).\n  --  Side effect: it writes into `risk`.\n  --\n  procedure Visit (x, y, risk_from : Integer) is\n    risk_to : Integer;\n  begin\n    if x in 1 .. sx and then y in 1 .. sy then\n      risk_to := risk_from + map (x, y);\n      if risk_to < c_risk (x, y) then\n        --  Ah-ha, we have found a better way, or perhaps\n        --  the first way, to (x, y).\n        c_risk (x, y) := risk_to;\n        --  Since we have a reduced risk (x, y), it's worth\n        --  continuing the exploration.\n        Visit (x - 1, y, risk_to);\n        Visit (x + 1, y, risk_to);\n        Visit (x, y - 1, risk_to);\n        Visit (x, y + 1, risk_to);\n      end if;\n    end if;\n  end Visit;\n  --\n  --  Now enters Dijkstra.\n  --  How many ready-made sorting containers are currently\n  --  available to HAC ? None! I.e., do it yourself!\n  --\n  procedure Dijkstra (start_x, start_y : Integer) is\n    list_length_max : constant := 250_000;  --  sx_max * sy_max;\n    type Node is record\n      c_risk : Natural;\n      x, y   : Positive;\n    end record;\n    list : array (1 .. list_length_max) of Node;\n    current, explored : Natural := 0;  --  0 <= current <= explored\n    --\n    --  Similar to the `Visit` above, but not recursive.\n    --\n    procedure Visit (x, y, risk_from : Integer) is\n      risk_to, ins : Integer;\n    begin\n      if x in 1 .. sx and then y in 1 .. sy then\n        risk_to := risk_from + map (x, y);\n        if risk_to < c_risk (x, y) then\n          --  Improvement on cell (x, y).\n          --  This happens only once per (x, y) point in this problem - see below.\n          c_risk (x, y) := risk_to;\n          --\n          --  Insert in a sorted way (slooow on HAC for Part 2).\n          --\n          ins := explored + 1;\n          for i in current + 1 .. explored loop\n            if risk_to < list (i).c_risk then\n              ins := i;  --  Insert here.\n              --  NB: we might want to remove another node with the same (x, y) and a\n              --  larger risk, but that case never happens in this specific problem!\n              --  Reason: the cost for reaching (x, y) is the same from every\n              --  side (= map (x, y)), and we reach it from (cur_x, cur_y) which has\n              --  the minimum score or (x, y)'s neighbours.\n              exit;\n            end if;\n          end loop;\n          for i in reverse ins .. explored loop\n            list (i + 1) := list (i);\n          end loop;\n          list (ins).c_risk := risk_to;\n          list (ins).x := x;\n          list (ins).y := y;\n          explored := explored + 1;\n        end if;\n      end if;\n    end Visit;\n    --\n    cur_x, cur_y : Positive;\n    risk_cur : Natural;\n  begin\n    c_risk (start_x, start_y) := 0;\n    cur_x := start_x;\n    cur_y := start_y;\n    loop\n      risk_cur := c_risk (cur_x, cur_y);\n      Visit (cur_x - 1, cur_y, risk_cur);\n      Visit (cur_x + 1, cur_y, risk_cur);\n      Visit (cur_x, cur_y - 1, risk_cur);\n      Visit (cur_x, cur_y + 1, risk_cur);\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      cur_x := list (current).x;\n      cur_y := list (current).y;\n      exit when cur_x = sx and then cur_y = sy;\n    end loop;\n  end Dijkstra;\n  --\n  procedure Enlarge_Map is\n    xn, yn : Integer;\n  begin\n    for tile_x in 0 .. 4 loop\n      for tile_y in 0 .. 4 loop\n        for x in 1 .. sx loop\n          xn := x + sx * tile_x;\n          for y in 1 .. sy loop\n            yn := y + sy * tile_y;\n            map (xn, yn) := 1 + (map (x, y) - 1 + tile_x + tile_y) mod 9;\n            c_risk (xn, yn) := risk_max;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    sx := sx * 5;\n    sy := sy * 5;\n  end Enlarge_Map;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  fast : constant Boolean := True;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  for part in 1 .. 2 loop\n    if part = 2 then\n      Enlarge_Map;\n    end if;\n    if fast then\n      Dijkstra (1, 1);\n    else\n      Visit (1, 1, -map (1, 1));\n    end if;\n    r (part) := c_risk (sx, sy);\n    exit when compiler_test_mode;\n    --  ^ We do only part 1 when in test mode.\n    --    Parts 1 & 2 take 96 seconds on an i7 9700 with HAC,\n    --    and only 0.047 seconds with GNAT.\n  end loop;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: total risk on small map: \" & r (1));\n    Put_Line (+\"Part 2: total risk on large map: \" & r (2));\n    --  Part 1: validated by AoC: 656\n    --  Part 2: validated by AoC: 2979\n  end if;\nend AoC_2021_15;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_15.txt",
    "content": "3885193879879881648295721863446819761149766587914443899626972913439119995971841919742454431896714994\n7771129199159639477916156846991956691722436614294489569877288313857938998569854848811311873297851994\n5397898789999499191819517198785943798491221139523487792596493985724999919868993675269878171629998699\n8959899713991722957643961289419687998443291919429187159951653349827977821257719997961312718268193198\n2846219932569842879891692234614311812799724893633989588399819579153814261516987262948716511752796311\n6725199579118269699472336812618911979957922329399797959986179939314145983243295469598939327129574198\n6818219696128568181789718885928896191549477191193599939262477914196391139665811994294494912838651859\n2221716296945891267779128161299579949218877525184884798227965899389488291774899969293987797832516878\n9213844231433499999179428692791378242173289513286965996976983442779617964787586326697988447265876996\n6313993561615886999167182992899141648998552369794394923931327323397566885891787478878722831777571486\n8713991289549818763589939991895849521891966988198382597778921227699759737659939699671923799995284356\n9591399317958271818963894572368319763963548141193644118635854987471693848981917779146394281461959595\n9371563863819447298489391362565198489677387981171916875818269275785921792592869889719184537255926941\n9759413213254611555382917156331878594951999289273329999795947169439981616213999777916131384672945781\n3679696586894978847711411569255844845182781854737976795191261169589939159794718699997493872499236216\n8494291884994125877784376799158842599959994569992371213981397915549319462895179958195199263973799942\n2735796245119192168162841995749994338197856789958799128998179176929129769798961229228259986315798618\n3919549626995852791812998455881197733986917951189161796996622918479591289192199822989316196969797761\n9221811969262729999666392749549395194914927623938931277683992712289972984156294168596935911994723579\n9259839967959351183699987369122784879628595673587616317281991469967675676149919714698676133489158258\n1871658432298942253177598476366881898185855558899669482116863111799951999125874191992364757787788358\n8739852825782614519891679845942972188264816197178738927924889282235769279955911364987337173691463948\n8299121513497179625559826719786159935487869889948649939416556967585528149132799993281891864295925273\n9667999482981521598853938199191994937627975958963142955995573785779998768777953536129524791999139921\n8565711677873119991423986336939891313758995995761498979518974799162693272998776826559842372285298158\n6822737359889336999591591889475198863399198181192341869964891549839939496253238918989492776598168948\n1932768376317118329349221931269281281579761312419134999386689181799263851995829415737796344479779161\n1146699126764988361859799888677969955699566981916991732711866985948137842221879714999415127978969556\n2716826999776621568995483149915971956954949792131367142893274976282898295419519294961429727779179618\n9819689511469361769815986275122539755735877514917521784678889599769389571241738999916766875682319681\n1739898836468191968269759173841389779923491989982797492258199917378161399777715818949121291398318935\n8991681277139272161888388992817669861998471779697922729191795771917917339123894529985942176275989194\n8788879213844991256944695116539936618798879147682219917761678773156192616821535733828489999993567517\n9792112419978643891198386999273939716785777389699733728699741312154995954284998916346921276226192923\n8936179399498567787146928338481217274594929625685299262145795358129817176299499988115561439969169721\n3711996665399999667439695218315649989919198455461991968853148989594896318519998541221179229418248199\n1291656132987641899759511819979169622814748741595934916983531975799629118915179362474688489529695892\n8714922154618318979688217298952681635899934279199225395668557918594721827676544381719997629385251241\n9593279399413929493478294797355334766829491318569163644378429481549576659858687835137187849471951446\n5854979532981199699169869431926898918194919286675941191958919822798687999927843765176497122196781784\n9997819331993888314786377865356591696892611198299964968995887152722272842273694726639232942699932183\n1896184172814918918624961195543395551748983681949128898432976291935921971198195382973914172929297364\n5837941661987651896287486979997298931652327946749692822583754186238849886262949839188999896727858939\n4461864711682831868916812799119298619958698189619694951249686988389189729672287957439646596874979222\n9992395918711165753212128992797846899956889991997831181969254119177984939821658789949262131839363344\n9913929894915753891516982919449993561972671531999989189396939298993831699699189992855785911896267529\n5977191539399768769691985346853389983329338128811976829923188998957757698766999482989529913351836217\n5869199599389289736799521175141562189996727899189998168814918991864194179395421179268799759179886971\n4995393573286591999148456775893729271716999944792426197991892963522993979581797912398388197438929879\n8175985762297792193449825891451669173639831696686977185968298848778111519969913991892852196913658589\n7551823929217592981312974557685142328463465848839872122469199897971199199199999869473895171251997563\n1487931558946968829951763519656937487546792895476992624978852921947139983499286385266138258935193694\n8195371149998678396987884326188152573756198921899135197653384711783648729791328851979354497969392986\n9179155119423919779667686698689126113994825739951498172517199198989915292457344126929486295984699195\n8692999656696952931996533623896191984859965893774589592193836681957292599821971991739911926636959666\n9985998695572727293692296815985734817249613192327999997928979519414463322843958491689891537727548424\n6785915139891383111991993528714959958913992938996589981164194172299991578319949554372972869927718986\n6812969848431999313262899194267519731924982239497181155761348191171378191195481196281927177836119913\n9241449944689196375316993727965949184951599169899984428189812459955788198778389997529996294911755145\n8263933869291918953191161435562974124985817581189466197959111943314796298198689894947297889469378986\n4993564891474912898412755199548395176295488917317973937991914952763769731425198161936449638498547989\n3919725846368347989866832637399995924176992897196895631935386266839399384868371191995999792294157491\n6721931979356517372592778489839423879114997193842669196756218474195487978729966911652681225999411831\n9597499799876611196188943929378999389985498674958963168888777783921914243997878195898999269889294551\n7897535911127197896722972984867282697846153651471124481587828169258769897847822878831383595997369791\n5831297848191951191794896484123496673799414573379198153884568889918681971924789669965852999915958216\n7823991369999344428821749717198796788139384181691959399667159925814883764695397857939481345499559511\n9836733614869491139178987881497398239923811838118399887762713912361489159279391783489832826615994916\n5877773698989894889438919996977776999993296984984712292923899479697593879272739579864981289939932771\n2542185648228941381995651795998445875943469118314769118387799816194799838958843997735743139876711369\n7882123912881669791399598994599691151814649879989998698859687888628677316516841799215998992997293761\n7767319886981189839889892188919899791985112499817113117779879369341826441898281556786828873779689187\n6517976954449996987552989793838655741268494369149928959518173199587537996199483924421127337969771577\n1678653257398811536189799659999587998996928746191167927896289997861386532556616499279932951899917642\n9572579385451723885561779217789536117629994941561764419872276282572795264367221933191167982181957692\n6315852299992498418936196529371999229568595139535889371219877199885619437539359128266112177998914116\n2985881397958192379949795596996995193595668153648864957619593653435123842865151846253963551826892972\n9181619666251279936984265494857188682368994967895269896197989182176863694399432137388934122967614868\n9593114153726456769958948828218389342288723549641819941784998231817667699584449492849222498974496136\n9916299479892917793359999793199917957999777682139987212993989599198969329559479959128381894449114895\n4921471293815869819213937928199292981798364834953986973773897966731399149773957385692948461798953879\n7939219727388581199654888522599499194589989324361564926162951286688874312293589785941177395118942618\n8437633823193749987229493992993524679593478997117499862387295887499449937233698762911944962872393932\n1957595152944134991298986921999686429196188856825582891848975799829298278988951176691983617917489212\n8139893189759536719371198967498834639886725963146991186976281274983731942436781991256754884914659449\n4822925997999862149916429996168888845197975949578265942598274998974448539673169651999879289189841361\n5241531889998799394875217768389396418913985512418883112994376949161819917922624829789318615483896826\n6952433478181299923958981383758182467119587745189738489917881951247839114135919899874698935397678939\n9998178281168138219688629715164393989381385362839223828189989111183769799437851885123913879668776872\n3479299968682178666263899849126199949521388659643946294899888287792876178914598796793938289488163984\n1225626697911721927373893967969993763233461954269119238318594463694999168939951368891298529984588448\n7889492445296989153714423965492969819915271485178757588997394798779977871918771629125225796727359893\n5778897199718433999153132896886712358389157788434824924928192158771497689159318619912199459651238768\n1795836197799479917189998598989489967373995198279891918988899853122171424496868123951671992389679399\n6529853939912918791899868397879535727748279386788285494854993938674449895593868599789269647149499765\n1878818925186485199559539319973289118966119867769847635447481798718159348669599911752797688859935711\n6236419319741929511583546874658811117988969497296985889278883242999599946847999979139915449889988998\n1198678683349613936877939891939118912969187857959968963634732792198997359438989686371429988735182698\n1998223474469228586568189895871742229825728879174631691151921998877937199256189155647765161238919158\n6432548917454758948968687351996995554975421965763752579179713997554661699137621894836694779175686366\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_15_questions.txt",
    "content": "--- Day 15: Chiton ---\r\n\r\nYou've almost reached the exit of the cave, but the walls are getting closer together. Your submarine can barely still fit, though; the main problem is that the walls of the cave are covered in chitons, and it would be best not to bump any of them.\r\n\r\nThe cavern is large, but has a very low ceiling, restricting your motion to two dimensions. The shape of the cavern resembles a square; a quick scan of chiton density produces a map of risk level throughout the cave (your puzzle input). For example:\r\n\r\n1163751742\r\n1381373672\r\n2136511328\r\n3694931569\r\n7463417111\r\n1319128137\r\n1359912421\r\n3125421639\r\n1293138521\r\n2311944581\r\n\r\nYou start in the top left position, your destination is the bottom right position, and you cannot move diagonally. The number at each position is its risk level; to determine the total risk of an entire path, add up the risk levels of each position you enter (that is, don't count the risk level of your starting position unless you enter it; leaving it adds no risk to your total).\r\n\r\nYour goal is to find a path with the lowest total risk. In this example, a path with the lowest total risk is highlighted here:\r\n\r\n(highlight only on the Web site!)\r\n\r\nThe total risk of this path is 40 (the starting position is never entered, so its risk is not counted).\r\n\r\nWhat is the lowest total risk of any path from the top left to the bottom right?\r\n\r\n--- Part Two ---\r\n\r\nNow that you know how to find low-risk paths in the cave, you can try to find your way out.\r\n\r\nThe entire cave is actually five times larger in both dimensions than you thought; the area you originally scanned is just one tile in a 5x5 tile area that forms the full map. Your original map tile repeats to the right and downward; each time the tile repeats to the right or downward, all of its risk levels are 1 higher than the tile immediately up or left of it. However, risk levels above 9 wrap back around to 1. So, if your original map had some position with a risk level of 8, then that same position on each of the 25 total tiles would be as follows:\r\n\r\n8 9 1 2 3\r\n9 1 2 3 4\r\n1 2 3 4 5\r\n2 3 4 5 6\r\n3 4 5 6 7\r\n\r\nEach single digit above corresponds to the example position with a value of 8 on the top-left tile. Because the full map is actually five times larger in both dimensions, that position appears a total of 25 times, once in each duplicated tile, with the values shown above.\r\n\r\nHere is the full five-times-as-large version of the first example above, with the original map in the top left corner highlighted:\r\n\r\n/---------|\r\n|11637517422274862853338597396444961841755517295286\r\n|13813736722492484783351359589446246169155735727126\r\n|21365113283247622439435873354154698446526571955763\r\n|36949315694715142671582625378269373648937148475914\r\n|74634171118574528222968563933317967414442817852555\r\n|13191281372421239248353234135946434524615754563572\r\n|13599124212461123532357223464346833457545794456865\r\n|31254216394236532741534764385264587549637569865174\r\n|12931385212314249632342535174345364628545647573965\r\n-23119445813422155692453326671356443778246755488935\r\n 22748628533385973964449618417555172952866628316397\r\n 24924847833513595894462461691557357271266846838237\r\n 32476224394358733541546984465265719557637682166874\r\n 47151426715826253782693736489371484759148259586125\r\n 85745282229685639333179674144428178525553928963666\r\n 24212392483532341359464345246157545635726865674683\r\n 24611235323572234643468334575457944568656815567976\r\n 42365327415347643852645875496375698651748671976285\r\n 23142496323425351743453646285456475739656758684176\r\n 34221556924533266713564437782467554889357866599146\r\n 33859739644496184175551729528666283163977739427418\r\n 35135958944624616915573572712668468382377957949348\r\n 43587335415469844652657195576376821668748793277985\r\n 58262537826937364893714847591482595861259361697236\r\n 96856393331796741444281785255539289636664139174777\r\n 35323413594643452461575456357268656746837976785794\r\n 35722346434683345754579445686568155679767926678187\r\n 53476438526458754963756986517486719762859782187396\r\n 34253517434536462854564757396567586841767869795287\r\n 45332667135644377824675548893578665991468977611257\r\n 44961841755517295286662831639777394274188841538529\r\n 46246169155735727126684683823779579493488168151459\r\n 54698446526571955763768216687487932779859814388196\r\n 69373648937148475914825958612593616972361472718347\r\n 17967414442817852555392896366641391747775241285888\r\n 46434524615754563572686567468379767857948187896815\r\n 46833457545794456865681556797679266781878137789298\r\n 64587549637569865174867197628597821873961893298417\r\n 45364628545647573965675868417678697952878971816398\r\n 56443778246755488935786659914689776112579188722368\r\n 55172952866628316397773942741888415385299952649631\r\n 57357271266846838237795794934881681514599279262561\r\n 65719557637682166874879327798598143881961925499217\r\n 71484759148259586125936169723614727183472583829458\r\n 28178525553928963666413917477752412858886352396999\r\n 57545635726865674683797678579481878968159298917926\r\n 57944568656815567976792667818781377892989248891319\r\n 75698651748671976285978218739618932984172914319528\r\n 56475739656758684176786979528789718163989182927419\r\n 67554889357866599146897761125791887223681299833479\r\n\r\nEquipped with the full map, you can now find a path from the top left corner to the bottom right corner with the lowest total risk:\r\n\r\n(highlight only on the Web site!)\r\n\r\nThe total risk of this path is 315 (the starting position is still never entered, so its risk is not counted).\r\n\r\nUsing the full map, what is the lowest total risk of any path from the top left to the bottom right?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_16.adb",
    "content": "--  Solution to Advent of Code 2021, Day 16\n-------------------------------------------\n--  Packet Decoder\n--\n--  https://adventofcode.com/2021/day/16\n--  Copy of questions in: aoc_2021_16_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_16 is\n  use HAT, Interfaces;\n\n  subtype Bit is Integer range 0 .. 1;\n  --\n  msg_max : constant := 32000;\n  msg : array (1 .. msg_max) of Bit;\n  bits : Natural := 0;\n  --\n  procedure Read_Data is\n    input : constant VString := +\"aoc_2021_16.txt\";\n    f : File_Type;\n    s : VString;\n    digit : Natural;\n  begin\n    --  Examples:\n    --  s := +\"D2FE28\";                          --  Literal: 2021.\n    --  s := +\"38006F45291200\";                  --  Operator with 2 subpackets: 10, 20.\n    --  s := +\"EE00D40C823060\";                  --  Operator with 3 subpackets: 1, 2, 3.\n    --  s := +\"8A004A801A8002F478\";              --  Sum of versions = 16.\n    --  s := +\"A0016C880162017C3686B18A3D4780\";  --  Sum of versions = 31.\n    --  s := +\"C200B40A82\";                      --  \"1 + 2\" -> 3.\n    --  s := +\"9C0141080250320F1802104A08\";      --  \"1 + 3 = 2 * 2\" -> 1.\n    --\n    Open (f, input); Get_Line (f, s); Close (f);\n    --\n    for i in 1 ..  Length (s) loop\n      digit := Integer_Value (+\"16#\" &  Element (s, i) & '#');\n      for j in reverse 1 .. 4 loop\n        msg (bits + j) := digit mod 2;\n        digit := digit / 2;\n      end loop;\n      bits := bits + 4;\n    end loop;\n  end Read_Data;\n  --\n  b : Integer_64 := 1;\n  vsum : Integer_64 := 0;\n  --\n  function Process return Integer_64 is\n    procedure Decode (var : out Integer_64; bits : Positive) is\n    begin\n      var := 0;\n      for i in 1 .. bits loop\n        var := var * 2 + Integer_64 (msg (Integer (b)));\n        b := b + 1;\n      end loop;\n    end Decode;\n    end_mark, length_id, sub_length, sub_num, version, id, lit, res : Integer_64;\n    --\n    id_sum     : constant := 0;\n    id_product : constant := 1;\n    id_minimum : constant := 2;\n    id_maximum : constant := 3;\n    id_literal : constant := 4;\n    id_greater : constant := 5;\n    id_less    : constant := 6;\n    id_equal   : constant := 7;\n    --\n    procedure Cumulate (first : Boolean) is\n      term : constant Integer_64 := Process;  --  Here is the recursion :-) .\n    begin\n      if first then\n        res := term;\n      else\n        case id is\n          when id_sum     => res := res + term;\n          when id_product => res := res * term;\n          when id_minimum => if term < res then res := term; end if;\n          when id_maximum => if term > res then res := term; end if;\n          when id_greater => if res > term then res := 1; else res := 0; end if;\n          when id_less    => if res < term then res := 1; else res := 0; end if;\n          when id_equal   => if res = term then res := 1; else res := 0; end if;\n          when others     => null;\n        end case;\n      end if;\n    end Cumulate;\n    b_mem : Integer_64;\n  begin\n    Decode (version, 3);\n    vsum := vsum + version;\n    Decode (id, 3);\n    case id is\n      when id_literal =>\n        res := 0;\n        loop\n          Decode (end_mark, 1);\n          Decode (lit, 4);\n          res := res * 16 + lit;\n          exit when end_mark = 0;\n        end loop;\n      when others =>\n        Decode (length_id, 1);\n        if length_id = 0 then\n          Decode (sub_length, 15);\n          b_mem := b;\n          loop\n            Cumulate (b = b_mem);\n            exit when b = b_mem + sub_length;\n          end loop;\n        else\n          Decode (sub_num, 11);\n          for i in 1 .. sub_num loop\n            Cumulate (i = 1);\n          end loop;\n        end if;\n    end case;\n    return res;\n  end Process;\n  --\n  r : array (1 .. 2) of Integer_64;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  r (2) := Process;\n  r (1) := vsum;\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: sum of version numbers:\" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2: value of expression:   \" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 927\n    --  Part 2: validated by AoC: 1725277876501\n  end if;\nend AoC_2021_16;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_16.txt",
    "content": "A20D6CE8F00033925A95338B6549C0149E3398DE75817200992531E25F005A18C8C8C0001849FDD43629C293004B001059363936796973BF3699CFF4C6C0068C9D72A1231C339802519F001029C2B9C29700B2573962930298B6B524893ABCCEC2BCD681CC010D005E104EFC7246F5EE7328C22C8400424C2538039239F720E3339940263A98029600A80021B1FE34C69100760B41C86D290A8E180256009C9639896A66533E459148200D5AC0149D4E9AACEF0F66B42696194031F000BCE7002D80A8D60277DC00B20227C807E8001CE0C00A7002DC00F300208044E000E69C00B000974C00C1003DC0089B90C1006F5E009CFC87E7E43F3FBADE77BE14C8032C9350D005662754F9BDFA32D881004B12B1964D7000B689B03254564414C016B004A6D3A6BD0DC61E2C95C6E798EA8A4600B5006EC0008542D8690B80010D89F1461B4F535296B6B305A7A4264029580021D1122146900043A0EC7884200085C598CF064C0129CFD8868024592FEE9D7692FEE9D735009E6BBECE0826842730CD250EEA49AA00C4F4B9C9D36D925195A52C4C362EB8043359AE221733DB4B14D9DCE6636ECE48132E040182D802F30AF22F131087EDD9A20804D27BEFF3FD16C8F53A5B599F4866A78D7898C0139418D00424EBB459915200C0BC01098B527C99F4EB54CF0450014A95863BDD3508038600F44C8B90A0801098F91463D1803D07634433200AB68015299EBF4CF5F27F05C600DCEBCCE3A48BC1008B1801AA0803F0CA1AC6200043A2C4558A710E364CC2D14920041E7C9A7040402E987492DE5327CF66A6A93F8CFB4BE60096006E20008543A8330780010E8931C20DCF4BFF13000A424711C4FB32999EE33351500A66E8492F185AB32091F1841C91BE2FDC53C4E80120C8C67EA7734D2448891804B2819245334372CBB0F080480E00D4C0010E82F102360803B1FA2146D963C300BA696A694A501E589A6C80\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_16_questions.txt",
    "content": "--- Day 16: Packet Decoder ---\r\n\r\nAs you leave the cave and reach open waters, you receive a transmission from the Elves back on the ship.\r\n\r\nThe transmission was sent using the Buoyancy Interchange Transmission System (BITS), a method of packing numeric expressions into a binary sequence. Your submarine's computer has saved the transmission in hexadecimal (your puzzle input).\r\n\r\nThe first step of decoding the message is to convert the hexadecimal representation into binary. Each character of hexadecimal corresponds to four bits of binary data:\r\n\r\n0 = 0000\r\n1 = 0001\r\n2 = 0010\r\n3 = 0011\r\n4 = 0100\r\n5 = 0101\r\n6 = 0110\r\n7 = 0111\r\n8 = 1000\r\n9 = 1001\r\nA = 1010\r\nB = 1011\r\nC = 1100\r\nD = 1101\r\nE = 1110\r\nF = 1111\r\n\r\nThe BITS transmission contains a single packet at its outermost layer which itself contains many other packets. The hexadecimal representation of this packet might encode a few extra 0 bits at the end; these are not part of the transmission and should be ignored.\r\n\r\nEvery packet begins with a standard header: the first three bits encode the packet version, and the next three bits encode the packet type ID. These two values are numbers; all numbers encoded in any packet are represented as binary with the most significant bit first. For example, a version encoded as the binary sequence 100 represents the number 4.\r\n\r\nPackets with type ID 4 represent a literal value. Literal value packets encode a single binary number. To do this, the binary number is padded with leading zeroes until its length is a multiple of four bits, and then it is broken into groups of four bits. Each group is prefixed by a 1 bit except the last group, which is prefixed by a 0 bit. These groups of five bits immediately follow the packet header. For example, the hexadecimal string D2FE28 becomes:\r\n\r\n110100101111111000101000\r\nVVVTTTAAAAABBBBBCCCCC\r\n\r\nBelow each bit is a label indicating its purpose:\r\n\r\n    The three bits labeled V (110) are the packet version, 6.\r\n    The three bits labeled T (100) are the packet type ID, 4, which means the packet is a literal value.\r\n    The five bits labeled A (10111) start with a 1 (not the last group, keep reading) and contain the first four bits of the number, 0111.\r\n    The five bits labeled B (11110) start with a 1 (not the last group, keep reading) and contain four more bits of the number, 1110.\r\n    The five bits labeled C (00101) start with a 0 (last group, end of packet) and contain the last four bits of the number, 0101.\r\n    The three unlabeled 0 bits at the end are extra due to the hexadecimal representation and should be ignored.\r\n\r\nSo, this packet represents a literal value with binary representation 011111100101, which is 2021 in decimal.\r\n\r\nEvery other type of packet (any packet with a type ID other than 4) represent an operator that performs some calculation on one or more sub-packets contained within. Right now, the specific operations aren't important; focus on parsing the hierarchy of sub-packets.\r\n\r\nAn operator packet contains one or more packets. To indicate which subsequent binary data represents its sub-packets, an operator packet can use one of two modes indicated by the bit immediately after the packet header; this is called the length type ID:\r\n\r\n    If the length type ID is 0, then the next 15 bits are a number that represents the total length in bits of the sub-packets contained by this packet.\r\n    If the length type ID is 1, then the next 11 bits are a number that represents the number of sub-packets immediately contained by this packet.\r\n\r\nFinally, after the length type ID bit and the 15-bit or 11-bit field, the sub-packets appear.\r\n\r\nFor example, here is an operator packet (hexadecimal string 38006F45291200) with length type ID 0 that contains two sub-packets:\r\n\r\n00111000000000000110111101000101001010010001001000000000\r\nVVVTTTILLLLLLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBBBBBB\r\n\r\n    The three bits labeled V (001) are the packet version, 1.\r\n    The three bits labeled T (110) are the packet type ID, 6, which means the packet is an operator.\r\n    The bit labeled I (0) is the length type ID, which indicates that the length is a 15-bit number representing the number of bits in the sub-packets.\r\n    The 15 bits labeled L (000000000011011) contain the length of the sub-packets in bits, 27.\r\n    The 11 bits labeled A contain the first sub-packet, a literal value representing the number 10.\r\n    The 16 bits labeled B contain the second sub-packet, a literal value representing the number 20.\r\n\r\nAfter reading 11 and 16 bits of sub-packet data, the total length indicated in L (27) is reached, and so parsing of this packet stops.\r\n\r\nAs another example, here is an operator packet (hexadecimal string EE00D40C823060) with length type ID 1 that contains three sub-packets:\r\n\r\n11101110000000001101010000001100100000100011000001100000\r\nVVVTTTILLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBCCCCCCCCCCC\r\n\r\n    The three bits labeled V (111) are the packet version, 7.\r\n    The three bits labeled T (011) are the packet type ID, 3, which means the packet is an operator.\r\n    The bit labeled I (1) is the length type ID, which indicates that the length is a 11-bit number representing the number of sub-packets.\r\n    The 11 bits labeled L (00000000011) contain the number of sub-packets, 3.\r\n    The 11 bits labeled A contain the first sub-packet, a literal value representing the number 1.\r\n    The 11 bits labeled B contain the second sub-packet, a literal value representing the number 2.\r\n    The 11 bits labeled C contain the third sub-packet, a literal value representing the number 3.\r\n\r\nAfter reading 3 complete sub-packets, the number of sub-packets indicated in L (3) is reached, and so parsing of this packet stops.\r\n\r\nFor now, parse the hierarchy of the packets throughout the transmission and add up all of the version numbers.\r\n\r\nHere are a few more examples of hexadecimal-encoded transmissions:\r\n\r\n    8A004A801A8002F478 represents an operator packet (version 4) which contains an operator packet (version 1) which contains an operator packet (version 5) which contains a literal value (version 6); this packet has a version sum of 16.\r\n    620080001611562C8802118E34 represents an operator packet (version 3) which contains two sub-packets; each sub-packet is an operator packet that contains two literal values. This packet has a version sum of 12.\r\n    C0015000016115A2E0802F182340 has the same structure as the previous example, but the outermost packet uses a different length type ID. This packet has a version sum of 23.\r\n    A0016C880162017C3686B18A3D4780 is an operator packet that contains an operator packet that contains an operator packet that contains five literal values; it has a version sum of 31.\r\n\r\nDecode the structure of your hexadecimal-encoded BITS transmission; what do you get if you add up the version numbers in all packets?\r\n\r\n--- Part Two ---\r\n\r\nNow that you have the structure of your transmission decoded, you can calculate the value of the expression it represents.\r\n\r\nLiteral values (type ID 4) represent a single number as described above. The remaining type IDs are more interesting:\r\n\r\n    Packets with type ID 0 are sum packets - their value is the sum of the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet.\r\n    Packets with type ID 1 are product packets - their value is the result of multiplying together the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet.\r\n    Packets with type ID 2 are minimum packets - their value is the minimum of the values of their sub-packets.\r\n    Packets with type ID 3 are maximum packets - their value is the maximum of the values of their sub-packets.\r\n    Packets with type ID 5 are greater than packets - their value is 1 if the value of the first sub-packet is greater than the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets.\r\n    Packets with type ID 6 are less than packets - their value is 1 if the value of the first sub-packet is less than the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets.\r\n    Packets with type ID 7 are equal to packets - their value is 1 if the value of the first sub-packet is equal to the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets.\r\n\r\nUsing these rules, you can now work out the value of the outermost packet in your BITS transmission.\r\n\r\nFor example:\r\n\r\n    C200B40A82 finds the sum of 1 and 2, resulting in the value 3.\r\n    04005AC33890 finds the product of 6 and 9, resulting in the value 54.\r\n    880086C3E88112 finds the minimum of 7, 8, and 9, resulting in the value 7.\r\n    CE00C43D881120 finds the maximum of 7, 8, and 9, resulting in the value 9.\r\n    D8005AC2A8F0 produces 1, because 5 is less than 15.\r\n    F600BC2D8F produces 0, because 5 is not greater than 15.\r\n    9C005AC2F8F0 produces 0, because 5 is not equal to 15.\r\n    9C0141080250320F1802104A08 produces 1, because 1 + 3 = 2 * 2.\r\n\r\nWhat do you get if you evaluate the expression represented by your hexadecimal-encoded BITS transmission?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_17.adb",
    "content": "--  Solution to Advent of Code 2021, Day 17\n-------------------------------------------\n--  Trick Shot\n--\n--  https://adventofcode.com/2021/day/17\n--  Copy of questions in: aoc_2021_17_questions.txt\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_17 is\n  use HAT;\n  --  Input target area: x=155..215, y=-132..-72\n  x_min : constant :=  155;\n  x_max : constant :=  215;\n  y_min : constant := -132;\n  y_max : constant :=  -72;\n\n  --  Example: target area: x=20..30, y=-10..-5\n  --  x_min : constant :=  20;\n  --  x_max : constant :=  30;\n  --  y_min : constant := -10;\n  --  y_max : constant :=  -5;\n\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n  x, y, ym, ymm, vx, vy, hits : Integer;\nbegin\n  ymm := 0;\n  hits := 0;\n  for vx_0 in 1 .. x_max loop  --  Above x_max you miss the area at first step.\n    for vy_0 in y_min .. 200 loop  --  Top value is heuristically searched (stable results).\n      vx := vx_0;\n      vy := vy_0;\n      x := 0;\n      y := 0;\n      ym := 0;\n      loop\n        x := x + vx;\n        y := y + vy;\n        ym := Max (ym, y);\n        vx := Max (0, vx - 1);\n        vy := vy - 1;\n        if x in x_min .. x_max and then y in y_min .. y_max then\n          hits := hits + 1;\n          if ym > ymm then\n            ymm := ym;\n            --  Put_Line (+\"hit ym =\" & ym & \"   vx_0 = \" & vx_0 & \", vy_0 = \" & vy_0);\n          end if;\n          exit;\n        end if;\n        exit when y < y_min;\n      end loop;\n    end loop;\n  end loop;\n  r (1) := ymm;\n  r (2) := hits;\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: highest y position reached on a trajectory with a hit:   \" & r (1));\n    Put_Line (+\"Part 2: number of distinct initial velocity values causing hits: \" & r (2));\n    --  Part 1: validated by AoC: 8646\n    --  Part 2: validated by AoC: 5945\n  end if;\nend AoC_2021_17;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_17_questions.txt",
    "content": "--- Day 17: Trick Shot ---\n\nYou finally decode the Elves' message. HI, the message says. You continue searching for the sleigh keys.\n\nAhead of you is what appears to be a large ocean trench. Could the keys have fallen into it? You'd better send a probe to investigate.\n\nThe probe launcher on your submarine can fire the probe with any integer velocity in the x (forward) and y (upward, or downward if negative) directions. For example, an initial x,y velocity like 0,10 would fire the probe straight up, while an initial velocity like 10,-1 would fire the probe forward at a slight downward angle.\n\nThe probe's x,y position starts at 0,0. Then, it will follow some trajectory by moving in steps. On each step, these changes occur in the following order:\n\n    The probe's x position increases by its x velocity.\n    The probe's y position increases by its y velocity.\n    Due to drag, the probe's x velocity changes by 1 toward the value 0; that is, it decreases by 1 if it is greater than 0, increases by 1 if it is less than 0, or does not change if it is already 0.\n    Due to gravity, the probe's y velocity decreases by 1.\n\nFor the probe to successfully make it into the trench, the probe must be on some trajectory that causes it to be within a target area after any step. The submarine computer has already calculated this target area (your puzzle input). For example:\n\ntarget area: x=20..30, y=-10..-5\n\nThis target area means that you need to find initial x,y velocity values such that after any step, the probe's x position is at least 20 and at most 30, and the probe's y position is at least -10 and at most -5.\n\nGiven this target area, one initial velocity that causes the probe to be within the target area after any step is 7,2:\n\n.............#....#............\n.......#..............#........\n...............................\nS........................#.....\n...............................\n...............................\n...........................#...\n...............................\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................TTTTTTTT#TT\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n\nIn this diagram, S is the probe's initial position, 0,0. The x coordinate increases to the right, and the y coordinate increases upward. In the bottom right, positions that are within the target area are shown as T. After each step (until the target area is reached), the position of the probe is marked with #. (The bottom-right # is both a position the probe reaches and a position in the target area.)\n\nAnother initial velocity that causes the probe to be within the target area after any step is 6,3:\n\n...............#..#............\n...........#........#..........\n...............................\n......#..............#.........\n...............................\n...............................\nS....................#.........\n...............................\n...............................\n...............................\n.....................#.........\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................T#TTTTTTTTT\n....................TTTTTTTTTTT\n\nAnother one is 9,0:\n\nS........#.....................\n.................#.............\n...............................\n........................#......\n...............................\n....................TTTTTTTTTTT\n....................TTTTTTTTTT#\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n....................TTTTTTTTTTT\n\nOne initial velocity that doesn't cause the probe to be within the target area after any step is 17,-4:\n\nS..............................................................\n...............................................................\n...............................................................\n...............................................................\n.................#.............................................\n....................TTTTTTTTTTT................................\n....................TTTTTTTTTTT................................\n....................TTTTTTTTTTT................................\n....................TTTTTTTTTTT................................\n....................TTTTTTTTTTT..#.............................\n....................TTTTTTTTTTT................................\n...............................................................\n...............................................................\n...............................................................\n...............................................................\n................................................#..............\n...............................................................\n...............................................................\n...............................................................\n...............................................................\n...............................................................\n...............................................................\n..............................................................#\n\nThe probe appears to pass through the target area, but is never within it after any step. Instead, it continues down and to the right - only the first few steps are shown.\n\nIf you're going to fire a highly scientific probe out of a super cool probe launcher, you might as well do it with style. How high can you make the probe go while still reaching the target area?\n\nIn the above example, using an initial velocity of 6,9 is the best you can do, causing the probe to reach a maximum y position of 45. (Any higher initial y velocity causes the probe to overshoot the target area entirely.)\n\nFind the initial velocity that causes the probe to reach the highest y position and still eventually be within the target area after any step. What is the highest y position it reaches on this trajectory?\n\n--- Part Two ---\n\nMaybe a fancy trick shot isn't the best idea; after all, you only have one probe, so you had better not miss.\n\nTo get the best idea of what your options are for launching the probe, you need to find every initial velocity that causes the probe to eventually be within the target area after any step.\n\nIn the above example, there are 112 different initial velocity values that meet these criteria:\n\n23,-10  25,-9   27,-5   29,-6   22,-6   21,-7   9,0     27,-7   24,-5\n25,-7   26,-6   25,-5   6,8     11,-2   20,-5   29,-10  6,3     28,-7\n8,0     30,-6   29,-8   20,-10  6,7     6,4     6,1     14,-4   21,-6\n26,-10  7,-1    7,7     8,-1    21,-9   6,2     20,-7   30,-10  14,-3\n20,-8   13,-2   7,3     28,-8   29,-9   15,-3   22,-5   26,-8   25,-8\n25,-6   15,-4   9,-2    15,-2   12,-2   28,-9   12,-3   24,-6   23,-7\n25,-10  7,8     11,-3   26,-7   7,1     23,-9   6,0     22,-10  27,-6\n8,1     22,-8   13,-4   7,6     28,-6   11,-4   12,-4   26,-9   7,4\n24,-10  23,-8   30,-8   7,0     9,-1    10,-1   26,-5   22,-9   6,5\n7,5     23,-6   28,-10  10,-2   11,-1   20,-9   14,-2   29,-7   13,-3\n23,-5   24,-8   27,-9   30,-7   28,-5   21,-10  7,9     6,6     21,-5\n27,-10  7,2     30,-9   21,-8   22,-7   24,-9   20,-6   6,9     29,-5\n8,-2    27,-8   30,-5   24,-7\n\nHow many distinct initial velocity values cause the probe to be within the target area after any step?\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_18.txt",
    "content": "[[[1,4],[1,6]],[0,[5,[6,3]]]]\n[[[8,2],5],[[[9,8],[3,5]],[2,1]]]\n[[[[6,2],[0,6]],[[9,8],[7,8]]],[[6,3],[[8,8],3]]]\n[[[1,[2,1]],[5,7]],[[[3,1],[3,1]],[[8,4],[8,5]]]]\n[[[[6,4],7],[[1,6],5]],[7,[9,5]]]\n[[7,[[5,3],[0,9]]],[[[6,2],[6,8]],[5,[5,7]]]]\n[9,5]\n[[[[7,8],[8,0]],[[3,8],[0,7]]],[[1,[1,2]],2]]\n[[[4,[5,5]],[[6,8],[4,3]]],[[9,9],[4,[3,6]]]]\n[[[[2,8],7],[[6,1],[1,0]]],[[6,2],9]]\n[[[8,1],3],[9,[[1,4],[4,1]]]]\n[[[[0,1],[3,9]],[[4,3],6]],[[[4,8],8],[[8,3],[9,5]]]]\n[[[[7,3],7],[[5,9],0]],7]\n[[[5,[1,6]],3],[[3,5],9]]\n[[[[2,5],[1,8]],[[6,5],[0,1]]],[[[4,1],1],[0,[9,6]]]]\n[[[4,8],[[3,6],[3,8]]],[[[2,3],3],[[9,8],[7,9]]]]\n[[[[5,6],0],[9,[4,4]]],[[[3,1],[3,6]],[[6,0],3]]]\n[[[[4,3],4],4],[[[1,6],7],[8,[6,0]]]]\n[[[0,2],1],5]\n[[[[7,2],[9,0]],[8,[0,1]]],2]\n[[[1,6],[[6,2],5]],[[1,[8,2]],[[9,8],7]]]\n[[[8,1],9],[[[4,3],2],[[2,9],6]]]\n[[[[9,4],0],[4,0]],4]\n[[[5,[2,8]],[[5,3],[6,4]]],[8,3]]\n[[0,5],[[[3,4],7],[[0,2],[9,1]]]]\n[[[8,[7,9]],[[1,8],6]],[[4,[6,0]],0]]\n[[[1,0],[[6,7],4]],[[[2,5],[9,7]],[[7,8],0]]]\n[[9,[[7,1],3]],[[[9,2],[4,3]],[2,[1,8]]]]\n[[[5,[9,6]],4],[1,[[9,2],[6,8]]]]\n[6,[[[6,1],7],6]]\n[[4,[[5,6],9]],[[9,[6,6]],[[6,1],[8,2]]]]\n[[1,[9,5]],[[[5,8],9],5]]\n[[[[6,6],[1,8]],6],[[[4,9],4],[8,[9,8]]]]\n[[[[6,5],[4,4]],[[0,2],8]],[[[0,6],[4,5]],3]]\n[[[1,[6,9]],[9,[5,8]]],[5,2]]\n[[2,[[2,8],[3,3]]],[[[1,9],9],6]]\n[[3,2],[9,[2,2]]]\n[4,[3,[6,[2,0]]]]\n[[[[1,0],4],3],[[0,9],[[9,8],[7,1]]]]\n[[[2,6],[3,8]],[[5,5],[2,3]]]\n[6,[[[8,8],4],[[8,1],[6,6]]]]\n[[[5,9],[5,3]],7]\n[[[5,[1,2]],[6,[7,2]]],[[[0,5],3],3]]\n[[8,[[7,3],[9,7]]],[[2,[3,9]],[[1,7],[5,7]]]]\n[8,[4,6]]\n[[[4,4],[[4,5],[2,5]]],[[[9,1],0],[[2,9],1]]]\n[[[2,[2,8]],9],[5,[6,9]]]\n[[[[4,1],5],[6,[2,7]]],[1,2]]\n[[[6,[3,5]],0],[[0,3],4]]\n[[[[3,2],[8,0]],[5,1]],[[[9,7],3],[[6,5],[2,6]]]]\n[[1,[0,[1,4]]],[[[8,6],[6,9]],[[4,9],8]]]\n[[[[5,2],[4,3]],[0,[3,5]]],[0,[1,7]]]\n[[[8,1],[3,[8,1]]],[[[7,9],[6,2]],[[0,8],2]]]\n[[[2,[9,7]],[[6,6],[2,7]]],[[8,[6,4]],0]]\n[[3,0],[[6,3],1]]\n[[[[5,5],2],[9,7]],[[0,[3,5]],7]]\n[[[[4,8],2],0],[[4,[7,9]],[6,6]]]\n[[[1,0],[[9,4],[8,8]]],2]\n[[[6,1],9],[5,2]]\n[[[7,[0,3]],[[5,5],7]],[5,[[0,5],[5,3]]]]\n[[[[8,0],4],[[5,5],[9,4]]],[[[9,0],[2,5]],[6,[8,1]]]]\n[[[7,8],[0,[5,4]]],[[[7,6],[0,9]],[7,2]]]\n[[[4,[0,2]],[3,[4,9]]],[[[4,7],8],3]]\n[[1,[5,[7,3]]],8]\n[[[[1,3],[6,8]],3],[[6,1],8]]\n[[[[7,9],5],[[6,2],4]],[[5,[6,9]],1]]\n[[2,[3,[9,3]]],[[6,[2,7]],[4,8]]]\n[7,[[6,2],[[6,7],[5,0]]]]\n[[[9,[8,6]],1],[[4,8],[[6,1],[0,1]]]]\n[[[[4,6],[4,0]],[[2,4],0]],[[[0,5],[9,8]],[[3,4],[2,5]]]]\n[9,[3,[[5,5],[3,1]]]]\n[[[5,[7,1]],3],[[[8,2],5],[[2,8],[0,0]]]]\n[[[[8,3],0],[[5,0],5]],[[3,[8,2]],[[8,2],3]]]\n[[4,[[9,4],5]],[[[1,6],[0,2]],[0,8]]]\n[[[0,0],[[1,8],2]],[[[1,8],1],[0,[0,8]]]]\n[[[6,[1,5]],5],[[2,[0,1]],9]]\n[[7,[2,[2,8]]],[4,[[1,1],5]]]\n[1,[[4,[0,5]],4]]\n[[3,[[3,1],[1,2]]],[[[5,3],8],[5,2]]]\n[[[3,[2,0]],6],[[9,3],[[3,0],[1,6]]]]\n[4,[[6,[5,9]],[[4,1],[6,6]]]]\n[8,[3,0]]\n[[[[5,3],[8,8]],[[5,1],4]],[[6,6],[8,2]]]\n[[1,[[7,1],5]],[[[2,3],7],[[7,6],0]]]\n[9,[[4,3],[[6,2],0]]]\n[[[[4,0],4],[1,7]],[[[3,8],8],[[9,1],1]]]\n[[[0,1],[9,9]],7]\n[[[[1,7],0],[1,5]],[1,[2,2]]]\n[[[[6,1],[3,3]],[6,[9,0]]],[[7,0],3]]\n[[[[6,1],[9,8]],[[2,2],2]],[8,[3,6]]]\n[[6,[5,0]],[7,[1,7]]]\n[[4,[[6,1],6]],[[2,5],7]]\n[8,[8,[[6,4],1]]]\n[[[[0,2],4],[[2,6],2]],0]\n[[2,[[6,1],9]],[[7,[0,5]],[5,[9,4]]]]\n[3,[[8,7],[[8,9],6]]]\n[[[[7,8],[1,1]],[[2,6],[3,7]]],4]\n[[[[6,1],1],5],5]\n[[9,[4,[6,6]]],[[5,1],[8,2]]]\n[[5,[[7,3],4]],9]\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_18_full_ada.adb",
    "content": "--  Solution to Advent of Code 2021, Day 18\n-------------------------------------------\n--  Snailfish\n--\n--  NB: this doesn't compile with HAC, only with a \"full Ada\" compiler.\n--\n--  To do: make a HAC solution using a heap structure for the\n--  binary tree (idea Maxim Reznik)\n\n--  https://adventofcode.com/2021/day/18\n--  Copy of questions in: aoc_2021_18_questions.txt\n--\nwith HAT;  --  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n\nwith Ada.Unchecked_Deallocation;\n\nprocedure AoC_2021_18_full_Ada is\n  use HAT;\n\n  type Node_Type;\n\n  type Node_Access is access Node_Type;\n\n  type Node_Type (is_pair : Boolean) is record\n    case is_pair is\n      when True  => left, right : Node_Access;\n      when False => number      : Integer;\n    end case;\n  end record;\n\n  procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);\n\n  procedure Clear (n : in out Node_Access) is\n  begin\n    if n /= null then\n      if n.is_pair then\n        Clear (n.left);\n        Clear (n.right);\n      end if;\n      Free (n);\n    end if;\n  end Clear;\n\n  subtype Snailfish_Number is Node_Access;  --  Just a nicer name.\n\n  procedure Show (node : Snailfish_Number) is\n  begin\n    if node.is_pair then\n      Put ('[');\n      Show (node.left);\n      Put (',');\n      Show (node.right);\n      Put (']');\n    else\n      Put (node.number, 0);\n    end if;\n  end Show;\n  pragma Unreferenced (Show);\n\n  procedure Reduce (number : in out Snailfish_Number) is\n    change : Boolean;\n    add_left, add_right : Natural;\n    --\n    procedure Solve_Left (node : Snailfish_Number)  is\n    begin\n      if add_left = 0 then\n        return;\n      end if;\n      if node.is_pair then\n        --  The left exploded number goes rightmost, on the left side:\n        Solve_Left (node.right);    --  Prioritize the right node.\n        Solve_Left (node.left);\n      elsif add_left > 0 then\n        node.number := node.number + add_left;\n        add_left := 0;\n      end if;\n    end Solve_Left;\n    --\n    procedure Solve_Right (node : Snailfish_Number)  is\n    begin\n      if add_right = 0 then\n        return;\n      end if;\n      if node.is_pair then\n        --  The right exploded number goes leftmost, on the right side:\n        Solve_Right (node.left);    --  Prioritize the left node.\n        Solve_Right (node.right);\n      elsif add_right > 0 then\n        node.number := node.number + add_right;\n        add_right := 0;\n      end if;\n    end Solve_Right;\n    --\n    procedure Explode (node : in out Snailfish_Number; level : Natural)  is\n    begin\n      if change then\n        return;\n      end if;\n      if node.is_pair then\n        if level = 5 then\n          pragma Assert (not node.left.is_pair);\n          pragma Assert (not node.right.is_pair);\n          add_left  := node.left.number;\n          add_right := node.right.number;\n          Free (node);\n          node := new Node_Type'(False, 0);\n          change := True;\n        else\n          Explode (node.left, level + 1);\n          if change then\n            --  There is always a number in the part of the tree\n            --  starting at the sibling node. So, no need to try\n            --  adding the number elsewhere in the tree.\n            Solve_Right (node.right);\n          else\n            Explode (node.right, level + 1);\n            if change then\n              --  Same remark as above.\n              Solve_Left (node.left);\n            end if;\n          end if;\n        end if;\n      end if;\n    end Explode;\n    --\n    procedure Split (node : in out Snailfish_Number) is\n      new_left, new_right : Snailfish_Number;\n    begin\n      if change then\n        return;\n      end if;\n      if node.is_pair then\n        Split (node.left);\n        Split (node.right);\n      elsif node.number > 9 then\n        new_left  := new Node_Type'(False, node.number / 2);\n        new_right := new Node_Type'(False, node.number - new_left.number);\n        Free (node);\n        node := new Node_Type'(True, new_left, new_right);\n        change := True;\n      end if;\n    end Split;\n    --\n  begin\n    loop\n      change := False;\n      add_left  := 0;\n      add_right := 0;\n      Explode (number, 1);\n      Split (number);\n      exit when not change;\n    end loop;\n  end Reduce;\n  --\n  function Magnitude (node : Snailfish_Number) return Integer is\n  begin\n    if node.is_pair then\n      return 3 * Magnitude (node.left) + 2 * Magnitude (node.right);\n    else\n      return node.number;\n    end if;\n  end Magnitude;\n  --\n  function \"+\" (a, b : Snailfish_Number) return Snailfish_Number is\n    a_plus_b : Snailfish_Number;\n  begin\n    if a = null then\n      return b;\n    end if;\n    if b = null then\n      return a;\n    end if;\n    --  Snailfish addition:\n    a_plus_b := new Node_Type'(True, a, b);\n    --  \"snailfish numbers must always be reduced, and the process\n    --     numbers of adding two snailfish numbers can result in\n    --     snailfish that need to be reduced.\"\n    --  This rule avoids nesting levels > 5 at any point, including\n    --  after the next unreduced addition.\n    Reduce (a_plus_b);\n    return a_plus_b;\n  end \"+\";\n  --\n  number_of_terms : Natural := 0;\n  root : Snailfish_Number := null;\n  --\n  procedure Read_Data (\n    l1, l2     : Natural := 0;     --  When not 0, read only lines l1, l2.\n    is_swapped : Boolean := False\n  )\n  is\n    input : constant VString := +\"aoc_2021_18.txt\";\n    --\n    c, sep : Character;\n    f : File_Type;\n    function Read_Item return Snailfish_Number is\n      node : Snailfish_Number;\n    begin\n      Get (f, c);\n      if c = '[' then\n        --  It's a pair\n        node := new Node_Type (is_pair => True);\n        node.left := Read_Item;\n        Get (f, sep);  --  ','\n        node.right := Read_Item;\n        Get (f, sep);  --  ']'\n      else\n        --  It's a literal\n        node := new Node_Type (is_pair => False);\n        node.number := Ord (c) - Ord ('0');\n      end if;\n      return node;\n    end Read_Item;\n    --\n    l : Natural := 0;\n    dummy : Snailfish_Number;\n  begin\n    Open (f, input);\n    loop\n      l := l + 1;\n      if l1 = 0 or else l = l1 or else l = l2 then\n        if is_swapped then\n          root := Read_Item + root;\n        else\n          root := root + Read_Item;\n        end if;\n      else\n        dummy := Read_Item;\n        Clear (dummy);\n      end if;\n      exit when End_Of_File (f);\n    end loop;\n    Close (f);\n    number_of_terms := l;\n  end Read_Data;\n  --\n  max : Natural := 0;\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  --\n  r (1) := Magnitude (root);\n  Clear (root);\n  for i in 1 .. number_of_terms - 1 loop\n    for j in i + 1 .. number_of_terms loop\n      for is_swapped in Boolean loop\n        --  Re-reading selectively the data is simpler\n        --  than deep-cloning trees.\n        Read_Data (i, j, is_swapped);\n        max := Integer'Max (max,  Magnitude (root));\n        Clear (root);\n      end loop;\n    end loop;\n  end loop;\n  r (2) := max;\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: Magnitude of the sum of all terms                : \" & r (1));\n    Put_Line (+\"Part 2: Largest magnitude of the sum of any pair of terms: \" & r (2));\n    --  Part 1: validated by AoC: 3665.\n    --  Part 2: validated by AoC: 4775.\n  end if;\nend AoC_2021_18_full_Ada;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_18_questions.txt",
    "content": "--- Day 18: Snailfish ---\r\n\r\nYou descend into the ocean trench and encounter some snailfish. They say they saw the sleigh keys! They'll even tell you which direction the keys went if you help one of the smaller snailfish with his math homework.\r\n\r\nSnailfish numbers aren't like regular numbers. Instead, every snailfish number is a pair - an ordered list of two elements. Each element of the pair can be either a regular number or another pair.\r\n\r\nPairs are written as [x,y], where x and y are the elements within the pair. Here are some example snailfish numbers, one snailfish number per line:\r\n\r\n[1,2]\r\n[[1,2],3]\r\n[9,[8,7]]\r\n[[1,9],[8,5]]\r\n[[[[1,2],[3,4]],[[5,6],[7,8]]],9]\r\n[[[9,[3,8]],[[0,9],6]],[[[3,7],[4,9]],3]]\r\n[[[[1,3],[5,3]],[[1,3],[8,7]]],[[[4,9],[6,9]],[[8,2],[7,3]]]]\r\n\r\nThis snailfish homework is about addition. To add two snailfish numbers, form a pair from the left and right parameters of the addition operator. For example, [1,2] + [[3,4],5] becomes [[1,2],[[3,4],5]].\r\n\r\nThere's only one problem: snailfish numbers must always be reduced, and the process of adding two snailfish numbers can result in snailfish numbers that need to be reduced.\r\n\r\nTo reduce a snailfish number, you must repeatedly do the first action in this list that applies to the snailfish number:\r\n\r\n    If any pair is nested inside four pairs, the leftmost such pair explodes.\r\n    If any regular number is 10 or greater, the leftmost such regular number splits.\r\n\r\nOnce no action in the above list applies, the snailfish number is reduced.\r\n\r\nDuring reduction, at most one action applies, after which the process returns to the top of the list of actions. For example, if split produces a pair that meets the explode criteria, that pair explodes before other splits occur.\r\n\r\nTo explode a pair, the pair's left value is added to the first regular number to the left of the exploding pair (if any), and the pair's right value is added to the first regular number to the right of the exploding pair (if any). Exploding pairs will always consist of two regular numbers. Then, the entire exploding pair is replaced with the regular number 0.\r\n\r\nHere are some examples of a single explode action:\r\n\r\n    [[[[[9,8],1],2],3],4] becomes [[[[0,9],2],3],4] (the 9 has no regular number to its left, so it is not added to any regular number).\r\n    [7,[6,[5,[4,[3,2]]]]] becomes [7,[6,[5,[7,0]]]] (the 2 has no regular number to its right, and so it is not added to any regular number).\r\n    [[6,[5,[4,[3,2]]]],1] becomes [[6,[5,[7,0]]],3].\r\n    [[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]] becomes [[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]] (the pair [3,2] is unaffected because the pair [7,3] is further to the left; [3,2] would explode on the next action).\r\n    [[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]] becomes [[3,[2,[8,0]]],[9,[5,[7,0]]]].\r\n\r\nTo split a regular number, replace it with a pair; the left element of the pair should be the regular number divided by two and rounded down, while the right element of the pair should be the regular number divided by two and rounded up. For example, 10 becomes [5,5], 11 becomes [5,6], 12 becomes [6,6], and so on.\r\n\r\nHere is the process of finding the reduced result of [[[[4,3],4],4],[7,[[8,4],9]]] + [1,1]:\r\n\r\nafter addition: [[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]\r\nafter explode:  [[[[0,7],4],[7,[[8,4],9]]],[1,1]]\r\nafter explode:  [[[[0,7],4],[15,[0,13]]],[1,1]]\r\nafter split:    [[[[0,7],4],[[7,8],[0,13]]],[1,1]]\r\nafter split:    [[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]\r\nafter explode:  [[[[0,7],4],[[7,8],[6,0]]],[8,1]]\r\n\r\nOnce no reduce actions apply, the snailfish number that remains is the actual result of the addition operation: [[[[0,7],4],[[7,8],[6,0]]],[8,1]].\r\n\r\nThe homework assignment involves adding up a list of snailfish numbers (your puzzle input). The snailfish numbers are each listed on a separate line. Add the first snailfish number and the second, then add that result and the third, then add that result and the fourth, and so on until all numbers in the list have been used once.\r\n\r\nFor example, the final sum of this list is [[[[1,1],[2,2]],[3,3]],[4,4]]:\r\n\r\n[1,1]\r\n[2,2]\r\n[3,3]\r\n[4,4]\r\n\r\nThe final sum of this list is [[[[3,0],[5,3]],[4,4]],[5,5]]:\r\n\r\n[1,1]\r\n[2,2]\r\n[3,3]\r\n[4,4]\r\n[5,5]\r\n\r\nThe final sum of this list is [[[[5,0],[7,4]],[5,5]],[6,6]]:\r\n\r\n[1,1]\r\n[2,2]\r\n[3,3]\r\n[4,4]\r\n[5,5]\r\n[6,6]\r\n\r\nHere's a slightly larger example:\r\n\r\n[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]\r\n[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]\r\n[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]\r\n[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]\r\n[7,[5,[[3,8],[1,4]]]]\r\n[[2,[2,2]],[8,[8,1]]]\r\n[2,9]\r\n[1,[[[9,3],9],[[9,0],[0,7]]]]\r\n[[[5,[7,4]],7],1]\r\n[[[[4,2],2],6],[8,7]]\r\n\r\nThe final sum [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]] is found after adding up the above snailfish numbers:\r\n\r\n  [[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]\r\n+ [7,[[[3,7],[4,3]],[[6,3],[8,8]]]]\r\n= [[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]\r\n\r\n  [[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]\r\n+ [[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]\r\n= [[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]\r\n\r\n  [[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]\r\n+ [[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]\r\n= [[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]\r\n\r\n  [[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]\r\n+ [7,[5,[[3,8],[1,4]]]]\r\n= [[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]\r\n\r\n  [[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]\r\n+ [[2,[2,2]],[8,[8,1]]]\r\n= [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]\r\n\r\n  [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]\r\n+ [2,9]\r\n= [[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]\r\n\r\n  [[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]\r\n+ [1,[[[9,3],9],[[9,0],[0,7]]]]\r\n= [[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]\r\n\r\n  [[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]\r\n+ [[[5,[7,4]],7],1]\r\n= [[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]\r\n\r\n  [[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]\r\n+ [[[[4,2],2],6],[8,7]]\r\n= [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]\r\n\r\nTo check whether it's the right answer, the snailfish teacher only checks the magnitude of the final sum. The magnitude of a pair is 3 times the magnitude of its left element plus 2 times the magnitude of its right element. The magnitude of a regular number is just that number.\r\n\r\nFor example, the magnitude of [9,1] is 3*9 + 2*1 = 29; the magnitude of [1,9] is 3*1 + 2*9 = 21. Magnitude calculations are recursive: the magnitude of [[9,1],[1,9]] is 3*29 + 2*21 = 129.\r\n\r\nHere are a few more magnitude examples:\r\n\r\n    [[1,2],[[3,4],5]] becomes 143.\r\n    [[[[0,7],4],[[7,8],[6,0]]],[8,1]] becomes 1384.\r\n    [[[[1,1],[2,2]],[3,3]],[4,4]] becomes 445.\r\n    [[[[3,0],[5,3]],[4,4]],[5,5]] becomes 791.\r\n    [[[[5,0],[7,4]],[5,5]],[6,6]] becomes 1137.\r\n    [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]] becomes 3488.\r\n\r\nSo, given this example homework assignment:\r\n\r\n[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]\r\n[[[5,[2,8]],4],[5,[[9,9],0]]]\r\n[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]\r\n[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]\r\n[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]\r\n[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]\r\n[[[[5,4],[7,7]],8],[[8,3],8]]\r\n[[9,3],[[9,9],[6,[4,9]]]]\r\n[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]\r\n[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]\r\n\r\nThe final sum is:\r\n\r\n[[[[6,6],[7,6]],[[7,7],[7,0]]],[[[7,7],[7,7]],[[7,8],[9,9]]]]\r\n\r\nThe magnitude of this final sum is 4140.\r\n\r\nAdd up all of the snailfish numbers from the homework assignment in the order they appear. What is the magnitude of the final sum?\r\n\r\n--- Part Two ---\r\n\r\nYou notice a second question on the back of the homework assignment:\r\n\r\nWhat is the largest magnitude you can get from adding only two of the snailfish numbers?\r\n\r\nNote that snailfish addition is not commutative - that is, x + y and y + x can produce different results.\r\n\r\nAgain considering the last example homework assignment above:\r\n\r\n[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]\r\n[[[5,[2,8]],4],[5,[[9,9],0]]]\r\n[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]\r\n[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]\r\n[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]\r\n[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]\r\n[[[[5,4],[7,7]],8],[[8,3],8]]\r\n[[9,3],[[9,9],[6,[4,9]]]]\r\n[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]\r\n[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]\r\n\r\nThe largest magnitude of the sum of any two snailfish numbers in this list is 3993. This is the magnitude of [[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]] + [[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]], which reduces to [[[[7,8],[6,6]],[[6,0],[7,7]]],[[[7,8],[8,8]],[[7,9],[0,6]]]].\r\n\r\nWhat is the largest magnitude of any sum of two different snailfish numbers from the homework assignment?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_19.adb",
    "content": "--  Solution to Advent of Code 2021, Day 19\n-------------------------------------------\n--  Beacon Scanner\n--\n--  https://adventofcode.com/2021/day/19\n--  Copy of questions in: aoc_2021_19_questions.txt\n--\n--  Note: this programs takes very long on HAC!\n--\n--  HAC 0.098 \"nice to have\"'s detected in this exercise:\n--    *     Performance: large \"in\" parameters passed as reference\n--    *     Comparison (equality operators) \"=\", \"/=\" of composite types (arrays and records)\n--    *     Detect an expression as a static (compile-time-known) value\n--\n--  Solved in HAC 0.26:\n--    *     Exiting multiple nested loops\n--    *     `EXIT [Label]`\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_19 is\n\n  type Vector is array (1 .. 3) of Integer;\n\n  subtype Cube_Face is Integer range 1 .. 6;\n  subtype Plane_Rotation is Integer range 1 .. 4;\n\n  use HAT;\n\n  procedure Rotate (v : in out Vector; face : Cube_Face; spin : Plane_Rotation) is\n    w : Vector;\n  begin\n    w (3) := v (3);\n    case spin is\n      when 1 => w (1) :=  v (1); w (2) := v (2);\n      --  Rotate around z\n      when 2 => w (1) := -v (2); w (2) :=  v (1);  --   90\n      when 3 => w (1) := -v (1); w (2) := -v (2);  --  180\n      when 4 => w (1) :=  v (2); w (2) := -v (1);  --  -90\n    end case;\n    --\n    case face is\n      when 1 => v := w;\n      --  Rotate around x axis (z axis turns and joins -y, -z, or +y)\n      when 2 => v (1) := w (1); v (2) := -w (3); v (3) :=  w (2);  --   90\n      when 3 => v (1) := w (1); v (2) := -w (2); v (3) := -w (3);  --  180\n      when 4 => v (1) := w (1); v (2) :=  w (3); v (3) := -w (2);  --  -90\n      --  Rotate around y axis (z axis turns and joins -x or x)\n      when 5 => v (2) := w (2); v (1) := -w (3); v (3) :=  w (1);  --   90\n      when 6 => v (2) := w (2); v (1) :=  w (3); v (3) := -w (1);  --  -90\n    end case;\n  end Rotate;\n\n  procedure Minus (a, b : Vector; c : out Vector) is\n  begin\n    for i in 1 .. 3 loop\n      c (i) := a (i) - b (i);\n    end loop;\n  end Minus;\n\n  function Dist_L1 (a, b : Vector) return Natural is\n    res : Natural := 0;\n  begin\n    for i in 1 .. 3 loop\n      res := res + abs (a (i) - b (i));\n    end loop;\n    return res;\n  end Dist_L1;\n\n  input : constant VString := +\"aoc_2021_19.txt\";\n\n  max_scanners : constant := 50;\n  max_coords : constant := 50;\n  coords : array (1 .. max_scanners) of Natural;\n  data : array (1 .. max_scanners, 1 .. max_coords) of Vector;\n  scanners : Natural;\n\n  verbose : constant := 1;\n\n  procedure Read_Data is\n    v1, v2 : Character;\n    f : File_Type;\n    s : VString;\n  begin\n    scanners := 0;\n    Open (f, input);\n    while not End_Of_File (f) loop\n      Get_Line (f, s);  --  Header\n      if verbose > 0 then\n        Put_Line (s);\n      end if;\n      scanners := scanners + 1;\n      coords (scanners) := 0;\n      loop\n        coords (scanners) := coords (scanners) + 1;\n        Get (f, data (scanners, coords (scanners)) (1));\n        Get (f, v1);\n        Get (f, data (scanners, coords (scanners)) (2));\n        Get (f, v2);\n        Get (f, data (scanners, coords (scanners)) (3));\n        exit when End_Of_File (f);\n        Skip_Line (f);\n        exit when End_Of_Line (f);\n      end loop;\n      exit when End_Of_File (f);\n      Skip_Line (f);  --  Empty line\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  type Scanner_Pair_Info is record\n    paired : Boolean;\n    face   : Cube_Face;\n    spin   : Plane_Rotation;\n    shift  : Vector;\n  end record;\n\n  info : array (1 .. max_scanners, 1 .. max_scanners) of Scanner_Pair_Info;\n\n  procedure Align is\n    vs_1, vs_2, vs_1_to_2, vs_2_o, v_test : Vector;\n    aligned : Natural;\n    threshold : constant := 12;  --  This is given.\n  begin\n    for s_1 in 1 .. scanners loop\n      for s_2 in s_1 + 1 .. scanners loop\n        info (s_1, s_2).paired := False;\n      end loop;\n    end loop;\n    --\n    Scanner_Loop_1 :\n    for s_1 in 1 .. scanners loop\n      Aligned_Beacon_1_Search :\n      for c1 in 1 .. coords (s_1) - threshold + 1 loop\n        vs_1 := data (s_1, c1);\n        Scanner_Loop_2 :\n        for s_2 in 1 .. scanners loop\n          if not (s_1 = s_2 or else info (s_1, s_2).paired) then\n            Rotation_Cube :\n            for face in Cube_Face loop\n              Rotation_Face :\n              for spin in Plane_Rotation loop\n                Aligned_Beacon_2_Search :\n                for cs_2 in 1 .. coords (s_2) loop\n                  vs_2 := data (s_2, cs_2);\n                  Rotate (vs_2, face, spin);\n                  Minus (vs_2, vs_1, vs_1_to_2);\n                  --  Now, try to align all data\n                  --  between scanner s_1 and scanner s_2\n                  aligned := 0;\n                  --\n                  --  Try matching any data of scanner 2 with any data of scanner 1.\n                  --\n                  for cs_1_o in 1 .. coords (s_1) loop\n                    for cs_2_o in 1 .. coords (s_2) loop\n                      vs_2_o := data (s_2, cs_2_o);\n                      Rotate (vs_2_o, face, spin);\n                      Minus (vs_2_o, vs_1_to_2, v_test);\n                      if Dist_L1 (v_test, data (s_1, cs_1_o)) = 0 then\n                        aligned := aligned + 1;\n                      end if;\n                    end loop;\n                  end loop;\n                  --\n                  if aligned >= threshold then\n                    info (s_1, s_2).paired := True;\n                    info (s_1, s_2).face   := face;\n                    info (s_1, s_2).spin   := spin;\n                    info (s_1, s_2).shift  := vs_1_to_2;\n                    if verbose > 0 then\n                      Put_Line\n                        (+\"aligned: \" & aligned &\n                          \" beacons between scanners \" & (s_1 - 1) & \" and \" & (s_2 - 1) &\n                          \" translation vector: \" &\n                          vs_1_to_2 (1) & \", \" & vs_1_to_2 (2) & \", \" & vs_1_to_2 (3));\n                    end if;\n                    exit Scanner_Loop_2;\n                  end if;\n                end loop Aligned_Beacon_2_Search;\n              end loop Rotation_Face;\n            end loop Rotation_Cube;\n          end if;\n        end loop Scanner_Loop_2;\n      end loop Aligned_Beacon_1_Search;\n    end loop Scanner_Loop_1;\n  end Align;\n\n  max_beacons : constant := 2500;  --  \"full Ada\": max_scanners * max_coords\n  beacons : Natural := 0;\n  beacon : array (1 .. max_beacons) of Vector;\n\n  scanner_pos : array (1 .. max_scanners) of Vector;\n\n  procedure Make_Beacon_List is\n    --  Shortcut in the connectivity tree towards the root (first scanner).\n    up : array (2 .. max_scanners) of Natural;\n    connected : Natural := 0;\n    found : Boolean;\n    s : Positive;\n    v, vt : Vector;\n  begin\n    for child_node in 2 .. scanners loop\n      up (child_node) := 0;\n      if info (1, child_node).paired then\n        up (child_node) := 1;\n        connected := connected + 1;\n      end if;\n    end loop;\n    while connected < scanners - 1 loop\n      for child_node in 2 .. scanners loop\n        if up (child_node) = 0 then\n          for parent_node in 2 .. scanners loop\n            if info (parent_node, child_node).paired\n              and then up (parent_node) /= 0  --  Check that the parent is itself connected!\n            then\n              up (child_node) := parent_node;\n              connected := connected + 1;\n              exit;\n            end if;\n          end loop;\n        end if;\n      end loop;\n    end loop;\n    --\n    beacons := coords (1);\n    for i in 1 .. beacons loop\n      beacon (i) := data (1, i);\n    end loop;\n    --\n    for d in 1 .. 3 loop\n      scanner_pos (1) (d) := 0;\n    end loop;\n    for i in 2 .. scanners loop\n      if verbose > 0 then\n        Put_Line (+\"Convert data from scanner \" & (i - 1) & \" to scanner 0\");\n      end if;\n      for j in 1 .. coords (i) loop\n        v := data (i, j);\n        s := i;\n        while s /= 1 loop\n          if verbose > 0 and j = 1 then\n            Put_Line (+\"  Convert data from scanner \" & (s - 1) & \" to scanner \" & (up (s) - 1));\n          end if;\n          Rotate (v, info (up (s), s).face, info (up (s), s).spin);\n          Minus (v, info (up (s), s).shift, vt);\n          v := vt;\n          s := up (s);\n        end loop;\n        found := False;\n        for k in 1 .. beacons loop\n          if Dist_L1 (vt, beacon (k)) = 0 then\n            found := True;\n            exit;\n          end if;\n        end loop;\n        if not found then\n          beacons := beacons + 1;\n          beacon (beacons) := v;\n        end if;\n      end loop;\n      for d in 1 .. 3 loop\n        v (d) := 0;\n      end loop;\n      s := i;\n      while s /= 1 loop\n        Rotate (v, info (up (s), s).face, info (up (s), s).spin);\n        Minus (v, info (up (s), s).shift, vt);\n        v := vt;\n        s := up (s);\n      end loop;\n      scanner_pos (i) := v;\n    end loop;\n    if verbose > 1 then\n      for k in 1 .. beacons loop\n        for d in 1 .. 3 loop\n          Put (beacon (k)(d)); Put (' ');\n        end loop;\n        New_Line;\n      end loop;\n    end if;\n  end Make_Beacon_List;\n\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  Align;\n  Make_Beacon_List;\n  r (1) := beacons;\n  r (2) := 0;\n  for i in 1 .. scanners loop\n    for j in i + 1 .. scanners loop\n      r (2) := Max (r (2), Dist_L1 (scanner_pos (i), scanner_pos (j)));\n    end loop;\n  end loop;\n  --\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: Number of beacons            : \" & r (1));\n    Put_Line (+\"Part 2: Max distance between scanners: \" & r (2));\n    --  Part 1: validated by AoC: 408\n    --  Part 2: validated by AoC: 13348\n  end if;\nend AoC_2021_19;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_19.txt",
    "content": "--- scanner 0 ---\n-812,-728,-591\n-259,678,-532\n735,-470,492\n-808,-734,-657\n518,-635,-807\n-487,402,391\n722,545,-708\n-529,-401,536\n-326,616,-504\n-330,707,-663\n878,574,-722\n670,-614,-747\n533,-501,495\n-508,406,332\n-797,-541,-583\n114,15,-132\n-522,-438,589\n587,-480,480\n-639,-447,471\n687,564,-674\n896,574,424\n-449,386,511\n652,-513,-789\n819,586,254\n836,538,409\n\n--- scanner 1 ---\n670,487,-847\n-432,537,-395\n-521,374,359\n-666,441,313\n740,701,863\n-432,701,-383\n721,-698,-623\n818,605,871\n-282,-564,-496\n766,577,737\n-375,-596,-489\n-433,-537,-427\n745,-562,-653\n650,-523,785\n24,36,8\n608,-417,733\n-386,-616,490\n453,-460,776\n745,-802,-648\n-454,633,-472\n-403,-500,596\n693,557,-710\n669,547,-874\n-462,-478,508\n-529,539,346\n\n--- scanner 2 ---\n-566,-825,-742\n-662,-843,343\n640,-448,544\n-593,-867,362\n-570,753,323\n-17,-6,-139\n757,831,503\n525,605,-563\n-549,694,319\n-591,549,-484\n763,-859,-617\n471,590,-584\n673,593,-553\n-701,614,-530\n-458,-744,-723\n-511,574,303\n-658,-773,306\n554,-488,396\n-584,496,-521\n646,-875,-525\n-522,-801,-721\n834,661,491\n620,-847,-523\n774,676,455\n535,-509,628\n\n--- scanner 3 ---\n-407,-676,-904\n734,-560,435\n-693,-416,552\n399,882,-572\n548,-513,-819\n11,183,-89\n519,898,-534\n432,710,811\n-700,739,637\n-703,-449,648\n-496,668,-411\n-469,-604,-856\n597,-462,-696\n-524,606,-344\n-738,-466,683\n386,-489,-727\n690,-596,610\n-407,-650,-695\n262,698,734\n-151,184,58\n-714,710,793\n-666,720,602\n340,878,-593\n-655,577,-415\n417,746,751\n-173,51,-105\n711,-649,610\n\n--- scanner 4 ---\n-685,686,-551\n-793,-850,-533\n506,696,563\n527,750,548\n-601,581,-490\n-402,-590,371\n-841,-861,-490\n800,-826,791\n830,-666,749\n892,-712,744\n-418,-589,365\n466,601,-889\n-489,-491,464\n679,-648,-544\n-24,2,-135\n496,548,551\n765,-778,-494\n745,-758,-567\n-453,667,-530\n-548,387,619\n-512,447,634\n-683,-770,-496\n-560,464,789\n468,575,-917\n560,458,-901\n\n--- scanner 5 ---\n732,615,-695\n-377,610,685\n-495,-902,-457\n-505,433,-576\n759,628,545\n-517,-805,-466\n-580,496,-693\n665,747,-728\n857,-888,591\n177,-41,-4\n-459,-809,-623\n-337,660,590\n485,-555,-387\n849,-900,646\n-644,-838,551\n-614,-772,389\n785,-859,453\n685,-519,-419\n613,-405,-367\n877,738,569\n-460,592,573\n-512,326,-661\n726,794,-640\n864,609,696\n-542,-810,573\n\n--- scanner 6 ---\n368,683,-372\n-857,-729,708\n457,760,741\n-3,99,-25\n545,663,-382\n480,897,862\n-905,509,-355\n-916,663,-479\n-906,-735,758\n422,-243,537\n606,-464,-412\n441,812,817\n273,-327,570\n-562,815,894\n-798,-679,712\n-905,559,-596\n-540,877,853\n-737,-434,-303\n439,538,-369\n-181,108,134\n-679,818,855\n-740,-438,-319\n-794,-617,-290\n695,-432,-474\n369,-298,651\n574,-454,-602\n\n--- scanner 7 ---\n-709,-537,525\n599,400,517\n663,-549,-537\n673,-739,-569\n-701,443,-586\n89,-29,-107\n-634,281,431\n-730,-492,-645\n695,-611,-448\n-777,425,-724\n-105,-82,14\n-788,-554,-704\n496,-458,611\n-731,-460,429\n418,-461,417\n-497,248,333\n598,545,385\n492,501,528\n800,433,-870\n-881,-561,-672\n884,400,-721\n829,514,-774\n-642,294,266\n362,-418,539\n-731,-448,593\n-760,531,-608\n\n--- scanner 8 ---\n868,710,-814\n690,-331,685\n565,-365,-644\n-685,583,-647\n-697,-418,-635\n-349,-747,573\n-493,633,703\n586,-389,-600\n773,450,395\n-744,575,-732\n9,-31,-170\n-518,485,615\n801,717,-874\n784,-343,542\n782,-315,568\n-818,-396,-542\n-517,527,665\n729,413,317\n-465,-739,603\n-770,385,-662\n88,113,15\n584,-446,-536\n-315,-721,499\n-829,-468,-584\n901,814,-873\n680,344,371\n\n--- scanner 9 ---\n-653,928,-587\n346,683,280\n358,723,474\n480,663,-657\n620,-449,-847\n396,-500,338\n590,-425,-711\n-590,784,464\n-363,-702,598\n375,797,-631\n433,643,397\n-56,55,-65\n-695,917,-515\n-701,-485,-565\n-575,869,266\n-423,-769,591\n-505,843,456\n-364,-802,695\n104,143,-139\n369,-501,398\n533,-477,408\n595,-425,-951\n-637,-487,-508\n-602,796,-537\n396,701,-702\n-593,-466,-484\n\n--- scanner 10 ---\n756,-811,536\n-758,-858,-662\n739,715,624\n806,663,-794\n-652,507,398\n667,-661,-781\n743,656,645\n725,-602,-719\n756,812,-753\n818,-634,-712\n759,536,683\n-107,-5,-89\n-726,-769,-724\n-601,458,521\n803,740,-620\n-628,669,490\n-692,-753,567\n-573,631,-846\n39,-141,-38\n-736,-737,-534\n-756,574,-833\n-795,-724,606\n-638,-667,644\n700,-905,601\n-752,577,-817\n719,-881,532\n\n--- scanner 11 ---\n613,-415,-869\n445,-621,752\n634,-608,-805\n372,329,-516\n-678,-535,350\n-108,-6,-44\n366,608,735\n-754,574,571\n-410,-728,-442\n424,549,797\n-754,814,576\n391,305,-585\n-477,-735,-382\n-694,428,-720\n423,-525,829\n-377,-832,-383\n273,576,728\n-702,-545,514\n-730,710,601\n335,399,-520\n619,-438,-850\n-679,-475,377\n-141,-123,113\n423,-689,841\n-692,371,-656\n-713,347,-612\n\n--- scanner 12 ---\n505,-657,846\n-749,-804,321\n-402,829,-859\n-697,-747,-878\n-40,16,-16\n6,-145,-110\n-736,362,736\n430,-544,830\n-695,382,662\n551,368,-797\n396,305,-817\n392,-594,853\n-692,-755,-648\n-659,-810,-829\n326,-775,-453\n674,256,394\n-430,828,-824\n-461,791,-808\n601,418,407\n-608,-913,341\n390,-836,-416\n378,-759,-593\n478,378,-719\n-664,-796,330\n-723,300,759\n719,347,368\n\n--- scanner 13 ---\n-683,-433,912\n-412,754,548\n875,592,853\n632,746,-671\n-762,-449,-503\n-404,724,432\n644,598,-661\n-786,-493,-482\n-430,650,398\n-808,693,-701\n-755,-391,901\n535,-511,-703\n872,-418,739\n-820,836,-607\n-733,-484,780\n629,544,-640\n29,142,144\n720,-392,823\n86,15,19\n-836,719,-699\n776,-433,907\n653,-628,-694\n-705,-385,-501\n785,426,889\n588,-518,-740\n907,419,813\n\n--- scanner 14 ---\n628,-598,-362\n-516,-802,-652\n686,-755,-366\n-286,494,718\n897,579,-580\n-250,670,-377\n-444,-854,-766\n-349,-780,795\n785,406,633\n723,-849,884\n165,-54,23\n631,462,682\n-370,-774,635\n644,-742,800\n551,427,609\n760,-750,817\n964,535,-476\n-315,583,-430\n-316,-834,-616\n-258,493,644\n664,-764,-269\n-276,636,663\n-421,632,-340\n24,-5,137\n-428,-673,723\n854,601,-573\n\n--- scanner 15 ---\n-749,785,-618\n417,-330,-362\n-443,-804,-604\n-753,865,-519\n375,468,-886\n-761,-303,467\n-680,-231,339\n641,-312,702\n586,758,698\n410,496,-885\n-534,-806,-420\n-319,870,752\n405,725,753\n-389,795,893\n437,-485,-425\n515,-412,-435\n40,131,60\n-418,-812,-408\n426,527,-848\n-287,937,853\n818,-324,779\n781,-260,718\n-788,804,-653\n356,763,690\n-78,-6,-26\n-617,-318,414\n\n--- scanner 16 ---\n-431,706,-288\n-482,756,-420\n756,435,-652\n-431,-753,-293\n-390,-697,-377\n705,-334,838\n421,-884,-387\n-541,-560,789\n-389,778,-299\n-437,-612,830\n133,-7,158\n-480,-698,721\n548,-356,897\n654,534,888\n726,427,-768\n-526,459,526\n636,632,763\n45,93,2\n538,505,792\n682,-308,868\n594,-852,-347\n-428,368,530\n652,453,-802\n428,-762,-311\n-632,372,515\n-416,-849,-461\n\n--- scanner 17 ---\n613,752,-489\n-669,-401,471\n830,-871,458\n465,-966,-607\n633,-880,521\n538,558,560\n562,528,696\n675,-828,415\n-550,668,506\n-638,-446,546\n-459,-792,-782\n543,-958,-703\n-610,790,-625\n-684,773,480\n-19,-95,-128\n614,779,-549\n590,615,-559\n-377,-719,-724\n-530,715,-548\n-637,-466,507\n-570,802,-431\n-588,752,551\n538,553,800\n-452,-883,-717\n517,-832,-579\n\n--- scanner 18 ---\n-652,609,-485\n-553,629,-400\n-797,-625,803\n742,693,613\n-747,-626,845\n-87,12,81\n-449,621,917\n-835,-601,697\n682,760,620\n16,-138,21\n337,-818,-760\n-608,761,-388\n483,615,-340\n489,-772,-735\n-527,665,880\n-661,-558,-657\n352,675,-367\n515,-793,747\n530,-878,945\n-773,-582,-587\n600,-852,755\n-710,-428,-598\n741,793,516\n378,-876,-798\n-503,572,986\n299,530,-336\n\n--- scanner 19 ---\n544,633,786\n-897,723,-366\n428,527,803\n378,616,-803\n704,-509,-669\n-817,-377,895\n-731,-354,-663\n-894,-551,892\n566,545,727\n282,535,-774\n-789,677,-422\n583,-637,-647\n-653,827,834\n480,-459,907\n-848,673,-372\n-23,-27,114\n-966,-418,845\n615,-447,-637\n507,-390,756\n-785,-325,-484\n448,-452,814\n-590,914,909\n-120,107,-57\n431,502,-858\n-509,842,781\n-728,-338,-667\n\n--- scanner 20 ---\n468,632,619\n-457,496,524\n186,-93,14\n-220,695,-807\n769,-571,-448\n766,-674,566\n647,638,564\n774,-341,-456\n936,-606,598\n-249,-766,-428\n-445,-529,681\n-573,-584,726\n515,571,531\n806,404,-253\n-313,-803,-367\n-301,-626,-444\n736,-390,-393\n829,-599,683\n881,334,-394\n-292,776,-679\n0,27,-3\n-610,-564,710\n-307,632,-732\n-461,437,474\n948,302,-293\n-411,388,468\n117,78,152\n\n--- scanner 21 ---\n826,-509,-542\n-398,-562,-530\n51,60,-92\n-421,734,361\n-319,-733,428\n808,-359,-646\n-349,-606,427\n752,461,756\n775,527,646\n-546,-537,-442\n795,-572,422\n834,-393,-572\n-257,636,-774\n-326,685,-828\n-365,849,387\n418,646,-460\n825,441,776\n-294,-548,435\n-363,729,-750\n879,-444,392\n145,-98,74\n849,-457,429\n-440,-561,-480\n-453,767,334\n430,740,-603\n402,738,-577\n\n--- scanner 22 ---\n-308,534,801\n-633,-448,-329\n-861,475,-605\n345,-401,879\n482,-523,877\n-598,-646,511\n-612,-389,-333\n675,430,949\n-7,103,77\n-481,-528,520\n877,402,-744\n-671,-568,-313\n898,564,-789\n505,-336,806\n670,428,929\n-591,-593,474\n765,-292,-316\n842,447,-767\n-790,606,-634\n632,-364,-269\n782,481,847\n-312,600,807\n-794,447,-543\n806,-441,-266\n-323,526,614\n\n--- scanner 23 ---\n496,-729,710\n825,723,-386\n-613,-891,470\n557,406,738\n-33,-165,-85\n-666,-651,-848\n-813,321,308\n-751,428,-367\n-644,-658,-805\n-710,-755,-915\n-814,466,-416\n824,695,-421\n-914,254,276\n758,-857,-383\n533,-814,583\n-173,-2,-88\n-575,-854,299\n-759,433,-597\n578,-771,-404\n-662,-801,364\n787,664,-437\n579,-920,-389\n592,387,777\n-954,396,378\n458,326,742\n479,-829,713\n\n--- scanner 24 ---\n-369,-585,-682\n-848,-535,620\n-359,838,803\n-367,813,607\n532,547,-468\n585,-256,525\n652,908,492\n590,-496,525\n-796,-641,662\n-434,-549,-650\n-414,-510,-651\n515,434,-573\n-24,114,10\n502,387,-427\n805,-576,-697\n560,-360,549\n812,843,419\n-365,722,791\n675,721,421\n700,-550,-563\n-839,-598,817\n-620,728,-861\n784,-505,-601\n-579,729,-733\n-686,686,-703\n\n--- scanner 25 ---\n-634,465,-978\n836,-736,352\n-114,-56,-6\n-557,844,715\n443,386,-469\n784,-720,492\n684,417,618\n772,-797,315\n-355,-849,743\n770,-555,-954\n-641,-533,-791\n657,-618,-947\n766,344,716\n-681,-571,-903\n23,49,-124\n488,295,-495\n-334,-894,581\n-736,-561,-685\n732,-505,-931\n-601,313,-932\n-565,523,-890\n-390,-872,698\n-562,824,717\n-450,742,664\n561,457,-508\n611,407,696\n\n--- scanner 26 ---\n-634,-845,-463\n709,-612,-774\n747,568,-391\n779,368,-427\n700,-634,-677\n-638,367,-613\n-549,-364,616\n473,-697,624\n526,609,922\n-487,311,509\n-346,381,584\n-38,59,151\n590,-622,561\n505,-629,454\n471,615,743\n799,496,-277\n543,-576,-681\n438,548,875\n-541,-594,621\n14,-42,-3\n-725,302,-666\n-386,279,442\n-687,473,-703\n-486,-413,654\n-656,-802,-470\n-590,-912,-567\n\n--- scanner 27 ---\n942,-325,-622\n653,572,551\n852,-309,-551\n-496,443,-571\n562,392,-533\n406,-302,686\n-44,118,134\n-492,627,839\n73,75,-10\n822,-297,-709\n435,582,606\n-775,-518,-455\n-479,664,944\n-648,443,-676\n547,544,646\n-400,-520,429\n-503,375,-727\n626,414,-598\n-605,-531,-394\n-492,620,722\n360,-454,653\n-689,-603,-505\n448,-512,722\n559,418,-683\n-461,-522,488\n-256,-497,436\n\n--- scanner 28 ---\n632,274,-680\n367,-616,715\n32,-122,-3\n-833,742,839\n808,-415,-420\n838,541,794\n834,632,635\n-854,787,677\n697,296,-616\n-623,-630,-794\n-547,426,-695\n352,-803,707\n-452,454,-589\n905,603,766\n-631,-951,811\n-798,765,794\n-587,-420,-836\n-626,-931,813\n356,-809,641\n-554,-572,-882\n-507,464,-807\n721,-443,-300\n650,-427,-390\n-738,-849,760\n782,300,-683\n\n--- scanner 29 ---\n650,-462,893\n-474,-732,-757\n696,-400,888\n408,486,-380\n632,-613,-400\n762,-527,-350\n-766,-765,692\n-712,-786,707\n-564,-796,695\n44,-15,-7\n-617,-826,-745\n616,563,781\n-556,423,-349\n378,358,-296\n810,-492,935\n742,-547,-423\n-660,273,-367\n-586,307,-341\n415,371,-326\n-884,764,848\n-591,-824,-773\n-718,728,938\n-91,-120,132\n782,510,743\n-891,688,970\n706,715,738\n\n--- scanner 30 ---\n-413,599,524\n-666,-613,-524\n767,-832,-734\n-675,-495,-641\n65,-17,-99\n929,795,-761\n809,679,309\n-307,-740,302\n675,653,414\n-5,49,68\n580,-444,582\n-454,826,-659\n539,-284,612\n-475,802,-703\n940,723,-719\n-380,-805,462\n685,-331,599\n-712,-548,-634\n-309,-618,439\n851,-680,-760\n-437,463,554\n808,773,-668\n-413,359,529\n713,608,330\n-473,745,-767\n935,-736,-719\n\n--- scanner 31 ---\n600,-425,411\n-761,-790,-561\n-437,353,-479\n854,339,-706\n-738,-719,-374\n273,-408,-444\n761,779,792\n-573,-842,390\n281,-604,-469\n-898,-792,-439\n-478,403,-330\n773,702,615\n767,414,-643\n-401,854,409\n782,467,-787\n-345,876,526\n755,-362,391\n-611,356,-402\n673,-435,489\n825,718,755\n-461,-760,443\n-366,831,364\n-40,-18,45\n279,-420,-560\n-568,-862,392\n\n--- scanner 32 ---\n375,548,-471\n-561,629,-647\n520,522,-443\n-635,-398,564\n424,-582,-461\n-303,-450,-754\n450,503,-445\n585,584,438\n-502,810,505\n-492,619,553\n-544,-394,723\n-473,654,519\n105,-30,-137\n806,-876,570\n-3,-96,14\n613,-865,644\n800,-880,636\n-522,534,-587\n707,450,420\n412,-424,-491\n-277,-600,-751\n-299,-535,-687\n-516,573,-732\n-606,-327,695\n686,602,480\n440,-511,-371\n\n--- scanner 33 ---\n-772,-465,-547\n-457,472,-525\n-752,565,511\n908,-813,712\n681,286,606\n-743,628,314\n-563,588,-542\n118,45,-42\n447,-773,-433\n-271,-783,524\n23,-105,-104\n656,390,582\n-263,-808,328\n748,-878,639\n-475,610,-601\n621,-850,-436\n771,-691,710\n-700,671,469\n-844,-546,-419\n529,524,-421\n-757,-609,-494\n-269,-692,340\n522,492,-514\n686,526,606\n460,551,-572\n488,-922,-483\n\n--- scanner 34 ---\n528,907,-644\n219,-657,839\n-670,-313,-652\n677,-838,-586\n-39,71,118\n652,576,852\n358,-618,879\n-573,428,-654\n-727,725,447\n-676,-436,739\n720,513,703\n625,-704,-614\n-595,505,-558\n731,625,767\n-595,822,433\n-597,-481,743\n281,-683,880\n-726,872,547\n529,880,-704\n-807,-280,-750\n552,743,-634\n-573,416,-490\n599,-830,-490\n-662,-326,-817\n-612,-453,767\n\n--- scanner 35 ---\n-663,869,837\n930,-557,831\n-393,792,-453\n499,-533,-282\n-480,-609,-256\n-741,906,793\n421,779,875\n448,811,842\n-687,975,744\n474,867,957\n515,913,-625\n577,-545,-247\n-443,834,-454\n-582,-399,933\n61,29,150\n-355,686,-429\n-538,-496,781\n-417,-598,-410\n-18,124,10\n485,-532,-307\n514,883,-498\n853,-608,733\n-637,-411,801\n-529,-668,-386\n522,938,-440\n956,-549,611\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_19_questions.txt",
    "content": "--- Day 19: Beacon Scanner ---\r\n\r\nAs your probe drifted down through this area, it released an assortment of beacons and scanners into the water. It's difficult to navigate in the pitch black open waters of the ocean trench, but if you can build a map of the trench using data from the scanners, you should be able to safely reach the bottom.\r\n\r\nThe beacons and scanners float motionless in the water; they're designed to maintain the same position for long periods of time. Each scanner is capable of detecting all beacons in a large cube centered on the scanner; beacons that are at most 1000 units away from the scanner in each of the three axes (x, y, and z) have their precise position determined relative to the scanner. However, scanners cannot detect other scanners. The submarine has automatically summarized the relative positions of beacons detected by each scanner (your puzzle input).\r\n\r\nFor example, if a scanner is at x,y,z coordinates 500,0,-500 and there are beacons at -500,1000,-1500 and 1501,0,-500, the scanner could report that the first beacon is at -1000,1000,-1000 (relative to the scanner) but would not detect the second beacon at all.\r\n\r\nUnfortunately, while each scanner can report the positions of all detected beacons relative to itself, the scanners do not know their own position. You'll need to determine the positions of the beacons and scanners yourself.\r\n\r\nThe scanners and beacons map a single contiguous 3d region. This region can be reconstructed by finding pairs of scanners that have overlapping detection regions such that there are at least 12 beacons that both scanners detect within the overlap. By establishing 12 common beacons, you can precisely determine where the scanners are relative to each other, allowing you to reconstruct the beacon map one scanner at a time.\r\n\r\nFor a moment, consider only two dimensions. Suppose you have the following scanner reports:\r\n\r\n--- scanner 0 ---\r\n0,2\r\n4,1\r\n3,3\r\n\r\n--- scanner 1 ---\r\n-1,-1\r\n-5,0\r\n-2,1\r\n\r\nDrawing x increasing rightward, y increasing upward, scanners as S, and beacons as B, scanner 0 detects this:\r\n\r\n...B.\r\nB....\r\n....B\r\nS....\r\n\r\nScanner 1 detects this:\r\n\r\n...B..\r\nB....S\r\n....B.\r\n\r\nFor this example, assume scanners only need 3 overlapping beacons. Then, the beacons visible to both scanners overlap to produce the following complete map:\r\n\r\n...B..\r\nB....S\r\n....B.\r\nS.....\r\n\r\nUnfortunately, there's a second problem: the scanners also don't know their rotation or facing direction. Due to magnetic alignment, each scanner is rotated some integer number of 90-degree turns around all of the x, y, and z axes. That is, one scanner might call a direction positive x, while another scanner might call that direction negative y. Or, two scanners might agree on which direction is positive x, but one scanner might be upside-down from the perspective of the other scanner. In total, each scanner could be in any of 24 different orientations: facing positive or negative x, y, or z, and considering any of four directions \"up\" from that facing.\r\n\r\nFor example, here is an arrangement of beacons as seen from a scanner in the same position but in different orientations:\r\n\r\n--- scanner 0 ---\r\n-1,-1,1\r\n-2,-2,2\r\n-3,-3,3\r\n-2,-3,1\r\n5,6,-4\r\n8,0,7\r\n\r\n--- scanner 0 ---\r\n1,-1,1\r\n2,-2,2\r\n3,-3,3\r\n2,-1,3\r\n-5,4,-6\r\n-8,-7,0\r\n\r\n--- scanner 0 ---\r\n-1,-1,-1\r\n-2,-2,-2\r\n-3,-3,-3\r\n-1,-3,-2\r\n4,6,5\r\n-7,0,8\r\n\r\n--- scanner 0 ---\r\n1,1,-1\r\n2,2,-2\r\n3,3,-3\r\n1,3,-2\r\n-4,-6,5\r\n7,0,8\r\n\r\n--- scanner 0 ---\r\n1,1,1\r\n2,2,2\r\n3,3,3\r\n3,1,2\r\n-6,-4,-5\r\n0,7,-8\r\n\r\nBy finding pairs of scanners that both see at least 12 of the same beacons, you can assemble the entire map. For example, consider the following report:\r\n\r\n--- scanner 0 ---\r\n404,-588,-901\r\n528,-643,409\r\n-838,591,734\r\n390,-675,-793\r\n-537,-823,-458\r\n-485,-357,347\r\n-345,-311,381\r\n-661,-816,-575\r\n-876,649,763\r\n-618,-824,-621\r\n553,345,-567\r\n474,580,667\r\n-447,-329,318\r\n-584,868,-557\r\n544,-627,-890\r\n564,392,-477\r\n455,729,728\r\n-892,524,684\r\n-689,845,-530\r\n423,-701,434\r\n7,-33,-71\r\n630,319,-379\r\n443,580,662\r\n-789,900,-551\r\n459,-707,401\r\n\r\n--- scanner 1 ---\r\n686,422,578\r\n605,423,415\r\n515,917,-361\r\n-336,658,858\r\n95,138,22\r\n-476,619,847\r\n-340,-569,-846\r\n567,-361,727\r\n-460,603,-452\r\n669,-402,600\r\n729,430,532\r\n-500,-761,534\r\n-322,571,750\r\n-466,-666,-811\r\n-429,-592,574\r\n-355,545,-477\r\n703,-491,-529\r\n-328,-685,520\r\n413,935,-424\r\n-391,539,-444\r\n586,-435,557\r\n-364,-763,-893\r\n807,-499,-711\r\n755,-354,-619\r\n553,889,-390\r\n\r\n--- scanner 2 ---\r\n649,640,665\r\n682,-795,504\r\n-784,533,-524\r\n-644,584,-595\r\n-588,-843,648\r\n-30,6,44\r\n-674,560,763\r\n500,723,-460\r\n609,671,-379\r\n-555,-800,653\r\n-675,-892,-343\r\n697,-426,-610\r\n578,704,681\r\n493,664,-388\r\n-671,-858,530\r\n-667,343,800\r\n571,-461,-707\r\n-138,-166,112\r\n-889,563,-600\r\n646,-828,498\r\n640,759,510\r\n-630,509,768\r\n-681,-892,-333\r\n673,-379,-804\r\n-742,-814,-386\r\n577,-820,562\r\n\r\n--- scanner 3 ---\r\n-589,542,597\r\n605,-692,669\r\n-500,565,-823\r\n-660,373,557\r\n-458,-679,-417\r\n-488,449,543\r\n-626,468,-788\r\n338,-750,-386\r\n528,-832,-391\r\n562,-778,733\r\n-938,-730,414\r\n543,643,-506\r\n-524,371,-870\r\n407,773,750\r\n-104,29,83\r\n378,-903,-323\r\n-778,-728,485\r\n426,699,580\r\n-438,-605,-362\r\n-469,-447,-387\r\n509,732,623\r\n647,635,-688\r\n-868,-804,481\r\n614,-800,639\r\n595,780,-596\r\n\r\n--- scanner 4 ---\r\n727,592,562\r\n-293,-554,779\r\n441,611,-461\r\n-714,465,-776\r\n-743,427,-804\r\n-660,-479,-426\r\n832,-632,460\r\n927,-485,-438\r\n408,393,-506\r\n466,436,-512\r\n110,16,151\r\n-258,-428,682\r\n-393,719,612\r\n-211,-452,876\r\n808,-476,-593\r\n-575,615,604\r\n-485,667,467\r\n-680,325,-822\r\n-627,-443,-432\r\n872,-547,-609\r\n833,512,582\r\n807,604,487\r\n839,-516,451\r\n891,-625,532\r\n-652,-548,-490\r\n30,-46,-14\r\n\r\nBecause all coordinates are relative, in this example, all \"absolute\" positions will be expressed relative to scanner 0 (using the orientation of scanner 0 and as if scanner 0 is at coordinates 0,0,0).\r\n\r\nScanners 0 and 1 have overlapping detection cubes; the 12 beacons they both detect (relative to scanner 0) are at the following coordinates:\r\n\r\n-618,-824,-621\r\n-537,-823,-458\r\n-447,-329,318\r\n404,-588,-901\r\n544,-627,-890\r\n528,-643,409\r\n-661,-816,-575\r\n390,-675,-793\r\n423,-701,434\r\n-345,-311,381\r\n459,-707,401\r\n-485,-357,347\r\n\r\nThese same 12 beacons (in the same order) but from the perspective of scanner 1 are:\r\n\r\n686,422,578\r\n605,423,415\r\n515,917,-361\r\n-336,658,858\r\n-476,619,847\r\n-460,603,-452\r\n729,430,532\r\n-322,571,750\r\n-355,545,-477\r\n413,935,-424\r\n-391,539,-444\r\n553,889,-390\r\n\r\nBecause of this, scanner 1 must be at 68,-1246,-43 (relative to scanner 0).\r\n\r\nScanner 4 overlaps with scanner 1; the 12 beacons they both detect (relative to scanner 0) are:\r\n\r\n459,-707,401\r\n-739,-1745,668\r\n-485,-357,347\r\n432,-2009,850\r\n528,-643,409\r\n423,-701,434\r\n-345,-311,381\r\n408,-1815,803\r\n534,-1912,768\r\n-687,-1600,576\r\n-447,-329,318\r\n-635,-1737,486\r\n\r\nSo, scanner 4 is at -20,-1133,1061 (relative to scanner 0).\r\n\r\nFollowing this process, scanner 2 must be at 1105,-1205,1229 (relative to scanner 0) and scanner 3 must be at -92,-2380,-20 (relative to scanner 0).\r\n\r\nThe full list of beacons (relative to scanner 0) is:\r\n\r\n-892,524,684\r\n-876,649,763\r\n-838,591,734\r\n-789,900,-551\r\n-739,-1745,668\r\n-706,-3180,-659\r\n-697,-3072,-689\r\n-689,845,-530\r\n-687,-1600,576\r\n-661,-816,-575\r\n-654,-3158,-753\r\n-635,-1737,486\r\n-631,-672,1502\r\n-624,-1620,1868\r\n-620,-3212,371\r\n-618,-824,-621\r\n-612,-1695,1788\r\n-601,-1648,-643\r\n-584,868,-557\r\n-537,-823,-458\r\n-532,-1715,1894\r\n-518,-1681,-600\r\n-499,-1607,-770\r\n-485,-357,347\r\n-470,-3283,303\r\n-456,-621,1527\r\n-447,-329,318\r\n-430,-3130,366\r\n-413,-627,1469\r\n-345,-311,381\r\n-36,-1284,1171\r\n-27,-1108,-65\r\n7,-33,-71\r\n12,-2351,-103\r\n26,-1119,1091\r\n346,-2985,342\r\n366,-3059,397\r\n377,-2827,367\r\n390,-675,-793\r\n396,-1931,-563\r\n404,-588,-901\r\n408,-1815,803\r\n423,-701,434\r\n432,-2009,850\r\n443,580,662\r\n455,729,728\r\n456,-540,1869\r\n459,-707,401\r\n465,-695,1988\r\n474,580,667\r\n496,-1584,1900\r\n497,-1838,-617\r\n527,-524,1933\r\n528,-643,409\r\n534,-1912,768\r\n544,-627,-890\r\n553,345,-567\r\n564,392,-477\r\n568,-2007,-577\r\n605,-1665,1952\r\n612,-1593,1893\r\n630,319,-379\r\n686,-3108,-505\r\n776,-3184,-501\r\n846,-3110,-434\r\n1135,-1161,1235\r\n1243,-1093,1063\r\n1660,-552,429\r\n1693,-557,386\r\n1735,-437,1738\r\n1749,-1800,1813\r\n1772,-405,1572\r\n1776,-675,371\r\n1779,-442,1789\r\n1780,-1548,337\r\n1786,-1538,337\r\n1847,-1591,415\r\n1889,-1729,1762\r\n1994,-1805,1792\r\n\r\nIn total, there are 79 beacons.\r\n\r\nAssemble the full map of beacons. How many beacons are there?\r\n\r\n--- Part Two ---\r\n\r\nSometimes, it's a good idea to appreciate just how big the ocean is. Using the Manhattan distance, how far apart do the scanners get?\r\n\r\nIn the above example, scanners 2 (1105,-1205,1229) and 3 (-92,-2380,-20) are the largest Manhattan distance apart. In total, they are 1197 + 1175 + 1249 = 3621 units apart.\r\n\r\nWhat is the largest Manhattan distance between any two scanners?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_20.adb",
    "content": "--  Solution to Advent of Code 2021, Day 20\n-------------------------------------------\n--  Trench Map\n--\n--  A Game-of-life puzzle!\n--\n--  https://adventofcode.com/2021/day/20\n--  Copy of questions in: aoc_2021_20_questions.txt\n--\n--  Note: this programs takes very long on HAC!\n--\n--  HAC 0.098 \"nice to have\"'s detected in this exercise:\n--\n--    *     Detect an expression as a static (compile-time-known) value\n--            ->  Good for arithmetic in number declaration\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nprocedure AoC_2021_20 is\n  use HAT;\n\n  iter_max   : constant :=   50;\n  --  margin : constant :=  101;  --  \"full Ada\": iter_max * 2 + 1\n  map_min    : constant := -101;  --  \"full Ada\": -margin\n\n  --  input : constant VString := +\"mini.txt\"; data_max : constant :=  4;\n  input : constant VString := +\"aoc_2021_20.txt\"; data_max : constant :=  99;\n  map_max  : constant :=  200;  --  \"full Ada\": data_max + margin\n\n  iea_max : constant := 511;\n  subtype Bit is Integer range 0 .. 1;\n  iea : array (0 .. iea_max) of Bit;\n  type Map_Type is array (map_min .. map_max, map_min .. map_max) of Bit;\n  map : array (0 .. 1) of Map_Type;\n  cur_map : Natural := 0;\n\n  procedure Read_Data is\n    --\n    c : Character;\n    s : VString;\n    f : File_Type;\n  begin\n    Open (f, input);\n    Get_Line (f, s);\n    for i in 0 .. iea_max loop\n      if Element (s, i + 1) = '#' then\n        iea (i) := 1;\n      else\n        iea (i) := 0;\n      end if;\n    end loop;\n    Skip_Line (f);\n    for y in map_min .. map_max loop\n      for x in map_min .. map_max loop\n        map (0)(x, y) := 0;\n        map (1)(x, y) := 0;\n        if x in 0 .. data_max and then y in 0 .. data_max then\n          Get (f, c);\n          if c = '#' then\n            map (cur_map)(x, y) := 1;\n          end if;\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show_Map (extension : Natural) is\n  begin\n    for y in -extension .. data_max + extension loop\n      for x in -extension .. data_max + extension loop\n        if map (cur_map)(x, y) = 1 then\n          Put ('#');\n        else\n          Put ('.');\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n    New_Line;\n  end Show_Map;\n\n  procedure Enhance is\n    code : Natural;\n    new_map : constant Natural := 1 - cur_map;\n  begin\n    for y in map_min + 1 .. map_max - 1 loop\n      for x in map_min + 1 .. map_max - 1 loop\n        code := 0;\n        for yy in -1 .. 1 loop\n          for xx in -1 .. 1 loop\n            code := code * 2 + map (cur_map)(x + xx, y + yy);\n          end loop;\n        end loop;\n        map (new_map)(x, y) := iea (code);\n      end loop;\n    end loop;\n    cur_map := new_map;\n  end Enhance;\n\n  function Count (extension : Natural)  return Natural is\n    total : Natural := 0;\n  begin\n    for y in -extension .. data_max + extension loop\n      for x in -extension .. data_max + extension loop\n        total := total + map (cur_map)(x, y);\n      end loop;\n    end loop;\n    return total;\n  end Count;\n\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := False;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  if verbose then Show_Map (0); end if;\n  for iteration in 1 .. iter_max loop\n    Enhance;\n    case iteration is\n      when      2 => r (1) := Count (2);\n      when     50 => r (2) := Count (50);\n      when others => null;\n    end case;\n    if verbose then\n      Show_Map (iteration);\n    end if;\n  end loop;\n  if verbose then\n    Show_Map (iter_max);\n  end if;\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: pixels after 2 iterations : \" & r (1));\n    Put_Line (+\"Part 2: pixels after 50 iterations: \" & r (2));\n    --  Part 1: validated by AoC: 5306\n    --  Part 2: validated by AoC: 17497\n  end if;\nend AoC_2021_20;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_20.txt",
    "content": "#.#.##...###......#.##..#..##....#.#.##...#..###....##...#####.#...#.#.#...#..###..#...#......####..#.#..########.#.###......##.##...###.###..######.....####.#..#.#..##..###..####..#....####..######.###..###.........##.##.###......##...#####.######..#.....##..#..#...#.#...#..#..#.#..#..#.##..#####..##.###.####...#..#....##....####...#.#.#.#.#.###...##..#....##......####.##.###...#####..##..#.#...#..#.#..####.###..###..#..####....#.#.##.#..#...#.#...##...#..#.#.##...##..##.####..#...###.#...#####.######.....\n\n...#.#...####.##.####.#...#..##.###..##...###..#.#.#.#...##....#####..#...##.#.##.#.#.....###.#....#\n.##.####......##.#.#..#.#.#.#.##....#..##...###.#..#..#.##...##.#..##.###.#......###....#..##.###..#\n####.#.####...#.#.#.#....#...#.##..###.#####..#...#.#..#.#.#.####...##.##..#.#.#..##.########..###..\n.####......#.##.##.##.#.#.....##..#.##....#######.##..##.####.#..#.#.#.#.#.###.#..#......#.#.#..###.\n..#.#.####..#.#.#....##....#...######..##......#.......###.#..###.#.#.#.#.###.##..#.####.....#.##.#.\n.#..##..#####.....#....#.#.#..###..#.###.#.###.##..##.#.###...#.##....##...#.###.#.##....#...###..##\n.#.##.####.##.##..#..#.##..##.##..##..#.##..#.######..####.##.#.##....##..#.##.####.##...####....##.\n##..#.#####.#.#.#..#...#...#.....##.#...#.##.#.#.#.#.....##...#.#.....##..##..###.#.####..#...##...#\n##..#.#.##.####....##.#.#..#.#.#.###.#.#..#.#.....#..##.##.#.#...##....##.########.#..#.....##...###\n######......#..#.#.####.#.###.#################.##..#.###.##.#...#..###.##..##..##..#..#.##..#.##.##\n...##.#.###.........#...#...##.###...######..#.#...#........##.#...###.###.###...#...#.......#####.#\n.#....##...##.#.#.##.#..########.#..#..#..#.##.##..###.##.#..##.#.#.#....#..##...###..###.##.#.##.##\n.##.......##.#.#...#.##.##..#.#...#..####.#....###..#.#.....#.###....#...#.##.....#..#...##.##...###\n..###.#..##..#....#...#.#.##.##.#.#.#.##.###.#####..###....#......##.....##..#..####.#....#####.#...\n#...#.##.#.#.#...#####.#..##.######......##.#.#.#..#..#.##.######..#.##...##.##.##..#.#....##.###..#\n##.##.##..#.##.########.##..##.##..####..#...####.######.####..####.#.#.#.#..#.##....#.##.#..#..###.\n#..#####.##..#.###.#.##.##.###....###.#..#.####..##...#...###.#..#.....##...#..####.#...###.#.####..\n....#.#####..##.###..#..#.....##..##.#...#.#..##.##.#.##..##....#.##..##..###...##.#..#.#.###..#..#.\n.#########..####.###...#.##.#.##..###....##.#..#...##....#.####.#..#.###.#.###....#......#...#.##.#.\n.#######....####..##..#..#....#..#.####........#.##.#..##.######.#.###.###.###..##..####...##..#.##.\n.#....###.####.###..#..##......##.##.##...#..##...##.####..##....######..####.#..##..#######.#.#...#\n.#.####..########.#.#.######...##.###...#.....#...###....###..####.........#.###.#.....#.###.##..##.\n...#.#.#..#.###..###.##.#.#.##...#..####.#..#.#...#....##.##.###.####.###...##..#.#......##..#......\n.#...######.#.##....##.##.##.....#...#.#.#######.#.#..###.#.#...##...#....#.#...#...#...##.###.###..\n.#...#..##.##.###.....##..#.###..####.##.########...#.##.....####...##...#.#..#....#...##.#.#..####.\n..##...##.#..####...#.#...##.##..##..##..##..#..#...##..#..###.#..###..#..#....#..##....##...######.\n##..###...##...##.#.#######..#.#.#..#...#.#..#..#....###..#.#####.##.#...##..#.....#..##.###..#.##..\n###.#.#..##.#.####..######....#.#.##....###.##.#.##..###.#.#...#..#####....#########...##..#....#.##\n#..#####.....##.#.#.###.#.#.......####..#.##.#.####.#..#...#...#.#.###.######.##..##..#.......####..\n...#####..#.####.#..##.####.#####...#.#...#####.##.##..#..#...##.###..#.#.###.#....#..##..###.##.#.#\n.##..#.##...##..#.#.##.#.#...#..####..#......##.###.#.##.#.#....####..#..#.####..###..#..#.#.###.#.#\n#.#####..#.###.#.#.###.#.#...#.#....###.#..#.####...#####.#..##...##......###.##..#.###.#..####.#.#.\n#..#......###...#.#...###....###.#####....#.#.###.##.#.#...##.....#.#####................#.###..#..#\n#....##....#.#..####..#.##.####.###.###..####.##.....###.##.##...#..#...#.###...#####......#...#....\n##.#..#.##..##..##.#.#.#.#.##.######.#..#.#..###.#....#...#.#.#.#.....#....##..##....####..#.##..###\n.##..#.#.####...##...#.######.....#.#...#####...##########.....##.###..#..######..#.#.....##..###..#\n####..#.#...#...###.#####.##.#...#####..#.....#.#####.##..#.##.#.#.###.#...#.#.#####.......##.####.#\n...###.##..###.#.#.#..##..#####......#####..#..##.##.....####..###...#...#####.....#.#....###...#.#.\n..#..#.#.....##.#.#...#.......##.###.....###..#####.#####.#..###..###..#..#.#.#.#..###.#.###..#.#.##\n####..#.##.##...#.#.#.##.#.#.#..#..#####..##.#.####.#..#######.####.#....#..###.##.#...##...###.#.#.\n..#...#..#...#.####.##..##..#######.#.##.####.#..#......#.#.###.##.#..#.#.....##....#.#.#.#.##.###.#\n.###..###.#...##..#....#.#..##..#.###.#...##.######.####.###.#..##..###.##.#.#....#.#...#...###.##.#\n#....#.#....#..#####..##..#.##.#.#..##.##.#.....#.##..##..##........#.##...##.#.#..##.#.#..###....#.\n##...#......#.#.#.#......#..#.#..#######...#.####..#...###..#...#..#...####..#.#.##....#...##..#....\n.####...##..###.##....#.#..#...#.##.#.##.#####.####.....#...#..#..#..##.#..####.#.#..###....##...#.#\n#..####.#.#.######.####.#..#####..#.####...#.#.#.##..##..#.##.#.#.##.#..#..##.###.#.#..#.##..####.##\n.#.###.....###....#...#..#.#####..#####..###..#..#...##...#.###..#..#.##..#..####..##..##########...\n.#.....##..#.#.##...#...#.#.#.#.#..#.###...##.#.####.....#....#.....#.#.####..###.#######..#..##.#..\n....##...#...####..###.##.#.#.#...##.##...####..##..###..#.#.######.##.....#............#.######.#..\n..#....#....#..##.....#.#.##....###.##..###.#####...#....#.#.#....##.#.#.#.#.....#.#.....##...#.#.#.\n.##...#.#.##.######..#.####..######.##.....##.##..##....#...#..##.#..#....#.##...#....#.##...##.#.##\n#...#.#...##.#.##.##..#..####.#...###.#...##.##....#.#..##.......##....####...#...#.......#....####.\n.#.##..###.##.##...##.#..##.###.#.#.#####.#.###...#.##....#...#..##..###..#..##.##.#..##.#.#....##..\n###.##.##..##.#.###.#...###.#..#.#.####..###.##.##..###.#####...##.....####.#.##.###..####.#..#.#.##\n#....#.#.##...##.#...#......#####..###.#.##..#.####..##..#..##..###...###.#.#.##.##..####.###.....#.\n#.##..#...#.#..##..##..#..###..##.#.###....#.#.####.##.##.###.#..#.##...#.###.##.#...#.#.##...#.....\n#......#......#.#.#.######.##.#.###.###..#..####...##.#.######..#.....###..#.....#########.#####.##.\n.#.#.#.##.#.###...#..#.##...#...##.#####.###..####.##..........####..#.#####.####..#.##.#####..###..\n...##.###.#.####.###.#.#.#.##...#####.#.......##.##...####.#..###....###.#..###..#.#####..#.###..#..\n#.#....#....###.###..##.##.##.##.#..###.##.....#.##.###...#.###....###.####...#.####...#.###.#.#####\n##....#..#......##.###.....##.###.##..##.#.##...#..#.##.##.##..##.#...#...#...#.#.#.#.##.###.....###\n.###..##.#....#..###..#.#.#..####.#.#.#.##.#...###.#.##....##..###.....#.##.....#......###.####..#..\n.....##.#...#####.#..###....#.#.#.#..##.###.#########.#.##..##.#.#.####..##..##..##.#..#.....#.#.#..\n#.####.#....##..#########...#.####..#.......#....##.#...##.#.##.##...#.#.#...#..###.#.#..#####.##..#\n..#####...#.#.###......#....#...###...##.##...##.#..##.#.#..##.##.###.#....##.##...#####.......####.\n#..##.###.....#...#.#.###.####..###.#....#..#...###.##.....#.##..##..###..##.##.###..#.#..#..#...#..\n##.###.....##.....##.#######.#.##....###.####.....#..##.#.###.#.#......##..####.#.####.##.#.##...###\n###..#..######..#.#.#...##..#.#...####...##........####....#...#..#########.#.###.##.##.#####...##..\n..#####.#.####...#.######.#..#.#.#.#....#...#.###...###.###..#...##..##..#####..#####.###..#.#.#.##.\n##.#..###..###.#.......##..####..######.#..#.####.##....#####.#.#.###.#..###..########..####..#..#..\n##.#.####....#.#.##..#..#..######.#..##.#.##..###.#..#.#....#.##...#.##.####...####.....##.##.##..##\n####..##....#..#.#.#.....#..#...#.#...#..###...##.#.###.#...#.##..##..###..###....#..########.#....#\n##..#...#.#.....#####..##..##....#......##.#.#...#..#####....##..#.##.........#.#.##...#.#.#..#.#.#.\n##...###..#.###...###.###.##...##.#.##...#...####..#.#.#.###...######......##..###.....#..#.##...#.#\n#.#....#.####.##.#.#.#.##..#.##.......#..##..#..##.##.##.#..##..#.##.#.#####.......#####..#........#\n.#.#..###..#....#.#.....#.##..#....#..##..##..##.#....###..#.######.#.#...#..###......####....####..\n.#...###.....#...#....#.##.##.#........####.####..#....#..#....#.#.#..#.#.##.#.######.#...###.##.###\n...#.#.#..##.#..#.##.#.#.##.##...##....###.....#####...#.#..#.##.#.####..##..#..#....#.##.##.##..##.\n####....###..#..####.##.#..##.#..##.#.......###..#.##....#..#####.##..##.#...####..#.#..#.#.####...#\n.#..###....#..#####.##..##...#.#...#.##.#..#....#.#.##.#.#.......#.#....#...#....#...#...#..##.#....\n#.#...####.#.##..###..#.##.##.#.##.#..##.#.##.###..#.###.#..##.#..#..#.#.####.#.###.##..#..#....##..\n.....#...#.####.#..##..#######.#.#.#...#.#####.#.#...#...####.....###.###.##..##..#..#..#.#..######.\n#..#.#.####..###.###..#.##...##..###.##.###..#.####.#####.....###..###..#.#...#.#.########.#.##..##.\n####..###..#...###.#.##.#.###..#.#...##.##....#####......###..##....###..#.#.#..##..######..####.#..\n...#....##.###..#.##.##..##..#.#.##.##...######....#....##.#.#.#.##.#...####...##...#.####.#.#.##.#.\n...##...#.##..###.###...#.#.#.#.##.####...#.###..####..#...###.....#....####..##.#..##......#..#.#..\n.#.#..#.....#.#.###....#.###.#..#..###...#.#####....#.....###.#..###.##.#..#...#.####..#.###.####...\n.####..#..##....#.##.##.#...#.###....#....#.##..#...#...##...#...###....###.##.#..#.###.#.##.#..###.\n##.###.#...#.....#.#.#......#.##..#.#.##.##...###...#.###.####..###..#..###.#..#.#...#...#......##..\n######...##.##..#...##.#.###.#.####.#.##.##...###.#.#.....###.##.##....##.##....##.##.#..##..#.#####\n#...#..#...####.#.###.##...#...#..##.#..##.....##.#..#.#..#....##.##..##..#..#.###..###.#......#..##\n.##.##.######..#.##....#...#.....#.#.###....######..#.#..##.###......##.#..#.#.####..#...###.###.#.#\n..#.#...##.#.....######.....####...##.###.#..#..#..######....###.....##...###..#.#####.#..##.###.###\n###........#.##..##.........#.##.....#..#.####.##...........###...#.#.###..###..#..###...#......####\n#...#.......#.##.#.#.##.#.#.##.#.#..#...##..#..#####.#.##.##.#####.####...#..##.#.###...#..##..##...\n..#......#..#####.....#.##.....#..#..#####..#.....###..##.####.###...#####.#...##.#..#.......#.....#\n###..#.#.###.#.#..##..##..##...#.#........#...#...#.#.#..#.##.##.....#.##.###############.##...#.#..\n.#.#....#..##.......#........#..#...#.#.##.#...##.#.#.#.#.#..##...#.####.##.#.#...#...##.##########.\n.######.##.........#.########....#.######....##.##.#..####.###.##.#..##..##..####.#...#####...##.#.#\n...#..#.#..#.#..#.#.#########.#..##.#.#.#.#.#########....#...####...#.#..#.......#.##....####....###\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_20_questions.txt",
    "content": "--- Day 20: Trench Map ---\r\n\r\nWith the scanners fully deployed, you turn their attention to mapping the floor of the ocean trench.\r\n\r\nWhen you get back the image from the scanners, it seems to just be random noise. Perhaps you can combine an image enhancement algorithm and the input image (your puzzle input) to clean it up a little.\r\n\r\nFor example:\r\n\r\n..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..##\r\n#..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###\r\n.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#.\r\n.#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#.....\r\n.#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#..\r\n...####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.....\r\n..##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#\r\n\r\n#..#.\r\n#....\r\n##..#\r\n..#..\r\n..###\r\n\r\nThe first section is the image enhancement algorithm. It is normally given on a single line, but it has been wrapped to multiple lines in this example for legibility. The second section is the input image, a two-dimensional grid of light pixels (#) and dark pixels (.).\r\n\r\nThe image enhancement algorithm describes how to enhance an image by simultaneously converting all pixels in the input image into an output image. Each pixel of the output image is determined by looking at a 3x3 square of pixels centered on the corresponding input image pixel. So, to determine the value of the pixel at (5,10) in the output image, nine pixels from the input image need to be considered: (4,9), (4,10), (4,11), (5,9), (5,10), (5,11), (6,9), (6,10), and (6,11). These nine input pixels are combined into a single binary number that is used as an index in the image enhancement algorithm string.\r\n\r\nFor example, to determine the output pixel that corresponds to the very middle pixel of the input image, the nine pixels marked by [...] would need to be considered:\r\n\r\n# . . # .\r\n#[. . .].\r\n#[# . .]#\r\n.[. # .].\r\n. . # # #\r\n\r\nStarting from the top-left and reading across each row, these pixels are ..., then #.., then .#.; combining these forms ...#...#.. By turning dark pixels (.) into 0 and light pixels (#) into 1, the binary number 000100010 can be formed, which is 34 in decimal.\r\n\r\nThe image enhancement algorithm string is exactly 512 characters long, enough to match every possible 9-bit binary number. The first few characters of the string (numbered starting from zero) are as follows:\r\n\r\n0         10        20        30  34    40        50        60        70\r\n|         |         |         |   |     |         |         |         |\r\n..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..##\r\n\r\nIn the middle of this first group of characters, the character at index 34 can be found: #. So, the output pixel in the center of the output image should be #, a light pixel.\r\n\r\nThis process can then be repeated to calculate every pixel of the output image.\r\n\r\nThrough advances in imaging technology, the images being operated on here are infinite in size. Every pixel of the infinite output image needs to be calculated exactly based on the relevant pixels of the input image. The small input image you have is only a small region of the actual infinite input image; the rest of the input image consists of dark pixels (.). For the purposes of the example, to save on space, only a portion of the infinite-sized input and output images will be shown.\r\n\r\nThe starting input image, therefore, looks something like this, with more dark pixels (.) extending forever in every direction not shown here:\r\n\r\n...............\r\n...............\r\n...............\r\n...............\r\n...............\r\n.....#..#......\r\n.....#.........\r\n.....##..#.....\r\n.......#.......\r\n.......###.....\r\n...............\r\n...............\r\n...............\r\n...............\r\n...............\r\n\r\nBy applying the image enhancement algorithm to every pixel simultaneously, the following output image can be obtained:\r\n\r\n...............\r\n...............\r\n...............\r\n...............\r\n.....##.##.....\r\n....#..#.#.....\r\n....##.#..#....\r\n....####..#....\r\n.....#..##.....\r\n......##..#....\r\n.......#.#.....\r\n...............\r\n...............\r\n...............\r\n...............\r\n\r\nThrough further advances in imaging technology, the above output image can also be used as an input image! This allows it to be enhanced a second time:\r\n\r\n...............\r\n...............\r\n...............\r\n..........#....\r\n....#..#.#.....\r\n...#.#...###...\r\n...#...##.#....\r\n...#.....#.#...\r\n....#.#####....\r\n.....#.#####...\r\n......##.##....\r\n.......###.....\r\n...............\r\n...............\r\n...............\r\n\r\nTruly incredible - now the small details are really starting to come through. After enhancing the original input image twice, 35 pixels are lit.\r\n\r\nStart with the original input image and apply the image enhancement algorithm twice, being careful to account for the infinite size of the images. How many pixels are lit in the resulting image?\r\n\r\n--- Part Two ---\r\n\r\nYou still can't quite make out the details in the image. Maybe you just didn't enhance it enough.\r\n\r\nIf you enhance the starting input image in the above example a total of 50 times, 3351 pixels are lit in the final output image.\r\n\r\nStart again with the original input image and apply the image enhancement algorithm 50 times. How many pixels are lit in the resulting image?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_21.adb",
    "content": "--  Solution to Advent of Code 2021, Day 21\n-------------------------------------------\n--  Dirac Dice\n--\n--  https://adventofcode.com/2021/day/21\n--  Copy of questions in: aoc_2021_21_questions.txt\n--\n--  HAC 0.098 \"nice to have\"'s detected in this exercise:\n--\n--    *     aggregates, like ` hits := (others => (others => 0)); `\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_21 is\n\n  use Interfaces;\n\n  r : array (1 .. 2) of Integer_64;\n\n  subtype Player_Range is Integer range 0 .. 1;\n\n  cells : constant := 10;\n\n  subtype Cell_Range is Integer range 0 .. 9;  --  \"full Ada\": cells - 1\n\n  procedure Play_Part_1 (start_player_1, start_player_2 : Positive) is\n    score : array (Player_Range) of Natural;\n    start : array (Player_Range) of Cell_Range;\n    space, rolls : Natural;\n    win_score : constant := 1000;\n  begin\n    score (0) := 0;\n    score (1) := 0;\n    start (0) := start_player_1 - 1;  -- Start position, 0-based\n    start (1) := start_player_2 - 1;  -- Start position, 0-based\n    for round in 1 .. win_score loop  --  Worst case for any player: +1 point on each round.\n      for playing in Player_Range loop\n        space := 1 + (start (playing) + 9 * round ** 2 + (9 * playing - 3) * round) mod cells;\n        score (playing) := score (playing) + space;\n        if score (playing) >= 1000 then\n          rolls := 3 * (1 + (round - 1) * 2 + playing);\n          r (1) := Interfaces.Integer_64 (score (1 - playing) * rolls);\n          return;\n        end if;\n      end loop;\n    end loop;\n  end Play_Part_1;\n\n  subtype Dirac_Dice_Range is Integer range 3 .. 9;\n\n  --  Number of combinations of 3 dice rolls for each outcome.\n  dice_counts : array (Dirac_Dice_Range) of Positive;\n  --  \"full Ada\": ` dice_counts ... := (1,3,6,7,6,3,1) `\n\n  procedure Init_Dirac is\n  begin\n    dice_counts (3) := 1;  --  One combination: 1,1,1\n    dice_counts (4) := 3;  --  3 combinations: 1,1,2, 1,2,1, 2,1,1\n    dice_counts (5) := 6;\n    dice_counts (6) := 7;\n    dice_counts (7) := 6;\n    dice_counts (8) := 3;\n    dice_counts (9) := 1;\n  end Init_Dirac;\n\n  --  Universes wins counts for player 1 and 2.\n  type Univs_Pair is array (1 .. 2) of Integer_64;\n\n  procedure Play_Part_2 (start_player_1, start_player_2 : Positive) is\n    win_score : constant := 21;\n    subtype Score_Range is Integer range 0 .. win_score;\n    --  Memoization of intermediate results, depending\n    --  on the possible scores and positions:\n    cache : array (Score_Range, Score_Range, Cell_Range, Cell_Range) of Univs_Pair;\n    not_seen : constant := -1;\n    --\n    --  We simulate player A (1 or 2) rolling the dice then\n    --  winning, or giving the hand to player B (2 or 1).\n    --\n    procedure Winning_Universes (\n      score_A, score_B : in  Natural;\n      pos_A,   pos_B   : in  Cell_Range;\n      univs            : out Univs_Pair\n    )\n    is\n      new_pos_A   : Cell_Range;\n      new_score_A : Natural;\n      other_play  : Univs_Pair;\n    begin\n      if cache (score_A, score_B, pos_A, pos_B)(1) /= not_seen then\n        univs := cache (score_A, score_B, pos_A, pos_B);\n        return;\n      end if;\n      univs (1) := 0;\n      univs (2) := 0;\n      --  Player A rolls the Dirac dices 3 times.\n      --  We go through the possible outcomes, after the 3 draws:\n      --  the parallel universes become only different\n      --  depending on the sum of the 3 draws.\n      for dirac_dice_3 in 3 .. 9 loop\n        new_pos_A   := (pos_A + dirac_dice_3) mod cells;\n        new_score_A := score_A + 1 + new_pos_A;  --  Our positions are 0-based.\n        if new_score_A >= win_score then\n          --  In this case, player A wins when reaching new_pos_A.\n          --  It happens once if the numbers diced were 1, 1, 1;\n          --  3 times if the numbers diced were 1, 1, 2 (in any order), etc.\n          univs (1) := univs (1) + Integer_64 (dice_counts (dirac_dice_3));\n        else\n          --  Player A doesn't win, so it's player B's turn to play.\n          Winning_Universes (\n            score_B,\n            new_score_A,\n            pos_B,\n            new_pos_A,\n            other_play  --  = (#universes where B wins, #universes where A wins)\n          );\n          univs (1) := univs (1) + Integer_64 (dice_counts (dirac_dice_3)) * other_play (2);\n          univs (2) := univs (2) + Integer_64 (dice_counts (dirac_dice_3)) * other_play (1);\n        end if;\n      end loop;\n      --\n      cache (score_A, score_B, pos_A, pos_B) := univs;\n    end Winning_Universes;\n    res : Univs_Pair;\n  begin\n    --  \"full Ada\": the following could be done in `cache` declaration\n    --  with a (others => (others => (others => (others => not_seen))))\n    for s1 in Score_Range loop\n      for s2 in Score_Range loop\n        for c1 in Cell_Range loop\n          for c2 in Cell_Range loop\n            cache (s1, s2, c1, c2)(1) := not_seen;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    --\n    Winning_Universes (0, 0, start_player_1 - 1, start_player_2 - 1, res);\n    r (2) := res (1);\n    if res (2) > res (1) then r (2) := res (2); end if;\n  end Play_Part_2;\n\n  use HAT;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Init_Dirac;\n  Play_Part_1 (7, 1);\n  Play_Part_2 (7, 1);\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2:\" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 684495\n    --  Part 2: validated by AoC: 152587196649184\n  end if;\nend AoC_2021_21;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_21_questions.txt",
    "content": "--- Day 21: Dirac Dice ---\r\n\r\nThere's not much to do as you slowly descend to the bottom of the ocean. The submarine computer challenges you to a nice game of Dirac Dice.\r\n\r\nThis game consists of a single die, two pawns, and a game board with a circular track containing ten spaces marked 1 through 10 clockwise. Each player's starting space is chosen randomly (your puzzle input). Player 1 goes first.\r\n\r\nPlayers take turns moving. On each player's turn, the player rolls the die three times and adds up the results. Then, the player moves their pawn that many times forward around the track (that is, moving clockwise on spaces in order of increasing value, wrapping back around to 1 after 10). So, if a player is on space 7 and they roll 2, 2, and 1, they would move forward 5 times, to spaces 8, 9, 10, 1, and finally stopping on 2.\r\n\r\nAfter each player moves, they increase their score by the value of the space their pawn stopped on. Players' scores start at 0. So, if the first player starts on space 7 and rolls a total of 5, they would stop on space 2 and add 2 to their score (for a total score of 2). The game immediately ends as a win for any player whose score reaches at least 1000.\r\n\r\nSince the first game is a practice game, the submarine opens a compartment labeled deterministic dice and a 100-sided die falls out. This die always rolls 1 first, then 2, then 3, and so on up to 100, after which it starts over at 1 again. Play using this die.\r\n\r\nFor example, given these starting positions:\r\n\r\nPlayer 1 starting position: 4\r\nPlayer 2 starting position: 8\r\n\r\nThis is how the game would go:\r\n\r\n    Player 1 rolls 1+2+3 and moves to space 10 for a total score of 10.\r\n    Player 2 rolls 4+5+6 and moves to space 3 for a total score of 3.\r\n    Player 1 rolls 7+8+9 and moves to space 4 for a total score of 14.\r\n    Player 2 rolls 10+11+12 and moves to space 6 for a total score of 9.\r\n    Player 1 rolls 13+14+15 and moves to space 6 for a total score of 20.\r\n    Player 2 rolls 16+17+18 and moves to space 7 for a total score of 16.\r\n    Player 1 rolls 19+20+21 and moves to space 6 for a total score of 26.\r\n    Player 2 rolls 22+23+24 and moves to space 6 for a total score of 22.\r\n\r\n...after many turns...\r\n\r\n    Player 2 rolls 82+83+84 and moves to space 6 for a total score of 742.\r\n    Player 1 rolls 85+86+87 and moves to space 4 for a total score of 990.\r\n    Player 2 rolls 88+89+90 and moves to space 3 for a total score of 745.\r\n    Player 1 rolls 91+92+93 and moves to space 10 for a final score, 1000.\r\n\r\nSince player 1 has at least 1000 points, player 1 wins and the game ends. At this point, the losing player had 745 points and the die had been rolled a total of 993 times; 745 * 993 = 739785.\r\n\r\nPlay a practice game using the deterministic 100-sided die. The moment either player wins, what do you get if you multiply the score of the losing player by the number of times the die was rolled during the game?\r\n\r\n--- Part Two ---\r\n\r\nNow that you're warmed up, it's time to play the real game.\r\n\r\nA second compartment opens, this time labeled Dirac dice. Out of it falls a single three-sided die.\r\n\r\nAs you experiment with the die, you feel a little strange. An informational brochure in the compartment explains that this is a quantum die: when you roll it, the universe splits into multiple copies, one copy for each possible outcome of the die. In this case, rolling the die always splits the universe into three copies: one where the outcome of the roll was 1, one where it was 2, and one where it was 3.\r\n\r\nThe game is played the same as before, although to prevent things from getting too far out of hand, the game now ends when either player's score reaches at least 21.\r\n\r\nUsing the same starting positions as in the example above, player 1 wins in 444356092776315 universes, while player 2 merely wins in 341960390180808 universes.\r\n\r\nUsing your given starting positions, determine every possible outcome. Find the player that wins in more universes; in how many universes does that player win?\r\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_22.adb",
    "content": "--  Solution to Advent of Code 2021, Day 22\n-------------------------------------------\n--  Reactor Reboot\n--\n--  https://adventofcode.com/2021/day/22\n--  Copy of questions in: aoc_2021_22_questions.txt\n--\n--  GNAT: - runs in 2081 seconds i.e. 35 min in fast mode\n--        - needs to use Integer_64 for counters.\n--\n--  To do: make a HAC variant of a smarter solution, with\n--  applying the \"on/off\" rules in the outer loop and\n--  (in dimension d) skipping sorted values not within\n--  current rule's range. Inspiration:\n--  https://github.com/mytbk/advent_of_code/blob/main/2021/22/advent_22_2.adb\n--\n--  Wish from HAC 0.098 solved in HAC 0.1:\n--    *     package Interfaces with at least\n--            Integer_64 for compatibility with GNAT\n--            (GNAT's Integer is always 32 bits)\n--\n--\nwith HAT;\n--  For a build with \"full Ada\": files HAT*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2021.gpr .\n\nwith Interfaces;  --  Needed for GNAT (Integer_64).\n\nprocedure AoC_2021_22 is\n  use HAT, Interfaces;\n\n  dim_max : constant := 3;\n  subtype Dimension_Range is Integer range 1 .. dim_max;\n  type Point is array (Dimension_Range) of Integer;\n\n  type Rule_Type is record\n    on        : Boolean;\n    low, high : Point;\n  end record;\n\n  rules_max : constant := 1000;\n  rules : Natural := 0;\n\n  rule : array (1 .. rules_max) of Rule_Type;\n\n  --  Lists of numbers\n  --  NB: of course in \"full Ada\" we would do it in a much\n  --      smarter way, with Vectors & sorting.\n  list_length_max : constant := rules_max;\n  type List_Array_Type is array (1 .. list_length_max) of Integer;\n  type List_Type is record\n    top : Natural;\n    val : List_Array_Type;\n  end record;\n\n  --  Insert and sort ascending\n  procedure Insert (list : in out List_Type; num : Integer) is\n    ins : Natural := list.top + 1;\n  begin\n    for i in 1 .. list.top loop\n      if num = list.val (i) then\n        return;\n      elsif num < list.val (i) then\n        ins := i;  --  Insert here.\n        exit;\n      end if;\n    end loop;\n    for i in reverse ins .. list.top loop\n      list.val (i + 1) := list.val (i);\n    end loop;\n    list.val (ins) := num;\n    list.top := list.top + 1;\n  end Insert;\n\n  --  We record every point in every dimension.\n  coord : array (Dimension_Range) of List_Type;\n\n  procedure Read_Data is\n    input : constant VString := +\"aoc_2021_22.txt\";\n    --\n    c, sep : Character;\n    num : Integer;\n    onoff : String (1 .. 3);\n    xyz, dotdot : String (1 .. 2);\n    f : File_Type;\n  begin\n    for d in Dimension_Range loop\n      coord (d).top := 0;\n    end loop;\n\n    Open (f, input);\n    while not End_Of_File (f) loop\n      rules := rules + 1;\n      Get (f, onoff);\n      rule (rules).on := onoff = \"on \";\n      if not rule (rules).on then\n        Get (f, c);\n      end if;\n      for d in Dimension_Range loop\n        Get (f, xyz);\n        Get (f, num);\n        rule (rules).low (d) := num;\n        Insert (coord (d), num);\n        Get (f, dotdot);\n        Get (f, num);\n        rule (rules).high (d) := num;\n        Insert (coord (d), num);\n        exit when d = dim_max;\n        Get (f, sep);\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (1 .. 2) of Integer_64;\n\n  procedure Part_1 is\n    on : Boolean;\n    count : Integer_64 := 0;\n  begin\n    for x in -50 .. 50 loop\n      for y in -50 .. 50 loop\n        for z in -50 .. 50 loop\n          on := False;\n          for r in 1 .. rules loop\n            if x in rule (r).low (1) .. rule (r).high (1) and then\n               y in rule (r).low (2) .. rule (r).high (2) and then\n               z in rule (r).low (3) .. rule (r).high (3)\n            then\n              on := rule (r).on;\n            end if;\n          end loop;\n          if on then count := count + 1; end if;\n        end loop;\n      end loop;\n    end loop;\n    r (1) := count;\n  end Part_1;\n\n  procedure Part_2 is\n    count : Integer_64 := 0;\n    --\n    --  When d <= dim_max we test different cuboid vertices,\n    --     for each dimension.\n    --  When d = dim_max + 1 we scan the cuboid delimited by\n    --     opposite vertices input_vertex_1 (included), input_vertex_2\n    --     (excluded) through the list of rules, and count the cuboid's\n    --     volume when it is `on`.\n    --\n    procedure Scan (input_vertex_1, input_vertex_2 : Point; d : Positive) is\n      vertex_1, vertex_2 : Point;\n      inside, on : Boolean;\n      volume : Integer_64;\n    begin\n      if d = dim_max + 1 then\n        --\n        --  Vertice are complete in all dimensions, we can check the cuboid.\n        --\n        on := False;\n        for r in 1 .. rules loop\n          inside := True;\n          for dd in Dimension_Range loop\n            inside := inside and then\n              --  Vertex 1 (or any point within the cuboid) is sufficient\n              --  for checking the whole cuboid against the rules since\n              --  we know that no rule goes through the cuboid.\n              input_vertex_1 (dd) in rule (r).low (dd) .. rule (r).high (dd);\n          end loop;\n          if inside then\n            on := rule (r).on;\n          end if;\n        end loop;\n        if on then\n          volume := 1;\n          for dd in Dimension_Range loop\n            volume := volume * Integer_64 (input_vertex_2 (dd) - input_vertex_1 (dd));\n          end loop;\n          count := count + volume;\n        end if;\n      else\n        --  We construct cuboids such that all the cubes they contain\n        --  are either \"on\" or \"off\". The union of all constructed cuboids\n        --  is itself a giant cuboid which contains all cuboids described\n        --  in the \"on/off\" rules.\n        --\n        --  A little drawing to explain the code below.\n        --    '#' are rule cuboid boundaries.\n        --    '.' are examples of constructed cuboids touching\n        --          no rule boundary.\n        --    '>' and '^' indicate boundaries of a rule (or more).\n        --    '-' and '|' indicate boundaries of the giant cuboid.\n        --\n        --              > --------##############------\n        --                |.. ....#            #     |\n        --              > #############        #######\n        --                #.. ....#...#   on   #     #\n        --                #.. ....#...#        # off #\n        --                #.. ....#...#        #     #\n        --                #.. ....#...#        #     #\n        --              > #       ####################\n        --              > #  #        #              |\n        --                #..      ...#              |\n        --              > #############---------------\n        --                ^  ^    ^   ^        ^     ^\n        --\n        for i in 1 .. coord (d).top loop\n          vertex_1 := input_vertex_1;\n          vertex_2 := input_vertex_2;\n          --  Check the cuboids, of width 1 in dimension d,\n          --  touching a boundary of a rule (or more).\n          vertex_1 (d) := coord (d).val (i);\n          vertex_2 (d) := coord (d).val (i) + 1;\n          Scan (vertex_1, vertex_2, d + 1);\n          if i < coord (d).top then\n            --  Check the cuboids with opposite vertices that\n            --  don't touch any rule cuboid's boundary in\n            --  dimension d.\n            vertex_1 (d) := coord (d).val (i) + 1;\n            vertex_2 (d) := coord (d).val (i + 1);\n            Scan (vertex_1, vertex_2, d + 1);\n          end if;\n        end loop;\n      end if;\n    end Scan;\n    --\n    dummy_vertex_1, dummy_vertex_2 : Point;\n  begin\n    Scan (dummy_vertex_1, dummy_vertex_2, 1);\n    r (2) := count;\n  end Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  Part_1;\n  Part_2;\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n      r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: : number of cubes which are \"\"on\"\" within small region \" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2: : number of cubes which are \"\"on\"\" \" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 587097\n    --  Part 2: validated by AoC: 1359673068597669\n  end if;\nend AoC_2021_22;\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_22.txt",
    "content": "on x=-5..46,y=-32..20,z=-18..26\non x=-47..-1,y=-28..19,z=-49..3\non x=-19..30,y=-22..31,z=-20..33\non x=-27..19,y=-38..7,z=-9..35\non x=-37..7,y=-11..34,z=-44..7\non x=-18..27,y=-13..39,z=1..45\non x=-8..37,y=-35..13,z=-29..21\non x=-8..46,y=-46..3,z=-18..30\non x=-34..10,y=0..48,z=-40..14\non x=-9..40,y=-42..5,z=-1..44\noff x=6..25,y=6..16,z=12..23\non x=-28..26,y=-35..9,z=-19..35\noff x=7..17,y=-38..-28,z=26..45\non x=-22..32,y=-8..36,z=-38..13\noff x=30..41,y=-42..-29,z=8..27\non x=-24..23,y=-18..28,z=-10..43\noff x=26..36,y=16..32,z=-47..-32\non x=-49..2,y=-19..28,z=-3..45\noff x=-38..-22,y=1..12,z=1..16\non x=-39..8,y=-5..49,z=-28..18\non x=51548..69612,y=-60212..-36528,z=-25189..-16754\non x=-59209..-41074,y=-47258..-18479,z=43187..67447\non x=-7732..15267,y=28887..44205,z=-78972..-69135\non x=-56485..-41367,y=35643..60725,z=9955..38448\non x=-45609..-30383,y=42538..67043,z=-62848..-27707\non x=16585..38511,y=61520..81118,z=35888..62067\non x=-67525..-48645,y=7892..19788,z=-59876..-45177\non x=-78784..-51262,y=32167..54511,z=4045..30666\non x=-58038..-30559,y=-34516..-9371,z=-74896..-49631\non x=59490..71576,y=-46392..-27677,z=-19354..4915\non x=2789..22240,y=-85959..-62180,z=18830..28722\non x=-57568..-43338,y=63096..75178,z=926..32659\non x=-36402..-25163,y=56158..72356,z=-34059..-23691\non x=19381..37737,y=52036..68217,z=29949..43546\non x=37800..56883,y=-65115..-54626,z=7625..22209\non x=29861..55671,y=-70522..-59084,z=-9952..22480\non x=-4943..4619,y=-82644..-55578,z=-47007..-23182\non x=-77849..-71032,y=16058..44694,z=-1827..11132\non x=-23897..4513,y=-32899..-19780,z=74118..93642\non x=-60931..-43684,y=41018..76777,z=-3631..29159\non x=-69808..-59244,y=-51812..-25532,z=-45864..-9434\non x=-15717..2260,y=35502..45822,z=-72800..-64438\non x=-43443..-25264,y=-34577..-4572,z=-71311..-49556\non x=33953..53184,y=-24517..-12192,z=67205..70115\non x=-41613..-10171,y=-90989..-64734,z=1939..27480\non x=46293..54347,y=34679..57929,z=41751..66847\non x=-76583..-57535,y=-48670..-21474,z=5815..29534\non x=-80510..-57928,y=-29414..-6514,z=-37580..-9861\non x=34411..44577,y=45833..60226,z=34129..52711\non x=-54987..-24702,y=35411..65161,z=22013..51876\non x=63172..82294,y=1664..5780,z=-28578..-11907\non x=-67996..-54355,y=-44787..-25403,z=37322..54489\non x=-88986..-66707,y=-438..8596,z=15392..26773\non x=24230..44153,y=30762..34631,z=-74945..-53755\non x=35628..53039,y=15552..30471,z=-73777..-45796\non x=-52060..-30732,y=-42710..-35117,z=-69599..-56932\non x=-25002..1751,y=-81083..-59751,z=-50786..-30720\non x=-73739..-54969,y=31242..54593,z=-15062..-5453\non x=-47432..-33101,y=-76534..-50415,z=14492..27925\non x=-41274..-24626,y=13752..36312,z=-77251..-62098\non x=-6015..10536,y=65091..87672,z=-8552..19147\non x=10536..33835,y=-45299..-21530,z=60435..67449\non x=-6943..11903,y=-12128..16312,z=-90681..-78248\non x=19487..42357,y=47438..82073,z=21946..53196\non x=-21443..-4774,y=-40617..-24129,z=54316..78982\non x=63707..77304,y=-38874..-28037,z=-18266..6915\non x=-6608..25825,y=72777..97505,z=-17109..11691\non x=2889..21341,y=65169..90385,z=18937..38113\non x=-77060..-67800,y=-51373..-14093,z=-8648..14762\non x=42229..66044,y=-60623..-46142,z=-54862..-31092\non x=-31747..-1959,y=-56945..-43565,z=-66618..-51357\non x=40909..51753,y=-30080..-16886,z=48239..61214\non x=69140..93786,y=5799..19749,z=-6841..872\non x=-6320..9006,y=-86599..-63122,z=-13738..12967\non x=-8408..7465,y=4860..11903,z=77529..78985\non x=-72765..-50331,y=6535..18747,z=-58335..-51186\non x=-4003..16109,y=51255..89213,z=-55782..-20348\non x=-80053..-69750,y=-4588..15466,z=21830..30736\non x=65397..85386,y=6545..33466,z=-21152..-13938\non x=-11846..-3287,y=-25751..-7512,z=65275..84910\non x=-8452..15638,y=-14228..5220,z=-90071..-73008\non x=33452..61442,y=-19321..15551,z=49363..80378\non x=20735..47619,y=58344..71302,z=21735..41485\non x=11894..17984,y=31286..38843,z=69448..84141\non x=-28901..-20476,y=56147..81693,z=25668..51544\non x=6892..29595,y=64220..87570,z=-4733..20349\non x=-19082..4923,y=-77762..-69631,z=-38618..-23768\non x=36297..71252,y=-46927..-22141,z=43163..67184\non x=37857..43987,y=-40548..-13497,z=55402..60685\non x=-18613..3908,y=63432..84514,z=-37998..-30669\non x=12594..38169,y=66206..86022,z=-39692..-17639\non x=-32769..-1538,y=-49140..-26552,z=-79489..-51197\non x=53359..70274,y=26290..55000,z=-47687..-20020\non x=-66712..-35804,y=-77484..-56383,z=2674..24161\non x=-43228..-29410,y=45851..81707,z=-40520..-25586\non x=-20560..-9751,y=51994..82219,z=31331..68243\non x=-21397..-2481,y=41154..66963,z=49167..79202\non x=-16407..13119,y=48433..79148,z=34394..65994\non x=-36116..-19914,y=-17493..-1274,z=-83827..-59340\non x=-65917..-60015,y=-22232..-8123,z=44955..52754\non x=35522..62422,y=-47708..-41694,z=30631..52175\non x=-19027..-16358,y=-69201..-59790,z=40059..63066\non x=-11051..9182,y=40384..59830,z=-82502..-64612\non x=45221..58438,y=-57873..-30492,z=-62317..-37220\non x=20911..38767,y=-83455..-67100,z=15685..42250\non x=-85424..-62312,y=15633..41768,z=-11400..1596\non x=-22319..1952,y=14052..20241,z=-80323..-60026\non x=-36511..-3117,y=76591..88287,z=-7433..10958\non x=-66952..-44475,y=14319..31064,z=-58790..-36803\non x=54959..76207,y=-35201..-16191,z=-16849..-5914\non x=1597..26993,y=-10079..6267,z=63496..85390\non x=16494..39087,y=-17926..9408,z=-96055..-57690\non x=61259..85576,y=1205..18753,z=-43630..-35549\non x=9246..42812,y=4903..18157,z=-91998..-64639\non x=56336..60328,y=38496..41872,z=-45204..-16725\non x=38207..53167,y=32557..48679,z=-45752..-31483\non x=35536..40478,y=59087..82670,z=-22132..-8228\non x=30311..65221,y=28463..49610,z=-56548..-43899\non x=39910..64396,y=-15554..6772,z=-77870..-61149\non x=63583..81517,y=-27533..4944,z=-25021..2998\non x=33270..48936,y=29978..53349,z=-64005..-46652\non x=-56719..-45447,y=48476..70535,z=19845..43624\non x=-18909..-4514,y=-33630..-18313,z=-81121..-68081\non x=31236..49957,y=37375..64529,z=40066..50479\non x=23928..60990,y=47394..71017,z=-38356..-19687\non x=14948..29328,y=10910..33468,z=-80969..-58848\non x=-3772..13969,y=-63212..-52751,z=-57568..-40117\non x=-87668..-65329,y=5661..25191,z=-16217..-2548\non x=-85618..-61349,y=-28751..724,z=-55669..-27090\non x=31666..50666,y=61760..79239,z=-5421..13325\non x=-43549..-16273,y=11600..29339,z=58406..69643\non x=-71478..-49781,y=27481..49069,z=11039..36531\non x=-17921..763,y=-88151..-58003,z=30178..41080\non x=46026..66776,y=14383..45440,z=40733..70614\non x=6163..18610,y=34482..54360,z=60951..89457\non x=19365..38532,y=-76528..-64410,z=11243..32396\non x=43561..71092,y=37565..67440,z=-7400..10989\non x=-78980..-62759,y=-37937..-18712,z=-1174..20466\non x=-84895..-61183,y=-49742..-11414,z=-40817..-27778\non x=-4950..15040,y=-68419..-47571,z=-53761..-38955\non x=49075..58693,y=47622..72167,z=-38355..-14042\non x=-251..24365,y=-83737..-52646,z=-46887..-23747\non x=7867..22830,y=-69902..-54281,z=39203..56857\non x=9363..26818,y=-90361..-66389,z=498..11013\non x=-83134..-56144,y=-28208..-24507,z=-54343..-27431\non x=6218..37705,y=-46023..-13463,z=63985..73956\non x=18495..39411,y=-26282..5248,z=-88148..-58497\non x=-45343..-35708,y=60706..70020,z=5612..17818\non x=-84718..-59568,y=-43294..-5711,z=-6416..2360\non x=31112..44903,y=68718..77761,z=-9607..6150\non x=38564..51370,y=-58071..-40868,z=16841..56101\non x=-90218..-62438,y=-16396..15602,z=7324..40169\non x=22063..40035,y=-82841..-51548,z=-12200..-2319\non x=61862..68317,y=-58231..-29405,z=-30145..-16073\non x=-35659..-26115,y=-80307..-58295,z=-7971..4817\non x=65798..82975,y=16152..37978,z=-13348..9888\non x=-22630..-2020,y=61028..82758,z=17882..53557\non x=-67183..-35832,y=53346..61736,z=-12538..-3992\non x=17561..43947,y=-691..17483,z=-80636..-71364\non x=-85254..-57085,y=-45670..-26674,z=-35836..-16893\non x=50248..59220,y=51067..53406,z=5200..24299\non x=-66088..-58018,y=-54019..-18590,z=22979..55616\non x=-21580..-1226,y=-70163..-50890,z=35971..58676\non x=-28699..-7879,y=58342..80552,z=-2944..4892\non x=32137..37434,y=57922..89847,z=-11139..4540\non x=-30782..-26050,y=-71857..-56160,z=25962..45221\non x=3458..14941,y=39444..54613,z=-78667..-51181\non x=-80957..-61391,y=-50519..-44099,z=558..36217\non x=56295..67502,y=-52211..-21726,z=-38237..-23495\non x=-59221..-26440,y=-8835..8022,z=-69874..-51958\non x=9703..31412,y=-66797..-44997,z=-69333..-41279\non x=-25059..-4256,y=50641..81219,z=41651..53960\non x=-78241..-51194,y=31612..49911,z=8201..31693\non x=54112..76706,y=12410..48082,z=-4849..18133\non x=-69337..-38953,y=49176..56256,z=23632..36858\non x=-2661..28887,y=-70999..-53499,z=-62680..-47815\non x=-47941..-29732,y=70681..92846,z=11502..17530\non x=42289..62010,y=36246..60613,z=27169..37328\non x=-91319..-65281,y=-12414..-1137,z=-562..33562\non x=67610..87861,y=-16375..5387,z=4908..37520\non x=-64941..-37494,y=12789..19739,z=43684..59305\non x=-48315..-23707,y=-63379..-46409,z=-52056..-50037\non x=39998..55060,y=-23924..174,z=47043..74650\non x=15519..54000,y=-37758..-7362,z=56719..86415\non x=-48899..-33632,y=-70284..-38768,z=-35439..-12719\non x=-32719..-19579,y=-72481..-55178,z=22036..45341\non x=3957..31100,y=-43843..-7496,z=-77904..-55904\non x=58913..74866,y=427..13237,z=-32194..-25180\non x=14045..39458,y=57126..69184,z=-56733..-40909\non x=-33890..-15281,y=-87080..-60332,z=-7896..17708\non x=-62854..-44941,y=25995..33486,z=-40656..-31936\non x=-92186..-67248,y=-31617..-10693,z=-13091..10422\non x=-20335..-1607,y=33592..61801,z=49129..66118\non x=4923..21291,y=56686..89367,z=13440..33655\non x=-85603..-58549,y=-57595..-29882,z=-29310..7688\non x=-31013..-12004,y=65998..87119,z=20798..38505\non x=-31477..631,y=-4218..13444,z=64468..96359\non x=-53080..-23970,y=-67988..-50724,z=35761..56920\non x=-3114..31515,y=-8351..9393,z=59128..93321\non x=-55700..-34434,y=2745..17959,z=61954..88396\non x=-11042..14693,y=-54901..-21447,z=67817..81842\non x=21055..36006,y=-87302..-60889,z=-15547..1734\non x=-54134..-40995,y=-47264..-26058,z=-60793..-32468\non x=58900..84612,y=19801..52338,z=-29863..-5113\non x=51518..67122,y=-73957..-44881,z=-21799..377\non x=-76186..-60253,y=-52998..-32671,z=-10966..22158\non x=-85814..-69675,y=-16314..-1479,z=12576..29151\non x=-17279..-7487,y=69461..82491,z=-43685..-20033\non x=40521..54246,y=27004..54142,z=29821..43721\non x=39205..48927,y=-76831..-53845,z=10907..30764\non x=-33186..-8425,y=-25334..-12643,z=-90320..-73208\non x=-28871..-10579,y=52805..71984,z=40782..48756\non x=-84199..-69384,y=-24294..10470,z=-31795..-504\non x=14215..35943,y=-68234..-54826,z=-40696..-26587\non x=-1154..8736,y=541..27118,z=-92688..-67093\non x=-78094..-57999,y=30080..50610,z=14623..47207\non x=-71351..-61777,y=32493..36723,z=-43154..-20385\non x=29680..49711,y=64389..80775,z=-14976..-7530\non x=21466..32444,y=-71107..-49184,z=32025..47710\non x=-13395..2005,y=55307..82256,z=13571..32919\noff x=-75925..-51372,y=38378..56338,z=4726..22058\noff x=-81435..-61321,y=-19944..14261,z=-12909..5888\non x=-28811..-418,y=-60179..-36825,z=60339..82792\non x=-56836..-42864,y=51509..69993,z=-38353..-9466\noff x=33241..47683,y=-57215..-42041,z=-66120..-48804\noff x=5602..32171,y=67207..82648,z=687..19684\non x=-77530..-54996,y=-18932..14116,z=-41205..-26951\noff x=-26770..539,y=34948..50177,z=48516..78552\noff x=-46087..-28406,y=-34280..-25940,z=-88646..-67393\noff x=18159..44447,y=61027..74243,z=11037..47721\non x=12856..22197,y=-77260..-63311,z=9644..14020\non x=73356..83326,y=-28895..-11586,z=-12672..-9461\noff x=67712..93385,y=4383..29307,z=-20971..-918\non x=-45997..-33017,y=-73653..-54744,z=-45919..-18834\non x=60720..69779,y=-36283..-5920,z=-50708..-27954\non x=19053..47867,y=2081..28770,z=64876..71876\non x=-527..17979,y=54470..79654,z=-40446..-35448\non x=57634..74279,y=-12554..-1277,z=-32432..-15188\noff x=-5832..-3671,y=-73172..-56981,z=-55793..-43538\non x=-1264..8465,y=-42248..-24987,z=-89062..-53822\noff x=-15774..21815,y=27050..48731,z=56418..72513\noff x=-46133..-21613,y=66137..75384,z=6208..30313\non x=33118..53938,y=-65582..-37843,z=-37735..-12944\noff x=-49999..-44727,y=-6444..11058,z=56795..82782\non x=48809..67169,y=19871..40744,z=-52762..-34126\noff x=-83411..-59176,y=25797..45572,z=-40278..-27145\noff x=32616..41066,y=-9846..22502,z=65723..76470\non x=-20460..-2811,y=-83364..-60153,z=29259..46240\non x=-4678..31497,y=-66769..-42660,z=47122..52963\noff x=-79373..-44004,y=15610..27145,z=-60155..-24820\non x=-75928..-66979,y=-38564..-25541,z=-19893..-6451\non x=-40648..-20377,y=-16448..15340,z=68020..86613\noff x=-62245..-35670,y=-31396..-7005,z=-65944..-45697\non x=-13973..20255,y=11258..38206,z=-88464..-74070\non x=-79431..-61223,y=-24640..2553,z=-45829..-35435\non x=-4924..9129,y=-80374..-53014,z=26057..45688\noff x=6404..27786,y=47552..72969,z=-56049..-33886\noff x=-60433..-45352,y=54256..72101,z=-1351..13871\non x=14354..49643,y=33977..50411,z=-78584..-53528\noff x=-1250..19190,y=-69591..-51054,z=32606..57993\non x=44601..65261,y=-22387..-4877,z=-47514..-27914\noff x=-76961..-53337,y=11751..35762,z=26662..51798\non x=-6110..17117,y=35295..55448,z=49203..65916\non x=-26314..7333,y=-10014..-190,z=-96699..-63078\non x=5073..27938,y=48893..68369,z=46606..53060\noff x=9161..32324,y=31253..49108,z=59376..78095\noff x=-76724..-46080,y=-37471..-7527,z=39313..59143\non x=-12104..25230,y=43873..63566,z=54973..71127\non x=-72007..-40895,y=-29918..-2483,z=-65639..-46254\noff x=23116..41418,y=-16707..518,z=66003..82373\noff x=7546..31315,y=-236..14978,z=73882..88170\noff x=2975..26627,y=-28535..4054,z=65551..79183\noff x=-63548..-40819,y=4251..34856,z=-69125..-53738\noff x=36116..53160,y=18391..43033,z=53283..69572\noff x=-8169..-7213,y=17466..44306,z=53116..81956\non x=43606..72143,y=38753..51975,z=30789..41812\non x=35845..48867,y=-15869..989,z=-69562..-58096\non x=-67758..-55029,y=-56935..-34340,z=-16747..14847\non x=45091..70880,y=18972..32828,z=-58444..-56030\noff x=11622..45729,y=-11464..15892,z=55396..77935\noff x=30723..44124,y=-50216..-38776,z=-58362..-52717\noff x=53359..57764,y=-28444..-7054,z=47399..61343\non x=-72327..-61742,y=36941..63691,z=-9967..9016\non x=1184..28614,y=-72042..-59895,z=29436..49413\noff x=-69303..-45932,y=-34340..-25505,z=-38098..-33099\non x=59045..88304,y=-30319..-10678,z=11682..39990\noff x=53524..67731,y=-68251..-44887,z=882..10308\noff x=-32029..-15563,y=-76737..-44100,z=-50442..-39369\noff x=194..33756,y=-81633..-73368,z=-43607..-17799\noff x=-48326..-13807,y=53400..85780,z=-5482..17259\non x=-4836..8518,y=-88585..-59292,z=-38817..-19966\noff x=-39059..-5289,y=-38701..-18212,z=62298..87934\non x=38636..52369,y=-67782..-55060,z=-39916..-24812\noff x=41566..50837,y=22379..30551,z=-65974..-50435\non x=-83246..-64136,y=-29788..2021,z=25088..51721\noff x=-7306..17520,y=73996..76916,z=-44293..-10369\non x=-64653..-52809,y=14691..34105,z=-58569..-42334\non x=15682..33355,y=50316..82171,z=27668..43094\noff x=-29490..-20692,y=51678..60437,z=39101..53564\noff x=19272..37050,y=13981..31882,z=67811..82763\noff x=24474..43806,y=-53159..-30998,z=29529..55383\non x=-90714..-55089,y=14725..45316,z=-1160..12104\non x=-64836..-35562,y=-8351..5014,z=-71436..-52114\noff x=30933..47732,y=-64548..-62131,z=6870..17374\non x=-77680..-53166,y=8312..40487,z=36033..43235\non x=-5863..28121,y=14413..32208,z=-86695..-63943\non x=32413..51029,y=-68162..-40475,z=-64026..-40258\non x=-48144..-41618,y=-28042..-10133,z=-64990..-50925\non x=73532..98724,y=-21663..8040,z=662..20743\noff x=51689..54423,y=40915..69007,z=3378..19020\noff x=-3711..20642,y=66808..81277,z=-32665..-18224\noff x=29497..56099,y=-59154..-38611,z=32874..69747\noff x=-32780..2492,y=-81309..-65288,z=-52012..-28083\noff x=12238..28287,y=60040..85737,z=2251..20540\noff x=-78514..-47095,y=-52287..-24038,z=-51482..-20767\non x=-2476..22624,y=76854..93819,z=-16182..1908\non x=25782..55736,y=61375..79709,z=9605..31807\non x=-12247..16212,y=-75039..-64291,z=-43708..-25037\noff x=-26281..-4119,y=31802..45275,z=61617..72578\noff x=-77629..-55347,y=-37694..-22601,z=-48750..-25744\non x=-41090..-17088,y=-42730..-21946,z=-71684..-44738\noff x=21171..52548,y=-73087..-62415,z=-24139..4853\non x=-10430..13741,y=-87082..-60233,z=29057..37997\noff x=-33776..-18921,y=-9022..10689,z=60785..92622\noff x=-17316..-5440,y=-46992..-37935,z=-72734..-65376\noff x=-25276..-1515,y=-4036..5863,z=-94213..-63783\non x=6018..30570,y=-75934..-59098,z=-3614..21349\noff x=47020..60774,y=16941..24239,z=52244..74152\non x=-28035..-8076,y=-83562..-56357,z=20214..35904\noff x=-4864..9282,y=-58885..-52290,z=46576..71092\noff x=-38607..-25227,y=-10107..20288,z=56552..78626\non x=-49296..-38783,y=1776..37729,z=-68328..-54075\noff x=27839..40291,y=-2748..5372,z=-73179..-64910\noff x=57012..63558,y=33773..63448,z=12538..30013\non x=7376..22139,y=46931..53925,z=40614..77423\non x=-36815..-4231,y=-79653..-53534,z=-54320..-30272\noff x=-72451..-44505,y=11708..45028,z=30438..48099\non x=19422..54740,y=61056..68389,z=11710..35395\non x=34256..51333,y=24928..52293,z=-65652..-36708\noff x=11235..22363,y=1316..13305,z=-95660..-75393\non x=40699..63818,y=-71842..-49029,z=-4105..24818\noff x=-56129..-51451,y=-4050..32239,z=-62360..-48415\noff x=7724..42005,y=-8468..7046,z=67268..89366\non x=-50038..-29191,y=190..9704,z=-85587..-62369\non x=52569..76812,y=29834..57890,z=-5460..24255\noff x=3998..24292,y=-20205..10100,z=77120..86720\noff x=-12018..6886,y=-28175..-5906,z=63737..83970\non x=64370..76913,y=20946..44292,z=-15861..-5899\noff x=3647..21883,y=-73520..-66435,z=19047..38036\non x=26881..35736,y=50047..83360,z=27009..43013\non x=-54204..-46977,y=-58133..-44730,z=25366..34727\non x=60963..72747,y=-40989..-1428,z=27149..44298\non x=-86903..-63974,y=15796..44312,z=14110..31846\non x=30800..51265,y=67817..83500,z=7398..35684\non x=26115..46933,y=-78183..-68457,z=16590..22235\non x=50801..69558,y=14960..41009,z=-52573..-42699\non x=-76762..-62114,y=-41535..-30916,z=30799..36061\noff x=-36971..-16432,y=69302..80179,z=5427..37800\non x=-59304..-42151,y=38961..75025,z=19077..30930\noff x=-68878..-43214,y=-38416..-34281,z=-56876..-32491\noff x=-41227..-30387,y=67997..78440,z=-18866..-4078\non x=-18264..4145,y=25638..53883,z=55825..72054\noff x=-34237..-23188,y=-18538..-14122,z=-84576..-66422\non x=48651..72652,y=-75451..-55934,z=-5750..21478\noff x=8517..15398,y=-47195..-20040,z=-91462..-57328\noff x=1946..24398,y=-9423..-7809,z=-98479..-63063\noff x=48647..64112,y=-44400..-36389,z=43567..50295\non x=-53108..-28792,y=-18105..16521,z=-79485..-50653\non x=10610..28165,y=74425..88696,z=-15151..11655\non x=26563..41972,y=-44034..-22600,z=-75006..-53514\non x=8785..23672,y=-17501..1486,z=70023..87851\noff x=-23526..-2495,y=-9907..13959,z=-86018..-74132\non x=39471..66769,y=-76484..-41637,z=4179..30148\non x=3968..41357,y=-12766..21564,z=-83232..-58999\noff x=5657..25453,y=69672..92433,z=-5865..1093\non x=196..22654,y=-76890..-45710,z=30347..50177\non x=53591..67443,y=641..12115,z=-53289..-40127\non x=38502..45974,y=26606..37157,z=-73606..-59489\noff x=-28470..-4391,y=65949..75960,z=-52362..-18690\noff x=-12052..12226,y=-43285..-11455,z=-76126..-67446\noff x=28539..47924,y=30936..61611,z=39553..62922\non x=-51301..-29348,y=-61136..-41356,z=-62122..-40860\noff x=-10842..12256,y=-4453..28219,z=62816..90429\noff x=-65177..-46992,y=-996..14455,z=43331..66866\noff x=-41471..-34895,y=-87935..-53932,z=-15068..10098\noff x=64368..85731,y=20782..34222,z=20343..56619\non x=-66495..-37890,y=53669..66986,z=16753..25052\noff x=-55523..-37167,y=-50099..-14312,z=-62328..-40509\non x=46869..65044,y=2893..32395,z=48728..67114\noff x=-22730..-6869,y=-89892..-55716,z=-39058..-9375\non x=-35338..-10108,y=-79088..-61919,z=-52266..-26583\non x=-87579..-54734,y=3661..13979,z=-43516..-26852\non x=-26237..6696,y=31736..52895,z=-88832..-51997\non x=-6261..18171,y=35455..40829,z=-82724..-51885\noff x=-84061..-53865,y=-37690..-28185,z=17406..27387\non x=22146..33574,y=-8382..21678,z=60530..93596\noff x=-34985..-14118,y=-85401..-53871,z=-27449..-20505\non x=-65653..-57152,y=-41709..-26255,z=-55300..-30989\non x=-41289..-18827,y=-54843..-30751,z=43268..77728\non x=52348..65143,y=-66867..-47070,z=-18590..-2919\non x=25408..46684,y=52219..74706,z=-45724..-26197\noff x=36306..61505,y=1854..18823,z=51517..71882\non x=28807..42884,y=-44933..-19495,z=-81888..-68452\noff x=-22712..10868,y=-91624..-66163,z=-29698..2061\non x=-44614..-22060,y=-12205..6362,z=-75228..-67848\noff x=69181..83413,y=22509..30155,z=-5505..7620\noff x=-541..33061,y=-29171..-1387,z=-89039..-65688\noff x=56369..86895,y=25436..32999,z=-36190..-5946\non x=-80106..-58102,y=4812..40730,z=-39905..-27846\noff x=38087..49836,y=12311..28936,z=56763..70449\noff x=-45431..-9536,y=27172..52966,z=54708..70851\non x=-49616..-21967,y=25466..55138,z=-65862..-49517\non x=-3678..22714,y=-89185..-68818,z=-38953..-22111\non x=57043..82773,y=-61228..-42569,z=6701..17395\non x=45714..76420,y=-58263..-27644,z=-39439..-20345\non x=-69167..-43379,y=7904..39678,z=-72903..-43716\noff x=-87370..-55908,y=41125..52870,z=-338..26930\non x=-20884..1182,y=-87244..-73126,z=-17967..-8207\noff x=-89696..-61051,y=-48909..-27178,z=-319..19788\noff x=11134..25390,y=40961..62596,z=-79259..-41800\n"
  },
  {
    "path": "exm/aoc/2021/aoc_2021_22_questions.txt",
    "content": "--- Day 22: Reactor Reboot ---\r\n\r\nOperating at these extreme ocean depths has overloaded the submarine's reactor; it needs to be rebooted.\r\n\r\nThe reactor core is made up of a large 3-dimensional grid made up entirely of cubes, one cube per integer 3-dimensional coordinate (x,y,z). Each cube can be either on or off; at the start of the reboot process, they are all off. (Could it be an old model of a reactor you've seen before?)\r\n\r\nTo reboot the reactor, you just need to set all of the cubes to either on or off by following a list of reboot steps (your puzzle input). Each step specifies a cuboid (the set of all cubes that have coordinates which fall within ranges for x, y, and z) and whether to turn all of the cubes in that cuboid on or off.\r\n\r\nFor example, given these reboot steps:\r\n\r\non x=10..12,y=10..12,z=10..12\r\non x=11..13,y=11..13,z=11..13\r\noff x=9..11,y=9..11,z=9..11\r\non x=10..10,y=10..10,z=10..10\r\n\r\nThe first step (on x=10..12,y=10..12,z=10..12) turns on a 3x3x3 cuboid consisting of 27 cubes:\r\n\r\n    10,10,10\r\n    10,10,11\r\n    10,10,12\r\n    10,11,10\r\n    10,11,11\r\n    10,11,12\r\n    10,12,10\r\n    10,12,11\r\n    10,12,12\r\n    11,10,10\r\n    11,10,11\r\n    11,10,12\r\n    11,11,10\r\n    11,11,11\r\n    11,11,12\r\n    11,12,10\r\n    11,12,11\r\n    11,12,12\r\n    12,10,10\r\n    12,10,11\r\n    12,10,12\r\n    12,11,10\r\n    12,11,11\r\n    12,11,12\r\n    12,12,10\r\n    12,12,11\r\n    12,12,12\r\n\r\nThe second step (on x=11..13,y=11..13,z=11..13) turns on a 3x3x3 cuboid that overlaps with the first. As a result, only 19 additional cubes turn on; the rest are already on from the previous step:\r\n\r\n    11,11,13\r\n    11,12,13\r\n    11,13,11\r\n    11,13,12\r\n    11,13,13\r\n    12,11,13\r\n    12,12,13\r\n    12,13,11\r\n    12,13,12\r\n    12,13,13\r\n    13,11,11\r\n    13,11,12\r\n    13,11,13\r\n    13,12,11\r\n    13,12,12\r\n    13,12,13\r\n    13,13,11\r\n    13,13,12\r\n    13,13,13\r\n\r\nThe third step (off x=9..11,y=9..11,z=9..11) turns off a 3x3x3 cuboid that overlaps partially with some cubes that are on, ultimately turning off 8 cubes:\r\n\r\n    10,10,10\r\n    10,10,11\r\n    10,11,10\r\n    10,11,11\r\n    11,10,10\r\n    11,10,11\r\n    11,11,10\r\n    11,11,11\r\n\r\nThe final step (on x=10..10,y=10..10,z=10..10) turns on a single cube, 10,10,10. After this last step, 39 cubes are on.\r\n\r\nThe initialization procedure only uses cubes that have x, y, and z positions of at least -50 and at most 50. For now, ignore cubes outside this region.\r\n\r\nHere is a larger example:\r\n\r\non x=-20..26,y=-36..17,z=-47..7\r\non x=-20..33,y=-21..23,z=-26..28\r\non x=-22..28,y=-29..23,z=-38..16\r\non x=-46..7,y=-6..46,z=-50..-1\r\non x=-49..1,y=-3..46,z=-24..28\r\non x=2..47,y=-22..22,z=-23..27\r\non x=-27..23,y=-28..26,z=-21..29\r\non x=-39..5,y=-6..47,z=-3..44\r\non x=-30..21,y=-8..43,z=-13..34\r\non x=-22..26,y=-27..20,z=-29..19\r\noff x=-48..-32,y=26..41,z=-47..-37\r\non x=-12..35,y=6..50,z=-50..-2\r\noff x=-48..-32,y=-32..-16,z=-15..-5\r\non x=-18..26,y=-33..15,z=-7..46\r\noff x=-40..-22,y=-38..-28,z=23..41\r\non x=-16..35,y=-41..10,z=-47..6\r\noff x=-32..-23,y=11..30,z=-14..3\r\non x=-49..-5,y=-3..45,z=-29..18\r\noff x=18..30,y=-20..-8,z=-3..13\r\non x=-41..9,y=-7..43,z=-33..15\r\non x=-54112..-39298,y=-85059..-49293,z=-27449..7877\r\non x=967..23432,y=45373..81175,z=27513..53682\r\n\r\nThe last two steps are fully outside the initialization procedure area; all other steps are fully within it. After executing these steps in the initialization procedure region, 590784 cubes are on.\r\n\r\nExecute the reboot steps. Afterward, considering only cubes in the region x=-50..50,y=-50..50,z=-50..50, how many cubes are on?\r\n\r\n--- Part Two ---\r\n\r\nNow that the initialization procedure is complete, you can reboot the reactor.\r\n\r\nStarting with all cubes off, run all of the reboot steps for all cubes in the reactor.\r\n\r\nConsider the following reboot steps:\r\n\r\non x=-5..47,y=-31..22,z=-19..33\r\non x=-44..5,y=-27..21,z=-14..35\r\non x=-49..-1,y=-11..42,z=-10..38\r\non x=-20..34,y=-40..6,z=-44..1\r\noff x=26..39,y=40..50,z=-2..11\r\non x=-41..5,y=-41..6,z=-36..8\r\noff x=-43..-33,y=-45..-28,z=7..25\r\non x=-33..15,y=-32..19,z=-34..11\r\noff x=35..47,y=-46..-34,z=-11..5\r\non x=-14..36,y=-6..44,z=-16..29\r\non x=-57795..-6158,y=29564..72030,z=20435..90618\r\non x=36731..105352,y=-21140..28532,z=16094..90401\r\non x=30999..107136,y=-53464..15513,z=8553..71215\r\non x=13528..83982,y=-99403..-27377,z=-24141..23996\r\non x=-72682..-12347,y=18159..111354,z=7391..80950\r\non x=-1060..80757,y=-65301..-20884,z=-103788..-16709\r\non x=-83015..-9461,y=-72160..-8347,z=-81239..-26856\r\non x=-52752..22273,y=-49450..9096,z=54442..119054\r\non x=-29982..40483,y=-108474..-28371,z=-24328..38471\r\non x=-4958..62750,y=40422..118853,z=-7672..65583\r\non x=55694..108686,y=-43367..46958,z=-26781..48729\r\non x=-98497..-18186,y=-63569..3412,z=1232..88485\r\non x=-726..56291,y=-62629..13224,z=18033..85226\r\non x=-110886..-34664,y=-81338..-8658,z=8914..63723\r\non x=-55829..24974,y=-16897..54165,z=-121762..-28058\r\non x=-65152..-11147,y=22489..91432,z=-58782..1780\r\non x=-120100..-32970,y=-46592..27473,z=-11695..61039\r\non x=-18631..37533,y=-124565..-50804,z=-35667..28308\r\non x=-57817..18248,y=49321..117703,z=5745..55881\r\non x=14781..98692,y=-1341..70827,z=15753..70151\r\non x=-34419..55919,y=-19626..40991,z=39015..114138\r\non x=-60785..11593,y=-56135..2999,z=-95368..-26915\r\non x=-32178..58085,y=17647..101866,z=-91405..-8878\r\non x=-53655..12091,y=50097..105568,z=-75335..-4862\r\non x=-111166..-40997,y=-71714..2688,z=5609..50954\r\non x=-16602..70118,y=-98693..-44401,z=5197..76897\r\non x=16383..101554,y=4615..83635,z=-44907..18747\r\noff x=-95822..-15171,y=-19987..48940,z=10804..104439\r\non x=-89813..-14614,y=16069..88491,z=-3297..45228\r\non x=41075..99376,y=-20427..49978,z=-52012..13762\r\non x=-21330..50085,y=-17944..62733,z=-112280..-30197\r\non x=-16478..35915,y=36008..118594,z=-7885..47086\r\noff x=-98156..-27851,y=-49952..43171,z=-99005..-8456\r\noff x=2032..69770,y=-71013..4824,z=7471..94418\r\non x=43670..120875,y=-42068..12382,z=-24787..38892\r\noff x=37514..111226,y=-45862..25743,z=-16714..54663\r\noff x=25699..97951,y=-30668..59918,z=-15349..69697\r\noff x=-44271..17935,y=-9516..60759,z=49131..112598\r\non x=-61695..-5813,y=40978..94975,z=8655..80240\r\noff x=-101086..-9439,y=-7088..67543,z=33935..83858\r\noff x=18020..114017,y=-48931..32606,z=21474..89843\r\noff x=-77139..10506,y=-89994..-18797,z=-80..59318\r\noff x=8476..79288,y=-75520..11602,z=-96624..-24783\r\non x=-47488..-1262,y=24338..100707,z=16292..72967\r\noff x=-84341..13987,y=2429..92914,z=-90671..-1318\r\noff x=-37810..49457,y=-71013..-7894,z=-105357..-13188\r\noff x=-27365..46395,y=31009..98017,z=15428..76570\r\noff x=-70369..-16548,y=22648..78696,z=-1892..86821\r\non x=-53470..21291,y=-120233..-33476,z=-44150..38147\r\noff x=-93533..-4276,y=-16170..68771,z=-104985..-24507\r\n\r\nAfter running the above reboot steps, 2758514936282235 cubes are on. (Just for fun, 474140 of those are also in the initialization procedure region.)\r\n\r\nStarting again with all cubes off, execute all reboot steps. Afterward, considering all cubes, how many cubes are on?\r\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Advent of Code 2022 examples.\n--\n--  Some programs work with both HAC and \"full Ada\" compilers like,\n--  GNAT some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject AoC_2022 is\n\n   for Source_Dirs use\n     (\".\",\n      \"..\",              --  For the AoC_Toolbox package\n      \"../../../src\");   --  GNAT's access to the HAT package.\n\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\"\n      );\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   type AoC_Styles_Checks_Type is\n      (\"Off\",\n       \"On\",\n       \"Extra\"\n      );\n   AoC_Styles_Checks : AoC_Styles_Checks_Type := external (\"AoC_Styles_Checks\", \"On\");\n\n   for Main use (\n     \"aoc_2022_25.adb\",\n     \"aoc_2022_24.adb\",\n     \"aoc_2022_23.adb\",\n     \"aoc_2022_22.adb\",\n     \"aoc_2022_21.adb\",\n     \"aoc_2022_20.adb\",\n     \"aoc_2022_19.adb\",\n     \"aoc_2022_19_full_ada.adb\",\n     \"aoc_2022_18.adb\",\n     \"aoc_2022_17.adb\",\n     \"aoc_2022_16.adb\",\n     \"aoc_2022_15.adb\",\n     \"aoc_2022_14.adb\",\n     \"aoc_2022_13.adb\",\n     \"aoc_2022_12.adb\",\n     \"aoc_2022_11.adb\",\n     \"aoc_2022_10.adb\",\n     \"aoc_2022_09.adb\",\n     \"aoc_2022_08.adb\",\n     \"aoc_2022_07.adb\",\n     \"aoc_2022_06.adb\",\n     \"aoc_2022_05.adb\",\n     \"aoc_2022_04.adb\",\n     \"aoc_2022_03.adb\",\n     \"aoc_2022_02.adb\",\n     \"aoc_2022_01.adb\",\n     \"gen_jumbo_day_1.adb\"\n   );\n   \n   case AoC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n   end case;\n\n   Common_Options := (\n     \"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n     \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n     \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n     \"-gnatf\",   --  Full errors. Verbose details, all undefined references\n     \"-gnatq\",   --  Don't quit, try semantics, even if parse errors\n     \"-gnatQ\");  --  Don't quit, write ali/tree file even if compile errors\n    \n   Style_Checks_1 := \n     (\"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",       --  Style: check x:no extra parens\n      \"-gnaty2\",       --  Style: check indentation\n      \"-gnatytc\");     --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   Style_Checks_2 := \n     (\"-gnatye\");      --  Style: check e:end/exit labels present\n\n   case AoC_Styles_Checks is\n      when \"Off\"   => null;\n      when \"On\"    => Common_Options := Common_Options & Style_Checks_1;\n      when \"Extra\" => Common_Options := Common_Options & Style_Checks_1 & Style_Checks_2;\n   end case;\n\n   Fast_Options := (\n     \"-O3\",\n     \"-funroll-loops\", \"-fpeel-loops\", \"-funswitch-loops\",\n     \"-ftracer\", \"-fweb\", \"-frename-registers\",\n     \"-ftree-vectorize\", \"-fipa-cp-clone\", \"-fgcse-after-reload\"\n   );\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Options & Debug_Options ;\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Options & Fast_Options & (\"-gnatpn\", \"-ffunction-sections\");\n      end case;\n   end Compiler;\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-g\");\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use (\"-g\", \"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend AoC_2022;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_01.adb",
    "content": "--  Solution to Advent of Code 2022, Day 1\n------------------------------------------\n--  Calorie Counting\n--\n--  https://adventofcode.com/2022/day/1\n--  Copy of questions in: aoc_2022_01_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_01 is\n  use HAT;\n  f : File_Type;\n  s : VString;\n  sum, max_1, max_2, max_3 : Integer := 0;\n\n  procedure Add_To_Top_3 is\n  begin\n    if sum > max_1 then\n      max_3 := max_2;\n      max_2 := max_1;\n      max_1 := sum;\n    elsif sum > max_2 then\n      max_3 := max_2;\n      max_2 := sum;\n    elsif sum > max_3 then\n      max_3 := sum;\n    end if;\n  end Add_To_Top_3;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\nbegin\n  Open (f, \"aoc_2022_01.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    Get_Line (f, s);\n    if s = \"\" then\n      Add_To_Top_3;\n      sum := 0;\n    else\n      sum := sum + Integer_Value (s);\n    end if;\n  end loop Read_Data;\n  Add_To_Top_3;\n  Close (f);\n\n  r (1) := max_1;\n  r (2) := max_1 + max_2 + max_3;\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line\n      (+\"Part 1: Calories carried by the Elf with the most calories:\" &\n       Integer'Image (r (1)));\n    Put_Line\n      (+\"Part 2: Calories carried by the top 3 . . . . . . . . . . :\" &\n       Integer'Image (r (2)));\n    --  Part 1: validated by AoC: 68442\n    --  Part 2: validated by AoC: 204837\n  end if;\nend AoC_2022_01;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_01.txt",
    "content": "62797\n\n1137\n6086\n6104\n1895\n7909\n1651\n4973\n6964\n5989\n6003\n6859\n\n2817\n3841\n5360\n2614\n1746\n3507\n1159\n3226\n4541\n1007\n3881\n4243\n1733\n4184\n2377\n\n2528\n2950\n5635\n3664\n5782\n4580\n4672\n5989\n3426\n5600\n2057\n2901\n6175\n\n48610\n\n8330\n9058\n2953\n10409\n10515\n6073\n6772\n2197\n\n1454\n1167\n5647\n5849\n2001\n1754\n3536\n1370\n1518\n1575\n5506\n3905\n\n2339\n2355\n5373\n5845\n5561\n2919\n6506\n1409\n5879\n4604\n4714\n2980\n4867\n1823\n\n4103\n20451\n23221\n\n3067\n1509\n7380\n6207\n1031\n8739\n1796\n7860\n8132\n\n2552\n4885\n14523\n4281\n8129\n\n8511\n1435\n4589\n2922\n9486\n8125\n9379\n3055\n3639\n\n38740\n\n16211\n4294\n7687\n1712\n\n10099\n9368\n7818\n11449\n3561\n2537\n11958\n\n7674\n6052\n3795\n3846\n4678\n3629\n7318\n6585\n2001\n7220\n5358\n\n9548\n4062\n7399\n7033\n11264\n\n46275\n\n2748\n20038\n7423\n\n6073\n3395\n3001\n1685\n3782\n4034\n7477\n2787\n5189\n4928\n7834\n\n6152\n2078\n3983\n5973\n3099\n2668\n5509\n6790\n5095\n5716\n3928\n3651\n4353\n\n2324\n4994\n7860\n6198\n5793\n8073\n6584\n3618\n\n5454\n4393\n2767\n3584\n3049\n1330\n6495\n2401\n2032\n6093\n4161\n2423\n2227\n1485\n\n47294\n\n3251\n4899\n4344\n7427\n5739\n3455\n7449\n6505\n5732\n5556\n4162\n\n7382\n6713\n2642\n3282\n6120\n6768\n2510\n1058\n5668\n3874\n6522\n2193\n\n68177\n\n1202\n16326\n5274\n\n5407\n4950\n1632\n7838\n7200\n2903\n7157\n7222\n2700\n1327\n3808\n\n9007\n18835\n\n8076\n2472\n8440\n2343\n3318\n1370\n7294\n7302\n1086\n7312\n\n3203\n1707\n2442\n4856\n2106\n4742\n5322\n1625\n3597\n1216\n1860\n2986\n4170\n2550\n2291\n\n1334\n5510\n6574\n7667\n3351\n5168\n1992\n1642\n7325\n3045\n3026\n\n11629\n30436\n\n4759\n4378\n2336\n2445\n1654\n3107\n3573\n5823\n3674\n5412\n4144\n6008\n5593\n2144\n\n4744\n3597\n7879\n9312\n2539\n6903\n5299\n2385\n1285\n\n2235\n1842\n2412\n3271\n7324\n4749\n4947\n6445\n3707\n5131\n6081\n2996\n\n6119\n1077\n1532\n3836\n3825\n1677\n2989\n2320\n2993\n4053\n3514\n4403\n2769\n1642\n\n3576\n1351\n2614\n1445\n5560\n1064\n1447\n3491\n4846\n1895\n4172\n5915\n4801\n6360\n\n5495\n3521\n1020\n7024\n2201\n1956\n5994\n7108\n4368\n6589\n2125\n\n9607\n7759\n8294\n9219\n13252\n9410\n\n1002\n2930\n2950\n1481\n4450\n6035\n4757\n3031\n1162\n4348\n3853\n4003\n3810\n5328\n3700\n\n7222\n7908\n10261\n8815\n5428\n5628\n\n5901\n5817\n2869\n4236\n3255\n6376\n3519\n3320\n1550\n5964\n3036\n6141\n3363\n3451\n\n8692\n5150\n6968\n2349\n9604\n1650\n5346\n4464\n\n14434\n\n1269\n2245\n3604\n4102\n3153\n4847\n5630\n1368\n4024\n3184\n3043\n4360\n5111\n2277\n4309\n\n1028\n5088\n4334\n2923\n4670\n5247\n2517\n2019\n2905\n2714\n4577\n6086\n3578\n3444\n\n3577\n1890\n2953\n6922\n2579\n8789\n5689\n3900\n5203\n2389\n\n9776\n2610\n4602\n5502\n10238\n4465\n7608\n4954\n\n8619\n4813\n7994\n2818\n3322\n4977\n4664\n8612\n1085\n1957\n\n8435\n2875\n8535\n2645\n5352\n5266\n8246\n\n6632\n4577\n2210\n6604\n6558\n7280\n6908\n2512\n6758\n2750\n\n1126\n9574\n9451\n16976\n\n5250\n6844\n3339\n7324\n6934\n5858\n6420\n1676\n8578\n\n5335\n10082\n9784\n4599\n7897\n7693\n8058\n\n18781\n3566\n20903\n\n6380\n1702\n3926\n\n3902\n6939\n8036\n5419\n1289\n5025\n5554\n3435\n3332\n1916\n\n7356\n12520\n7346\n11017\n11388\n4624\n\n5334\n5736\n5901\n1639\n1296\n2931\n4830\n4069\n4097\n5665\n5529\n5345\n4527\n2858\n\n5476\n1781\n6609\n4309\n7392\n1871\n5736\n7117\n6936\n3482\n4152\n\n4186\n6365\n5636\n4565\n4235\n6395\n2761\n3815\n7923\n6308\n7684\n\n9859\n4769\n8278\n12910\n1311\n2143\n\n2474\n3505\n2759\n3216\n3787\n3693\n2637\n3237\n5553\n5879\n5727\n2734\n3346\n2406\n\n2187\n4922\n1515\n2084\n3633\n6094\n1252\n6325\n3206\n5142\n6339\n1757\n5358\n\n11241\n7086\n6813\n14664\n1548\n\n7377\n5783\n11235\n9630\n4109\n8722\n\n16111\n3786\n13852\n14660\n14906\n\n3257\n9139\n2882\n5982\n10228\n3118\n\n13293\n5413\n11057\n\n12677\n17863\n9645\n\n3589\n13556\n15197\n7093\n\n7078\n9565\n15193\n7844\n\n5907\n1152\n2321\n3793\n1991\n7892\n10004\n3540\n\n5861\n11769\n10640\n9553\n1750\n3876\n\n4046\n2345\n5389\n5518\n6114\n5106\n5426\n3467\n1493\n1241\n5264\n5131\n3364\n5723\n\n1905\n2588\n4692\n3798\n1245\n6449\n3754\n1998\n6074\n3699\n2096\n1999\n5222\n5688\n\n10979\n5452\n2078\n11543\n\n1844\n7544\n10666\n5272\n6913\n8789\n7957\n8348\n\n4984\n7278\n2353\n2444\n7917\n5469\n8641\n1132\n4171\n4078\n\n20787\n18527\n\n5276\n6022\n1680\n4706\n2061\n5053\n3811\n2078\n2219\n3921\n4008\n3360\n1241\n3652\n5379\n\n3261\n1286\n12019\n15867\n\n9142\n6718\n6759\n1763\n5639\n8586\n2769\n8583\n5679\n\n7839\n7346\n6043\n2270\n8994\n2060\n12109\n\n47450\n\n4222\n3717\n2902\n1498\n3681\n1365\n5850\n4158\n3379\n2187\n1534\n3932\n4737\n6031\n\n4562\n4430\n3096\n2073\n6403\n4148\n3698\n2477\n3360\n2148\n2615\n2159\n6438\n1214\n\n6891\n6856\n7163\n2424\n7346\n4006\n3889\n5080\n4668\n5496\n6872\n\n8337\n13654\n\n3495\n8348\n5138\n3214\n5881\n2857\n6331\n7476\n1135\n4155\n\n4699\n7203\n6356\n8627\n2205\n5096\n2580\n7067\n1478\n4245\n\n3098\n8610\n9747\n3238\n10772\n4767\n8079\n5361\n\n7130\n5330\n9323\n4661\n3677\n2658\n9525\n9844\n\n1451\n1186\n1323\n3923\n4568\n1052\n4270\n4108\n3231\n4942\n5792\n6037\n5366\n5402\n\n9001\n15082\n9282\n11469\n7401\n\n2070\n2095\n3183\n6326\n1557\n4983\n6324\n1198\n5658\n5539\n4435\n5491\n1304\n\n7164\n2101\n8308\n3432\n6310\n9321\n6141\n6546\n7730\n\n6191\n4811\n1707\n3732\n7322\n3741\n5246\n2825\n5243\n4113\n4916\n\n5626\n7351\n3369\n2744\n2540\n3542\n5842\n3729\n1105\n\n1135\n13062\n2337\n14278\n\n8078\n8178\n4760\n8051\n1113\n4351\n5652\n5403\n4777\n\n4998\n1638\n3990\n5943\n2335\n4550\n4345\n3359\n1514\n4685\n4102\n4274\n6022\n5273\n\n7334\n7391\n6920\n5420\n6627\n3521\n6289\n6204\n6416\n4061\n4534\n\n4935\n3249\n3556\n3618\n4499\n4136\n1690\n5033\n2002\n2454\n1912\n2113\n4829\n4944\n2339\n\n4860\n1381\n5035\n4417\n3075\n2366\n3567\n1740\n3126\n1691\n1147\n1525\n\n13371\n14166\n9536\n10956\n2600\n\n3575\n2155\n4514\n2401\n3693\n6379\n6587\n1079\n4094\n3327\n7573\n\n3948\n5553\n3883\n1557\n4833\n4933\n4883\n1973\n2027\n4852\n5735\n5726\n1879\n1185\n3525\n\n2863\n1210\n2359\n6505\n3668\n2682\n5567\n6375\n6425\n6476\n6051\n1022\n5208\n3114\n\n8666\n11550\n4922\n3332\n7784\n6833\n3659\n\n3279\n3382\n8593\n9552\n2903\n\n2951\n2006\n1185\n5092\n5625\n1309\n4907\n3835\n2464\n2644\n5631\n2786\n4778\n2325\n4312\n\n9449\n9341\n8140\n8892\n5531\n1109\n7598\n8012\n\n5204\n5931\n4082\n3376\n3591\n2371\n4945\n2603\n6084\n2646\n5100\n3494\n5278\n3099\n\n11334\n6895\n3636\n6227\n5295\n12703\n\n8582\n6879\n\n10795\n11724\n13546\n14298\n\n12038\n3535\n11070\n8190\n1032\n1780\n8630\n\n10640\n13274\n10643\n11940\n10745\n9333\n\n5299\n6239\n1648\n6467\n6426\n2154\n7880\n5169\n3356\n6129\n5647\n\n6595\n2143\n1898\n12562\n13508\n2781\n\n59552\n\n16571\n4935\n17641\n12096\n\n6189\n3250\n5458\n5146\n5237\n2684\n\n18772\n5692\n9163\n9268\n\n5695\n3416\n2703\n3018\n4433\n1425\n1974\n4673\n2166\n3893\n3446\n1994\n2070\n2429\n\n3554\n5665\n3356\n4739\n1915\n6877\n5874\n2883\n2279\n4966\n7503\n\n1155\n2329\n5544\n2294\n3644\n6202\n7787\n6605\n7045\n\n3263\n1268\n2627\n1220\n5707\n1469\n4518\n5697\n3414\n2047\n2939\n3679\n2503\n5031\n3764\n\n5935\n3138\n2639\n4127\n5061\n2213\n5332\n5037\n4830\n3694\n3624\n3598\n4000\n2683\n\n5122\n6805\n10017\n1863\n11675\n2237\n10887\n\n1055\n1975\n2769\n6245\n3790\n1178\n2163\n5553\n5305\n6089\n1417\n1221\n6235\n\n54647\n\n8508\n5207\n1608\n3986\n8532\n7425\n4530\n8413\n2097\n\n33681\n\n2280\n7109\n2871\n6096\n6170\n1314\n4713\n1607\n4944\n3316\n2818\n\n7431\n1166\n6475\n1105\n1780\n5602\n5682\n6187\n4856\n7860\n3409\n\n4299\n3875\n3364\n4489\n3995\n1565\n4798\n2285\n1420\n5877\n3158\n3045\n2505\n1329\n\n9029\n1967\n7691\n3366\n7301\n2855\n4228\n3900\n2025\n\n3340\n6056\n5221\n5220\n1911\n2349\n3789\n3567\n2859\n3079\n5720\n1134\n3072\n1291\n\n22613\n20435\n13975\n\n14789\n\n5745\n5492\n1882\n3895\n6104\n8598\n3351\n1932\n4913\n2592\n\n1662\n3183\n3923\n5857\n6563\n3160\n3119\n5727\n6071\n3931\n\n6513\n1218\n10399\n3885\n3363\n2470\n9626\n3802\n\n6307\n2664\n9753\n10741\n1295\n\n3046\n1421\n4492\n2172\n6367\n5986\n1478\n1235\n1913\n1700\n2661\n3187\n3694\n1704\n\n2332\n2555\n1548\n1891\n3985\n2238\n3802\n4168\n5491\n1374\n5104\n6353\n\n64543\n\n2774\n7026\n2622\n1898\n7236\n1896\n4399\n3438\n2436\n2732\n7431\n2737\n\n5452\n3365\n8054\n2730\n4786\n11186\n\n2474\n22732\n\n2187\n2855\n7552\n9401\n6355\n10015\n4238\n9319\n\n7351\n5587\n3761\n6320\n4344\n7272\n1465\n1207\n5586\n6134\n2607\n6004\n\n6759\n4749\n4338\n1058\n5400\n3173\n3262\n7818\n6438\n5852\n6804\n\n11175\n14866\n6020\n1809\n1258\n\n4816\n3171\n6714\n2291\n4243\n4824\n10385\n4451\n\n3102\n5924\n6672\n1872\n1009\n1176\n5943\n2068\n3702\n\n14085\n14731\n\n5651\n6762\n1985\n5851\n7277\n1493\n7316\n1193\n3737\n3291\n\n1918\n9163\n3715\n5271\n8317\n3085\n2782\n7762\n5383\n\n1195\n2050\n4127\n1946\n5662\n1608\n6606\n6708\n2771\n5533\n2638\n6048\n\n8916\n2959\n16153\n3649\n\n17831\n11271\n4407\n11756\n\n1932\n5296\n4133\n3164\n2942\n5498\n4442\n4447\n3267\n4143\n2401\n5074\n1831\n4235\n\n1529\n1414\n4775\n3829\n3121\n3573\n3423\n3269\n1017\n4698\n5104\n2655\n2427\n5958\n\n1209\n7712\n3681\n6730\n6569\n1763\n5465\n2218\n4656\n1828\n\n2045\n10343\n3841\n7177\n8506\n12930\n\n3801\n4977\n5578\n2208\n4739\n4811\n2201\n3004\n5233\n4112\n5234\n5615\n2187\n\n7309\n7544\n1423\n2269\n5221\n4858\n4996\n1683\n9331\n\n1834\n6149\n6941\n1568\n1886\n6818\n7022\n5841\n5568\n8000\n3910\n\n8233\n5998\n2020\n6423\n7691\n1420\n5081\n8221\n5648\n7694\n\n14918\n18742\n10687\n19905\n\n3390\n8841\n2124\n10402\n4664\n10831\n\n9777\n7834\n10672\n9873\n6758\n1471\n11828\n\n1679\n6895\n6007\n2245\n8309\n3319\n1232\n10468\n\n51082\n\n2292\n6231\n3446\n3591\n1553\n1615\n1514\n6233\n6327\n3430\n1732\n5356\n4799\n\n2583\n4699\n5594\n3530\n3477\n3473\n4356\n3594\n5404\n2738\n5766\n5897\n2218\n1597\n3830\n\n4683\n4634\n6635\n5255\n2092\n6636\n3209\n7142\n1022\n\n6301\n9915\n4277\n11866\n10155\n\n24693\n24851\n\n4192\n10576\n9003\n7156\n11894\n\n8088\n14949\n19773\n13274\n\n4683\n22445\n14904\n\n10069\n9513\n7768\n11446\n6753\n12021\n\n2863\n6080\n3395\n2648\n6585\n1411\n3363\n5331\n2830\n1437\n3281\n5924\n6409\n\n6012\n4523\n1688\n5603\n3035\n3220\n7254\n4670\n6197\n4181\n6032\n4619\n\n2186\n5986\n5703\n3074\n7566\n4097\n7971\n4868\n7182\n5065\n1279\n\n10973\n9182\n13792\n9868\n1509\n9266\n\n2846\n4728\n5432\n1085\n4273\n1620\n3800\n1631\n1141\n4895\n1402\n5547\n1131\n2330\n\n8273\n3309\n8168\n12350\n11300\n4743\n\n11440\n5977\n1085\n13808\n2190\n9288\n\n2271\n11361\n\n4963\n1680\n7510\n5354\n2117\n7728\n6051\n5256\n3478\n1075\n1961\n\n3812\n4709\n2691\n4316\n3328\n2828\n2937\n2812\n1539\n5201\n1182\n2697\n2406\n2574\n4539\n\n4415\n8204\n1583\n10931\n7518\n3135\n11661\n\n3389\n5173\n5986\n3872\n3959\n8821\n7434\n2166\n8156\n\n2463\n4935\n7038\n6770\n5818\n6881\n2282\n7335\n4367\n1801\n2507\n4071\n\n9939\n14902\n7567\n15568\n10587\n\n2163\n2588\n2715\n4589\n6593\n6838\n4404\n3186\n4271\n3686\n3641\n5165\n5708\n\n6209\n13133\n25360\n\n3109\n5778\n4388\n1042\n4937\n8197\n1456\n8167\n\n9199\n7098\n14027\n\n6382\n1660\n2778\n8067\n3405\n2429\n6503\n7984\n5799\n7534\n5088\n\n9638\n14010\n5875\n6893\n\n2598\n2706\n3987\n4140\n3171\n5672\n5529\n3617\n5198\n2429\n2728\n4763\n2852\n5389\n\n3719\n1285\n4554\n3677\n5209\n3827\n5062\n4835\n8068\n4674\n5854\n\n6077\n6747\n6325\n4287\n7242\n6317\n3989\n6724\n1754\n5498\n1931\n\n10902\n11104\n10540\n4778\n7178\n4711\n\n1705\n3407\n6048\n3364\n3743\n3938\n4784\n6080\n3543\n1957\n2590\n2031\n\n28157\n6204\n\n7129\n7476\n1886\n10496\n4930\n2967\n1258\n3532\n\n4133\n2586\n1916\n4464\n1008\n3310\n5367\n4347\n5569\n3878\n3210\n2442\n2355\n5997\n3101\n\n4460\n18575\n6967\n17122\n\n1720\n2723\n5410\n8981\n3355\n4210\n2549\n3094\n\n14639\n17107\n14832\n\n3736\n24734\n\n3133\n3998\n5708\n6961\n1514\n3927\n4208\n5004\n2708\n1381\n5082\n4476\n\n4021\n1075\n1593\n3541\n2463\n4776\n4665\n6168\n1928\n6421\n3967\n5875\n2584\n1946\n\n3506\n1054\n1846\n4946\n3394\n7435\n7099\n3703\n6746\n2129\n1980\n4505\n\n7828\n8885\n8007\n4297\n1731\n3825\n1728\n4304\n\n3217\n12089\n2242\n10288\n9462\n11809\n\n10335\n3139\n10617\n6833\n1976\n3093\n8219\n\n7749\n5487\n7508\n6975\n5363\n4141\n3823\n7609\n5667\n4064\n7969\n\n6803\n1600\n8970\n8154\n3949\n9138\n6012\n4745\n6778\n\n5215\n8264\n3784\n14282\n\n5819\n13811\n5523\n3645\n\n12004\n8659\n1039\n1507\n3797\n2568\n12129\n\n3547\n7073\n5035\n2269\n7986\n6478\n5045\n6103\n1003\n7281\n7503\n\n2567\n6027\n6497\n5871\n2833\n2117\n4851\n4934\n6324\n4101\n2032\n4308\n4369\n\n4262\n15796\n13104\n9996\n\n4521\n4209\n4691\n11223\n1369\n11416\n8253\n\n8708\n11136\n15770\n\n1132\n1488\n4493\n5822\n3022\n4249\n1436\n5324\n4237\n3740\n3071\n1298\n5247\n5217\n\n6199\n9151\n9154\n8903\n9415\n6703\n7137\n7053\n4727\n\n15631\n16811\n14050\n\n5183\n4988\n3932\n6304\n6914\n4061\n5694\n5111\n3668\n5769\n6458\n6400\n3736\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_01_questions.txt",
    "content": "--- Day 1: Calorie Counting ---\n\nSanta's reindeer typically eat regular reindeer food,\nbut they need a lot of magical energy to deliver presents\non Christmas. For that, their favorite snack is a special\ntype of star fruit that only grows deep in the jungle.\nThe Elves have brought you on their annual expedition to\nthe grove where the fruit grows.\n\nTo supply enough magical energy, the expedition needs to\nretrieve a minimum of fifty stars by December 25th.\nAlthough the Elves assure you that the grove has plenty of fruit,\nyou decide to grab any fruit you see along the way, just in case.\n\nCollect stars by solving puzzles. Two puzzles will be made available\non each day in the Advent calendar; the second puzzle is unlocked\nwhen you complete the first.\nEach puzzle grants one star. Good luck!\n\nThe jungle must be too overgrown and difficult to navigate\nin vehicles or access from the air; the Elves' expedition\ntraditionally goes on foot. As your boats approach land,\nthe Elves begin taking inventory of their supplies.\nOne important consideration is food - in particular,\nthe number of Calories each Elf is carrying (your puzzle input).\n\nThe Elves take turns writing down the number of Calories\ncontained by the various meals, snacks, rations, etc.\nthat they've brought with them, one item per line.\nEach Elf separates their own inventory from the\nprevious Elf's inventory (if any) by a blank line.\n\nFor example, suppose the Elves finish writing their\nitems' Calories and end up with the following list:\n\n1000\n2000\n3000\n\n4000\n\n5000\n6000\n\n7000\n8000\n9000\n\n10000\n\nThis list represents the Calories of the food carried by five Elves:\n\n    The first Elf is carrying food with 1000, 2000, and 3000\n      Calories, a total of 6000 Calories.\n      \n    The second Elf is carrying one food item with 4000 Calories.\n\n    The third Elf is carrying food with 5000 and 6000 Calories,\n      a total of 11000 Calories.\n\n    The fourth Elf is carrying food with 7000, 8000, and 9000 Calories,\n      a total of 24000 Calories.\n\n    The fifth Elf is carrying one food item with 10000 Calories.\n\nIn case the Elves get hungry and need extra snacks, they need to\nknow which Elf to ask: they'd like to know how many Calories are\nbeing carried by the Elf carrying the most Calories.\nIn the example above, this is 24000 (carried by the fourth Elf).\n\nFind the Elf carrying the most Calories.\nHow many total Calories is that Elf carrying?\n\n--- Part Two ---\n\nBy the time you calculate the answer to the Elves' question,\nthey've already realized that the Elf carrying the most\nCalories of food might eventually run out of snacks.\n\nTo avoid this unacceptable situation, the Elves would\ninstead like to know the total Calories carried by the\ntop three Elves carrying the most Calories. That way,\neven if one of those Elves runs out of snacks,\nthey still have two backups.\n\nIn the example above, the top three Elves are the fourth\nElf (with 24000 Calories), then the third Elf (with 11000 Calories),\nthen the fifth Elf (with 10000 Calories).\nThe sum of the Calories carried by these three elves is 45000.\n\nFind the top three Elves carrying the most Calories.\nHow many Calories are those Elves carrying in total?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_02.adb",
    "content": "--  Solution to Advent of Code 2022, Day 2\n------------------------------------------\n--  Rock Paper Scissors\n--\n--  https://adventofcode.com/2022/day/2\n--  Copy of questions in: aoc_2022_02_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_02 is\n  use HAT;\n\n  c, sep : Character;\n  f : File_Type;\n  --\n  verbose : constant Boolean := False;\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n  --\n  type Object is (Rock, Paper, Scissors);\n  them, you : Object;\n\n  function Defeats (opponent : Object) return Object is\n  begin\n    case opponent is\n      when Rock     => return Paper;\n      when Paper    => return Scissors;\n      when Scissors => return Rock;\n    end case;\n  end Defeats;\n\n  function Is_Defeated_By (opponent : Object) return Object is\n  begin\n    case opponent is\n      when Paper    => return Rock;\n      when Scissors => return Paper;\n      when Rock     => return Scissors;\n    end case;\n  end Is_Defeated_By;\n\n  score, total : Integer;\n\nbegin\nParts :\n  for part in 1 .. 2 loop\n    total := 0;\n    Open (f, \"aoc_2022_02.txt\");\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get (f, c);\n      them := Object'Val (Character'Pos (c) - Character'Pos ('A'));\n      Get (f, sep);\n      Get (f, c);\n      case part is\n        when 1 =>\n          --  In the puzzle's part 1, the second column with X, Y or Z\n          --  seems to represent what your move should be.\n          you := Object'Val (Character'Pos (c) - Character'Pos ('X'));\n        when 2 =>\n          --  Actually the Elf explains that the second column\n          --  contains what the outcome of your move should be.\n          case c is\n            when 'X' =>  --  You lose\n              you := Is_Defeated_By (them);\n            when 'Y' =>  --  Draw\n              you := them;\n            when 'Z' =>  --  You win\n              you := Defeats (them);\n            when others => null;\n          end case;\n      end case;\n      score := Object'Pos (you) + 1;\n      if them = you then\n        --  Draw\n        score := score + 3;\n      end if;\n      if you = Defeats (them) then\n        --  You win\n        score := score + 6;\n      end if;\n      if verbose then\n        Put_Line (+them'Image & ' ' & you'Image & ' ' & score);\n      end if;\n      total := total + score;\n    end loop Read_Data;\n    Close (f);\n    --\n    r (part) := total;\n  end loop Parts;\n  --\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: total score, rule #1: \" & Integer'Image (r (1)));\n    Put_Line (+\"Part 2: total score, rule #2: \" & Integer'Image (r (2)));\n    --  Part 1: validated by AoC: 14531\n    --  Part 2: validated by AoC: 11258\n  end if;\nend AoC_2022_02;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_02.txt",
    "content": "A Y\nC Y\nC X\nA Y\nC X\nC Y\nB Z\nA Y\nA Y\nC Z\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA X\nB X\nA X\nA Y\nC Y\nC X\nA Y\nA Y\nC Y\nA X\nA Y\nB Z\nA Y\nC X\nA Y\nA Y\nC Z\nC Y\nC X\nA Y\nA Z\nA Y\nA Y\nA Y\nA Y\nC Y\nC Y\nB Z\nB Z\nC Y\nB X\nA Y\nA Y\nA Y\nC Z\nA Y\nC X\nA Z\nC Y\nA Y\nA Y\nA Y\nA Y\nA Y\nC X\nA Y\nC Y\nA Y\nC Y\nA Y\nA X\nC Y\nA X\nA Y\nC Y\nC Y\nA Y\nC X\nA Y\nA Y\nA Y\nC X\nA Y\nA Y\nA Y\nC X\nA Y\nC X\nA Y\nA Y\nC Z\nA Y\nA Y\nA Y\nC X\nA Y\nA X\nC Y\nA X\nB Z\nC Y\nA Y\nA Y\nB Z\nC Y\nA Y\nA Z\nC Z\nC Y\nB Z\nA Y\nA Y\nC Y\nA Y\nC X\nA Y\nA Y\nC X\nC X\nC Y\nA Y\nA Y\nC X\nA Y\nA Y\nA Y\nA Y\nC X\nC Y\nA Y\nA Y\nA Y\nC Z\nA Y\nC Y\nA Y\nC X\nC Z\nA Y\nB X\nA Y\nC X\nA Y\nB X\nA Y\nC Z\nA Y\nA Y\nA Y\nA X\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nC Y\nC X\nA Y\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA Y\nC Y\nB X\nA Y\nA Y\nA Y\nA Y\nA Y\nA X\nC Y\nA Y\nC X\nA X\nB Y\nA Y\nC X\nA Y\nC Y\nC Y\nA Z\nC Z\nC X\nB X\nC Y\nA Y\nC Z\nA Z\nA Y\nC X\nA Y\nA Y\nC X\nA Y\nB X\nC X\nA Z\nC Y\nA Y\nC X\nA Y\nA Y\nA Y\nB Z\nC Z\nA Y\nA X\nC X\nA Y\nA Y\nC Y\nA Y\nA Y\nA X\nA X\nC Y\nC X\nB X\nA Y\nA Y\nA Y\nA Y\nB Y\nA Y\nC Y\nA Y\nA X\nB Z\nA X\nC Z\nC X\nC X\nC Y\nC X\nC X\nA X\nC X\nA Y\nC Y\nA X\nC X\nB Z\nC Z\nA Y\nC X\nB Y\nA Z\nC Y\nC X\nA Y\nA Y\nA Y\nC X\nA Y\nA Y\nA Y\nA X\nB Y\nC Y\nC X\nB Z\nA Y\nA Y\nB Y\nA Y\nA Y\nA Y\nC X\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nC Y\nC Z\nA Y\nC Y\nA Y\nA Y\nA X\nA X\nA Y\nA Y\nC Y\nA Y\nA X\nA Y\nA Y\nC X\nA Y\nC X\nC X\nC Y\nB Y\nA Y\nC X\nA Y\nA Y\nA X\nA Y\nA Y\nA X\nA Y\nB Z\nC Y\nA Y\nA Y\nA Y\nC Y\nC Z\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nC Y\nC Y\nC Y\nC Y\nA X\nC Y\nA Y\nA Y\nA Y\nA Y\nC X\nA Y\nC Z\nA Y\nB Y\nA X\nA Y\nA Y\nA Y\nC Y\nC Y\nA X\nC Y\nA Y\nA Y\nA Y\nB Z\nA X\nA Y\nA Y\nA Z\nC Y\nA Y\nC X\nC Y\nC Y\nC Z\nB Y\nC X\nC X\nA Z\nC Y\nA Y\nA Z\nA X\nA Z\nC Y\nC X\nB Z\nA X\nC Y\nA Y\nC Y\nB Z\nA Y\nA Y\nC X\nC X\nC X\nA Y\nB X\nC X\nC Y\nC X\nA X\nA X\nB X\nA Y\nA Y\nA Y\nC X\nA Y\nC Y\nC X\nA Y\nB Z\nA Y\nA Y\nA Y\nB X\nA Y\nA Y\nA Y\nC Y\nA Y\nC X\nC Y\nC Y\nA Y\nB Z\nC Y\nC X\nC Y\nC X\nC X\nC Y\nA Y\nA Z\nA Y\nA Y\nA Y\nA Y\nC Z\nA Y\nA Y\nC Y\nA Y\nA X\nC Z\nC Y\nC X\nC X\nA Y\nA Z\nA Z\nB Y\nA X\nC X\nC X\nA Y\nA Y\nA Y\nC Z\nC X\nC X\nC X\nA Y\nC Z\nA Z\nC X\nC Y\nA X\nC X\nC X\nA Y\nC Y\nC Y\nB X\nB Z\nA Y\nA Y\nA Y\nB Z\nC Y\nA Y\nB Z\nA X\nC Y\nC Y\nB X\nC X\nB Y\nA Y\nB X\nC Z\nA Y\nA Z\nC Z\nC Z\nA Y\nA X\nA Y\nA X\nC Y\nA Y\nA Y\nA Y\nC X\nC X\nC X\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nA Y\nC Y\nA Z\nC X\nC Y\nA Y\nA Y\nB Y\nC Y\nA Y\nC Z\nC Z\nA Y\nB Y\nA Y\nA Y\nA X\nC Y\nA Y\nA Y\nA Y\nC Z\nC Y\nC X\nA Y\nA Y\nB Z\nC Y\nC X\nC Z\nA Y\nC Y\nA Y\nA Y\nC X\nC Y\nC Y\nA Y\nC Y\nC X\nC Y\nA Y\nA Y\nA Y\nA Z\nB Z\nA Y\nA Y\nA X\nC Z\nC X\nA Y\nA Y\nA Y\nC X\nC Y\nB Z\nC X\nA Y\nA Y\nA Y\nC Y\nA Y\nC X\nC Z\nC X\nA Y\nA X\nA Y\nC Z\nC X\nB Y\nA Y\nA X\nA Y\nB Y\nA Y\nA Y\nC Y\nC Z\nC Y\nC Y\nC X\nA Y\nA Y\nA X\nA Y\nA Y\nA Z\nA X\nC Y\nA Y\nC Y\nC Y\nC Z\nC Y\nC Y\nA Z\nA Y\nC Z\nC Y\nC Y\nC Y\nB X\nC Y\nA Y\nC X\nA Y\nB X\nC Z\nC Z\nC Y\nA Y\nC X\nA Y\nA Y\nA Y\nA Y\nC Z\nA Z\nA X\nC Y\nC X\nA Y\nA Y\nC X\nC Y\nC Z\nC X\nC Y\nA X\nA Y\nA Y\nB X\nA Y\nA X\nC X\nA Y\nA Y\nA Y\nB Z\nA Z\nB Z\nC X\nB Z\nA Y\nC X\nA Y\nC X\nA Y\nA Y\nC Y\nA Y\nA Y\nB X\nA Y\nC Y\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA Y\nB Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nC Y\nA X\nB X\nA Y\nB Z\nC X\nA X\nB X\nC Y\nA Y\nB X\nC Y\nA Y\nB X\nA Y\nC X\nB X\nA Y\nA Y\nA Y\nA Y\nC X\nC X\nA Y\nB X\nC Y\nA Y\nA Y\nA Y\nA Y\nB X\nA Y\nB Z\nC X\nA Y\nB Z\nC X\nC Z\nC Z\nB X\nC Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA X\nA X\nC X\nA Y\nC Z\nC Y\nA Y\nC X\nA Z\nA Z\nA Y\nC Z\nA Y\nA Y\nA Y\nC Y\nA X\nC X\nC Z\nA Y\nA Y\nC X\nB X\nA Y\nA Z\nC Y\nA Z\nA Y\nA Y\nA Y\nA Y\nA Y\nB X\nA Y\nC Y\nC X\nA Y\nA Y\nC Z\nC Z\nC Y\nA Y\nB Z\nA Y\nA Y\nA Y\nA Y\nA Y\nC X\nA Z\nA Y\nC Y\nA Z\nC X\nA Y\nC X\nA Y\nA Y\nC Z\nC Y\nA Y\nA Z\nC X\nC X\nA Y\nB Z\nA Y\nB X\nC Y\nC X\nC Z\nA Y\nA X\nC X\nC Z\nC Y\nC X\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nA Y\nC Y\nA Y\nC Y\nB Y\nA Y\nA Y\nA Y\nA Y\nB Z\nC Y\nA Y\nC Y\nA X\nC Y\nA Y\nB Y\nC Y\nC X\nC X\nA Y\nA Y\nA Y\nC X\nA X\nA Y\nA X\nC Y\nA Y\nA Y\nC Y\nC Y\nA Z\nA Y\nA Y\nB X\nA Z\nB X\nA Y\nC Y\nA X\nC Y\nC Z\nB Z\nA Y\nA Y\nC Y\nA Y\nC Z\nA Y\nA X\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nC X\nC Y\nA Y\nA Z\nA Y\nC X\nA Y\nC Z\nA Y\nC X\nA X\nA Y\nC Y\nA Y\nC X\nA X\nA Y\nA Y\nA Y\nC Y\nA Y\nC Y\nA Y\nB Y\nC Y\nC Y\nA Y\nA Y\nA Y\nA Y\nC Z\nA Y\nC Z\nA Y\nC Y\nB X\nA X\nC Y\nC Z\nA X\nA Z\nA Y\nA X\nC Z\nC Y\nA Z\nC Y\nA X\nA Y\nA Y\nA X\nC Z\nA X\nA Z\nC Y\nA Y\nC Y\nA Z\nB Z\nA Y\nC X\nC X\nA Y\nA Y\nA X\nA Y\nA Y\nA Y\nC X\nA Y\nB X\nA Y\nC X\nA Y\nC Y\nA Y\nC Y\nC Z\nC Y\nC Z\nA Z\nA Y\nC Y\nC Z\nC Z\nA Y\nA Y\nC Y\nA X\nA Y\nC Y\nA Y\nA Y\nA Y\nA X\nA Y\nB Z\nC Y\nC X\nA Y\nC X\nB X\nC Y\nC Y\nA Y\nC Y\nC Y\nA X\nA Y\nA X\nA Y\nA Z\nC Z\nB X\nA Y\nC X\nA Y\nC Z\nA Y\nC Y\nA Z\nA Y\nA Y\nA Y\nC Y\nC Y\nA Y\nA Y\nC Y\nA Y\nC Y\nC Y\nA X\nA Y\nC X\nC Z\nA Y\nA Y\nA Y\nC X\nC X\nC Y\nC Y\nC Z\nA X\nA Y\nC Y\nC Z\nA Y\nB Y\nA Y\nC Z\nC Z\nA Y\nA Y\nA Y\nB Z\nA Y\nA Z\nA X\nC X\nC X\nC Z\nA Y\nC Z\nA Z\nC Y\nC Z\nC X\nC Y\nC X\nA Y\nC Y\nA Z\nA Y\nA Y\nA Y\nA Y\nC Y\nA X\nC X\nA Y\nA Y\nC Z\nB Z\nA Y\nA Y\nC X\nA Y\nC Y\nC Y\nB Z\nA Y\nC Y\nA Y\nC X\nC X\nA Y\nC Y\nA X\nC X\nA Y\nC Z\nA Y\nC X\nA Y\nC X\nA Y\nC Y\nA Y\nC Z\nA Y\nC Z\nA Y\nA Y\nA Y\nC Y\nA Y\nA X\nA Z\nA Y\nC Y\nC Y\nA Y\nA Y\nB Z\nA X\nA X\nC X\nC X\nC Z\nC Z\nA Y\nA Y\nA Y\nA X\nA X\nA Y\nA Z\nC Y\nC Y\nC X\nA Y\nC X\nB X\nA X\nA Z\nA Y\nB X\nA Y\nB Z\nB Z\nA Y\nB X\nC Y\nA Y\nA Y\nC Y\nC Y\nA Y\nA Y\nA Z\nA Y\nC Z\nB X\nA Y\nC Y\nC Y\nA Y\nB X\nC X\nC Y\nA X\nC X\nA Y\nA X\nA Y\nA Y\nB Z\nA X\nC Y\nA Y\nA Z\nB Y\nA Y\nB X\nA Z\nC Y\nC Z\nC Z\nC Z\nC Y\nA Y\nC Y\nC Y\nB Y\nA Y\nC Z\nB Y\nA Y\nA Y\nA Y\nA X\nB Z\nA Y\nC Z\nA Y\nA X\nC Z\nC X\nA Y\nA Y\nA Y\nB Z\nB Z\nA Y\nC Z\nA Y\nA Y\nA Y\nC Y\nC Z\nC X\nA Y\nB Z\nC Y\nB Z\nC X\nC X\nA Y\nA X\nA X\nB Z\nC Y\nC Y\nC X\nA Y\nC X\nC X\nA Y\nC X\nC Z\nA X\nC Y\nC Y\nC Y\nA Y\nA X\nC Y\nA Y\nA Y\nC Y\nC X\nC Y\nB X\nC X\nA Z\nA X\nA Y\nC Y\nA Y\nA X\nC Y\nA Y\nA X\nC X\nA X\nC X\nC Y\nC Y\nA Y\nC X\nA Y\nA X\nC Y\nA Y\nC Z\nA Z\nA Y\nA Y\nA Y\nA Z\nA Y\nB X\nB Z\nC X\nA Z\nC X\nA Y\nA Z\nA X\nC Y\nC Y\nB Z\nA Z\nA Y\nA Y\nA Y\nB X\nC Y\nA Y\nA X\nA Y\nB Z\nB Z\nA Y\nA Y\nA Y\nC X\nC X\nC X\nC Y\nA Y\nC Y\nC Y\nA Y\nA Y\nA Y\nA Y\nC Y\nA Y\nC X\nA Y\nC X\nC Y\nC Y\nC Z\nB X\nA Y\nC Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nB Z\nC Z\nC Y\nA X\nC Y\nA Y\nC Y\nC Y\nA Y\nB Z\nC Y\nB X\nB X\nA Y\nA Y\nC Y\nC Y\nB X\nA X\nC Y\nC X\nC Y\nA Y\nA Y\nC X\nA X\nA Z\nA Y\nA Z\nA Y\nB X\nA X\nC X\nA X\nC X\nC Z\nA Y\nC X\nC Y\nC X\nC Y\nA Y\nC Y\nA Y\nA Y\nC Y\nC Z\nC X\nA Y\nA Y\nA X\nC Y\nB Z\nA Y\nC Y\nB Z\nC Y\nA Y\nC Y\nA X\nA X\nA Y\nB X\nA Y\nC X\nC Y\nA Y\nA Y\nA Y\nC X\nC Z\nA Y\nC Y\nA Z\nC Y\nA Y\nC Y\nA Y\nC Z\nC Y\nC X\nA Y\nC X\nA Z\nB Z\nA Y\nA X\nA Y\nA Y\nA X\nA Y\nA Y\nA Y\nA Y\nC Y\nC X\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nC Y\nC Y\nA X\nA Z\nA Y\nC X\nA Y\nA Y\nC Y\nB Y\nC Y\nA X\nA Y\nA Y\nA Y\nC X\nA X\nC Y\nC Z\nA Y\nB Z\nA Z\nC Y\nA Y\nA Y\nB Z\nA X\nA Y\nC Y\nA Y\nA X\nB X\nC Z\nB X\nA Y\nA Y\nC Y\nA Y\nA Z\nA Y\nA Y\nA Y\nC X\nA Y\nA Z\nA Z\nA Y\nC X\nA Y\nC Z\nC Y\nB X\nC Y\nA Y\nC Z\nB Z\nA Y\nC Y\nA Z\nA Y\nC X\nC Y\nA X\nA Y\nC Z\nA Y\nA Y\nA Y\nA Y\nB Z\nA Z\nC Z\nA X\nA Y\nA Y\nA Y\nA Y\nA Y\nC Y\nC Y\nA Y\nC X\nA Y\nA Y\nA X\nA X\nA Y\nC Y\nC Z\nA Z\nA Y\nA X\nB X\nB X\nB Z\nC X\nC Y\nA Y\nA Y\nA Y\nC Z\nA Y\nA Y\nA Y\nC Y\nC Y\nB Y\nC Z\nB Z\nC Y\nB Z\nA Y\nA X\nC X\nA X\nC X\nB Y\nA Y\nA Z\nA Y\nA X\nA Y\nA Y\nC X\nA Y\nA Y\nC X\nC X\nA Y\nC X\nC Z\nC X\nB Z\nB Z\nB Z\nC Y\nB Z\nC Y\nC Z\nB Y\nA Y\nC Z\nA Y\nC X\nC X\nB Z\nB Y\nA Y\nA Z\nC Y\nC X\nC Y\nA Z\nC X\nC X\nC X\nA Y\nA Y\nC Y\nA Y\nC Y\nC Y\nA Y\nC Y\nC Z\nA Y\nB Y\nC Y\nC X\nA Y\nA Y\nA X\nA Y\nC Y\nB Z\nA Y\nA Y\nA Y\nA Y\nC X\nB X\nA Y\nA Y\nA Y\nA Y\nB X\nA Y\nA Y\nA X\nC Y\nA Y\nA Y\nC X\nA Y\nA Y\nA Y\nC X\nB Y\nA Z\nC Y\nC X\nA Y\nA Z\nB X\nA Y\nA Y\nA X\nC Y\nC Y\nC Y\nA Y\nC Z\nA Y\nA Y\nC Y\nB Z\nA Y\nA Y\nC X\nA X\nA Y\nA Y\nA Y\nB Z\nC Y\nA Y\nC Y\nC Y\nA Y\nA Y\nC Y\nC Y\nA Y\nC Y\nA Y\nB X\nC Y\nA X\nA Z\nA Y\nA Y\nC Y\nC Y\nA Y\nC Z\nA Z\nA Y\nA Y\nC Y\nC Y\nC X\nC Y\nA Y\nC X\nC Y\nA Y\nC X\nC Y\nC Y\nA Y\nA Y\nA Y\nC X\nC Y\nA Y\nA Y\nC Y\nA Y\nC Y\nA Y\nA Y\nC Y\nC Y\nC Y\nA Z\nA Y\nC Y\nC Y\nA Y\nA X\nC X\nA Y\nC Y\nB X\nC Y\nA Y\nA Y\nC Y\nC Y\nA Y\nA Y\nA Y\nB Z\nA Y\nC Y\nA Y\nA Y\nC X\nC Y\nA Y\nA Y\nC Y\nC Y\nC Y\nC Z\nA Y\nA Y\nC X\nA Y\nC Z\nA X\nC X\nB X\nA Y\nC Y\nA Y\nA Y\nA X\nA Y\nA Z\nB Y\nA X\nA Y\nC Y\nC Y\nC X\nA Y\nC Y\nA Y\nC Y\nA Y\nC X\nC X\nA Y\nC Y\nC Z\nC X\nB X\nA Y\nB X\nA Y\nA Y\nC Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nA X\nA Z\nA Y\nB X\nA Y\nA Y\nC X\nA Y\nC Z\nA Y\nA Y\nC Y\nC X\nC X\nA Y\nA Y\nB X\nC X\nA Y\nC Y\nA Y\nC Y\nA Y\nB Z\nA Y\nC Y\nA Y\nA Y\nA Y\nC Z\nA Y\nA X\nC X\nA X\nA Y\nA Y\nA Y\nC X\nC Y\nC Y\nC Y\nA Y\nA Y\nA Z\nC X\nA Y\nA Y\nA Y\nC Y\nC Y\nA X\nA Y\nC Y\nB Y\nA Y\nA Z\nC X\nA Y\nA Z\nA X\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA X\nC Y\nA X\nB X\nC X\nC Y\nA Y\nA Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA X\nC X\nA Y\nA Y\nA Y\nC Y\nA Y\nB Y\nC Y\nC Y\nC Y\nC Y\nA Y\nA Y\nC Y\nC Y\nA Y\nC Y\nC Y\nA Y\nC Y\nC X\nC X\nC Y\nA X\nC X\nC X\nA Z\nC Y\nC Z\nA Y\nB Z\nA Y\nA Y\nB X\nC Y\nA Y\nC Z\nA Y\nC Z\nA Y\nA Y\nA X\nC Y\nC X\nC X\nC Y\nC X\nA Y\nA Y\nC X\nA Y\nA Z\nB X\nC X\nC Y\nB X\nB Z\nA Y\nA Y\nA Y\nC Y\nA X\nC Y\nC Y\nC X\nA Y\nC X\nA Y\nA X\nC X\nA Y\nA Y\nA X\nC Y\nB Y\nA Y\nA X\nA Y\nC Y\nA X\nC Y\nA Z\nA Y\nA Y\nC Z\nA Z\nC Y\nA Y\nC Y\nA Y\nA Z\nC Y\nC Y\nB Z\nB Y\nC X\nC X\nB Z\nA Y\nA Y\nA Y\nA Y\nA Y\nA Y\nC X\nA Y\nC Y\nA Y\nB Y\nA Y\nA Y\nB X\nA X\nC X\nC Y\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nC X\nB Z\nA Z\nC Y\nB Y\nC X\nA Y\nA X\nA Y\nA Y\nC Y\nC Y\nA Y\nA Y\nC Y\nB Z\nC Y\nA X\nC Y\nA Z\nA Y\nA Y\nA Y\nB X\nA Y\nC Y\nC X\nB Y\nC Y\nA Y\nB Y\nA Y\nA Y\nC X\nC Y\nC Y\nA Y\nA Y\nC X\nC X\nC Y\nA Y\nC X\nC X\nB X\nC Y\nA Y\nC Y\nB Z\nA Y\nB X\nC Y\nC X\nA X\nA Y\nC Y\nA Y\nA Y\nA Y\nC X\nA Y\nC X\nC X\nA Y\nC Y\nA Y\nB Z\nC X\nC Y\nC Y\nB X\nA Y\nC Y\nA X\nA X\nB Z\nC X\nA Y\nC Y\nA Y\nA X\nC Y\nA Y\nA Y\nA X\nA X\nA Z\nC Z\nB Y\nC Y\nC X\nA Y\nA Y\nC Y\nA Y\nC Z\nC X\nC X\nC Z\nC Y\nC X\nC X\nA Y\nC Z\nB X\nC Z\nA Y\nA Y\nC Y\nC X\nC Z\nC X\nC X\nC Y\nC X\nC Y\nA Y\nA X\nA Y\nC X\nA Y\nA Y\nA Y\nA Y\nA Z\nC X\nA X\nB X\nA Y\nA Y\nC Z\nC Y\nA Y\nA Y\nC Y\nC Y\nC Y\nA Y\nA Y\nA Y\nB X\nA Y\nB Z\nA Z\nA X\nA X\nC Y\nA Y\nC Z\nA Y\nA Y\nC Y\nA Y\nA X\nC Y\nC Y\nA X\nA Y\nC Y\nA Y\nC X\nA Y\nC X\nA X\nA Y\nA Y\nA Y\nB X\nC Z\nA Z\nB Y\nA Y\nB Z\nB Z\nA Y\nC Z\nB Z\nA Y\nA Y\nA Y\nC Y\nB X\nA Y\nC X\nA Y\nC Z\nC X\nB Y\nC X\nC X\nB X\nC Y\nB Z\nA X\nA Y\nB Y\nC Z\nA Y\nA Z\nA Y\nC X\nA Y\nA Y\nC Y\nC X\nB Y\nB X\nC Y\nB X\nC Y\nA X\nA Z\nA X\nC X\nB Z\nC Y\nC X\nA Y\nA Y\nA X\nB X\nC X\nA Y\nB Y\nC Z\nA Y\nC Y\nA Y\nA Y\nA Y\nB X\nA Y\nC X\nA Y\nA Y\nA Y\nA X\nC X\nA X\nC Z\nC Y\nA Y\nA Y\nC Y\nA X\nC Z\nA Y\nA Y\nA Y\nB Y\nC Y\nC Y\nC Z\nC Z\nC Z\nA Y\nC Y\nA Y\nA Y\nA Y\nA Y\nA Y\nB Y\nC Y\nC Y\nA X\nC Z\nC Y\nA Y\nA Y\nA Y\nC X\nA Z\nA Y\nA Y\nA X\nA Z\nC X\nB Y\nA Y\nA Y\nC Y\nB X\nA Y\nA Y\nC Y\nC Y\nC Z\nA X\nC Y\nC X\nC X\nC Z\nA X\nB Z\nC X\nC X\nC Y\nC X\nC Z\nC X\nC X\nB Z\nB Z\nA Y\nB Z\nA Y\nA Y\nA Y\nB X\nC X\nA Y\nC Z\nA Z\nA X\nA Y\nB Y\nB X\nB Z\nA Y\nA X\nA X\nA Y\nC X\nB X\nA Y\nC Y\nA Y\nA Y\nC X\nC Y\nC X\nC Z\nB X\nC X\nC Z\nA Z\nA X\nA Y\nA Y\nA Y\nC Z\nA Y\nC Y\nC X\nA Y\nA Y\nC X\nC X\nA Y\nC Y\nC Z\nC Y\nC X\nB Y\nC Y\nC X\nA Y\nB X\nC X\nA Y\nA Y\nC Y\nC Z\nA Y\nA Z\nB Y\nA Y\nB X\nC Y\nC Z\nB X\nB X\nC X\nA Y\nB Z\nA Y\nA Y\nA Y\nA Y\nC X\nA Y\nA Y\nC Z\nC X\nB Y\nC Y\nC Y\nA Y\nC X\nB Z\nA Z\nC Y\nA Y\nB Y\nB X\nB Y\nA Z\nC Y\nC Z\nA Y\nC Z\nC X\nA Y\nA Z\nC Z\nA Y\nA Y\nA Y\nC X\nA Y\nC Y\nB Z\nA Y\nC X\nA X\nA Y\nC Y\nC Z\nC Y\nA Y\nC Z\nA Z\nA Y\nC Y\nA Y\nC X\nA Y\nA Y\nB Z\nA Y\nA Y\nA Y\nC Y\nC Y\nC Y\nC X\nC Y\nC X\nB Z\nA Y\nA Y\nA Z\nA Z\nA Y\nA Z\nA Y\nA Y\nA X\nC Z\nA Y\nA Y\nA Y\nC X\nC Y\nC X\nA Y\nA Y\nA Y\nC Y\nC X\nB Y\nA Y\nC Y\nC Y\nA Z\nC Z\nA Y\nA X\nA Y\nA Y\nB X\nA Y\nC Y\nA X\nC Y\nA Y\nA Y\nA X\nC Y\nA X\nB X\nC Y\nA Y\nA Y\nA Y\nA Y\nC Z\nC Y\nC X\nA X\nA Y\nC X\nC Y\nA X\nA X\nB Y\nB Z\nA Y\nC Z\nA X\nC Y\nA X\nA Y\nC Y\nC X\nC Y\nC X\nA Y\nA X\nA Y\nA X\nC Z\nA X\nA Y\nC Y\nC X\nC Y\nC X\nA Y\nC Y\nC X\nA Y\nA Y\nC Y\nC Y\nA Y\nA Z\nC Y\nA Z\nA Y\nC Y\nA Y\nA Y\nC Y\nA Y\nB X\nC X\nC Y\nC X\nA Y\nB Y\nC Z\nA Y\nC X\nA Y\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_02_questions.txt",
    "content": "--- Day 2: Rock Paper Scissors ---\n\nThe Elves begin to set up camp on the beach.\nTo decide whose tent gets to be closest to the snack storage,\na giant Rock Paper Scissors tournament is already in progress.\n\nRock Paper Scissors is a game between two players.\nEach game contains many rounds; in each round, the players\neach simultaneously choose one of Rock, Paper, or Scissors using\na hand shape. Then, a winner for that round is selected:\nRock defeats Scissors, Scissors defeats Paper, and Paper defeats Rock.\nIf both players choose the same shape, the round instead ends in a draw.\n\nAppreciative of your help yesterday, one Elf gives you an encrypted\nstrategy guide (your puzzle input) that they say will be sure\nto help you win. \"The first column is what your opponent is going\nto play: A for Rock, B for Paper, and C for Scissors.\nThe second column--\" Suddenly, the Elf is called away to help\nwith someone's tent.\n\nThe second column, you reason, must be what you should play\nin response: X for Rock, Y for Paper, and Z for Scissors.\nWinning every time would be suspicious, so the responses must\nhave been carefully chosen.\n\nThe winner of the whole tournament is the player with the\nhighest score. Your total score is the sum of your scores\nfor each round. The score for a single round is the score\nfor the shape you selected (1 for Rock, 2 for Paper, and 3\nfor Scissors) plus the score for the outcome of the round\n(0 if you lost, 3 if the round was a draw, and 6 if you won).\n\nSince you can't be sure if the Elf is trying to help you or trick you,\nyou should calculate the score you would get if you were to\nfollow the strategy guide.\n\nFor example, suppose you were given the following strategy guide:\n\nA Y\nB X\nC Z\n\nThis strategy guide predicts and recommends the following:\n\n    In the first round, your opponent will choose Rock (A), and you\n      should choose Paper (Y). This ends in a win for you with a\n      score of 8 (2 because you chose Paper + 6 because you won).\n\n    In the second round, your opponent will choose Paper (B),\n      and you should choose Rock (X).\n      This ends in a loss for you with a score of 1 (1 + 0).\n\n    The third round is a draw with both players choosing\n      Scissors, giving you a score of 3 + 3 = 6.\n\nIn this example, if you were to follow the strategy guide,\nyou would get a total score of 15 (8 + 1 + 6).\n\nWhat would your total score be if everything goes\nexactly according to your strategy guide?\n\n--- Part Two ---\n\nThe Elf finishes helping with the tent and sneaks back over to you.\n\"Anyway, the second column says how the round needs to end: X means\nyou need to lose, Y means you need to end the round in a draw, and Z\nmeans you need to win. Good luck!\"\n\nThe total score is still calculated in the same way, but now you need\nto figure out what shape to choose so the round ends as indicated.\nThe example above now goes like this:\n\n    In the first round, your opponent will choose Rock (A), and you\n      need the round to end in a draw (Y), so you also choose Rock.\n      This gives you a score of 1 + 3 = 4.\n\n    In the second round, your opponent will choose Paper (B), and you\n      choose Rock so you lose (X) with a score of 1 + 0 = 1.\n\n    In the third round, you will defeat your opponent's Scissors\n      with Rock for a score of 1 + 6 = 7.\n\nNow that you're correctly decrypting the ultra top secret strategy\nguide, you would get a total score of 12.\n\nFollowing the Elf's instructions for the second column, what would\nyour total score be if everything goes exactly according to your\nstrategy guide?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_03.adb",
    "content": "--  Solution to Advent of Code 2022, Day 3\n------------------------------------------\n--  Rucksack Reorganization\n--\n--  https://adventofcode.com/2022/day/3\n--  Copy of questions in: aoc_2022_03_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_03 is\n  use HAT;\n\n  T0 : constant Time := Clock;\n\n  si : Character;\n  f : File_Type;\n  s : VString;\n\n  function Score (c : Character) return Natural is\n  begin\n    case c is\n      when 'a' .. 'z' =>\n        return 1 + Character'Pos (c) - Character'Pos ('a');\n      when 'A' .. 'Z' =>\n        return 27 + Character'Pos (c) - Character'Pos ('A');\n      when others =>\n        return 0;\n    end case;\n  end Score;\n\n  type Set is array (Character) of Boolean;\n  group : array (0 .. 2) of Set;\n\n  procedure Reset is\n  begin\n    for i in group'Range loop\n      for c in Character loop\n        group (i)(c) := False;\n      end loop;\n    end loop;\n  end Reset;\n\n  line, t1, t2 : Natural := 0;\n  count : Natural;\n  item : Set;\n\nbegin\n  Reset;\n  Open (f, \"aoc_2022_03.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    Get_Line (f, s);\n    --  Part 1's job:   Add priority of the item that\n    -----------------   is on both halves of each sack.\n    for c in Character loop\n      item (c) := False;\n    end loop;\n    for i in 1 .. Length (s) / 2 loop\n      item (Element (s, i)) := True;\n    end loop;\n    for i in Length (s) / 2 + 1 .. Length (s) loop\n      si := Element (s, i);\n      if item (si) then\n        t1 := t1 + Score (si);\n        exit;\n      end if;\n    end loop;\n    --  Part 2's job:   Add priority of the item that is\n    -----------------   on each sack of a group of three.\n    for i in 1 .. Length (s) loop\n      group (line mod 3)(Element (s, i)) := True;\n    end loop;\n    line := line + 1;\n    if line mod 3 = 0 then\n      for c in Character loop\n        count := 0;\n        for i in group'Range loop\n          if group (i)(c) then\n            count := count + 1;\n            if count = 3 then\n              t2 := t2 + Score (c);\n            end if;\n          end if;\n        end loop;\n      end loop;\n      Reset;\n    end if;\n  end loop Read_Data;\n  Close (f);\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if t1 /= Integer'Value (To_String (Argument (1))) or\n       t2 /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Priorities of items present in ...\");\n    Put_Line (+\" (part 1) both half-sacks . . . . . . . : \" & t1);\n    Put_Line (+\" (part 2) all sacks of a group of three : \" & t2);\n    --  Part 1: validated by AoC: 8185\n    --  Part 2: validated by AoC: 2817\n  end if;\nend AoC_2022_03;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_03.txt",
    "content": "shzsFcPssFhjFssBzdpRcNHNZrpdJdJVJZ\nfwvMCntfCCbSbSbtDgDNrDtDtJHZVH\nGbCwwbwwnGrLhBzjFFFsWPhL\nPpCqRsqqmmtCwMJC\nLHFrLLHDSNHlfWNhDzmjzzJlJzPJMvPJjQ\nSGSWDNrhZhPDSWDZLgVVRgbRppgpGVnpnn\nGRRjbVjmJZlgMRzzrN\nFpDptHpfHfnpPTvDFTWpFPnPcMfNCClNrzcVcrMMzVsCZlsZ\nTFTQDnvLHPFDtVbLwbjdGjdwwJ\nlhljvvhCjjzhjszzBPmnmGVZMGzG\nFbTcTwbtSFdtcMPnTBPQVnnBZT\nSFMpHDtNDSSbSdwppvgJWjJCJJgWgvlJHH\nwzNCWpzCzJnWWpRRNdJrgHLhjfbLrHrchV\nlBMStmPmmLQDPQZlshrdhgrfrcrrddgHgs\nmvGDGQSvDPBlGMLGCvCWpNvpzRWFwqRw\nstBttBThtDZqPWssPWZp\ngRggwwggCGFSBBvPRpHZZrHdZLZq\nccFJGCNJmmGQzbTDhnQhBBnB\nHJqMqtZbJMmJTqtLtVMqhpfphNdQfhfzzjhhlHll\nrWSBrnwFwWCvwWCwBgPgCgzjQccQhhgRzcdQzjfcNfzR\nCWBCwCvCvvwssWLMtJJGMdMZJsGV\nnFwSFQwsNrrsssSwCrhrCNnfcCRgJRMJTJcMfRzMCMCRvW\nDdbGdLZLttllWWvTzgzzgR\nZqGzPdLtDjBjDZGPZVmnhQFwqrFQhVFnss\nsNNpCjttjsJjSpgpWjslCTnqqSVffrnhSfDhmhrhfm\ndBwcGzbPBHbbwZcwJbcTTFDFFFDVrdVmFdnDqf\nHzGcczQPHGwzPzGHRctWlvRgtvJlvNlJvRNj\ncFNCFdvcCHvFBCZcwBfRSpttGhDmCghGShmSRt\nQjLnTTzQVzTTnLMqhDgPhGDDSjGPrgSh\nTTJGnJJlLQdNWZWJNBJZ\nWHBpHcMDZHLDbHLtGCnmRmLNGmRqvsCC\nPzTFzPPTJzrSbGsvnmqfsqfqRz\ndJSQQdVFQgjTrjQPWcWHbBVcZVccZtWp\nJDtnRtJzNzTTNlHc\nrQPJFrLPGMMwrGPFwjFMVLjSTWHdWBTdSWdWZlcWTHlZ\nMGFrCvLLwrwPFVVhvLMGGtnqfsmRJgDnqbRgfbqmfC\njnTtFjcSSvctJjznzvFmpqqPMqQDRVpRqPzqQzVQ\nbhHBfrWpfHsfGNllRrRCPqDCqPqq\ngsGZZpbWgbwHWGNgfZNjvLSTTjtnTgjSSSSJmL\nRLQNdVNnRQdQHVVLGpspNqvtsqptqpTtsp\nMlRWwbRBBFMFjCTFTTFDvj\nWmlWBmBwwmrndnmLRHRQ\nWnftJWlfnWSHGCjWWWSCFqFGBDqBwMcDmmMmGmqD\npTNhpTrPhhhRPzbhrppLhThLgqDmwccwqPBmMMqnFBcwwmBB\nZrhQTpzdjSVVtnvZ\njgtnJtBjtlTdJBZJVQBngQGDCGWpPGCcPWCbWdWMbcpP\nwHstNNttSHPDmHcMCp\nrrFFSvLLNfsFtNSqrtfrhsNjjVTBVgVvnTBvTQvjTgjVZz\nqhZwlqFqFwlJwrDHqHcDvgcNzv\nRCCTQmjCbQTBtRTbjJRDpBrgDHPPpPDvHccDPc\nVmjVWstQJhlJlGVJ\nGggpGwZmgvgJMvbJFQQDbDFbBbFCQDCW\nrtrLzNLtNSPnNqDSQDcQCWlqBQ\nVtzdRPtztLtVRtZmmMTRwCGZpMwp\nvtvqjsCqtshfjcWFHWGjGFJj\nzGrnzDDMpPcTHcSTVTJP\nDbDwMbZRDrZdBBnMznZMGZDfwtlgQhsqCttClsqvsLfCff\nJLzLtLsrzsQdvrWRwMHwcc\nqPmCTzlPjljjFTZmWwcwwvHMMRWwHvMm\nPFqZnVCqTCNjCzNgQsbGBLzLQQ\nCBnppDHllVpPCBshBHpjDTSmZcSrfwvmJcDDTJfw\ndFRLdLFQzNSTBTSNmBJv\nFzFFzRMBFWtQlPlsjjPVMnhC\nCVCfwnfdVvBdBbTNTT\nLNzsHPNWsDjTZqDHqT\nPtLgQsGQLSzWLstPgGWcgQLSNrpplffrnrNhpVCwlGVlrwMn\njPPVqPsHffzVnHzvSgMcCJGGMSVCll\npdbpDpBLNmNNppJgcvgSllGjDSGQ\nhrbBwLpjLhhhNZLhNrhZZLHzfsztFzzsrtHfRFnFfRHf\ntdjBdbmSfdHBdHHmZlWjFrnlWQlqvMFvFn\npDNDJhLhPVPLLLJphJLwNcwnQTcWWTqTrqMWTZvqMrlvFM\ngpVLhNwpgZJCghCLDNwphgmsBdzHHHmSstmfggzdbR\nTfMpfMBVftLMDBSjWDHgzHbgwLgHHvdzggzs\nQJnZcFFnZRHdHjJvwgdg\nRjjRRnmNmmZNjZqZnQcVffBrWqVTqrtffTSTVV\nfZTdTVcVjrjdBzdTnGtgnnGSHHNFGn\nthMWPtPMslmGnWnNnS\nthvbMvQMRphhLCjrzBjZVdcQfC\nMpmgZFgMGdrFrBCVnJ\nJsbJlTTlvLQbVffRRvBBRVjd\nLWlbhHlJhLTJmmGcMMHNmNgN\nbhvmhPrbhqNqQRRGzQjVvvRL\nwTwBZDBTwwggfnngcDfdsVVFQCdzCzDVRsFdQs\npngWMcgzMgpZWncnMpWNrbNHrNbmHhltWlbl\nnPndBjLPscWSccBVGnScsSzMdhMppMthdMgpMgrzvhhp\nCCFTFDwqZqCCJmhvpDzztVzDNztp\nqQFJTbRVbmCfwTwfmnnssWBGnLnWlRLSGn\nJRlJDSvLRRCdvmDSvdlbZNVBSWZGNgWsZGNgZBVs\nQrjPMqMnLzzjLjFnNNgBpsgtgGGGVZ\nhrjrFqjqFrQfMHPhQzDvvCLJdwwwmvbJbwDH\nHDGrDDDpNsGQNdZQ\njpjgtgjSjpjllfZZtZsvNdtshqqq\ncbgMfjclWTJcMwjWJfpfmVPLPBnVBHnmVbnmLBbD\nrPrMZNsNrsvrwqvFFFdgQWNzLJJzRW\npStppStHmcmHpgVSllVcbVbWWDdLFhdbzdRRFhJFLLRF\ncltCHmCBmtSlgjpllgGvTwPZPMfZvPsCMCwZvC\nFRQQMdlFMDWRFQRQMQQDWdFbSSSVJSBbJSlBVVBnPJnzJL\nrsftPfhsrgwznSzzHSLgJG\nfhNsjrjhvsTTvdjcCRMRMRPcCW\ntRtJttHFrjtDQHHBQMMBgMBSghhZQb\nvqWPLpLvqrmPdmqwvqfmPhNBBBlSnbwbgnlnlhNSZZ\npGpdfzLLspddmqsqPvfvvPpGTVcJJCDRjHrccRtDjcRDFD\nGJMHCdTMWJRhSTlhhSPllt\nfVvqpfBFrqvqNzzgVDFrpDPmSVtQSlSmhjwltlRtmVhn\npzpBNDBzfDrsNsDRJJRdCssMLdLZWZ\nhFfvWWvdpCwwcwFhphpcZCMmllHLfmbQlbrQLBJmGgQrQm\nnVSNGjGzzSVNTsjzSJrbSrHBSHlrrmQHJB\nPttTNsTRVnNjNqRnzRzRWCCCcpMCWGPMwwFZvFwW\nDvZbFnDDsqDBwwRQgNBm\nHhWpWWRMWChlChdHLlGlGtQtggSNPSSpgPmNgPJQtw\nCMlWGMhhCVHlLCdHTHdrGHdbzjVqnzcvqqjRjFbbzbFFqR\nZZgCNqqBmjZsNgZCqJgNBdrLFHbBrWlPdHWFbPnHPW\nTVwTDfzDwSDzmcSTcrzdbllnHPHdFlLzbF\ntvDQwVtVvDVmtRsNMgRpJg\nBBpDCpNJnmnpnDDmDGGmtTzqHcGTvTTjTbGjHLVcLb\nswNNhPwwHzTVwwHw\nrPRlPRhSQmmBDpnNfl\npbRhffPzcPDmfcNTpVBLpBjMGBGjZLLg\nssrCsqrszgJjZMqZLQ\nSzCwnsllCrssvdrvwzPmDmPPbFRbSThPTPDD\nQWLfcfczQQpcDTpLPfdZRRvRRVqbFWvZbvtqvv\nNsGGJBhCmNdZVqsbdssZ\nrMwwwBBJMrdzPfQMpzMnLQ\nrdtCQhrCtQQprtTWQCHFjPgGBPdFPgvBqRRPqB\nlsVsSnVSbLmmgBcgTLTFGgvq\nwTTDTszsbzMDppJrJhDQ\nZlmsGLBVCBBZFCFFHqcHVvQhqVQSSHpH\ndbbTRMrRwwzDfrTbFtMvcptvHFQQpqtc\ngdJTDWgfwDwTwmgmNPnNsgFBlZ\nPWhWhGFzzzrLdHCPccbJQJcHPD\nNRpVTpTgRWVlHJNHMcHQMb\npSRSpVSZWRSTZjgTRTWnFLdZLrrndhdzZvtvzn\nLgctLgVBVLhlPjqRhBLVcVlhbDDcGnNGfwCrbNDnrGbGCJNw\nHmppHMWWmQmMqZZHWQrDDfDCffJrDGJrCb\nqpWZsZZZMZWTLPhTRgTtThRP\nhfhQfFQWzBfhfTQdmzdLDtDjtvHLjt\nqsgpcqMNRmgpqsCwpCmZDvjwvdddHZHvZDtrrd\nSgmNmqScbTSJbhJQ\ndvMTQvTnZJsrQdbbSvMVZMblDwlflfDGgwwHcfGjPfjjrG\nFqBLpBpFpFzRzqNFmgjGlDRHcwPPGwgcgs\ntLNtWshsLLqWMJhTQVVbhvJd\nbgZLMZgzbbLCcPCbMZbcNMgBqSTqSWVtSzvvTTBTqBvRBW\nFhQpJQnGrlhGlrnTqRtTRJqSwDwtVR\nFqlnnFnqFHnGHHdNZdbZbCNMdPLMPb\nHHFnbftcfnfbbTbTnHTNVZZzJlPQlFrFzVJFZsdr\nmvpGCBgwqCvLCqvMQWWzsQQWlPzwzsrV\nhpGSGgqSvqbHcnhfVfct\nlGVrnHsGcnVHzscrlGjHcrHqqWPlJCPJClTLLqCSPLPdqS\nfRbwbtMQZtMMRFMSqfJTTWCTJPJCmd\nggdvtvdbVVGnpDGg\nBnBjTcbnvhjjlMnNJJfnDnQDGdNDfP\nqwFqVSWwqLpWFmFVCSqFpDDCJNJRQTRfRDGPfdfDQN\nzwHwWVVWWFSqqwWTLqzzztHMvBhlcghblMlcttMllh\nPFFNPNPmlFllbctNLmcjBstrsVrQHJSSHHSnnB\nfddfDhdwGhTWWTDMwMggssjsjndsBsjsnSrVqSVV\nMCvvTWvRMwCvGPpzCcmbplpCVC\nthTqlPPTNbGNhGdqRRhRrNtFWnDnvvFZDpnFvfQDZtvWvv\nHcMzVcVVcHrgHzcMcmmgfQvFQnMjnWDjfnvjQFfQ\nVSmHJLHBJrTrJTlT\nNjnsHjLLjNRddNdBFBSR\nftsbqfDcDqsrDtqsfSVBhJVFJgdBRVFS\nwvDqwtDlsDDczjzjHvLzLQQM\nqDwstwDtRfpJfVhBVZBMvnlRvv\nzSFzQHFWdgZBVTZhTzrp\nNHdggjGjWHQFPWHNPPbpJfPDtCwCtqDqJfbt\npvnbqHvnTvlCCpjsBsMGBGWWPp\nRJSJhJCRVJmJwScrhSJdfwFsBGhZBjhGFFFFGgFPGhZW\ncdRrdmwtfcdSmLtcSCQlvQNqQTlqqvtTlv\nrnSlSrgWjVGpTTRhSffpRd\nHtgHPsNNgNHszPcTBphMdhHhBcTc\nJNNbZPZZsszNmtDbPgsmJlwFvWVnCwrlmWlnjnGvCC\nWrVBVgVGGQCrSTTqvVjDqDjv\nFmwRRwwRQhhLFMjFMzdqSSzS\nRcJtbnnLtQWrGHcfrP\nvpzssjmVjVZWNZzzQwtQwccpQhgtQCct\nqDdfLMnMrrTbBLqTqltlTfbGQnghgRwggGgRnhhccCJJcG\nMtdLfSSSddMftlrjjzsSWVSjFvjNvs\nqTRPpRPzJglzGJzpGRHWHljwDtbwffjtbhjfwNfHmwwf\nSZLVdsvrrdFdBcdZvsBdDCNtbmftNwfNbNhCNvtz\nMLzzddLsQRppRlQGPq\nPDDpdJgtpppGgttgdGdgJFzLjVcvVnnCTrVrRPTLvwnTTC\nZSbHBsSNlZcsfNnnvRrnVjrHwvCC\nNmSmsfsfhmzcDmctJW\nNbrLfrrLqpqWQHtBzbFttJgcgB\nCmwjPPjjjShPvljwvwwjPBFttBtcHzFJcHTRHJRRmT\nCCljjDGhvPCVdVSCdPvrrNfnnQsGqMpqqMqnFW\nbdPdbcDZlddsZbHjrrgrmZmCZhCGjv\nBffLfLVFVMMBRfwMpfzhFGFhGWvWvrhNvvNj\nRMBpRSnffBJjSbJqdPHsDcbqtl\nBgwGwDDZttDDTNND\nWzNNnFRWFtTFlFsh\nWJjPpPqqzWRbrqnNqvVvgvvdcBwgdrVBZG\nFFbMVMFPvJppgvcvrZMjHlCJWHmHHBlqhCmqChCl\nRGQVdVVLnLsQnQnnqWBlBmDRBDWWlhBD\nSftLzQndGfVgFfjvvM\nnpvLlFLTWWqdLnJCmBmmpjQjjmjB\ntfgDwzwVVVVtgtrsJtrbjSPQjQmjNBCNBNhPHDHC\nggVzVtMRgzMrvJLqFnnRnnRT\ngZFZssWgNZTDwHDWzsFwWDQMMpqqpBPMjFtMPSQFqqqM\nvrmvhdnVvQpftStnMN\nJCdLddhhdJdcCdrrmCGhlgNsWDWDwWsgwHgHLZHW\nvSsSGjSPvjvRSGpFprFbqFpppRfp\nZdmlndtBZbwrwfpWFn\nJmdHdBBHtgllZldBhJZldLLBjPVQTfvGPNzQQSjjzPgTGNTs\nTjTjBjVrTsLRRrMBsMMgzLqGGqgQHQdCQGgpgd\nnbZcmNnPNcbNftvhlhZpgQgCqdSpgCHCqPFzSH\nWfcNvtmmNmQlvNcbsWWjMwMVMRDVMDJM\nhHHnfZSwHDgHcfclSGSnvrnvBCvWWntvzvzbWWVq\ndTJTmspFTsFdRRLvtvLzvvVqtPVtrb\nVFMNFpRJNTppTpsJVRcMGgfGfgZwghgGfcGh\nlLGvwsMJLCMVnTrCrVdHRd\ntbzqtDNNBpNWBtqzfRrFFnrVTTdrQVSVGp\ntztfzmfzzPDzgWNNBbhGMlJLsvhJJjGJhGmM\nrHrVJQVQVJLggDQQLbTvdCCSTdWLLLbCbS\npNtnwPthmZGRpmPFtqbMSzqffFSdTvbSzW\nGpvvshwtmwsZDljjssHjVBVj\nSmhJdtJhhzQSrzVhtQbtBRNfnFNSnDNGRfFGGMgR\nlHwqPjqwTjLHCWLvPpvNrNMvnNGNfNGNBffGRN\nlCrPTrwpPZWlqPlqpWWqZjsmJzbzVtVhhdsJcQdddZVJ\nQqpCWHdQdVQlWcQCqcfRjnZZZPDnSPqPhhqZ\ntmmzgWGgwJwwStSZZDRnZssR\nGbFbLLvgmMMwGgmLCrppQrWVlWrFTHHd\nqdqCgSVdVSVqfwsdZhpJspZsph\nRjZBbmRlrlmmJwLNNNhLpwhB\nvZlRrtTZCzCMfSPT\nJBjhCNwjrlJlHJJRsscZrTcvLLgTsLPP\ndDztmntCSgbLgqTzgc\nfGVWnSMFtVGMNNNQllBjWHJC\ndSDhVVdVZtnSgHQGThQvFNQQqF\nLcfLRpMpcBpbrJfsbsscBNWRNPRGHvqPdTGPGqPWFH\nspmrCcrdJJpLLmcmLLLDlzSzCCjVwZVtgnSZzn\nZJtgPTHtZPZQGbtNzzprVWWVrbrpCD\nBRlfcRmBhSMVBqSVfBvNWrDrjWCjjzprCDCl\nLfMRSmfqfSLcnnMqVSfccnhZwJFHZFTGZQGFLggwZTZGPJ\nBChWddRRRcfmDbfhDP\nMgpMFFsvMfGwvLgPjQPzPPmDcztDtw\nNFgJpqvpLgqFnWWVNSfnNSCR\nzMMMRmMfJpfhpzQJLMVtjtjPntgBtlZlVgJP\nSdNbZvZbvbHTNbZbSWTdrTVBglBDlWBjDPDgntPqBDPt\nrrNcrFwNdSrfzwMzZMLQQs\nJPmCSfHTGJdTCbHgpgqLgRhghhffhg\nZWSSFVSVFQghQvwpphgh\nlsDtZjVMMSdCNdbGCbjb\nPBQPvDvVVRvQDqLDzJTlzwjz\ntGcZTcdgGcncdrFrsTjzJSJqJqqwHSzzSZwq\nCgtgdFgcFCMnMgsGFGGQWPQpQTCBvbNpNVVWVT\nFHVFWMHMgVhnLWWMpnppfcdZNcPplnfn\nRSvSCBSqGgDRjqCpPlPpppTpPjlcNP\nzRzsGgJDqJwLVWVFwM\nThhWhNthVWTWqbWbFWbTdBtWSdMlHSlGlCGCdsCMClmnSlMn\nDPPpvvfDHfLgDHvzpvPDsssMsmmzsMcClScMMcGG\nrgPLHHJJHgZfvvZQQZfrpfFqBBwFBTNTBNBwtthQwVqt\nJJgSWDSmSDQCFrhbRLSwLS\nVznqzVNsMsZLdqslbRChtbHdHRrwHb\nLVfNLMsLTmWDpBpf\ncbTsnNpcnnchllFQlMRgJhRP\nWddmdMVSBMWSBWjwCJVCPRwPFCQRRC\nDWSSfjdSrTpDnHHMbZ\nfgsVqqwQQtHhCrDfJH\npvbnBZWBbvWbTdthrJbDmqrmHq\nTvZSNSNNSvFMBpqpnLnTBZBFGQwlQFggcFzcVGRlswsRll\nzfMcQHzPtRNvlllc\nBLnMhbZMLJLNNVtCdNgZgt\nBJGFpqMBhBLLMqnwBhbrbhLssjFzssjfDzsmFmjmQFQPjT\nJPBJPnpBFrqBJHtjlCjHJcCthM\nwQZggQWQGfZFVmmGfDRjlvvNcvlNDhcNttlctt\nSfmWfwVFwVGZWQVGSTdTbBpTPSqBbLnnrn\nRJqBRJbqpqqJGvqHMmcfczfcjvHQfm\nllgVnSWSlsssTnlWjhTcsZMcZcZMZMcccMNmcH\nTnFhhllnWCnVCTllLnhhVSrbDDPrdpjRRqjBPRBBpbFJ\nmRwRRNDjNTqwDNjNnNRTsQLcQWpQWZJLlLpQWs\nPMFGCSzzgbBVzCGShVQZcgWsQLLftttQtlZZ\nSlGVldCGGbBPMhPCVSBrNNdjRqjDrNmDnmrRwN\nmqGGqGHnqGBCMrnGCbbbLgTTFFNNghHNTj\nSdRfcsDPPcDdRzWPWltSlscwTSbShhgpQhgbFLbTQFjwhN\nDPWWZzzztsDDtfzlscsPdcWZnVMNVqqGJnBrVqCrMrVvZnBJ\nZgglFCrrrlrWCJswHmwRVmFSwSsP\nzhzqBLcjjnpzMzjhTtcqnVGbwssVRmqbHNPbwPsVNH\nftBjzLtptRWdvZlQQZQf\nnGpsMncVRMGSnfsBllZdppwrTljZrQ\ngcgHmtbCthHWhwBFBWZBlWlWrd\nbCDDqHhcqbbtqcqtvJMzsGRsvVfPsfnzJV\nTclPvSGZsPZRjhjWDgjp\nJtnwHFtJqtwfQfgWgRWhdhjtgdRM\nJBwnHwgFFqVJrsGmPvNTPsVvSN\nZJnfZNnDNZJLzNntDtDNNzNWTVBPrrvRRGdBcVRfPPcvfdMr\nCFgjFmggQSQQmSggVMMvRdTvBVRjrdrc\nmbsqQFqFgwwmgmSbwQWWLDWzpLcLnzZzLbLL\nPnwSFSLSTwbbHdtstW\nRrDZVVfJNZCmDCfVDVlblZHbddtHScbWbMjt\nNmzqhzCCqmzffhCCqrhhLLnPvpnTPPgpGTTBSL\nShhfLSDDFMPQddpMrDgNbjzffqqqzgcjbqZR\nsCstmwJwVBtmTltVmTVbRbcbcRvqvrZvBRvZbR\nVwCnwnVrrrWShWPHHDdQFL\npbpDpWjZMmFCmmmb\njTjtJLJgJncCFmnJFC\nLvhvhTQhBSdRNtLNsSszlGrHSGjZDlGf\nJrhvTNJJhhCrtVtcrNLwDBSBwqzDwQVbBLQS\nRnCgHmHHGMdPsGMfDlDqlSQbQnQQDbzD\nRdPMPsmWHmjfMffPcCWrptcprpFTFrFp\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_03_questions.txt",
    "content": "--- Day 3: Rucksack Reorganization ---\n\nOne Elf has the important job of loading all of the rucksacks with\nsupplies for the jungle journey.\nUnfortunately, that Elf didn't quite follow the packing instructions,\nand so a few items now need to be rearranged.\n\nEach rucksack has two large compartments. All items of a given type\nare meant to go into exactly one of the two compartments.\nThe Elf that did the packing failed to follow this rule for exactly\none item type per rucksack.\n\nThe Elves have made a list of all of the items currently in each\nrucksack (your puzzle input), but they need your help finding\nthe errors. Every item type is identified by a single lowercase\nor uppercase letter (that is, a and A refer to different types\nof items).\n\nThe list of items for each rucksack is given as characters all\non a single line. A given rucksack always has the same number\nof items in each of its two compartments, so the first half\nof the characters represent items in the first compartment,\nwhile the second half of the characters represent items in\nthe second compartment.\n\nFor example, suppose you have the following list of\ncontents from six rucksacks:\n\nvJrwpWtwJgWrhcsFMMfFFhFp\njqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL\nPmmdzqPrVvPwwTWBwg\nwMqvLMZHhHMvwLHjbvcjnnSBnvTQFn\nttgJtRGJQctTZtZT\nCrZsJsPPZsGzwwsLwLmpwMDw\n\n    The first rucksack contains the items vJrwpWtwJgWrhcsFMMfFFhFp,\n      which means its first compartment contains\n      the items vJrwpWtwJgWr, while the second compartment contains\n      the items hcsFMMfFFhFp.\n      The only item type that appears in both compartments\n      is lowercase p.\n\n    The second rucksack's compartments\n      contain jqHRNqRjqzjGDLGL and rsFMfFZSrLrFZsSL.\n      The only item type that appears in both\n      compartments is uppercase L.\n\n    The third rucksack's compartments\n      contain PmmdzqPrV and vPwwTWBwg; the only common item\n      type is uppercase P.\n\n    The fourth rucksack's compartments only share item type v.\n    The fifth rucksack's compartments only share item type t.\n    The sixth rucksack's compartments only share item type s.\n\nTo help prioritize item rearrangement, every item type\ncan be converted to a priority:\n\n    Lowercase item types a through z have priorities 1 through 26.\n    Uppercase item types A through Z have priorities 27 through 52.\n\nIn the above example, the priority of the item type that appears\nin both compartments of each rucksack is 16 (p), 38 (L), 42 (P),\n22 (v), 20 (t), and 19 (s); the sum of these is 157.\n\nFind the item type that appears in both compartments of each rucksack.\nWhat is the sum of the priorities of those item types?\n\n--- Part Two ---\n\nAs you finish identifying the misplaced items, the Elves come\nto you with another issue.\n\nFor safety, the Elves are divided into groups of three.\nEvery Elf carries a badge that identifies their group.\nFor efficiency, within each group of three Elves, the badge\nis the only item type carried by all three Elves.\nThat is, if a group's badge is item type B, then all three Elves\nwill have item type B somewhere in their rucksack, and at most\ntwo of the Elves will be carrying any other item type.\n\nThe problem is that someone forgot to put this year's updated\nauthenticity sticker on the badges.\nAll of the badges need to be pulled out of the rucksacks so the\nnew authenticity stickers can be attached.\n\nAdditionally, nobody wrote down which item type corresponds\nto each group's badges. The only way to tell which item type\nis the right one is by finding the one item type that is\ncommon between all three Elves in each group.\n\nEvery set of three lines in your list corresponds to a\nsingle group, but each group can have a different badge item type.\nSo, in the above example, the first group's rucksacks\nare the first three lines:\n\nvJrwpWtwJgWrhcsFMMfFFhFp\njqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL\nPmmdzqPrVvPwwTWBwg\n\nAnd the second group's rucksacks are the next three lines:\n\nwMqvLMZHhHMvwLHjbvcjnnSBnvTQFn\nttgJtRGJQctTZtZT\nCrZsJsPPZsGzwwsLwLmpwMDw\n\nIn the first group, the only item type that appears in all\nthree rucksacks is lowercase r; this must be their badges.\nIn the second group, their badge item type must be Z.\n\nPriorities for these items must still be found to organize\nthe sticker attachment efforts: here, they are 18 (r) for\nthe first group and 52 (Z) for the second group.\nThe sum of these is 70.\n\nFind the item type that corresponds to the badges\nof each three-Elf group.\nWhat is the sum of the priorities of those item types?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_04.adb",
    "content": "--  Solution to Advent of Code 2022, Day 4\n------------------------------------------\n--  Camp Cleanup\n--\n--  https://adventofcode.com/2022/day/4\n--  Copy of questions in: aoc_2022_04_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_04 is\n  use HAT;\n\n  T0 : constant Time := Clock;\n  f : File_Type;\n  sep1, sep2, sep3 : Character;\n  l1, u1, l2, u2 : Natural;\n  t1, t2 : Natural := 0;\n\nbegin\n  Open (f, \"aoc_2022_04.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    --  Read data in the form: \"2-4,6-8\":\n    Get (f, l1);\n    Get (f, sep1);\n    Get (f, u1);\n    Get (f, sep2);\n    Get (f, l2);\n    Get (f, sep3);\n    Get (f, u2);\n    if (l1 >= l2 and u1 <= u2) or (l2 >= l1 and u2 <= u1) then\n      --  Count redundancies (one set contained in the other one):\n      t1 := t1 + 1;\n    end if;\n    if u1 >= l2 and u2 >= l1 then\n      --  Count overlaps:\n      t2 := t2 + 1;\n      --  The sets are separated when and only when u1 < l2 or u2 < l1.\n      --  Thus the condition for an overlap is:\n      --     not (u1 < l2 or u2 < l1)\n      --  which is equivalent to:\n      --     u1 >= l2 and u2 >= l1\n    end if;\n  end loop Read_Data;\n  Close (f);\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if t1 /= Integer'Value (To_String (Argument (1))) or\n       t2 /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: pairs with redundancies . . : \" & t1);\n    Put_Line (+\"Part 2: pairs with overlaps . . . . : \" & t2);\n    --  Part 1: validated by AoC: 657\n    --  Part 2: validated by AoC: 938\n  end if;\nend AoC_2022_04;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_04.txt",
    "content": "54-59,17-62\n20-93,57-92\n6-54,7-54\n3-99,59-98\n5-8,5-8\n89-94,32-89\n1-91,1-90\n26-90,91-93\n33-76,21-75\n59-60,19-60\n15-94,15-94\n60-62,59-77\n16-26,12-21\n5-10,11-98\n10-97,9-10\n62-92,61-92\n57-74,38-74\n79-85,84-86\n14-86,13-86\n23-27,22-93\n20-99,19-99\n37-62,36-63\n77-95,88-94\n1-1,3-28\n18-19,18-84\n75-94,74-99\n34-52,20-21\n63-95,2-63\n98-98,82-85\n1-89,2-90\n18-99,22-91\n26-43,27-43\n40-97,41-96\n43-94,88-97\n35-79,11-36\n10-63,10-88\n54-69,53-70\n4-53,2-52\n40-77,77-77\n17-84,79-84\n4-45,5-46\n6-43,7-33\n26-81,26-81\n12-76,11-65\n47-94,47-84\n27-99,26-99\n81-87,80-87\n16-30,1-15\n23-77,23-77\n35-43,36-36\n3-90,17-90\n16-50,15-18\n13-37,37-69\n45-45,44-52\n28-70,28-70\n61-68,61-69\n32-94,32-93\n48-48,31-51\n33-35,34-49\n27-38,38-39\n11-37,11-14\n4-49,3-49\n16-73,72-73\n16-98,22-78\n5-92,91-91\n11-96,10-96\n67-86,82-95\n28-91,92-99\n5-9,5-25\n7-98,6-30\n2-79,11-78\n13-85,85-85\n6-99,98-98\n24-97,68-97\n4-39,3-39\n24-82,57-82\n3-99,1-99\n52-90,90-91\n69-70,69-70\n62-83,61-61\n71-72,17-71\n5-95,4-94\n50-70,46-48\n33-34,34-96\n29-84,29-98\n28-88,27-87\n20-96,21-96\n21-45,46-68\n54-87,54-97\n10-22,10-22\n75-87,15-76\n15-36,14-99\n10-99,9-92\n28-89,29-84\n8-71,7-72\n36-87,36-88\n76-80,46-82\n36-49,7-36\n38-40,40-61\n94-99,28-93\n15-69,54-69\n31-53,52-52\n69-71,5-70\n27-83,3-84\n6-59,59-60\n34-43,33-79\n3-97,4-88\n13-47,13-47\n3-11,10-42\n13-83,12-83\n63-63,62-80\n40-60,60-70\n6-96,7-96\n6-40,21-40\n30-43,27-42\n4-11,21-69\n96-99,5-97\n2-92,2-91\n22-67,23-52\n17-94,17-27\n25-25,24-93\n18-86,18-71\n32-38,38-76\n45-91,45-83\n72-72,72-72\n34-64,64-76\n64-95,43-96\n19-91,2-90\n38-85,84-84\n4-68,3-5\n7-9,8-20\n12-12,12-97\n43-76,75-76\n49-72,71-71\n84-88,84-88\n24-64,23-63\n27-79,11-27\n8-85,5-89\n38-77,6-78\n24-98,25-98\n8-98,25-83\n15-32,5-15\n72-97,7-98\n69-91,70-87\n45-92,5-91\n25-75,76-76\n10-99,10-99\n4-12,10-12\n95-96,64-95\n29-84,29-84\n56-95,94-95\n14-93,11-42\n43-43,3-44\n5-93,47-93\n80-88,79-96\n25-56,16-25\n25-88,26-64\n1-93,2-2\n20-74,20-74\n95-98,96-98\n41-41,40-40\n18-19,12-19\n29-37,36-36\n2-50,3-50\n2-97,3-96\n12-12,11-30\n25-86,26-87\n18-42,18-36\n8-10,9-11\n47-49,27-48\n2-69,69-69\n16-18,17-96\n18-18,17-99\n34-55,34-55\n8-83,88-98\n55-56,46-55\n22-63,11-64\n47-86,32-85\n2-2,1-67\n5-97,6-6\n4-35,1-44\n43-86,54-97\n23-95,23-95\n29-39,29-38\n5-93,5-93\n3-3,3-99\n2-96,22-68\n47-78,48-78\n58-77,58-78\n2-75,2-89\n23-53,17-20\n26-60,9-27\n7-7,6-64\n25-42,15-43\n27-75,37-75\n20-96,21-96\n18-36,35-35\n10-97,10-97\n4-6,9-68\n12-83,13-13\n43-48,26-44\n43-98,43-99\n40-96,40-40\n1-2,2-82\n14-85,14-85\n11-44,10-45\n71-92,91-92\n23-69,24-64\n75-75,11-76\n14-99,2-99\n67-74,73-73\n12-85,13-85\n39-80,40-40\n33-34,32-34\n58-59,13-59\n83-88,84-84\n17-24,9-70\n4-87,1-99\n1-48,2-94\n14-95,10-89\n31-43,31-92\n67-81,49-72\n15-74,16-16\n29-66,29-66\n30-98,97-97\n3-75,3-76\n40-41,26-40\n68-68,67-78\n23-53,24-90\n51-55,36-58\n3-97,4-93\n8-90,8-48\n9-64,8-95\n17-48,47-48\n19-69,46-68\n21-96,21-96\n41-41,37-42\n2-98,97-99\n13-13,13-13\n21-82,38-82\n6-82,81-81\n2-38,37-37\n26-93,5-93\n1-45,2-28\n3-70,8-63\n48-54,51-54\n3-8,7-41\n17-76,16-77\n40-44,40-43\n57-86,27-57\n27-87,24-71\n81-93,92-93\n27-46,46-46\n4-94,7-93\n48-85,84-85\n61-63,13-62\n11-12,11-22\n33-86,33-34\n17-34,18-34\n8-30,31-34\n6-91,6-90\n21-55,21-55\n15-48,25-35\n28-29,30-53\n48-81,47-83\n12-26,11-26\n89-89,22-89\n20-98,21-98\n5-97,76-81\n3-76,3-76\n17-79,79-90\n20-75,28-74\n9-58,8-59\n55-57,56-72\n52-58,45-49\n6-97,21-86\n8-74,8-74\n48-95,75-94\n1-87,8-88\n40-49,36-49\n8-72,8-73\n2-76,3-76\n22-33,2-33\n46-94,18-94\n13-98,7-98\n52-66,14-65\n7-8,8-8\n34-35,34-72\n8-21,20-86\n96-97,2-97\n60-60,59-89\n4-11,10-96\n14-43,14-43\n31-44,43-79\n36-78,35-78\n70-91,67-91\n65-66,43-65\n3-6,5-96\n27-50,9-35\n27-28,13-28\n73-82,72-81\n2-43,2-42\n76-77,75-79\n88-89,23-89\n5-5,4-68\n6-6,5-98\n21-22,9-22\n6-94,5-6\n26-89,20-88\n39-93,13-95\n5-93,22-93\n8-23,9-23\n30-52,31-51\n55-55,6-55\n26-83,26-83\n52-72,51-78\n25-28,41-87\n35-98,36-64\n96-97,79-97\n56-81,57-79\n40-42,17-41\n30-82,30-81\n6-14,9-15\n11-29,11-30\n8-41,6-40\n28-97,97-97\n33-67,33-68\n29-90,28-91\n2-30,12-29\n5-70,6-6\n8-39,9-79\n5-29,28-35\n17-55,17-55\n3-90,2-90\n15-30,15-72\n77-78,16-78\n60-82,36-83\n2-91,4-89\n37-52,52-52\n11-98,10-98\n55-56,24-55\n27-59,25-59\n2-2,1-93\n11-49,49-50\n23-71,23-86\n17-52,3-51\n98-98,21-99\n3-92,4-4\n81-85,81-85\n17-99,18-95\n5-90,1-2\n33-78,33-77\n34-47,20-47\n1-97,35-98\n95-98,34-96\n80-92,94-98\n63-70,69-70\n89-94,90-95\n38-38,39-81\n74-75,33-75\n16-33,25-97\n29-97,29-29\n28-30,29-93\n26-75,74-75\n98-99,1-98\n37-60,32-46\n18-36,17-88\n29-95,29-95\n16-32,32-33\n36-37,19-38\n36-84,33-42\n56-68,6-69\n14-57,42-57\n68-76,67-73\n14-24,23-37\n59-60,60-87\n16-98,15-98\n46-47,43-72\n97-97,64-97\n45-65,64-64\n35-98,12-35\n1-99,1-98\n7-77,8-76\n7-89,8-56\n65-65,54-68\n19-94,13-95\n86-90,85-88\n14-79,13-80\n15-15,15-77\n6-68,6-68\n6-6,5-60\n50-89,37-90\n7-66,7-67\n20-38,20-37\n45-92,46-97\n77-78,67-77\n3-3,2-99\n3-91,3-4\n4-84,25-84\n10-11,10-66\n4-45,4-45\n33-62,25-34\n38-67,39-39\n15-70,63-64\n58-75,57-74\n6-98,3-7\n22-54,47-53\n20-45,32-46\n1-91,1-90\n3-97,99-99\n1-45,1-1\n3-92,28-91\n5-83,5-84\n5-98,20-98\n51-52,51-52\n15-93,12-23\n18-21,21-89\n89-92,88-95\n8-27,12-54\n12-28,13-28\n25-27,26-27\n63-64,63-70\n1-75,1-25\n13-41,14-14\n15-30,30-93\n9-89,9-90\n14-70,15-70\n11-12,11-52\n3-3,2-98\n8-10,9-91\n67-68,57-68\n7-33,8-94\n33-90,2-89\n13-57,12-58\n62-91,73-74\n31-99,32-77\n4-19,1-3\n26-35,34-42\n19-64,18-55\n51-64,87-91\n3-99,98-99\n4-45,8-92\n53-86,85-86\n22-84,22-79\n17-79,80-86\n37-37,36-82\n7-83,7-82\n94-95,78-95\n93-94,49-93\n70-82,18-98\n4-85,3-84\n31-84,30-71\n16-32,24-31\n10-91,4-63\n11-94,11-92\n70-71,62-70\n43-83,60-82\n10-47,6-46\n12-58,57-58\n10-64,10-56\n24-95,42-94\n1-38,18-37\n19-53,20-53\n26-37,26-37\n76-80,77-81\n10-16,16-16\n24-98,40-79\n26-92,27-92\n14-99,14-15\n1-98,96-96\n85-99,84-96\n34-60,14-61\n40-82,81-85\n1-99,1-21\n20-28,20-29\n4-73,1-73\n2-2,3-93\n55-97,7-98\n18-66,19-74\n78-80,80-80\n9-80,26-81\n26-97,4-99\n14-87,13-88\n81-82,82-86\n29-33,30-35\n81-89,13-82\n33-42,34-68\n27-94,26-95\n5-93,93-94\n8-86,64-87\n5-74,4-75\n66-90,94-97\n58-61,58-60\n52-90,50-58\n22-22,22-22\n53-61,53-54\n9-66,65-77\n42-60,43-43\n68-97,68-97\n16-89,15-90\n44-96,95-97\n12-89,13-88\n35-52,34-52\n45-78,46-86\n7-24,7-20\n6-53,5-54\n57-58,14-57\n73-82,77-81\n43-50,44-50\n32-48,32-70\n91-92,29-91\n4-86,70-87\n91-92,45-90\n34-98,35-35\n34-98,90-97\n24-96,23-97\n30-62,29-62\n37-37,36-66\n20-91,49-90\n85-94,19-99\n37-77,10-36\n1-46,45-72\n50-88,19-88\n87-89,19-98\n3-91,2-97\n10-75,10-75\n4-96,3-97\n50-85,22-50\n68-94,69-92\n7-66,7-8\n18-72,25-73\n13-52,51-52\n84-87,2-87\n4-86,87-93\n45-49,49-56\n4-25,3-26\n26-55,24-27\n25-47,26-26\n45-56,44-56\n61-64,60-64\n33-96,34-95\n49-50,26-51\n3-94,4-94\n8-97,8-95\n6-64,5-35\n21-31,22-32\n33-73,11-72\n14-75,11-11\n97-97,5-98\n28-29,29-30\n90-99,23-47\n83-84,1-83\n3-92,2-4\n3-4,4-96\n96-97,28-91\n23-52,22-53\n67-67,66-68\n23-91,22-92\n2-99,2-99\n3-41,2-94\n36-87,59-86\n69-77,69-77\n9-99,8-99\n4-96,3-96\n52-52,21-51\n19-89,18-53\n86-87,29-87\n18-65,25-54\n62-82,4-61\n49-94,49-93\n95-98,5-96\n22-87,22-49\n98-98,41-99\n8-93,7-96\n67-72,67-73\n29-62,50-78\n4-95,95-96\n29-90,16-89\n2-75,74-74\n54-56,30-57\n1-95,1-95\n7-98,8-8\n83-90,40-92\n50-93,49-94\n34-47,46-47\n72-87,72-75\n26-69,27-69\n15-58,14-16\n14-63,17-99\n9-87,9-86\n1-99,3-97\n45-51,34-63\n24-43,13-13\n5-20,4-21\n5-75,6-6\n99-99,8-97\n12-40,11-85\n26-85,27-84\n5-86,6-6\n22-82,22-81\n42-94,43-75\n6-7,6-96\n5-92,4-92\n32-37,32-38\n64-87,65-82\n58-63,60-60\n15-97,15-91\n10-17,16-45\n70-71,49-71\n2-34,29-35\n7-81,6-7\n36-88,37-54\n81-86,76-87\n2-93,2-5\n33-89,88-88\n25-37,18-36\n11-56,12-55\n8-91,7-95\n5-83,6-66\n65-97,19-66\n60-81,80-82\n23-94,1-93\n42-91,41-92\n79-94,79-93\n3-99,2-17\n75-75,24-76\n16-61,16-76\n33-75,34-74\n32-88,87-88\n4-26,24-27\n36-46,40-50\n15-76,5-11\n2-12,3-12\n3-97,4-92\n9-21,20-20\n9-95,66-94\n14-92,14-25\n33-49,20-48\n31-67,35-68\n1-97,96-96\n35-35,34-92\n57-86,56-72\n68-85,53-86\n80-87,67-89\n94-94,5-94\n65-84,84-91\n11-99,7-9\n20-92,21-82\n3-61,1-3\n34-59,33-58\n12-98,13-13\n80-80,13-80\n55-97,54-98\n59-76,3-77\n8-97,7-74\n45-46,43-45\n60-81,9-82\n4-88,25-87\n5-97,96-96\n39-70,25-51\n44-61,41-42\n33-36,33-34\n91-92,6-91\n39-53,43-53\n9-31,30-32\n60-96,59-98\n17-98,17-17\n41-41,40-43\n16-44,35-44\n42-42,14-43\n1-5,5-98\n18-87,33-87\n56-56,46-57\n6-99,2-98\n9-22,10-10\n14-15,15-61\n17-82,18-34\n95-98,14-95\n81-81,38-82\n30-50,39-46\n94-94,6-95\n14-54,15-53\n3-80,2-4\n55-55,54-98\n99-99,2-99\n70-70,9-71\n8-20,9-9\n1-98,98-99\n31-71,63-71\n74-97,25-97\n4-61,61-61\n37-58,38-53\n15-20,14-15\n44-79,45-80\n45-68,29-75\n24-94,19-98\n42-86,9-41\n75-89,70-75\n25-55,6-25\n41-69,40-41\n6-96,4-4\n20-94,93-94\n16-69,2-68\n76-78,47-77\n7-54,3-36\n2-38,1-98\n4-16,16-16\n1-99,88-99\n12-35,15-35\n14-98,13-99\n60-61,8-61\n26-68,58-67\n28-98,28-95\n13-15,14-30\n23-41,24-24\n33-88,14-81\n36-94,3-67\n16-74,73-74\n83-93,3-94\n3-65,6-66\n31-93,32-32\n30-54,41-54\n9-77,76-96\n11-12,11-74\n14-14,19-72\n34-60,33-61\n3-4,3-25\n3-75,75-76\n28-99,29-97\n29-85,30-84\n21-31,24-29\n10-35,10-11\n92-98,56-93\n3-96,95-96\n36-55,36-90\n4-91,5-91\n1-93,92-98\n21-37,22-36\n9-32,30-33\n46-83,47-89\n31-63,30-32\n28-54,58-66\n33-97,33-97\n71-80,59-79\n11-97,12-98\n68-69,66-70\n9-62,6-46\n50-92,50-91\n5-19,18-77\n23-25,19-25\n2-11,3-15\n11-92,12-92\n21-99,22-87\n57-92,56-93\n12-91,2-9\n6-13,1-14\n8-92,9-91\n7-38,4-71\n2-11,2-80\n6-99,6-99\n23-56,55-65\n44-78,54-77\n47-63,48-63\n9-81,8-31\n67-84,67-87\n2-74,3-73\n3-11,10-97\n18-20,21-99\n92-92,34-93\n44-95,33-94\n4-61,14-61\n4-97,1-97\n79-88,80-90\n13-93,10-97\n16-44,15-44\n47-90,8-75\n17-59,8-60\n11-87,4-11\n4-64,4-69\n66-67,67-91\n48-67,49-66\n26-50,25-51\n4-91,4-91\n60-60,59-83\n1-1,1-16\n4-15,16-16\n68-72,67-68\n42-84,41-85\n22-73,18-72\n50-51,51-78\n6-98,6-97\n72-83,72-86\n1-98,1-97\n6-28,6-79\n27-82,81-82\n3-72,2-3\n2-97,6-66\n9-92,8-44\n3-6,5-65\n85-86,30-86\n75-97,8-69\n5-60,6-6\n9-64,8-76\n36-88,41-92\n1-57,57-57\n76-92,75-93\n18-85,2-18\n18-68,14-31\n48-49,11-48\n86-86,15-87\n41-93,42-92\n9-40,10-39\n5-6,6-86\n2-38,24-84\n16-90,7-17\n19-63,18-64\n6-97,78-99\n19-48,20-93\n6-8,7-55\n3-74,2-73\n5-22,6-6\n6-84,6-92\n30-30,30-82\n17-37,16-37\n82-89,5-98\n49-98,97-98\n6-19,18-20\n6-95,5-95\n10-46,29-45\n5-84,6-83\n97-97,21-98\n57-83,58-82\n21-59,45-60\n2-98,1-99\n52-56,9-51\n71-86,44-87\n3-81,2-82\n53-94,80-93\n1-83,2-84\n31-32,31-84\n79-87,80-87\n77-79,6-78\n27-88,18-73\n77-93,6-94\n76-76,8-76\n36-38,34-39\n20-37,9-20\n33-34,34-99\n22-98,98-99\n97-98,5-98\n1-40,2-40\n62-93,62-93\n47-94,48-94\n5-89,1-5\n5-62,23-61\n7-60,8-59\n88-89,43-88\n3-95,94-95\n18-31,6-31\n60-73,48-74\n5-56,5-56\n33-78,34-55\n33-37,34-36\n2-68,2-68\n80-82,13-84\n73-73,63-73\n54-70,53-96\n7-16,8-48\n39-79,39-80\n12-37,13-67\n4-72,5-71\n77-88,34-78\n40-74,40-74\n97-98,97-97\n31-92,32-32\n37-61,28-61\n1-91,2-91\n31-58,4-13\n27-80,60-80\n33-94,33-94\n67-72,13-90\n31-51,30-52\n18-90,18-90\n33-43,33-44\n23-98,33-97\n13-45,12-49\n89-90,54-90\n4-60,4-59\n5-92,6-85\n19-23,9-22\n8-96,1-8\n37-87,23-37\n30-62,31-61\n29-79,29-79\n27-96,23-95\n5-99,6-97\n92-93,4-93\n13-36,35-78\n32-48,32-47\n17-96,99-99\n4-98,98-98\n17-17,17-92\n79-84,11-85\n34-95,33-95\n10-79,8-80\n7-32,27-27\n3-98,2-99\n3-63,2-64\n22-98,13-21\n9-20,19-96\n62-97,60-74\n14-86,13-14\n15-90,15-91\n11-92,10-89\n93-98,7-94\n1-75,8-63\n3-92,4-59\n54-72,72-72\n52-84,84-89\n55-55,55-72\n5-5,4-52\n21-84,66-75\n13-18,7-87\n82-83,6-82\n19-66,11-12\n69-96,69-95\n3-98,36-97\n12-31,6-12\n21-49,14-18\n35-97,8-97\n16-82,81-82\n4-92,4-99\n68-79,19-67\n36-56,77-83\n46-47,29-46\n91-92,21-91\n2-2,1-90\n61-93,39-74\n6-33,33-33\n7-95,2-7\n59-60,53-60\n7-90,4-8\n94-94,84-95\n69-85,68-94\n9-73,9-73\n47-99,48-99\n7-37,7-7\n3-3,2-74\n18-18,17-28\n25-51,46-50\n1-98,1-99\n48-80,49-56\n16-94,93-95\n59-83,60-82\n16-79,78-78\n24-26,29-85\n10-77,10-11\n4-96,4-48\n44-97,43-87\n33-71,70-71\n27-57,26-57\n30-53,16-31\n15-68,14-69\n14-95,7-94\n82-82,15-81\n22-40,22-23\n6-94,53-65\n76-95,77-83\n12-83,13-82\n41-94,40-98\n37-58,38-58\n7-91,1-6\n23-68,34-67\n27-97,96-96\n56-57,56-57\n1-61,3-7\n28-55,27-55\n32-32,31-56\n13-76,13-76\n10-18,11-56\n5-99,2-5\n7-80,14-39\n16-82,81-82\n4-24,2-4\n2-97,97-98\n24-88,87-88\n28-95,29-96\n56-72,57-71\n71-73,1-72\n52-98,51-98\n4-57,57-58\n82-83,40-82\n54-78,29-77\n10-25,25-26\n46-89,87-88\n59-89,68-89\n84-86,57-84\n24-94,54-93\n41-63,40-63\n87-90,89-90\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_04_questions.txt",
    "content": "--- Day 4: Camp Cleanup ---\n\nSpace needs to be cleared before the last supplies can be unloaded\nfrom the ships, and so several Elves have been assigned the job of\ncleaning up sections of the camp. Every section has a unique ID number,\nand each Elf is assigned a range of section IDs.\n\nHowever, as some of the Elves compare their section assignments with\neach other, they've noticed that many of the assignments overlap.\nTo try to quickly find overlaps and reduce duplicated effort, the Elves\npair up and make a big list of the section assignments for\neach pair (your puzzle input).\n\nFor example, consider the following list of section assignment pairs:\n\n2-4,6-8\n2-3,4-5\n5-7,7-9\n2-8,3-7\n6-6,4-6\n2-6,4-8\n\nFor the first few pairs, this list means:\n\n    Within the first pair of Elves, the first Elf was assigned\n      sections 2-4 (sections 2, 3, and 4), while the second Elf was\n      assigned sections 6-8 (sections 6, 7, 8).\n\n    The Elves in the second pair were each assigned two sections.\n\n    The Elves in the third pair were each assigned three sections:\n      one got sections 5, 6, and 7, while the other also\n      got 7, plus 8 and 9.\n\nThis example list uses single-digit section IDs to make it easier\nto draw; your actual list might contain larger numbers. Visually,\nthese pairs of section assignments look like this:\n\n.234.....  2-4\n.....678.  6-8\n\n.23......  2-3\n...45....  4-5\n\n....567..  5-7\n......789  7-9\n\n.2345678.  2-8\n..34567..  3-7\n\n.....6...  6-6\n...456...  4-6\n\n.23456...  2-6\n...45678.  4-8\n\nSome of the pairs have noticed that one of their assignments fully\ncontains the other. For example, 2-8 fully contains 3-7, and 6-6 is\nfully contained by 4-6. In pairs where one assignment fully contains\nthe other, one Elf in the pair would be exclusively cleaning sections\ntheir partner will already be cleaning, so these seem like the most\nin need of reconsideration. In this example, there are 2 such pairs.\n\nIn how many assignment pairs does one range fully contain the other?\n\n--- Part Two ---\n\nIt seems like there is still quite a bit of duplicate work planned.\nInstead, the Elves would like to know the number of pairs that\noverlap at all.\n\nIn the above example, the first two pairs (2-4,6-8 and 2-3,4-5)\ndon't overlap, while the remaining four pairs (5-7,7-9, 2-8,3-7,\n6-6,4-6, and 2-6,4-8) do overlap:\n\n    5-7,7-9 overlaps in a single section, 7.\n    2-8,3-7 overlaps all of the sections 3 through 7.\n    6-6,4-6 overlaps in a single section, 6.\n    2-6,4-8 overlaps in sections 4, 5, and 6.\n\nSo, in this example, the number of overlapping assignment pairs is 4.\n\nIn how many assignment pairs do the ranges overlap?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_05.adb",
    "content": "--  Solution to Advent of Code 2022, Day 5\n------------------------------------------\n--  Supply Stacks\n--\n--  https://adventofcode.com/2022/day/5\n--  Copy of questions in: aoc_2022_05_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_05 is\n  use HAT;\n\n  type Storage is array (1 .. 100) of Character;\n\n  type Stack is record\n    top : Natural;\n    s   : Storage;\n  end record;\n\n  subtype Crane_Range is Integer range 1 .. 9;\n\n  s : array (Crane_Range) of Stack;\n\n  procedure Show (title : VString) is\n    empty : Boolean;\n  begin\n    Put_Line (title);\n    New_Line;\n    for y in reverse 1 .. Storage'Last loop\n      empty := True;\n      for x in s'Range loop\n        empty := empty and y > s (x).top;\n      end loop;\n      if not empty then\n        for x in s'Range loop\n          if y > s (x).top then\n            Put (\"    \");\n          else\n            Put (+'[' & s (x).s (y) & \"] \");\n          end if;\n        end loop;\n        New_Line;\n      end if;\n    end loop;\n    Put_Line ((4 * s'Length - 1) * '-');\n    New_Line;\n  end Show;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of String (Crane_Range);\n\n  c, sep, bra, ket : Character;\n  move : String (1 .. 4);\n  from : String (1 .. 5);\n  to   : String (1 .. 4);\n  a, b, n : Integer;\n  max_y : Natural := 0;\n  name : constant VString := +\"aoc_2022_05.txt\";\n  f : File_Type;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := not compiler_test_mode;\n\nbegin\n  --  Get the maximum height of the crates stacks:\n  Open (f, name);\n  while not End_Of_File (f) loop\n    Get (f, sep);\n    Get (f, c);\n    exit when c in '1' .. '9';\n    max_y := max_y + 1;\n    Skip_Line (f);\n  end loop;\n  Close (f);\n  --\nParts :\n  for part in 1 .. 2 loop\n    for x in s'Range loop\n      s (x).top := 0;\n    end loop;\n    --  Get the initial setup of the crates:\n    Open (f, name);\n    for y in reverse 1 .. max_y loop\n      for x in s'Range loop\n        Get (f, bra);\n        Get (f, c);\n        if c in 'A' .. 'Z' then\n          s (x).s (y) := c;\n          s (x).top := Max (s (x).top, y);\n        end if;\n        Get (f, ket);\n        if x < s'Last then\n          Get (f, sep);\n        end if;\n      end loop;\n    end loop;\n    if verbose and part = 1 then\n      Show (+\"Data:\");\n    end if;\n    --  Skip the \"1 2 3 ...\" line and the next empty one:\n    Skip_Line (f, 2);\n    --  Read and execute the instructions for moving crates:\n    while not End_Of_File (f) loop\n      --  Read line \"move n from a to b\":\n      Get (f, move);\n      Get (f, n);\n      Get (f, from);\n      Get (f, a);\n      Get (f, to);\n      Get (f, b);\n      for count in 1 .. n loop\n        case part is\n          when 1 =>\n            --  CrateMover 9000\n            --  Move one by one, taking each crate `c` from the top, downwards:\n            c := s (a).s (s (a).top - count + 1);\n          when 2 =>\n            --  CrateMover 9001\n            --  Move the crates \"stack-wise\":\n            c := s (a).s (s (a).top - n + count);\n        end case;\n        s (b).s (s (b).top + count) := c;\n      end loop;\n      s (a).top := s (a).top - n;\n      s (b).top := s (b).top + n;\n    end loop;\n    Close (f);\n    if verbose then\n      Show (+\"Result, part \" & part & ':');\n    end if;\n    for x in s'Range loop\n      r (part)(x) := s (x).s (s (x).top);\n    end loop;\n  end loop Parts;\n  --\n  if compiler_test_mode then\n    if +r (1) /= Argument (1) or +r (2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Top crates after...\");\n    Put_Line (+\" (part 1) one-by-one moves: \" & r (1));\n    Put_Line (+\" (part 2) stack-wise moves: \" & r (2));\n    --  Part 1: validated by AoC: VQZNJMWTR\n    --  Part 2: validated by AoC: NLCDCLVMQ\n  end if;\nend AoC_2022_05;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_05.txt",
    "content": "            [L] [M]         [M]    \n        [D] [R] [Z]         [C] [L]\n        [C] [S] [T] [G]     [V] [M]\n[R]     [L] [Q] [B] [B]     [D] [F]\n[H] [B] [G] [D] [Q] [Z]     [T] [J]\n[M] [J] [H] [M] [P] [S] [V] [L] [N]\n[P] [C] [N] [T] [S] [F] [R] [G] [Q]\n[Z] [P] [S] [F] [F] [T] [N] [P] [W]\n 1   2   3   4   5   6   7   8   9 \n\nmove 7 from 3 to 9\nmove 5 from 8 to 9\nmove 3 from 9 to 5\nmove 6 from 9 to 2\nmove 9 from 9 to 3\nmove 3 from 7 to 3\nmove 8 from 2 to 3\nmove 9 from 3 to 1\nmove 11 from 3 to 8\nmove 5 from 6 to 9\nmove 1 from 6 to 3\nmove 1 from 2 to 7\nmove 1 from 4 to 8\nmove 1 from 3 to 9\nmove 4 from 4 to 3\nmove 6 from 8 to 3\nmove 2 from 8 to 2\nmove 4 from 9 to 3\nmove 3 from 2 to 5\nmove 2 from 5 to 4\nmove 5 from 3 to 4\nmove 11 from 1 to 4\nmove 1 from 7 to 6\nmove 1 from 3 to 5\nmove 2 from 1 to 9\nmove 1 from 1 to 4\nmove 7 from 5 to 8\nmove 21 from 4 to 6\nmove 6 from 6 to 2\nmove 6 from 8 to 9\nmove 5 from 8 to 5\nmove 2 from 2 to 7\nmove 4 from 3 to 7\nmove 1 from 2 to 6\nmove 1 from 2 to 5\nmove 2 from 2 to 7\nmove 4 from 3 to 7\nmove 1 from 4 to 6\nmove 9 from 5 to 3\nmove 7 from 3 to 4\nmove 7 from 7 to 3\nmove 7 from 4 to 1\nmove 8 from 3 to 5\nmove 1 from 3 to 5\nmove 3 from 8 to 2\nmove 2 from 2 to 9\nmove 13 from 9 to 4\nmove 5 from 5 to 3\nmove 4 from 7 to 6\nmove 1 from 7 to 4\nmove 2 from 4 to 2\nmove 3 from 3 to 4\nmove 2 from 5 to 2\nmove 6 from 1 to 7\nmove 1 from 2 to 8\nmove 1 from 3 to 8\nmove 1 from 1 to 6\nmove 1 from 3 to 4\nmove 1 from 2 to 6\nmove 24 from 6 to 1\nmove 3 from 2 to 3\nmove 3 from 3 to 5\nmove 2 from 8 to 6\nmove 2 from 5 to 4\nmove 3 from 5 to 1\nmove 7 from 4 to 8\nmove 3 from 8 to 9\nmove 2 from 9 to 5\nmove 2 from 6 to 3\nmove 1 from 9 to 8\nmove 5 from 7 to 5\nmove 2 from 3 to 1\nmove 1 from 7 to 1\nmove 7 from 4 to 7\nmove 2 from 4 to 8\nmove 6 from 8 to 6\nmove 3 from 6 to 9\nmove 10 from 5 to 1\nmove 7 from 7 to 1\nmove 1 from 4 to 9\nmove 1 from 6 to 3\nmove 2 from 9 to 7\nmove 1 from 4 to 2\nmove 1 from 9 to 5\nmove 1 from 8 to 5\nmove 39 from 1 to 8\nmove 1 from 2 to 5\nmove 2 from 6 to 9\nmove 3 from 9 to 5\nmove 3 from 1 to 6\nmove 1 from 7 to 2\nmove 1 from 3 to 2\nmove 2 from 6 to 2\nmove 3 from 2 to 3\nmove 1 from 6 to 2\nmove 1 from 1 to 8\nmove 3 from 1 to 2\nmove 3 from 2 to 4\nmove 2 from 4 to 5\nmove 2 from 3 to 8\nmove 8 from 5 to 2\nmove 8 from 8 to 2\nmove 15 from 2 to 7\nmove 1 from 1 to 5\nmove 25 from 8 to 7\nmove 2 from 2 to 4\nmove 2 from 4 to 3\nmove 1 from 8 to 4\nmove 2 from 4 to 6\nmove 1 from 2 to 1\nmove 26 from 7 to 2\nmove 15 from 2 to 1\nmove 7 from 8 to 9\nmove 10 from 1 to 6\nmove 10 from 7 to 2\nmove 1 from 8 to 1\nmove 5 from 9 to 8\nmove 1 from 8 to 9\nmove 2 from 6 to 9\nmove 3 from 7 to 1\nmove 1 from 7 to 1\nmove 5 from 9 to 2\nmove 1 from 3 to 1\nmove 9 from 6 to 3\nmove 1 from 6 to 1\nmove 4 from 2 to 4\nmove 3 from 4 to 8\nmove 1 from 4 to 1\nmove 9 from 3 to 1\nmove 1 from 7 to 6\nmove 9 from 2 to 5\nmove 14 from 1 to 6\nmove 1 from 3 to 8\nmove 5 from 2 to 6\nmove 8 from 1 to 8\nmove 6 from 6 to 8\nmove 14 from 6 to 7\nmove 1 from 1 to 7\nmove 10 from 5 to 4\nmove 11 from 8 to 5\nmove 15 from 7 to 1\nmove 4 from 5 to 6\nmove 4 from 8 to 9\nmove 6 from 5 to 3\nmove 1 from 6 to 9\nmove 1 from 1 to 6\nmove 1 from 5 to 8\nmove 2 from 6 to 2\nmove 6 from 1 to 5\nmove 1 from 5 to 8\nmove 2 from 5 to 4\nmove 9 from 2 to 9\nmove 13 from 9 to 8\nmove 1 from 2 to 1\nmove 1 from 4 to 8\nmove 3 from 3 to 1\nmove 2 from 4 to 5\nmove 2 from 1 to 5\nmove 1 from 9 to 3\nmove 17 from 8 to 1\nmove 3 from 3 to 2\nmove 4 from 5 to 1\nmove 2 from 2 to 4\nmove 1 from 6 to 1\nmove 1 from 2 to 8\nmove 4 from 4 to 6\nmove 1 from 5 to 9\nmove 5 from 6 to 8\nmove 1 from 5 to 4\nmove 1 from 5 to 6\nmove 3 from 8 to 6\nmove 8 from 4 to 5\nmove 32 from 1 to 7\nmove 11 from 7 to 6\nmove 8 from 5 to 3\nmove 3 from 8 to 7\nmove 6 from 3 to 9\nmove 4 from 3 to 8\nmove 5 from 8 to 2\nmove 1 from 8 to 5\nmove 11 from 6 to 3\nmove 1 from 5 to 2\nmove 2 from 8 to 6\nmove 12 from 7 to 8\nmove 2 from 6 to 2\nmove 2 from 6 to 4\nmove 5 from 2 to 5\nmove 8 from 7 to 2\nmove 2 from 7 to 1\nmove 2 from 7 to 6\nmove 5 from 5 to 4\nmove 5 from 4 to 7\nmove 5 from 8 to 2\nmove 2 from 9 to 7\nmove 5 from 8 to 4\nmove 2 from 7 to 3\nmove 2 from 9 to 3\nmove 3 from 7 to 9\nmove 1 from 1 to 8\nmove 2 from 6 to 1\nmove 2 from 9 to 8\nmove 1 from 7 to 8\nmove 1 from 2 to 5\nmove 1 from 7 to 9\nmove 7 from 4 to 3\nmove 3 from 3 to 6\nmove 5 from 8 to 6\nmove 3 from 9 to 5\nmove 16 from 3 to 1\nmove 2 from 9 to 1\nmove 7 from 1 to 8\nmove 1 from 1 to 2\nmove 5 from 8 to 2\nmove 12 from 1 to 4\nmove 1 from 3 to 5\nmove 1 from 2 to 9\nmove 1 from 9 to 4\nmove 4 from 6 to 5\nmove 5 from 6 to 1\nmove 1 from 6 to 5\nmove 1 from 1 to 4\nmove 1 from 4 to 7\nmove 1 from 3 to 7\nmove 9 from 4 to 6\nmove 2 from 7 to 8\nmove 1 from 3 to 4\nmove 2 from 8 to 9\nmove 4 from 8 to 4\nmove 4 from 2 to 8\nmove 2 from 9 to 7\nmove 2 from 7 to 8\nmove 10 from 2 to 4\nmove 1 from 2 to 1\nmove 5 from 4 to 7\nmove 1 from 1 to 3\nmove 3 from 8 to 7\nmove 6 from 7 to 2\nmove 3 from 2 to 7\nmove 1 from 6 to 7\nmove 5 from 5 to 8\nmove 4 from 1 to 3\nmove 4 from 3 to 1\nmove 8 from 4 to 2\nmove 1 from 3 to 2\nmove 2 from 7 to 2\nmove 2 from 6 to 3\nmove 4 from 7 to 2\nmove 4 from 5 to 7\nmove 14 from 2 to 7\nmove 3 from 2 to 1\nmove 3 from 8 to 2\nmove 1 from 5 to 7\nmove 6 from 2 to 4\nmove 2 from 2 to 7\nmove 2 from 3 to 6\nmove 6 from 8 to 2\nmove 4 from 6 to 4\nmove 2 from 6 to 9\nmove 4 from 4 to 2\nmove 2 from 4 to 8\nmove 10 from 7 to 2\nmove 18 from 2 to 6\nmove 2 from 2 to 6\nmove 2 from 9 to 2\nmove 2 from 8 to 5\nmove 1 from 2 to 9\nmove 1 from 2 to 9\nmove 1 from 5 to 7\nmove 1 from 2 to 6\nmove 2 from 9 to 2\nmove 6 from 7 to 3\nmove 7 from 6 to 8\nmove 5 from 7 to 2\nmove 1 from 7 to 4\nmove 1 from 5 to 7\nmove 4 from 8 to 7\nmove 5 from 2 to 3\nmove 1 from 7 to 5\nmove 2 from 2 to 8\nmove 9 from 4 to 3\nmove 13 from 6 to 8\nmove 10 from 3 to 1\nmove 1 from 5 to 2\nmove 3 from 6 to 8\nmove 5 from 1 to 2\nmove 1 from 1 to 8\nmove 2 from 4 to 3\nmove 17 from 8 to 6\nmove 5 from 6 to 3\nmove 3 from 1 to 2\nmove 9 from 6 to 5\nmove 2 from 6 to 8\nmove 5 from 5 to 9\nmove 3 from 9 to 8\nmove 3 from 1 to 3\nmove 3 from 7 to 5\nmove 6 from 5 to 8\nmove 7 from 2 to 4\nmove 1 from 6 to 3\nmove 1 from 1 to 5\nmove 4 from 4 to 5\nmove 2 from 2 to 9\nmove 3 from 1 to 3\nmove 4 from 5 to 8\nmove 1 from 4 to 5\nmove 6 from 8 to 7\nmove 1 from 5 to 2\nmove 4 from 9 to 2\nmove 2 from 5 to 9\nmove 2 from 1 to 8\nmove 2 from 4 to 9\nmove 6 from 7 to 5\nmove 3 from 5 to 2\nmove 3 from 2 to 5\nmove 10 from 8 to 3\nmove 2 from 8 to 5\nmove 3 from 2 to 5\nmove 6 from 5 to 1\nmove 4 from 5 to 6\nmove 1 from 7 to 5\nmove 23 from 3 to 7\nmove 2 from 5 to 9\nmove 2 from 1 to 5\nmove 2 from 6 to 3\nmove 6 from 3 to 1\nmove 1 from 1 to 7\nmove 4 from 3 to 1\nmove 1 from 8 to 5\nmove 2 from 9 to 2\nmove 3 from 3 to 8\nmove 2 from 6 to 8\nmove 12 from 1 to 3\nmove 1 from 9 to 7\nmove 3 from 5 to 9\nmove 9 from 3 to 8\nmove 1 from 1 to 7\nmove 1 from 9 to 4\nmove 3 from 3 to 6\nmove 3 from 2 to 1\nmove 3 from 8 to 6\nmove 1 from 4 to 2\nmove 1 from 2 to 9\nmove 1 from 2 to 7\nmove 20 from 7 to 5\nmove 3 from 7 to 3\nmove 3 from 1 to 3\nmove 5 from 8 to 1\nmove 5 from 1 to 5\nmove 4 from 5 to 2\nmove 3 from 2 to 6\nmove 3 from 8 to 7\nmove 1 from 2 to 6\nmove 2 from 8 to 6\nmove 2 from 7 to 5\nmove 2 from 3 to 6\nmove 12 from 5 to 1\nmove 6 from 5 to 7\nmove 12 from 6 to 8\nmove 4 from 9 to 3\nmove 4 from 5 to 8\nmove 3 from 1 to 5\nmove 4 from 7 to 4\nmove 3 from 5 to 9\nmove 7 from 1 to 6\nmove 1 from 1 to 3\nmove 6 from 7 to 6\nmove 1 from 1 to 3\nmove 10 from 3 to 6\nmove 10 from 6 to 2\nmove 2 from 9 to 5\nmove 4 from 6 to 5\nmove 9 from 6 to 1\nmove 16 from 8 to 7\nmove 3 from 8 to 7\nmove 1 from 8 to 1\nmove 7 from 2 to 1\nmove 1 from 5 to 9\nmove 1 from 6 to 1\nmove 2 from 2 to 1\nmove 3 from 1 to 4\nmove 1 from 6 to 8\nmove 7 from 4 to 1\nmove 1 from 8 to 2\nmove 22 from 1 to 8\nmove 18 from 7 to 9\nmove 6 from 5 to 2\nmove 2 from 2 to 7\nmove 2 from 1 to 5\nmove 4 from 7 to 6\nmove 1 from 5 to 6\nmove 2 from 8 to 2\nmove 3 from 2 to 6\nmove 1 from 5 to 6\nmove 15 from 9 to 6\nmove 6 from 9 to 5\nmove 1 from 9 to 8\nmove 1 from 2 to 9\nmove 5 from 5 to 9\nmove 9 from 8 to 6\nmove 3 from 2 to 7\nmove 12 from 8 to 9\nmove 1 from 7 to 5\nmove 1 from 5 to 7\nmove 3 from 7 to 1\nmove 17 from 6 to 3\nmove 1 from 2 to 6\nmove 2 from 1 to 4\nmove 16 from 6 to 4\nmove 7 from 4 to 6\nmove 1 from 5 to 7\nmove 8 from 4 to 5\nmove 9 from 9 to 8\nmove 16 from 3 to 7\nmove 1 from 1 to 5\nmove 3 from 5 to 1\nmove 5 from 6 to 2\nmove 3 from 1 to 7\nmove 3 from 6 to 7\nmove 3 from 9 to 3\nmove 5 from 8 to 5\nmove 11 from 5 to 7\nmove 2 from 3 to 7\nmove 1 from 2 to 1\nmove 1 from 3 to 6\nmove 17 from 7 to 9\nmove 1 from 3 to 2\nmove 3 from 4 to 6\nmove 1 from 1 to 2\nmove 1 from 6 to 4\nmove 14 from 7 to 6\nmove 15 from 9 to 6\nmove 4 from 8 to 7\nmove 1 from 4 to 7\nmove 7 from 9 to 5\nmove 5 from 2 to 9\nmove 7 from 5 to 1\nmove 3 from 1 to 7\nmove 29 from 6 to 4\nmove 1 from 2 to 4\nmove 18 from 4 to 2\nmove 3 from 1 to 4\nmove 1 from 1 to 7\nmove 18 from 2 to 4\nmove 3 from 6 to 5\nmove 15 from 4 to 1\nmove 1 from 5 to 1\nmove 1 from 5 to 4\nmove 9 from 4 to 1\nmove 5 from 1 to 3\nmove 9 from 1 to 5\nmove 2 from 4 to 3\nmove 5 from 5 to 6\nmove 3 from 7 to 9\nmove 7 from 7 to 5\nmove 6 from 4 to 6\nmove 2 from 3 to 7\nmove 6 from 5 to 8\nmove 2 from 8 to 4\nmove 1 from 8 to 9\nmove 9 from 6 to 2\nmove 3 from 9 to 3\nmove 1 from 2 to 1\nmove 6 from 7 to 4\nmove 2 from 2 to 8\nmove 3 from 9 to 5\nmove 5 from 4 to 8\nmove 1 from 6 to 9\nmove 1 from 3 to 1\nmove 1 from 3 to 4\nmove 1 from 6 to 5\nmove 1 from 9 to 3\nmove 10 from 8 to 7\nmove 3 from 9 to 2\nmove 7 from 2 to 4\nmove 6 from 5 to 7\nmove 4 from 5 to 8\nmove 7 from 3 to 2\nmove 3 from 7 to 1\nmove 9 from 1 to 5\nmove 5 from 7 to 9\nmove 7 from 1 to 4\nmove 11 from 4 to 2\nmove 4 from 8 to 3\nmove 5 from 4 to 7\nmove 4 from 4 to 1\nmove 1 from 3 to 6\nmove 12 from 7 to 4\nmove 2 from 1 to 8\nmove 5 from 9 to 7\nmove 7 from 5 to 6\nmove 1 from 1 to 4\nmove 1 from 9 to 8\nmove 1 from 4 to 7\nmove 1 from 8 to 9\nmove 5 from 7 to 9\nmove 2 from 7 to 5\nmove 2 from 6 to 3\nmove 5 from 2 to 7\nmove 1 from 7 to 8\nmove 1 from 1 to 6\nmove 3 from 5 to 1\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_05_questions.txt",
    "content": "--- Day 5: Supply Stacks ---\n\nThe expedition can depart as soon as the final supplies have been\nunloaded from the ships. Supplies are stored in stacks of marked\ncrates, but because the needed supplies are buried under many other\ncrates, the crates need to be rearranged.\n\nThe ship has a giant cargo crane capable of moving crates between\nstacks. To ensure none of the crates get crushed or fall over, the\ncrane operator will rearrange them in a series of carefully-planned\nsteps. After the crates are rearranged, the desired crates will be\nat the top of each stack.\n\nThe Elves don't want to interrupt the crane operator during this\ndelicate procedure, but they forgot to ask her which crate will\nend up where, and they want to be ready to unload them as soon\nas possible so they can embark.\n\nThey do, however, have a drawing of the starting stacks of crates\nand the rearrangement procedure (your puzzle input). For example:\n\n    [D]    \n[N] [C]    \n[Z] [M] [P]\n 1   2   3 \n\nmove 1 from 2 to 1\nmove 3 from 1 to 3\nmove 2 from 2 to 1\nmove 1 from 1 to 2\n\nIn this example, there are three stacks of crates.\nStack 1 contains two crates: crate Z is on the bottom,\nand crate N is on top.\nStack 2 contains three crates; from bottom to top, they\nare crates M, C, and D.\nFinally, stack 3 contains a single crate, P.\n\nThen, the rearrangement procedure is given.\nIn each step of the procedure, a quantity of crates is moved\nfrom one stack to a different stack. In the first step of the\nabove rearrangement procedure, one crate is moved from\nstack 2 to stack 1, resulting in this configuration:\n\n[D]        \n[N] [C]    \n[Z] [M] [P]\n 1   2   3 \n\nIn the second step, three crates are moved from stack 1 to stack 3.\nCrates are moved one at a time, so the first crate to be moved (D)\nends up below the second and third crates:\n\n        [Z]\n        [N]\n    [C] [D]\n    [M] [P]\n 1   2   3\n\nThen, both crates are moved from stack 2 to stack 1.\nAgain, because crates are moved one at a time,\ncrate C ends up below crate M:\n\n        [Z]\n        [N]\n[M]     [D]\n[C]     [P]\n 1   2   3\n\nFinally, one crate is moved from stack 1 to stack 2:\n\n        [Z]\n        [N]\n        [D]\n[C] [M] [P]\n 1   2   3\n\nThe Elves just need to know which crate will end up on top of each\nstack; in this example, the top crates are C in stack 1, M in stack 2,\nand Z in stack 3, so you should combine these together and give\nthe Elves the message CMZ.\n\nAfter the rearrangement procedure completes, what crate ends\nup on top of each stack?\n\n--- Part Two ---\n\nAs you watch the crane operator expertly rearrange the crates,\nyou notice the process isn't following your prediction.\n\nSome mud was covering the writing on the side of the crane, and\nyou quickly wipe it away. The crane isn't a CrateMover 9000 -\nit's a CrateMover 9001.\n\nThe CrateMover 9001 is notable for many new and exciting features:\nair conditioning, leather seats, an extra cup holder, and the ability\nto pick up and move multiple crates at once.\n\nAgain considering the example above, the crates begin in the\nsame configuration:\n\n    [D]    \n[N] [C]    \n[Z] [M] [P]\n 1   2   3 \n\nMoving a single crate from stack 2 to stack 1 behaves the\nsame as before:\n\n[D]        \n[N] [C]    \n[Z] [M] [P]\n 1   2   3 \n\nHowever, the action of moving three crates from stack 1 to\nstack 3 means that those three moved crates stay in the same\norder, resulting in this new configuration:\n\n        [D]\n        [N]\n    [C] [Z]\n    [M] [P]\n 1   2   3\n\nNext, as both crates are moved from stack 2 to stack 1, they\nretain their order as well:\n\n        [D]\n        [N]\n[C]     [Z]\n[M]     [P]\n 1   2   3\n\nFinally, a single crate is still moved from stack 1 to stack 2,\nbut now it's crate C that gets moved:\n\n        [D]\n        [N]\n        [Z]\n[M] [C] [P]\n 1   2   3\n\nIn this example, the CrateMover 9001 has put the crates in a\ntotally different order: MCD.\n\nBefore the rearrangement process finishes, update your simulation\nso that the Elves know where they should stand to be ready to unload\nthe final supplies. After the rearrangement procedure completes,\nwhat crate ends up on top of each stack?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_06.adb",
    "content": "--  Solution to Advent of Code 2022, Day 6\n------------------------------------------\n--  Tuning Trouble\n--\n--  https://adventofcode.com/2022/day/6\n--  Copy of questions in: aoc_2022_06_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_06 is\n  use HAT;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\n  f : File_Type;\n  s : VString;\n  s_i : Character;\n  count : array (Character) of Natural;\n  marker_length : Positive;\n  duplicates : Natural;\nbegin\n  Open (f, \"aoc_2022_06.txt\");\n  Get_Line (f, s);\n  Close (f);\nParts :\n  for part in 1 .. 2 loop\n    for c in Character loop\n      count (c) := 0;\n    end loop;\n    duplicates := 0;\n    --\n    for i in 1 .. Length (s) loop\n      s_i := Element (s, i);\n      --  Count occurrences of the character at position i.\n      count (s_i) := count (s_i) + 1;\n      if count (s_i) = 2 then\n        duplicates := duplicates + 1;\n      end if;\n      case part is\n        when 1 => marker_length := 4;\n        when 2 => marker_length := 14;\n      end case;\n      if i >= marker_length then\n        if i > marker_length then\n          --  Forget occurrence of the character that has\n          --  just disappeared from the marker candidate.\n          s_i := Element (s, i - marker_length);\n          count (s_i) := count (s_i) - 1;\n          if count (s_i) = 1 then\n            duplicates := duplicates - 1;\n          end if;\n        end if;\n        if duplicates = 0 then\n          r (part) := i;\n          exit;  --  Leave after first match.\n        end if;\n      end if;\n    end loop;\n  end loop Parts;\n  --\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Number of characters that need to be \" &\n               \" processed before the first...\");\n    Put_Line (+\"  (part 1) start-of-packet marker . . . : \" & r (1));\n    Put_Line (+\"  (part 2) start-of-message marker  . . : \" & r (2));\n    --  Part 1: validated by AoC: 1802\n    --  Part 2: validated by AoC: 3551\n  end if;\nend AoC_2022_06;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_06.txt",
    "content": "qhbhzbzzfrzrbzzcjzjrrvcvrvqvvnggnngcgssswbblplrlflfnnnmmjppgddqndnrnlnccpfcfjcjvjdjqqqmhhmwhwmmsnsvsjvjnvjnvjvsjsmjsjccwcqwcqwqjqwjwmwbmmbzbsbvsslbsbbbntnvvphpqqvrrtbrtrfftppbggpzzfhfcfsfmssffmbmzzmqzzblzzzmwwnggjwgjwgjgpgmmjvvmcvmmcfchfhllwmlljqqldqdqttsgsvscsmsnsmstmtssvgsgddwdffbppwfpplhlchhhdvvdrrmttmptmmmjsmshmmmgqmgggzjgzzmwzwcwhchqqfpfvvbqvbqbrblrrmtmstmmjvmmdnmmzczdzpztppjhjjwzjjjtdjjpljpjcppjllsffhbffbhhgttqjqzzfzbzcbzcbcrrjjrwrgwwbcbpcccctrtqtfqqfjjpgpdgdfgfrggpjjljglgclcqcqmcqmmgjjllpmphpjjgfjjqrrbppwmpmccftctjtjgjtgggzffcggwzzzdjdzzlgzgjzzvqvppczzjnjvvfhhtwtttdwtdtvddpzpnpcnppmvmcmcsmstthctchcggtssdttvztvvldlfftqqbzzjttvzztppscctzccgmcmvmhhchcscbbshbssgwwthwhmwwcgwcwrrvrzvrzzzvhvdvmmprrdmrmfmrmbmjbbmqbmbqqhbbszsjjlqjljtjstshhgphpffdhhtggtgbbqcqgqccfffcpcbpbfppwqpqcclbbwdwsscpchhfpfmpfmflfnnmggwrrznnghgvhhghrrhwrrcschcscqcmcfcvvgzztjtqjjshspsqsmmjnnmttsshvhmmqfqzztbzttvhttmwttnqnfncfcpfflmllmtlmmphmhlmmltmtztcczhzbbfmmlglnnfpppqplljwjfwfdwdzwddszddqzqnzzzwwlzzqvvjlllrwlrrmpmrmbmpplpspqsqmqcmcjjshsvstvvwtvthvvrfvvqmmjpmjmrjmmlvvnnrjjrcrwrhwwqzzvgvngncgcqqcffmfzfssbnbfblbggwhggmtgtvvqhhpttbcbczcjjbqbhqbhqbbccbhbqhbbmppdlpdllbvvdpvdvwvsvppllgblbttmcmtccbsswmswwwzfwfhhtfhthctchcfhhhfjjvhjhgjjjcwjwggrtgrttcqcwcswccfdffvpvtptprrvjjqvjjghggshhwmmcscmsmhmvmppprfrwwrhhvghhtnhncctbbbwzzbgzgdzgdzdpdvpvbbwgbwwrqwrqwqbqvvclccfcfzfdfrrthrrqcqddplpqlppbbfrfmmrmnnwhhgddmwwrzrsswpwhwdwhhsmhshqsqllbvlbllwbwbpwwfwmwsmspsvsdsbscctpctppvvpggtjjdmdqqgqbgglccvzcvcnczcgzgmzznpzzpcpnpvpcvvffrttqrqttflfbfjfnnwnlwlhwwqzqnqfftstdsttglldwwgqwwvqqzczfzdffbfsfssfwswdwnwdnnbcncwctttvsvjsvsrvvbtvvzhhvjvtvtjtsjjvhjjwpjjnzzpczzppgcpgcpgcgsgvsgvsscrcpcpspllzvzddpssssdpsddhffllzmzhzfhhdvhhvbvwwpwqpwqpwwmvwmvwvgvmvpvmpmrmzrrblltjtggvnggvppthhzjhzhffrvrhvrhrlrslsflfhhtvhvmmhppjgpjpcccmqcqvqhvvfssrtmnwjjslwhjgpvrwspjlwdwrmvfgwmplrmjrllndrjzvjfbwvzpjpfqrnjspwcpsgcvdlmfdfrvwdcvmbrnzncgnqlcvgqtpsbbpvprncdsgvpqbpcnffwqmmfsvnzspchhrlnzbhcdfdgtsllmqfbrcqwbmmzrfvsghjpmrndsdbqvtprmblnbvbnpvhtphbpjwdssvwgdzwztbpzdcsqzldjzrgcwhhspblrtncvntppcgttlflflnntcnzpbpgsclcjvbjhldcdzwjjhnfwzjmgcwtljhvbncwqnjhbrhfqcmnsdvntsbgnpqttzvbhzzpdznrhjpnsqzsztsblstbghlpwbmqjctlnqnttwshfvmjdhgbgjdhbzrfjqndrrhlqcmplczjtwpstlsmwwzqzmgvhsvjgbrtfwmvwlbhpccbqvmfmlgmbmbmldbcwmmhpnnbnffbnqgwhclgpzgbpjqvzmqhhhpltnwrdfrrnmlfrzflpnjztlnfzzzgmncprtblpsvrqgrnzbzfzhzhjjjdrnpvjpnwmlmlgvvtqmdvpnhvcrdmthcnnnvhnzmvgrtdvcthgjtvcgmtpsvmfztrflrrzbmcfhftwwcnjfpjtsnzjccmvdnrrwvbfjgcjttdvzncqhlqqphwphclztbhlqcfmnhcjmsscplnrsjqpdzrrzbthbcdnrzgdmstpgqqsvzclvmzjjdfqhhhttwcjtmwcbltghmslqvltqbjqqjpjvgntvnlttjcnhltflglgsmjwjjfldpfgjgrhttbwfhpsdbsmsfmfbtjlnhvjfqjrqhwdrcwpfthdgqzjjjfcvgdffrhvvwzfghpszmjjgscjvjnlgnbfbgfrbbzbzbnzngthrddfmsgsqqdddpfqwlchfblrvjdcgnzfzwmmnmvnzmpfmhbbhsbfdfclzcnbrlgpbsvfgfpshrpvpgccmmghphrcvzwnlqjcfwrtwvlvcsdldldvnpwgrcsqlftllcctnvcwbdswvqlzwzzbpmvvctcrgnjfstbqvnzczrjlljfqzrwtfwmlvvdfbfntrrljtbrtbdfsqpnppfbppbsmghbnqddhrvwmgzttnqjrqlfrdhqjndmnjlbctgclltmznmrqtfjsjwnztdvhnhlfwpnnqlhhsrfzglsnrdnfvrqssbtlthzfnjdvrcgzsbnpdgqhhrlwspfqfqpvzdfwgrlhwplzvbzprsqzcwvhggvzpgjztnvwvddsflgsvqljmmhhdzqsqmthwzvllqwmsnvdpdbjcgdtrsnmwhnzhbhgjssstmhrpssnhnntmrbbbjgmjqtncbdljcgtmbctpgdrnqcnrpssrdtpbsmlzlcztbrggglswnjzqgbsmgbqdzppqrwgtnlrjrvlpnqlcdwhltzzlqdwwrglldzcqrjtjtlgdqrtwzjgtdthsdccsmsrbjjsgdqcwdltvnjwtddsnpnsvzcdbfqnvsjbngqrztmbrnbvhhjzdtqrgldpvjqjpnshbjdsdgbjdjzdmrvzhwmtgcjrfnprstqgfgnwfpcjzhlnwpdbtqbspssqdrzhmmsrqtlwngvbrvgdgztnrlwcnqwvcdmhhdrmpfqbgbjpvzwbsbgcpsnpjplcrjdhflqvsdctclqqnmprngtvbmlmpqrsqdsrzgsmzmsczpsnmfmtfnjvnddjhqbjdvtgftjfvjhgpjqdhlszqjmcbnwrppzwjvmgblspjmfhjdbnmrllnfqlpcbndvqdzhhmmrpsljgdshpnrgnmwfjsdncqcwlctccrqghfdbsqqbnwctcqpvlrqqqvdjwlcnzmvdmcvlwnftjnqqldfwhmdtcpnlgfcdjdrfvmwqdzsjzctmmmrswhlwthttvcsqqscdcsmjgqfjhswlpsfjrppdmbwrthcwszqwwgnjsdqdrswmnzbrvqcwlrlwwvjmrrhsnzprggbzhhdqwvnspsmzzqdtbphzvwrzvqnbntjndrwllzwchczdwvnfjjdwfhdlgncftldzwdtjzjrmnfwwgmqdrltmgrfsjztfcvwjsggtvbnsvthflwfdtljrgqhmfqhmhfffqhtgwtlmwgzsglqnfwnrnvgvbdgqjrqtsmgsmzdpffnnzwlpbqphqmgdzspfrdqlptwmfwlgnqqdhtbbjtfhllrhhdcszjtmrprzhzzlgjqbcnhzcmhzrsnmmrzztffrldthhfvwhgjhwmjfbdvnllfmlpdsldjnpcwlpbwqzdwbgjb\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_06_questions.txt",
    "content": "--- Day 6: Tuning Trouble ---\n\nThe preparations are finally complete; you and the Elves leave camp\non foot and begin to make your way toward the star fruit grove.\n\nAs you move through the dense undergrowth, one of the Elves gives\nyou a handheld device. He says that it has many fancy features, but\nthe most important one to set up right now is the communication system.\n\nHowever, because he's heard you have significant experience dealing\nwith signal-based systems, he convinced the other Elves that it would\nbe okay to give you their one malfunctioning device - surely you'll\nhave no problem fixing it.\n\nAs if inspired by comedic timing, the device emits\na few colorful sparks.\n\nTo be able to communicate with the Elves, the device needs to lock\non to their signal. The signal is a series of seemingly-random\ncharacters that the device receives one at a time.\n\nTo fix the communication system, you need to add a subroutine to\nthe device that detects a start-of-packet marker in the datastream.\nIn the protocol being used by the Elves, the start of a packet is\nindicated by a sequence of four characters that are all different.\n\nThe device will send your subroutine a datastream buffer (your\npuzzle input); your subroutine needs to identify the first position\nwhere the four most recently received characters were all different.\nSpecifically, it needs to report the number of characters from the\nbeginning of the buffer to the end of the first such\nfour-character marker.\n\nFor example, suppose you receive the following datastream buffer:\n\nmjqjpqmgbljsphdztnvjfqwrcgsmlb\n\nAfter the first three characters (mjq) have been received, there\nhaven't been enough characters received yet to find the marker.\nThe first time a marker could occur is after the fourth character\nis received, making the most recent four characters mjqj. Because\nj is repeated, this isn't a marker.\n\nThe first time a marker appears is after the seventh character\narrives. Once it does, the last four characters received are jpqm,\nwhich are all different. In this case, your subroutine should report\nthe value 7, because the first start-of-packet marker is complete\nafter 7 characters have been processed.\n\nHere are a few more examples:\n\n    bvwbjplbgvbhsrlpgdmjqwftvncz: first marker after character 5\n    nppdvjthqldpwncqszvftbrmjlhg: first marker after character 6\n    nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: first marker after character 10\n    zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: first marker after character 11\n\nHow many characters need to be processed before the first\nstart-of-packet marker is detected?\n\n--- Part Two ---\n\nYour device's communication system is correctly detecting packets,\nbut still isn't working. It looks like it also needs to\nlook for messages.\n\nA start-of-message marker is just like a start-of-packet marker,\nexcept it consists of 14 distinct characters rather than 4.\n\nHere are the first positions of start-of-message markers for all\nof the above examples:\n\n    mjqjpqmgbljsphdztnvjfqwrcgsmlb: first marker after character 19\n    bvwbjplbgvbhsrlpgdmjqwftvncz: first marker after character 23\n    nppdvjthqldpwncqszvftbrmjlhg: first marker after character 23\n    nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: first marker after character 29\n    zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: first marker after character 26\n\nHow many characters need to be processed before the first\nstart-of-message marker is detected?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_07.adb",
    "content": "--  Solution to Advent of Code 2022, Day 7\n------------------------------------------\n--  No Space Left On Device\n--\n--  https://adventofcode.com/2022/day/7\n--  Copy of questions in: aoc_2022_07_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_07 is\n  use HAT;\n\n  root : constant := -1;\n  subtype Cat_Entry_Range is Integer range root .. 1000;\n\n  type Dir_Info is record\n    name   : VString;\n    parent : Cat_Entry_Range;\n    size   : Natural;\n  end record;\n\n  cat : array (Cat_Entry_Range) of Dir_Info;\n\n  current, up, last, i_min : Cat_Entry_Range := root;\n\n  size, new_disk_size,\n  size_cumul_small_dirs, best_new_size : Natural := 0;\n\n  f : File_Type;\n  s : VString;\n\n  verbose : constant Boolean := False;\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\nbegin\n  Open (f, \"aoc_2022_07.txt\");\n  cat (root).name   := +\"/\";\n  cat (root).parent := root;\n  cat (root).size   := 0;\nRead_Data :\n  while not End_Of_File (f) loop\n    Get_Line (f, s);\n    s := s & ' ';\n    case Element (s, 1) is\n      when '$' =>\n        --  Command:\n        case Element (s, 3) is\n          when 'c' =>\n            --  \"cd\":\n            case Element (s, 6) is\n              when '.' =>\n                current := cat (current).parent;\n              when '/' =>\n                current := root;\n              when others =>\n                --  Subdirectory (hopefully unseen so far...):\n                last := last + 1;\n                cat (last).name :=\n                  cat (current).name &\n                  Slice (s, 6, Index (s, ' ', 6) - 1) & '/';\n                cat (last).parent := current;\n                cat (last).size   := 0;\n                current := last;\n            end case;\n            if verbose then\n              Put_Line (+\"New dir \" & cat (current).name);\n            end if;\n          when others => null;\n        end case;\n\n      when '0' .. '9' =>\n        size := Integer_Value (Slice (s, 1, Index (s, ' ') - 1));\n        if verbose then\n          Put_Line (+\"  File size : \" & size);\n        end if;\n        up := current;\n        loop\n          cat (up).size := cat (up).size + size;\n          if verbose then\n            Put_Line\n              (+\"    New total size for \" &\n               cat (up).name & \" : \" & cat (up).size);\n          end if;\n          exit when up = root;\n          up := cat (up).parent;\n        end loop;\n\n      when others =>\n        --  Any other information, unused.\n        null;\n    end case;\n  end loop Read_Data;\n  Close (f);\n\n  for i in root .. last loop\n    --\n    --  We sum up the size of all directories with total sizes up to 100_000.\n    --  Sub-directories are double-counted.\n    --\n    if cat (i).size <= 100_000 then\n      size_cumul_small_dirs := size_cumul_small_dirs + cat (i).size;\n    end if;\n    --\n    --  We look for removing the smallest possible directory,\n    --  which means getting the largest possible new disk size,\n    --  as long as the new disk size is up to 40_000_000.\n    --\n    new_disk_size := cat (root).size - cat (i).size;\n    if new_disk_size > best_new_size and then new_disk_size <= 40_000_000 then\n      best_new_size := new_disk_size;\n      i_min := i;\n    end if;\n  end loop;\n\n  r (1) := size_cumul_small_dirs;\n  r (2) := cat (i_min).size;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: sum of total sizes of at most 100_000 : \" & r (1));\n    Put_Line (+\"Part 2: smallest directory to delete          : \" & r (2));\n    --  Part 1: validated by AoC: 1749646\n    --  Part 2: validated by AoC: 1498966\n  end if;\nend AoC_2022_07;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_07.txt",
    "content": "$ cd /\n$ ls\ndir gqlg\ndir hchrwstr\ndir lswlpt\n189381 mzsnhlf\ndir plmdrbn\ndir rjwmjd\ndir stqq\n93174 zfn\ndir zjhqnlrr\ndir zssdlnc\n$ cd gqlg\n$ ls\n187654 cfrdsjf\n100589 ntvmgbw\n46922 zcmfcjhf.tzw\n$ cd ..\n$ cd hchrwstr\n$ ls\n227766 cljjlcp.pjh\n102770 rdbrcf.pjl\n9887 rfnjn.lqn\ndir rzsrp\ndir shlhgj\ndir slwwgc\n$ cd rzsrp\n$ ls\ndir rzsrp\n$ cd rzsrp\n$ ls\ndir dvzvmsjz\n208001 tnflwcsn\ndir zfn\n$ cd dvzvmsjz\n$ ls\n149823 hvgbhm.zsc\n$ cd ..\n$ cd zfn\n$ ls\n292424 gqlg.tzc\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd shlhgj\n$ ls\n61753 fzpzwjdt.jvl\n195204 jjhc.tzr\n288094 zcmfcjhf.tzw\n$ cd ..\n$ cd slwwgc\n$ ls\n118185 jjhc.tzr\n291916 jwnw.wqv\n116377 ptlz\n300849 pzjpw.hwg\n28679 zfn.grz\n$ cd ..\n$ cd ..\n$ cd lswlpt\n$ ls\n124160 dbnlt.rqz\n154412 sfd\n$ cd ..\n$ cd plmdrbn\n$ ls\ndir fmzjhrq\n224144 rlc.qns\n2985 zcmfcjhf.tzw\n$ cd fmzjhrq\n$ ls\n9749 lqj.szc\ndir rrjjsvm\n$ cd rrjjsvm\n$ ls\n66652 zcmfcjhf.tzw\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd rjwmjd\n$ ls\ndir twcrf\n125294 zpfws.ctc\ndir zwmmrqj\n$ cd twcrf\n$ ls\n229364 tnflwcsn\n262716 zcmfcjhf.tzw\n$ cd ..\n$ cd zwmmrqj\n$ ls\n11466 gqlg.ftg\n220272 lflcgss.jrm\n79574 tnflwcsn\n$ cd ..\n$ cd ..\n$ cd stqq\n$ ls\n185160 cwjqldbf.cnm\n266439 dpg.pwn\ndir hpgbcvtb\n139357 jvps\ndir llbthqc\n250148 mctn.dqw\ndir rzsrp\n22196 tnflwcsn\ndir whmdbn\n$ cd hpgbcvtb\n$ ls\n231579 fvjjtd.wdb\n168118 gjdtscqs\n113434 ldbqbg\ndir mqjfvg\n182214 nnnr\n112389 pqqdt.wnn\n$ cd mqjfvg\n$ ls\n170328 gqlg.jjc\n$ cd ..\n$ cd ..\n$ cd llbthqc\n$ ls\n25611 bftwd.qrr\n91550 tnflwcsn\n$ cd ..\n$ cd rzsrp\n$ ls\n272315 wrsfh.pzd\n123877 zcmfcjhf.tzw\n$ cd ..\n$ cd whmdbn\n$ ls\n29628 jjhc.tzr\n65193 mrhb\n$ cd ..\n$ cd ..\n$ cd zjhqnlrr\n$ ls\ndir bzzvj\ndir ddzmvh\ndir dsjd\n180806 fqz.dch\ndir nnzvl\n109161 rptmqt\n6463 rzsrp.sjf\n111549 rzsrp.wwz\n241532 zfn\n$ cd bzzvj\n$ ls\n278759 gqlg.nsn\n174223 mvggzqrq\n156518 tnflwcsn\ndir wjtlg\ndir zfn\n$ cd wjtlg\n$ ls\n52198 fvqbtm.tch\n44881 tnflwcsn\n$ cd ..\n$ cd zfn\n$ ls\n22926 tnflwcsn\n$ cd ..\n$ cd ..\n$ cd ddzmvh\n$ ls\ndir cpvfln\n180764 gqlg.bjq\ndir hgrnmh\n186254 hgrnmh.tpr\ndir hjpgf\ndir mghmb\ndir pvdwhmcr\n256578 rzsrp\n269955 shlhgj\n172163 vrr.nnm\n$ cd cpvfln\n$ ls\n87025 hgrnmh.lvr\n187453 rwmq.dph\ndir sthhc\n$ cd sthhc\n$ ls\n289580 fdzwmfnf\n57504 hgrnmh.vqj\n277639 mzcfchr.mch\ndir slsj\ndir vsvvprg\n94836 zqglfrl\n$ cd slsj\n$ ls\n178013 hdjgtqt\n$ cd ..\n$ cd vsvvprg\n$ ls\n102783 fvqbtm.tch\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd hgrnmh\n$ ls\ndir mrnmbbt\n240216 rzsrp.nfg\n$ cd mrnmbbt\n$ ls\n245579 gqlg\n$ cd ..\n$ cd ..\n$ cd hjpgf\n$ ls\n257544 cjfd.wdq\n296077 jjhc.tzr\n195752 zcmfcjhf.tzw\n$ cd ..\n$ cd mghmb\n$ ls\ndir bgrcsdc\ndir btjq\ndir gqlg\ndir gtwdqw\ndir hgrnmh\ndir jts\ndir jvp\ndir jvrjcv\n206272 pgf.rgj\n130746 tnflwcsn\n256698 zfn.dhl\n$ cd bgrcsdc\n$ ls\n235762 lflcgss.jrm\n$ cd ..\n$ cd btjq\n$ ls\ndir bvrcqb\ndir drslln\ndir dwzpblb\ndir gqlg\ndir hgrnmh\ndir hvb\ndir rqtc\ndir vsdz\ndir wrnftqh\n$ cd bvrcqb\n$ ls\n51508 gjjg.msw\ndir gqlg\n13206 pdwn\n10427 vbw\n6909 zfn.ztq\n$ cd gqlg\n$ ls\n20816 cmgcvlh.mzs\n10358 fvqbtm.tch\n215142 rzsrp.dns\n192153 wdjdppzm\n$ cd ..\n$ cd ..\n$ cd drslln\n$ ls\n258102 tnflwcsn\n$ cd ..\n$ cd dwzpblb\n$ ls\n302466 fvqbtm.tch\n$ cd ..\n$ cd gqlg\n$ ls\ndir hnr\ndir mdzdht\n$ cd hnr\n$ ls\ndir fjd\n159298 fvqbtm.tch\n46324 gchdll.nrm\n287907 lflcgss.jrm\ndir mqp\n140272 twdff\n47399 zfn\n$ cd fjd\n$ ls\n227109 fvqbtm.tch\n223413 wdsfwwwm.rmd\n$ cd ..\n$ cd mqp\n$ ls\ndir rzsrp\n$ cd rzsrp\n$ ls\ndir pgwng\n$ cd pgwng\n$ ls\n218271 hgrnmh.gnf\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd mdzdht\n$ ls\ndir gqlg\ndir tvd\n$ cd gqlg\n$ ls\ndir gfjqbdp\n108335 jjhc.tzr\n$ cd gfjqbdp\n$ ls\n143536 fzvn.jtv\n$ cd ..\n$ cd ..\n$ cd tvd\n$ ls\n238491 wsjmrlqv.bwb\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd hgrnmh\n$ ls\n265289 lflcgss.jrm\n111283 thb\n$ cd ..\n$ cd hvb\n$ ls\ndir hgrnmh\ndir smmwg\n$ cd hgrnmh\n$ ls\ndir wpvssts\n84939 zcmfcjhf.tzw\n$ cd wpvssts\n$ ls\n305634 whcmr\n$ cd ..\n$ cd ..\n$ cd smmwg\n$ ls\n36722 cvdbwg.rll\n16840 nnhbcbwz\ndir rzsrp\n9405 zfn.jzr\n$ cd rzsrp\n$ ls\ndir fzsngr\n$ cd fzsngr\n$ ls\n142687 zcmfcjhf.tzw\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd rqtc\n$ ls\ndir pbzhfsg\ndir rzsrp\ndir shlhgj\n$ cd pbzhfsg\n$ ls\n41865 hpshz.sdf\n$ cd ..\n$ cd rzsrp\n$ ls\ndir gqlg\ndir mbsjjzft\n$ cd gqlg\n$ ls\ndir gqlg\ndir nvjqp\n$ cd gqlg\n$ ls\n21860 tnflwcsn\n$ cd ..\n$ cd nvjqp\n$ ls\ndir gcq\n$ cd gcq\n$ ls\ndir mslhm\ndir rzsrp\n$ cd mslhm\n$ ls\n41304 rpgvllw.zfj\n$ cd ..\n$ cd rzsrp\n$ ls\n290199 ddsnt\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd mbsjjzft\n$ ls\n47727 ggpmg.pps\ndir stgszvmj\n275954 tnflwcsn\n248613 vbgnwh.sjz\n$ cd stgszvmj\n$ ls\ndir dthcrbmr\ndir shlhgj\n206580 zcmfcjhf.tzw\ndir zfn\n$ cd dthcrbmr\n$ ls\ndir lhp\ndir npf\ndir qbgrjr\n$ cd lhp\n$ ls\n37925 hgrnmh.lvm\n$ cd ..\n$ cd npf\n$ ls\n77162 bqvd\n$ cd ..\n$ cd qbgrjr\n$ ls\n48767 fvqbtm.tch\n$ cd ..\n$ cd ..\n$ cd shlhgj\n$ ls\ndir wtlngn\n35422 zfn\n$ cd wtlngn\n$ ls\ndir gqlg\n$ cd gqlg\n$ ls\n64761 fwtqw\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd zfn\n$ ls\n47247 dmlr.flv\n259570 htvn.rbz\n149238 qrdw\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd shlhgj\n$ ls\ndir cjmv\ndir tns\n$ cd cjmv\n$ ls\n140919 jjhc.tzr\n$ cd ..\n$ cd tns\n$ ls\n248127 fvqbtm.tch\n216202 pwg\ndir qhhtgsvz\n$ cd qhhtgsvz\n$ ls\n68979 fvqbtm.tch\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd vsdz\n$ ls\n224491 hgrnmh\ndir jsrqjjtc\ndir shlhgj\n123062 zfn.gss\n$ cd jsrqjjtc\n$ ls\n245991 phc\n$ cd ..\n$ cd shlhgj\n$ ls\n284208 ctwmwlp.lnm\n11067 vwsrmlf.dvz\n$ cd ..\n$ cd ..\n$ cd wrnftqh\n$ ls\n237658 lldrh\n14804 nszc.wdf\n$ cd ..\n$ cd ..\n$ cd gqlg\n$ ls\n211474 jjhc.tzr\n$ cd ..\n$ cd gtwdqw\n$ ls\n92613 fvqbtm.tch\n206813 ppzhmnb.grd\n$ cd ..\n$ cd hgrnmh\n$ ls\n249351 bftm\n$ cd ..\n$ cd jts\n$ ls\n132190 gqlg.vnn\n208091 ldnq\n202593 zcmfcjhf.tzw\n$ cd ..\n$ cd jvp\n$ ls\n258220 lflcgss.jrm\n$ cd ..\n$ cd jvrjcv\n$ ls\n20148 dzzlwp.bdj\n289774 hgrnmh.bvc\n296981 jwscd.cvj\n16617 tbnwvcl.tlv\n$ cd ..\n$ cd ..\n$ cd pvdwhmcr\n$ ls\ndir bhmmsbmb\ndir bjwbvcq\ndir hgrnmh\ndir ltvtrtth\ndir prtqcb\ndir rmn\ndir shlhgj\ndir tmzcmb\ndir vlbqvps\ndir wmmfp\n$ cd bhmmsbmb\n$ ls\ndir nccjwf\n$ cd nccjwf\n$ ls\ndir drwhjfjn\n206638 lflcgss.jrm\n$ cd drwhjfjn\n$ ls\n291772 zcmfcjhf.tzw\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd bjwbvcq\n$ ls\ndir zfn\n$ cd zfn\n$ ls\n303808 wrbldbd\n$ cd ..\n$ cd ..\n$ cd hgrnmh\n$ ls\n142765 fvqbtm.tch\n159497 scqf.scf\n270819 zcmfcjhf.tzw\n$ cd ..\n$ cd ltvtrtth\n$ ls\ndir fwtwqvn\n156894 jnmqdq.zgp\n297860 lflcgss.jrm\ndir mcgcc\ndir zfn\n179328 zfn.vnn\ndir zzsnz\n$ cd fwtwqvn\n$ ls\ndir rqndc\ndir rzsrp\n124999 rzsrp.tvr\ndir shlhgj\n$ cd rqndc\n$ ls\n45124 zrcv\n$ cd ..\n$ cd rzsrp\n$ ls\n74041 rzsrp\n$ cd ..\n$ cd shlhgj\n$ ls\n117219 qptfpz.cgc\n281188 shlhgj.bhd\n121750 sptql\n173637 vqp.dbs\n$ cd ..\n$ cd ..\n$ cd mcgcc\n$ ls\n18295 gqlg\ndir ngvwhnvf\n177283 rjsrn.rlq\n54239 rzsrp.tfq\n$ cd ngvwhnvf\n$ ls\n207616 jjhc.tzr\n$ cd ..\n$ cd ..\n$ cd zfn\n$ ls\ndir cwzbljh\n$ cd cwzbljh\n$ ls\n134952 hmchpgn.nwf\n$ cd ..\n$ cd ..\n$ cd zzsnz\n$ ls\n273014 shlhgj.pls\n$ cd ..\n$ cd ..\n$ cd prtqcb\n$ ls\ndir dtr\ndir rzsrp\n199012 tnflwcsn\n$ cd dtr\n$ ls\ndir gqlg\ndir grwpbs\ndir hgrnmh\n115701 lflcgss.jrm\n247838 tnflwcsn\n268721 zcmfcjhf.tzw\n15320 zwcd.dqb\n$ cd gqlg\n$ ls\n285009 jjhc.tzr\n125691 nhnlcjjt.zlj\n54424 rzsrp.rll\n$ cd ..\n$ cd grwpbs\n$ ls\n59390 rzsrp.cms\n$ cd ..\n$ cd hgrnmh\n$ ls\n185747 lvtnqqdh.nzq\n$ cd ..\n$ cd ..\n$ cd rzsrp\n$ ls\n268631 hvvpfd.smn\n263890 tcrctpb.pcc\n$ cd ..\n$ cd ..\n$ cd rmn\n$ ls\ndir gtnvc\n205894 hqb.fwh\n280887 lvvmjb.scj\ndir rsnqlfsz\n$ cd gtnvc\n$ ls\n28523 jjhc.tzr\n$ cd ..\n$ cd rsnqlfsz\n$ ls\ndir hgrnmh\ndir nsfhtthc\n$ cd hgrnmh\n$ ls\n183216 fvqbtm.tch\n$ cd ..\n$ cd nsfhtthc\n$ ls\n284747 jspmbh.rvh\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd shlhgj\n$ ls\n144391 dzf\ndir lrths\n178083 nhlmsd.mnc\ndir rwn\n173833 shlhgj.qss\n39183 tnflwcsn\n125029 zfn.hjr\n$ cd lrths\n$ ls\ndir hgrnmh\ndir pfc\n86563 rzsrp.gbc\n280631 tmhnc.hmc\n28181 ttsnjc.rhm\n98060 vdmr.czg\ndir vlshvmvj\ndir wsn\n210337 zfn.pqp\n$ cd hgrnmh\n$ ls\ndir mvrlcvj\n$ cd mvrlcvj\n$ ls\n121034 vssbr.qjm\n$ cd ..\n$ cd ..\n$ cd pfc\n$ ls\ndir gqlg\n$ cd gqlg\n$ ls\n305519 hdhn.wds\n$ cd ..\n$ cd ..\n$ cd vlshvmvj\n$ ls\n56641 lflcgss.jrm\n29190 rzsrp.vsh\n36663 zcmfcjhf.tzw\n$ cd ..\n$ cd wsn\n$ ls\n137307 gmdfbfjf.crs\ndir hgtqj\n297924 lflcgss.jrm\ndir shlhgj\n$ cd hgtqj\n$ ls\n214202 qnlszftb.bzg\n$ cd ..\n$ cd shlhgj\n$ ls\ndir pmldlbbh\n$ cd pmldlbbh\n$ ls\n263722 zwfptl.wsh\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd rwn\n$ ls\n279589 ttqg.qct\n$ cd ..\n$ cd ..\n$ cd tmzcmb\n$ ls\n138557 jjhc.tzr\n$ cd ..\n$ cd vlbqvps\n$ ls\ndir nmfnf\n123659 rzsrp\n$ cd nmfnf\n$ ls\ndir jhpnd\n50537 trzvzvgz.bqp\n41828 vps\n195245 wlwt.ftj\n$ cd jhpnd\n$ ls\n257519 shlhgj.fwz\n32963 wzmbdtz\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd wmmfp\n$ ls\n94749 lflcgss.jrm\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd dsjd\n$ ls\n284923 bjvwg.phz\ndir bwjp\ndir gqlg\ndir hgrnmh\n8771 jjhc.tzr\ndir jntt\n271995 qbtn.vps\n299501 shlhgj.crl\ndir vmph\ndir zvg\n$ cd bwjp\n$ ls\n117739 vtrg\n$ cd ..\n$ cd gqlg\n$ ls\ndir dwhr\n159876 hgrnmh.jvw\ndir rzsrp\n$ cd dwhr\n$ ls\n193289 gqlg\n171323 lflcgss.jrm\n$ cd ..\n$ cd rzsrp\n$ ls\ndir pmsgd\n$ cd pmsgd\n$ ls\n12648 lflcgss.jrm\ndir wbppspwq\n$ cd wbppspwq\n$ ls\n38834 tnflwcsn\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd hgrnmh\n$ ls\n76649 cfdcbvdl.gfs\n257249 gmmzf\n83045 lhrtfcz\n$ cd ..\n$ cd jntt\n$ ls\n286866 lhqvt.lst\n$ cd ..\n$ cd vmph\n$ ls\ndir fnvpsr\ndir gfnvsznj\n19765 zcmfcjhf.tzw\n204319 zzsnj.dcp\n$ cd fnvpsr\n$ ls\ndir flz\n173924 fvqbtm.tch\n248297 mjrhs.scq\ndir rzsrp\n130580 zfn\n$ cd flz\n$ ls\n106168 brsgg\n$ cd ..\n$ cd rzsrp\n$ ls\n221882 hgrnmh.nsl\ndir smd\n$ cd smd\n$ ls\ndir drsld\n131686 fvqbtm.tch\ndir gqlg\n288283 hcw\n$ cd drsld\n$ ls\n85885 zfn.wdf\n$ cd ..\n$ cd gqlg\n$ ls\n8466 dzjtj.zbc\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd gfnvsznj\n$ ls\ndir fqb\n265075 gqlg\ndir hdhmbtj\n74385 hpz\ndir lzdq\ndir rlvqmwv\ndir rzsrp\n$ cd fqb\n$ ls\n55182 ccjgpg\n245930 ppdgwcm.zfb\n164364 sgtgqdn.tfp\n$ cd ..\n$ cd hdhmbtj\n$ ls\ndir gqlg\n68609 jjhc.tzr\ndir rzsrp\ndir vrmrnt\n66988 zcmfcjhf.tzw\n$ cd gqlg\n$ ls\n156776 tnflwcsn\ndir vdcbg\n$ cd vdcbg\n$ ls\n261780 lflcgss.jrm\n$ cd ..\n$ cd ..\n$ cd rzsrp\n$ ls\n27818 zfn\n$ cd ..\n$ cd vrmrnt\n$ ls\n273664 msmzfnj.llc\n145156 svzmwnrq.chh\n$ cd ..\n$ cd ..\n$ cd lzdq\n$ ls\n214363 fms\n190021 lfzcgh.dsq\n21357 qtvvmj.zqw\n$ cd ..\n$ cd rlvqmwv\n$ ls\ndir gqlg\n198296 gqlg.sdz\n842 gshcswc.dcb\ndir shlhgj\n199828 snng\n$ cd gqlg\n$ ls\n183087 zfn.nsj\n$ cd ..\n$ cd shlhgj\n$ ls\n73040 tzgjrqmb\n$ cd ..\n$ cd ..\n$ cd rzsrp\n$ ls\n229576 vtftgng.wfz\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd zvg\n$ ls\n85701 shlhgj.dvf\n$ cd ..\n$ cd ..\n$ cd nnzvl\n$ ls\ndir wwzsf\n$ cd wwzsf\n$ ls\n105177 tvbdz\n$ cd ..\n$ cd ..\n$ cd ..\n$ cd zssdlnc\n$ ls\ndir nfgh\n166004 twdcrh.zld\ndir zfn\n$ cd nfgh\n$ ls\n102281 fvqbtm.tch\n$ cd ..\n$ cd zfn\n$ ls\ndir fbmww\ndir jsst\n206602 shlhgj.cln\n$ cd fbmww\n$ ls\n179734 fll\n$ cd ..\n$ cd jsst\n$ ls\ndir flp\n$ cd flp\n$ ls\n32274 gctgt.stn\n67650 ggvj.bwz\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_07_questions.txt",
    "content": "--- Day 7: No Space Left On Device ---\n\nYou can hear birds chirping and raindrops hitting leaves as\nthe expedition proceeds. Occasionally, you can even hear much louder\nsounds in the distance; how big do the animals get out here, anyway?\n\nThe device the Elves gave you has problems with more than just its\ncommunication system. You try to run a system update:\n\n$ system-update --please --pretty-please-with-sugar-on-top\nError: No space left on device\n\nPerhaps you can delete some files to make space for the update?\n\nYou browse around the filesystem to assess the situation and save\nthe resulting terminal output (your puzzle input). For example:\n\n$ cd /\n$ ls\ndir a\n14848514 b.txt\n8504156 c.dat\ndir d\n$ cd a\n$ ls\ndir e\n29116 f\n2557 g\n62596 h.lst\n$ cd e\n$ ls\n584 i\n$ cd ..\n$ cd ..\n$ cd d\n$ ls\n4060174 j\n8033020 d.log\n5626152 d.ext\n7214296 k\n\nThe filesystem consists of a tree of files (plain data) and directories\n(which can contain other directories or files). The outermost directory\nis called /. You can navigate around the filesystem, moving into or\nout of directories and listing the contents of the directory you're\ncurrently in.\n\nWithin the terminal output, lines that begin with $ are commands you\nexecuted, very much like some modern computers:\n\n    cd means change directory. This changes which directory is\n      the current directory, but the specific result depends\n      on the argument:\n\n        cd x moves in one level: it looks in the current directory for\n               the directory named x and makes it the current directory.\n        cd .. moves out one level: it finds the directory that\n                contains the current directory, then makes that\n                directory the current directory.\n        cd / switches the current directory to the\n               outermost directory, /.\n\n    ls means list. It prints out all of the files and directories\n      immediately contained by the current directory:\n\n        123 abc means that the current directory contains a file\n                  named abc with size 123.\n        dir xyz means that the current directory contains\n                  a directory named xyz.\n\nGiven the commands and output in the example above, you can\ndetermine that the filesystem looks visually like this:\n\n- / (dir)\n  - a (dir)\n    - e (dir)\n      - i (file, size=584)\n    - f (file, size=29116)\n    - g (file, size=2557)\n    - h.lst (file, size=62596)\n  - b.txt (file, size=14848514)\n  - c.dat (file, size=8504156)\n  - d (dir)\n    - j (file, size=4060174)\n    - d.log (file, size=8033020)\n    - d.ext (file, size=5626152)\n    - k (file, size=7214296)\n\nHere, there are four directories: / (the outermost directory), a and d\n(which are in /), and e (which is in a).\nThese directories also contain files of various sizes.\n\nSince the disk is full, your first step should probably be to find\ndirectories that are good candidates for deletion.\nTo do this, you need to determine the total size of each directory.\nThe total size of a directory is the sum of the sizes of the files\nit contains, directly or indirectly. (Directories themselves do not\ncount as having any intrinsic size.)\n\nThe total sizes of the directories above can be found as follows:\n\n    The total size of directory e is 584 because it contains a single\n      file i of size 584 and no other directories.\n\n    The directory a has total size 94853 because it contains files f\n      (size 29116), g (size 2557), and h.lst (size 62596), plus file\n      i indirectly (a contains e which contains i).\n\n    Directory d has total size 24933642.\n\n    As the outermost directory, / contains every file.\n      Its total size is 48381165, the sum of the size of every file.\n\nTo begin, find all of the directories with a total size of at\nmost 100000, then calculate the sum of their total sizes.\nIn the example above, these directories are a and e; the sum of their\ntotal sizes is 95437 (94853 + 584). (As in this example, this process\ncan count files more than once!)\n\nFind all of the directories with a total size of at most 100000.\nWhat is the sum of the total sizes of those directories?\n\nYour puzzle answer was 1749646.\n--- Part Two ---\n\nNow, you're ready to choose a directory to delete.\n\nThe total disk space available to the filesystem is 70000000.\nTo run the update, you need unused space of at least 30000000.\nYou need to find a directory you can delete that will free up\nenough space to run the update.\n\nIn the example above, the total size of the outermost directory\n(and thus the total amount of used space) is 48381165; this means\nthat the size of the unused space must currently be 21618835, which\nisn't quite the 30000000 required by the update.\nTherefore, the update still requires a directory with total\nsize of at least 8381165 to be deleted before it can run.\n\nTo achieve this, you have the following options:\n\n    Delete directory e, which would increase unused space by 584.\n    Delete directory a, which would increase unused space by 94853.\n    Delete directory d, which would increase unused space by 24933642.\n    Delete directory /, which would increase unused space by 48381165.\n\nDirectories e and a are both too small; deleting them would not free\nup enough space. However, directories d and / are both big enough!\nBetween these, choose the smallest: d, increasing unused\nspace by 24933642.\n\nFind the smallest directory that, if deleted, would free up enough\nspace on the filesystem to run the update.\nWhat is the total size of that directory?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_08.adb",
    "content": "--  Solution to Advent of Code 2022, Day 8\n------------------------------------------\n--  Treetop Tree House\n--\n--  https://adventofcode.com/2022/day/8\n--  Copy of questions in: aoc_2022_08_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_08 is\n  use HAT;\n\n  m : constant := 99;\n  subtype Tree_Height is Natural range 0 .. 9;\n  map : array (1 .. m, 1 .. m) of Tree_Height;\n\n  dump : constant Boolean := False;\n\n  procedure Dump_CSV is\n    d : File_Type;\n  begin\n    Create (d, \"forest.csv\");\n    for i in 1 .. m loop\n      for j in 1 .. m loop\n        Put (d, map (i, j));\n        Put (d, ';');\n      end loop;\n      New_Line (d);\n    end loop;\n    Close (d);\n  end Dump_CSV;\n\n  --  PPM output. Sources:\n  --  https://codeberg.org/rommudoh/aoc2022-Ada/src/branch/main/src/day08.adb\n  --  https://rosettacode.org/wiki/Bitmap/Write_a_PPM_file#Ada\n  --\n  procedure Dump_PPM is\n    subtype Color_Range is Natural range 0 .. 255;\n    type Pixel is record\n      R, G, B : Color_Range;\n    end record;\n    d : File_Type;\n    px : Pixel;\n  begin\n    Create (d, \"forest.ppm\");\n    Put (d, \"P6\" & Chr (10));\n    Put (d, m); Put (d, ' '); Put (d, m); Put (d, Chr (10));\n    Put (d, \"255\" & Chr (10));\n    for i in 1 .. m loop\n      for j in 1 .. m loop\n        case map (i, j) is\n          when 0 .. 1 => px.R := 16#99#; px.G := 16#99#; px.B := 16#ff#;\n          when 2 .. 3 => px.R := 16#99#; px.G := 16#33#; px.B := 16#66#;\n          when 4 .. 5 => px.R := 16#ff#; px.G := 16#ff#; px.B := 16#cc#;\n          when 6 .. 7 => px.R := 16#cc#; px.G := 16#ff#; px.B := 16#ff#;\n          when 8 .. 9 => px.R := 16#66#; px.G := 16#00#; px.B := 16#66#;\n        end case;\n        Put (d, Chr (px.R));\n        Put (d, Chr (px.G));\n        Put (d, Chr (px.B));\n      end loop;\n    end loop;\n    Close (d);\n  end Dump_PPM;\n\n  new_tree : array (1 .. m, 1 .. m) of Boolean;\n  scenic : array (1 .. m, 1 .. m) of Natural;\n  h : Tree_Height;\n  score, visible_trees : Natural;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n  c : Character;\n  f : File_Type;\n\nbegin\n  Open (f, \"aoc_2022_08.txt\");\nRead_Data :\n  for i in 1 .. m loop\n    for j in 1 .. m loop\n      Get (f, c);\n      map (i, j) := Ord (c) - Ord ('0');\n      scenic (i, j) := 1;\n      new_tree (i, j) := True;\n    end loop;\n  end loop Read_Data;\n  Close (f);\n\n  if dump then\n    --  Just for plotting the forest :-)\n    Dump_CSV;\n    Dump_PPM;\n  end if;\n\n  ---------------------------\n  --  Part 1               --\n  --  Count visible trees  --\n  ---------------------------\n\n  visible_trees := 0;\n\nHorizontal_Scans :\n  for i in 2 .. m - 1 loop\n\n    h := map (i, 1);\n  From_Left :\n    for j in 2 .. m - 1 loop\n      if map (i, j) > h then\n        if new_tree (i, j) then\n          visible_trees := visible_trees + 1;\n          new_tree (i, j) := False;\n        end if;\n        h := map (i, j);\n      end if;\n    end loop From_Left;\n\n    h := map (i, m);\n  From_Right :\n    for j in reverse 2 .. m - 1 loop\n      if map (i, j) > h then\n        if new_tree (i, j) then\n          visible_trees := visible_trees + 1;\n          new_tree (i, j) := False;\n        end if;\n        h := map (i, j);\n      end if;\n    end loop From_Right;\n  end loop Horizontal_Scans;\n\nVertical_Scans :\n  for j in 2 .. m - 1 loop\n\n    h := map (1, j);\n  From_Top :\n    for i in 2 .. m - 1 loop\n      if map (i, j) > h then\n        if new_tree (i, j) then\n          visible_trees := visible_trees + 1;\n          new_tree (i, j) := False;\n        end if;\n        h := map (i, j);\n      end if;\n    end loop From_Top;\n\n    h := map (m, j);\n  From_Bottom :\n    for i in reverse 2 .. m - 1 loop\n      if map (i, j) > h then\n        if new_tree (i, j) then\n          visible_trees := visible_trees + 1;\n          new_tree (i, j) := False;\n        end if;\n        h := map (i, j);\n      end if;\n    end loop From_Bottom;\n  end loop Vertical_Scans;\n\n  --  Variable `visible_trees` holds now the number\n  --  of visible trees that are inside the forest.\n  --  The trees on the edge are all visible.\n\n  r (1) := 2 * m + 2 * (m - 2) + visible_trees;\n\n  ------------------------------------\n  --  Part 2                        --\n  --  Compute highest scenic score  --\n  ------------------------------------\n\n  for i in 1 .. m loop\n    for j in 1 .. m loop\n      score := 0;\n    To_the_Left :\n      for jj in reverse 1 .. j - 1 loop\n        score := score + 1;\n        exit To_the_Left when map (i, jj) >= map (i, j);\n      end loop To_the_Left;\n      scenic (i, j) := scenic (i, j) * score;\n      score := 0;\n    To_the_Right :\n      for jj in j + 1 .. m loop\n        score := score + 1;\n        exit To_the_Right when map (i, jj) >= map (i, j);\n      end loop To_the_Right;\n      scenic (i, j) := scenic (i, j) * score;\n      score := 0;\n    To_the_Top :\n      for ii in reverse 1 .. i - 1 loop\n        score := score + 1;\n        exit To_the_Top when map (ii, j) >= map (i, j);\n      end loop To_the_Top;\n      scenic (i, j) := scenic (i, j) * score;\n      score := 0;\n    To_the_Bottom :\n      for ii in i + 1 .. m loop\n        score := score + 1;\n        exit To_the_Bottom when map (ii, j) >= map (i, j);\n      end loop To_the_Bottom;\n      scenic (i, j) := scenic (i, j) * score;\n    end loop;\n  end loop;\n  --  Compute highest scenic score:\n  score := 0;\n  for i in 2 .. m - 1 loop\n    for j in 2 .. m - 1 loop\n      score :=  Max (score, scenic (i, j));\n    end loop;\n  end loop;\n  r (2) := score;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: visible trees . . . . . . : \" & r (1));\n    Put_Line (+\"Part 2: highest scenic score  . . : \" & r (2));\n    --  Part 1: validated by AoC: 1843\n    --  Part 2: validated by AoC: 180000\n  end if;\nend AoC_2022_08;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_08.txt",
    "content": "102212110110302230012132130441442043243242145112422525112333344240121120342411110001231112222021211\n222101001302011022124443303121322323142224235123233315215333545242421321241403143213333101310210211\n200201223122002022301310313414224443253123231515151513541254251131310343344222040320023211301320200\n200010213032223103230132143412204353411323525332513442523314324332413034422122304413120211230122212\n010211000332000340422300132032513533513115523254315325423242433353351244232123121111220123121333221\n200122303232310323111312343413321244422555551325423211253434511531321144403333313021201212232131220\n000212003210330240303442205443113542544534111314155152232435243131155352422402104202123433111201232\n103312101101443020314140255354241134315242455146454323625133153413235312512313332430221300331131100\n010220000301314241214335313133422432322123354664326463436444322422342554355225140334421002113133121\n323101132001123022243353315252233331435562622453564455524652525652244413142424222440021003003130221\n311311300011420441113315524451532135232526456634245324454325625255644144511435413342301130211231301\n122330114303143110342335214315243456332354435254662545365545352556636544332142113343020330142302023\n022120000403423231542555223312544433353262526636242665353354342624542223253541435144031113311431220\n210013131013443325232155555522255445233525524424425466462465252544334662211253135515414212121223103\n122130234323200111421534352526522446635243456643673475346653325362454362443421552412233011444032132\n330230413401024335441342264233664326224445367753634776764473243636265344556415445523524224043114211\n020342003212232435413445263654334245243765543345436537434453757662242253666363442422244144403424000\n200102231042423341434316352256242653765564636564563755363577363456266625662553514113422123403421132\n313204040243524231344465644555626363733665445433637447335677545646763646633226445435325125112213414\n314103222004445425153443435336445733737355475744355366644536666633436334423645665121453234041020422\n241224100115215322523535566553547766677645474354634357364574375657645546622424324323251244433440201\n022222042544545521533326245235374365344376774543443767376646565377535776236535264522124353322203234\n422222135434133533655352463473735556656745548755787857555356377355447565365456463664354434453044312\n304324242134435426624362552443745545463386458858447758455754543677463336472433462334512421444332223\n341414135242433442655442346556355346658767857767584647675766884536373667347366462552211223152411402\n322422011132511352664233364365653466744454566746588468655774844685736565337465223255264314431430230\n230422221453335454423325334433457458687888455486757548466746647544834643335672463455634151341522302\n234004552353522225535427357745555646855484747845567786675574858868655476475453443665223324353452113\n020135314133142653352266355334757758775757788848887684458858675874884637537467525625364253131211244\n414342423551254236456446367655347867476487576757978699668748774646468564677435372565356631415154301\n402224514555445234247373353744455587885585976595966767878796785855864485334466564262266452143444311\n322114434454542333646465444736668764744886688767569596959858556668754886535574755434322662442212133\n121324243324423343546763375477766585857886776859668579795978997478645686674366773535335522313423220\n133542124333622654643366436564658876577978579997657798669999767568447887467776367522435455533321443\n023413415133262422437473376558558855786797675666795779995686567865485584745545375742263662533555543\n141153353554563662677655657576756468676875598877958956899955978897446555748753563362626454221131125\n325353321363522257537756588466744857658697678559699997698595865765578845586445367745536633643312255\n423213544666625365635544655675458885666985859697786876896858858797786874566466456657466442525434421\n111454444524556247634754788885848856779676996689987686878899758967589455644666556534542332454425232\n113454234223324274556335586767549686998856766879779799897977886877798476548873366444323624534235512\n413111246643442463347377577668885588996599677886898888866767856868795965878475573774545255562121514\n033322552545543547534354548647668766698879698968876698988768678695558875847754474335753623445451141\n033335136263443377434448478688978869869678786967679698969669778569788867674444636373445324354533414\n234114125435462653577777876855756557856867678669979986768879699797765796588455677467665646523542244\n315515242442526536477764768685998958898698776897898777978978889975778988546787635537642445246521555\n321543542424553344445665648775695579876967767799989797989877898976866779658748865436436245526532153\n214442166263264436546368554888589767787766679977779878789696679785859879648657647656345336454331514\n534225433653422444656547767677967556776977788979899998877878867678798578885766845756635543235613324\n451252264522467473463764566489668785797977788978898788799896886865858766846568667573775654463254212\n142243545346537474556565585866986596889698977988978988797896887869755867746847846457535246243622521\n314533543366656735447764644785876759686776988887899987977868668886569975674466755746757543333613415\n423155324556563534544657846546998786988679877979797897977866789679597759764485834747537363422511525\n111123232243256547763345885669578779768699999987898779978667968776659685647547563666543566442343212\n153351242236666565346454875568986796797687677988888979789886768978999686477777536735573656352555412\n323332424652563666766546867459698977996778977989988888888788678879875896444874453373545246666243111\n135523512363264534676375878685595968577686668988899788976766699895667985668547534554755246336443443\n532252346635325565376768676458557777667966786898889778979967688766768868568846557747445423253133325\n021423433266355547435457658778656599566767767766877768698699878975689884477647674353546424463554451\n143143223365543567635335747757587977786897796676679778966786689768589657474877567637754423223422312\n042415253643232575556737767785757788676996887999678977967666877589856675557885677334454634555223453\n234134135655336276745375664665486567958579869999988689769887997756966947584657365476724435655111251\n042425212462644477445435755454677877597667699897769689877689755868578567458576456463552232355231414\n354513445446645356573335466767579577676958688689866686776999686878859666766855753737445265524242214\n233154124332425336374475485444574569589885768789686679877995988778897787557646674666625354631424244\n242554311144536267576756377488488867896687566758869688757566767878568654674856637746343532221224535\n031352533424343666353537635778657888979797968869596858555897765778484557476745657576565652351431515\n244111523123546656444743447588484547797769687556999759895965969964878878867565456634442462655533330\n101154321124235234634644573645444776899979778958586696559589578574766767767776545323635556543324520\n230453243413346443656346633655876856466765588966595989676877687676564857856756335622566465554243444\n400115531525436425435363466676884457554568997656888965766988578885546646566546575455244664152151421\n121244523334642663334357574375756475655847758985795997565974854847688754735474744655256243422233523\n442124553352143426554554663364376844777584585568578895884475557584464677453543662566322652421252333\n121445542333545553333233367636337576575784548858744665868786757667467367567665363332432223545423200\n020321333225342646522423376435557446777478648478548458845546545678744437577337244622534425211350022\n041332232423124342256245433633577566478865647545565685666764666787764767576462433566522451433113043\n014424132244453224234546334667567447876654868784855884886878754645547664773756545644453424241524312\n414311054242342142224533466634464356437556445785767567866777856766576577644556443654324531342222310\n310322213415213433425552662577476354776577788877577647884464577437343437336643223244511135242014011\n300241033122121121456356264344335565375647366774864774858553747547334674624355256434534221515041124\n244113020144235342335234634564444633644736357543455335653765466354354346565443633362331511132134132\n143133204011342551536234336443376364333444577754334556634356574777657644433624432451425543542044012\n124214441344114214133244352626436376363654365447576564735347353654435326246226356243423532004304101\n101243244443555155315534544462433463654377635665747456733666473757525254363464365544115552421213312\n220422144420114253554354265345456453344337374375545645445347674334436455364526444454513431401002123\n313223311020451432455413454445642422634537364635666546754656735345535652356322545145325423121103202\n331004402420123535413315226646464442326356744477434645574333466622343266264444114525225333122240311\n112302121222114254552233452266654536466263462644653436655626223464363536324452444455541022040211131\n212012013423120023144244325334534664552523526224436442254665635246443333635121151334524401320433130\n001121341442114243125433441523554465523535244533322625264462365223623553532133143211423424102210003\n223220023212441130233151252342414632544243253526323465544536453355466344221452532544441122243331202\n312121212403143043222224331132453532666642654664652655433535463465343224212113542013034330243203021\n202012103340130001242425435444222111424542356345243653462563232352212415345354221301440242321032000\n212202110121021140441443523243344241514332562652664256563344623454345255222133212212024343023301122\n021010131200334014423400143154151315325512332544243346551323121315214235513143134101443433302011002\n122302321231131322434420345125245413215132313112255444513255422341524133353314114412224230231302110\n110111100102010040122344032453213533213254233521331414232113423512123251530432223244441332003202300\n200023022231020232023042313022141535414442413511535352414333413345343120402340033343211011203223002\n001120213231313130220231100314421411535333234424124253354254335222245404210032440401122303031121122\n011011030023132123022011022032214014533223521512511221453113132215230244324434210342210100311021222\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_08_questions.txt",
    "content": "--- Day 8: Treetop Tree House ---\n\nThe expedition comes across a peculiar patch of tall trees\nall planted carefully in a grid. The Elves explain that a previous\nexpedition planted these trees as a reforestation effort.\nNow, they're curious if this would be a good location for a tree house.\n\nFirst, determine whether there is enough tree cover here to keep\na tree house hidden. To do this, you need to count the number of\ntrees that are visible from outside the grid when looking\ndirectly along a row or column.\n\nThe Elves have already launched a quadcopter to generate a map\nwith the height of each tree (your puzzle input). For example:\n\n30373\n25512\n65332\n33549\n35390\n\nEach tree is represented as a single digit whose value is its\nheight, where 0 is the shortest and 9 is the tallest.\n\nA tree is visible if all of the other trees between it and an\nedge of the grid are shorter than it. Only consider trees in\nthe same row or column; that is, only look up, down, left, or\nright from any given tree.\n\nAll of the trees around the edge of the grid are visible - since\nthey are already on the edge, there are no trees to block the view.\nIn this example, that only leaves the interior nine trees to consider:\n\n    The top-left 5 is visible from the left and top. (It isn't visible\n      from the right or bottom since other trees of height 5\n      are in the way.)\n    The top-middle 5 is visible from the top and right.\n    The top-right 1 is not visible from any direction; for it to be\n      visible, there would need to only be trees of height 0 between\n      it and an edge.\n    The left-middle 5 is visible, but only from the right.\n    The center 3 is not visible from any direction; for it to be\n      visible, there would need to be only trees of at most\n      height 2 between it and an edge.\n    The right-middle 3 is visible from the right.\n    In the bottom row, the middle 5 is visible, but the 3 and 4 are not.\n\nWith 16 trees visible on the edge and another 5 visible in the interior,\na total of 21 trees are visible in this arrangement.\n\nConsider your map; how many trees are visible from outside the grid?\n\n--- Part Two ---\n\nContent with the amount of tree cover available, the Elves just need\nto know the best spot to build their tree house: they would like\nto be able to see a lot of trees.\n\nTo measure the viewing distance from a given tree, look up, down,\nleft, and right from that tree; stop if you reach an edge or at\nthe first tree that is the same height or taller than the tree\nunder consideration. (If a tree is right on the edge, at least\none of its viewing distances will be zero.)\n\nThe Elves don't care about distant trees taller than those\nfound by the rules above; the proposed tree house has large\neaves to keep it dry, so they wouldn't be able to see higher\nthan the tree house anyway.\n\nIn the example above, consider the middle 5 in the second row:\n\n30373\n25512\n65332\n33549\n35390\n\n    Looking up, its view is not blocked; it can see 1 tree (of height 3).\n    Looking left, its view is blocked immediately; it can see only\n      1 tree (of height 5, right next to it).\n    Looking right, its view is not blocked; it can see 2 trees.\n    Looking down, its view is blocked eventually; it can see 2\n      trees (one of height 3, then the tree of height 5\n      that blocks its view).\n\nA tree's scenic score is found by multiplying together its viewing\ndistance in each of the four directions.\nFor this tree, this is 4 (found by multiplying 1 * 1 * 2 * 2).\n\nHowever, you can do even better: consider the tree of\nheight 5 in the middle of the fourth row:\n\n30373\n25512\n65332\n33549\n35390\n\n    Looking up, its view is blocked at 2 trees\n      (by another tree with a height of 5).\n    Looking left, its view is not blocked; it can see 2 trees.\n    Looking down, its view is also not blocked; it can see 1 tree.\n    Looking right, its view is blocked at 2 trees\n      (by a massive tree of height 9).\n\nThis tree's scenic score is 8 (2 * 2 * 1 * 2);\nthis is the ideal spot for the tree house.\n\nConsider each tree on your map.\nWhat is the highest scenic score possible for any tree?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_09.adb",
    "content": "--  Solution to Advent of Code 2022, Day 9\n------------------------------------------\n--  Rope Bridge\n--\n--  https://adventofcode.com/2022/day/9\n--  Copy of questions in: aoc_2022_09_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_09 is\n  use HAT;\n\n  mx : constant := 300;\n  my : constant := 1000;\n  type Column is array (1 .. my) of Boolean;\n  empty : Column;\n  map : array (1 .. mx) of Column;\n\n  --  PPM output adapted from AoC_2022_08.\n  --\n  procedure Dump_PPM (title : VString) is\n    subtype Color_Range is Natural range 0 .. 255;\n    type Pixel is record\n      R, G, B : Color_Range;\n    end record;\n    d : File_Type;\n    px : Pixel;\n    min_x : constant := 1;\n    max_x : constant := mx;  --  200;\n    min_y : constant := 1;   --  401;\n    max_y : constant := my;  --  990;\n  begin\n    Create (d, title & \".ppm\");\n    Put (d, \"P6\" & Chr (10));\n    Put (d, max_x - min_x + 1); Put (d, ' ');\n    Put (d, max_y - min_y + 1); Put (d, Chr (10));\n    Put (d, \"255\" & Chr (10));\n    for y in reverse min_y .. max_y loop\n      for x in min_x .. max_x loop\n        case map (x)(y) is\n          when False => px.R := 16#ff#; px.G := 16#ff#; px.B := 16#cc#;\n          when True  => px.R := 16#66#; px.G := 16#00#; px.B := 16#66#;\n        end case;\n        Put (d, Chr (px.R));\n        Put (d, Chr (px.G));\n        Put (d, Chr (px.B));\n      end loop;\n    end loop;\n    Close (d);\n  end Dump_PPM;\n\n  type Movement is (L, R, U, D);\n\n  move : Movement;\n\n  type Pos is record\n    x, y : Natural;\n  end record;\n\n  type Rope_Type is array (0 .. 9) of Pos;\n\n  rope, old_rope : Rope_Type;\n\n  len : Positive;\n\n  type Method_for_following is\n    (use_previous_position,\n     --  ^ When needed for preserving the distance, a tail knot goes\n     --    into the head knot's previous position.\n     --    This method is correct but doesn't deliver the result\n     --    expected by Advent of Code - the rules represent a rare\n     --    case of ambiguity in AoC...\n     reduce_distance);\n     --  ^ We move the tail knot by at most one in each dimension\n     --    towards the head knot.\n\n  method : constant Method_for_following := reduce_distance;\n\n  verbose : constant Boolean := False;\n  T0 : constant Time := Clock;\n  res : array (1 .. 2) of Integer;\n\n  c : Character;\n  total, steps : Integer;\n  f : File_Type;\n\n  function Dist (a, b : Pos) return Natural is\n  begin\n    return\n      Max (abs (a.x - b.x), abs (a.y - b.y));\n  end Dist;\n\n  procedure Follow_Geometrically (head : in Pos; tail : in out Pos) is\n  begin\n    --  The tail follows the head with a step of maximum 1 in each dimension.\n    tail.x := tail.x + Sgn (head.x - tail.x);\n    tail.y := tail.y + Sgn (head.y - tail.y);\n  end Follow_Geometrically;\n\nbegin\n  for y in Column'Range loop\n    empty (y) := False;\n  end loop;\n\nParts :\n  for part in 1 .. 2 loop\n    for i in rope'Range loop\n      rope (i).x := mx / 2;\n      rope (i).y := my / 2;\n    end loop;\n    for x in map'Range loop\n      map (x) := empty;\n    end loop;\n    case part is\n      when 1 => len := 1;\n      when 2 => len := 9;\n    end case;\n\n    Open (f, \"aoc_2022_09.txt\");\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get (f, c);\n      Get (f, steps);\n      move := Movement'Value (c & \"\");\n      for count in 1 .. steps loop\n        old_rope := rope;\n        --  Move the head of the rope:\n        case move is\n          when L => rope (0).x := rope (0).x - 1;\n          when R => rope (0).x := rope (0).x + 1;\n          when D => rope (0).y := rope (0).y - 1;\n          when U => rope (0).y := rope (0).y + 1;\n        end case;\n        for i in 1 .. len loop\n          if Dist (rope (i - 1), rope (i)) > 1 then\n            case method is\n              when use_previous_position =>\n                rope (i) := old_rope (i - 1);\n              when reduce_distance =>\n                Follow_Geometrically (rope (i - 1), rope (i));\n            end case;\n          end if;\n        end loop;\n        map (rope (len).x)(rope (len).y) := True;\n      end loop;\n    end loop Read_Data;\n    Close (f);\n\n    if verbose then\n      Dump_PPM\n        (To_Lower\n           (+\"length_\" & Image (len) & '_' &\n            Method_for_following'Image (method)));\n    end if;\n\n    total := 0;\n    for x in 1 .. mx loop\n      for y in 1 .. my loop\n        if map (x)(y) then total := total + 1; end if;\n      end loop;\n    end loop;\n\n    res (part) := total;\n  end loop Parts;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if res (1) /= Integer'Value (To_String (Argument (1))) or\n       res (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Method for following: \" & To_Lower (+Method_for_following'Image (method)));\n    Put_Line (+\"Number of visited points tail for a rope of...\");\n    Put_Line (+\"  (part 1) length 1: \" & res (1));\n    Put_Line (+\"  (part 2) length 9: \" & res (2));\n    --  Part 1: validated by AoC: 6314\n    --  Part 2: validated by AoC: 2504\n  end if;\nend AoC_2022_09;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_09.txt",
    "content": "L 1\nD 2\nR 1\nL 1\nR 2\nL 1\nU 2\nL 2\nD 1\nL 2\nU 2\nR 2\nD 2\nL 1\nD 2\nU 2\nL 2\nR 2\nL 1\nU 2\nD 2\nU 2\nD 2\nL 1\nR 2\nL 2\nD 2\nR 1\nD 1\nR 2\nU 1\nR 2\nL 2\nR 1\nU 2\nR 1\nD 1\nU 1\nL 2\nR 1\nD 2\nU 1\nR 1\nU 2\nL 1\nR 2\nU 1\nR 2\nL 2\nR 1\nD 2\nR 1\nD 1\nU 2\nR 1\nD 1\nU 1\nD 2\nL 1\nU 1\nD 1\nR 2\nD 2\nR 1\nD 2\nL 2\nD 2\nU 1\nL 1\nD 1\nL 1\nR 2\nU 2\nL 2\nD 2\nL 2\nD 1\nU 2\nD 2\nL 2\nR 1\nD 1\nL 1\nU 1\nL 1\nU 2\nL 1\nU 1\nD 1\nR 1\nL 1\nR 2\nD 1\nL 2\nD 2\nR 1\nD 2\nR 1\nD 1\nR 2\nL 2\nU 1\nD 2\nL 2\nU 2\nD 2\nR 1\nD 1\nU 2\nR 2\nU 2\nD 3\nL 1\nU 2\nR 2\nD 1\nU 1\nL 1\nU 3\nL 3\nU 2\nL 3\nU 3\nL 3\nD 3\nR 1\nU 3\nR 3\nU 3\nD 2\nR 2\nU 2\nR 3\nL 3\nU 1\nR 1\nD 3\nL 1\nU 1\nR 3\nU 3\nD 1\nL 3\nR 1\nU 3\nD 2\nU 2\nD 2\nR 1\nU 2\nL 2\nU 3\nL 1\nU 3\nD 3\nU 3\nL 2\nR 3\nD 1\nL 1\nR 3\nL 2\nD 3\nU 3\nR 2\nL 1\nR 2\nD 3\nU 3\nR 2\nU 3\nL 1\nR 2\nU 3\nD 2\nU 3\nL 3\nR 3\nD 3\nU 1\nD 1\nU 2\nR 2\nU 3\nD 3\nU 2\nD 2\nL 2\nD 2\nL 2\nR 1\nU 2\nD 2\nL 2\nR 1\nD 3\nL 3\nD 2\nL 3\nD 3\nL 2\nD 2\nL 2\nD 2\nU 2\nL 3\nD 3\nL 2\nU 2\nD 2\nR 3\nD 2\nU 3\nL 1\nR 1\nD 2\nU 3\nR 1\nU 2\nD 2\nR 2\nU 3\nR 2\nU 1\nL 1\nD 2\nR 4\nD 1\nU 4\nD 2\nU 3\nR 1\nD 2\nR 3\nL 2\nD 3\nL 3\nR 1\nD 1\nU 2\nR 1\nL 2\nR 2\nD 1\nL 1\nD 1\nL 4\nD 3\nR 1\nU 3\nR 2\nU 1\nR 1\nD 2\nL 2\nD 2\nU 3\nL 4\nD 4\nR 4\nL 2\nU 1\nR 2\nL 2\nU 4\nD 1\nR 4\nL 3\nR 4\nU 1\nD 2\nL 2\nR 2\nD 1\nL 2\nU 1\nD 3\nR 2\nU 2\nL 3\nD 4\nU 3\nR 4\nL 4\nR 1\nU 1\nD 2\nL 3\nD 1\nU 4\nR 2\nD 4\nL 2\nD 3\nL 2\nD 2\nL 1\nU 3\nL 4\nU 3\nD 4\nL 3\nD 1\nR 2\nD 2\nU 4\nL 4\nU 3\nL 4\nD 2\nR 3\nU 1\nL 2\nR 2\nD 2\nU 4\nL 2\nU 4\nD 1\nU 2\nR 4\nL 2\nU 4\nL 4\nU 2\nD 2\nU 4\nL 2\nU 3\nD 2\nL 3\nU 1\nL 2\nR 3\nD 2\nR 5\nL 5\nD 3\nR 4\nD 2\nR 4\nU 4\nR 5\nD 5\nR 5\nL 4\nU 2\nD 2\nR 2\nU 4\nR 2\nL 4\nR 3\nU 2\nR 5\nD 3\nL 4\nR 2\nL 3\nU 4\nR 2\nD 4\nR 2\nL 4\nD 4\nR 3\nD 5\nU 1\nL 2\nR 5\nL 5\nU 5\nD 1\nU 1\nL 3\nD 1\nU 5\nD 2\nR 3\nU 4\nR 4\nU 3\nL 5\nU 5\nD 5\nR 1\nD 3\nL 5\nR 5\nU 2\nD 2\nU 4\nD 3\nR 5\nU 5\nL 3\nU 3\nL 2\nU 4\nL 2\nR 4\nD 3\nL 4\nU 3\nD 1\nL 1\nD 4\nU 4\nD 1\nR 2\nL 5\nD 1\nU 4\nR 2\nD 3\nR 1\nD 1\nL 4\nD 2\nL 4\nR 3\nU 5\nL 1\nD 1\nL 5\nU 5\nR 5\nU 4\nD 5\nU 3\nD 5\nR 2\nU 2\nR 4\nD 1\nU 4\nR 3\nD 2\nU 3\nR 3\nL 1\nR 2\nD 4\nL 5\nD 6\nL 2\nD 3\nR 3\nU 3\nL 3\nR 3\nU 5\nR 4\nD 3\nR 5\nL 4\nD 6\nU 3\nR 2\nL 4\nD 3\nL 3\nR 3\nU 5\nR 1\nD 6\nL 5\nD 3\nU 2\nR 3\nD 3\nR 3\nU 1\nL 5\nR 6\nD 2\nU 4\nR 5\nU 1\nD 2\nU 5\nR 3\nL 4\nD 3\nL 6\nU 6\nR 2\nU 6\nL 3\nD 1\nR 2\nU 2\nR 3\nU 6\nL 4\nD 3\nR 2\nU 2\nL 3\nR 6\nU 3\nR 6\nL 2\nU 3\nR 3\nD 2\nR 6\nD 2\nL 4\nU 6\nD 2\nU 6\nL 1\nD 1\nL 5\nD 3\nR 6\nL 5\nR 6\nD 2\nR 4\nL 1\nU 4\nL 5\nU 5\nD 5\nR 6\nL 5\nU 5\nR 2\nD 6\nU 3\nR 2\nD 3\nU 3\nL 4\nD 5\nR 3\nU 5\nD 3\nR 3\nL 6\nR 3\nD 1\nU 2\nL 4\nD 4\nU 2\nL 4\nU 6\nD 5\nL 6\nU 5\nD 1\nU 6\nD 5\nU 2\nR 7\nU 6\nR 2\nD 2\nR 7\nD 4\nL 7\nU 5\nL 2\nU 4\nD 2\nR 2\nL 2\nD 3\nU 3\nD 6\nL 7\nR 5\nD 5\nL 7\nU 1\nD 5\nL 6\nU 1\nR 1\nD 7\nU 5\nD 4\nL 2\nU 1\nD 2\nU 6\nD 5\nU 1\nR 1\nL 3\nD 3\nU 3\nL 5\nD 5\nU 3\nR 6\nL 6\nR 1\nU 2\nD 3\nL 2\nU 6\nD 3\nR 3\nU 2\nD 1\nL 4\nU 2\nL 7\nU 4\nR 2\nD 6\nL 4\nD 6\nL 1\nD 3\nL 6\nD 4\nR 6\nU 3\nD 1\nL 4\nR 6\nU 5\nR 5\nU 5\nR 3\nL 6\nU 1\nD 2\nU 3\nD 1\nL 7\nD 6\nU 4\nD 5\nL 6\nU 7\nL 2\nU 4\nL 6\nR 6\nU 3\nD 4\nR 6\nU 1\nD 5\nR 5\nU 6\nR 4\nU 2\nD 2\nU 2\nR 3\nL 6\nU 6\nR 2\nL 2\nR 6\nL 1\nD 6\nR 2\nD 2\nL 8\nU 6\nR 7\nL 7\nD 3\nL 3\nR 8\nU 2\nL 7\nD 4\nR 5\nD 4\nR 1\nU 5\nD 2\nR 6\nL 7\nU 2\nL 4\nR 1\nD 2\nU 4\nD 3\nR 2\nU 1\nL 5\nU 5\nL 5\nR 7\nD 6\nR 2\nD 7\nR 1\nL 6\nR 8\nD 7\nR 3\nU 6\nL 7\nR 7\nU 8\nL 4\nD 4\nU 6\nL 5\nR 2\nL 2\nR 7\nD 8\nL 7\nD 2\nR 1\nU 1\nR 6\nD 5\nU 8\nR 5\nL 1\nR 7\nU 1\nL 7\nD 5\nL 6\nR 5\nL 3\nU 7\nL 8\nR 6\nU 6\nR 4\nU 1\nR 8\nU 1\nD 1\nU 8\nD 7\nR 1\nL 8\nR 1\nL 6\nD 8\nL 6\nU 7\nR 8\nD 4\nU 6\nR 7\nL 8\nU 4\nL 4\nD 6\nR 5\nL 1\nU 2\nD 1\nL 3\nD 7\nR 6\nL 3\nR 5\nL 1\nD 5\nL 3\nR 5\nU 5\nR 7\nU 6\nD 6\nU 2\nR 8\nD 3\nL 7\nD 5\nU 9\nR 5\nL 9\nD 5\nR 2\nU 6\nL 5\nU 9\nL 7\nD 3\nL 6\nU 3\nR 5\nD 7\nR 3\nL 5\nR 2\nL 6\nR 9\nL 8\nD 4\nL 6\nU 8\nL 8\nD 4\nR 2\nU 1\nD 6\nU 6\nR 3\nL 8\nU 2\nL 8\nD 9\nR 9\nL 1\nD 3\nR 6\nD 6\nL 9\nD 3\nR 9\nL 2\nD 8\nU 2\nR 8\nL 3\nD 9\nL 6\nD 9\nU 3\nD 9\nR 5\nL 2\nD 7\nL 6\nU 2\nL 8\nD 9\nL 5\nR 7\nL 3\nD 7\nU 4\nL 8\nR 9\nL 5\nR 7\nD 7\nR 6\nD 6\nL 6\nR 8\nL 6\nD 4\nR 5\nD 2\nL 5\nU 2\nD 8\nR 9\nL 3\nU 1\nL 6\nD 1\nR 9\nL 4\nU 1\nR 4\nL 1\nD 3\nR 5\nD 9\nL 4\nD 3\nU 9\nD 7\nL 5\nR 3\nL 7\nR 8\nL 1\nU 6\nL 8\nD 8\nR 6\nL 1\nU 1\nD 7\nR 10\nU 3\nD 4\nU 5\nD 3\nR 7\nU 8\nD 3\nU 8\nD 9\nL 10\nD 5\nL 7\nU 3\nD 3\nU 5\nR 5\nU 7\nL 2\nD 6\nU 6\nR 6\nU 9\nR 9\nL 5\nR 1\nL 4\nD 3\nU 4\nD 8\nU 3\nR 7\nD 1\nU 5\nL 6\nR 4\nU 2\nL 8\nU 10\nD 8\nU 8\nR 6\nL 1\nU 9\nR 9\nD 10\nU 8\nL 9\nD 5\nU 9\nD 9\nU 6\nD 10\nL 9\nR 4\nD 3\nR 10\nD 6\nR 8\nD 1\nU 4\nL 1\nD 6\nR 1\nL 1\nD 7\nR 1\nL 4\nR 5\nU 9\nR 5\nU 1\nR 9\nD 3\nU 4\nD 6\nL 3\nU 10\nD 3\nU 10\nR 10\nD 7\nL 5\nR 4\nD 4\nL 1\nR 7\nL 4\nR 5\nD 2\nL 9\nD 9\nL 5\nD 8\nR 1\nD 3\nL 8\nD 4\nL 8\nU 8\nL 7\nD 7\nU 4\nD 7\nR 10\nU 2\nR 7\nD 4\nL 6\nD 4\nU 3\nL 4\nU 8\nD 7\nL 9\nR 4\nD 9\nU 10\nL 7\nU 11\nR 5\nU 2\nD 4\nU 10\nL 3\nR 5\nU 8\nD 10\nL 7\nD 7\nR 2\nD 5\nU 6\nL 1\nU 11\nR 6\nD 9\nU 1\nL 4\nU 2\nD 1\nL 3\nD 6\nL 8\nU 9\nD 9\nL 5\nD 3\nR 2\nL 11\nD 9\nU 9\nR 10\nU 7\nD 11\nR 4\nL 11\nU 6\nR 2\nU 6\nD 1\nU 8\nL 11\nR 5\nL 11\nU 10\nR 2\nL 3\nD 8\nU 7\nR 11\nL 9\nU 7\nD 8\nR 2\nL 2\nR 5\nL 10\nR 4\nD 3\nR 5\nL 7\nD 2\nU 7\nR 2\nU 10\nL 1\nD 1\nU 2\nR 2\nD 1\nR 10\nL 6\nU 8\nR 3\nD 8\nU 10\nD 5\nR 3\nU 1\nL 2\nD 5\nR 11\nU 2\nR 11\nL 9\nU 1\nR 5\nL 6\nU 5\nD 1\nU 11\nD 1\nR 7\nL 9\nU 5\nD 11\nL 9\nU 1\nL 4\nD 1\nR 3\nD 10\nU 9\nL 3\nR 11\nL 9\nR 12\nU 8\nD 9\nL 12\nD 1\nU 10\nR 11\nU 9\nR 8\nU 11\nR 8\nU 6\nD 7\nR 7\nU 10\nL 10\nU 4\nL 10\nR 2\nD 6\nL 10\nD 10\nR 10\nU 1\nL 7\nD 8\nL 12\nR 9\nU 9\nL 10\nR 11\nD 12\nR 6\nU 10\nR 3\nD 12\nU 12\nR 1\nD 3\nR 5\nU 8\nD 2\nU 4\nD 12\nL 3\nD 11\nU 9\nL 2\nR 7\nL 5\nU 2\nR 5\nL 5\nU 1\nL 4\nR 12\nL 11\nR 8\nD 4\nU 5\nR 5\nU 9\nR 7\nL 6\nR 7\nL 1\nU 6\nD 6\nL 3\nU 1\nL 4\nU 6\nR 5\nL 9\nU 12\nD 11\nR 11\nU 11\nD 7\nU 3\nL 12\nU 7\nL 2\nD 3\nU 10\nD 2\nU 6\nL 9\nR 2\nD 12\nR 11\nU 12\nL 1\nD 9\nR 4\nD 4\nU 5\nD 12\nR 9\nU 6\nL 8\nD 5\nU 6\nD 10\nR 3\nL 1\nU 4\nR 2\nL 8\nU 9\nL 6\nD 1\nL 6\nU 5\nR 6\nD 4\nL 7\nU 2\nR 12\nU 12\nR 13\nU 6\nR 7\nD 12\nR 3\nU 3\nD 10\nU 12\nR 11\nD 3\nU 11\nL 6\nR 5\nD 7\nL 10\nD 5\nL 7\nU 8\nL 3\nU 5\nR 1\nL 1\nR 1\nD 10\nL 2\nR 1\nU 9\nL 10\nU 13\nR 3\nD 9\nR 6\nD 1\nR 7\nU 8\nD 7\nU 13\nR 3\nU 11\nL 13\nR 8\nL 13\nD 6\nL 8\nU 6\nD 10\nR 3\nD 9\nR 11\nU 1\nL 11\nU 5\nR 6\nU 6\nD 10\nR 5\nL 1\nR 6\nU 11\nL 8\nR 3\nD 7\nU 4\nR 5\nD 8\nU 7\nL 6\nU 6\nL 9\nU 10\nR 5\nL 7\nR 5\nL 13\nU 7\nD 1\nL 7\nU 2\nR 9\nL 8\nU 5\nL 13\nR 11\nD 4\nR 6\nU 13\nD 13\nL 9\nR 8\nD 12\nR 6\nD 1\nL 12\nR 8\nU 1\nL 7\nR 13\nD 13\nL 13\nU 7\nD 7\nL 4\nU 13\nR 7\nU 14\nD 11\nR 7\nU 3\nL 9\nU 8\nL 3\nR 14\nD 2\nU 4\nR 1\nL 13\nU 2\nD 5\nU 2\nR 7\nU 14\nD 10\nL 1\nD 7\nL 2\nU 14\nL 14\nR 12\nU 2\nD 5\nL 10\nU 3\nR 11\nD 12\nR 14\nU 7\nR 10\nD 9\nL 13\nD 13\nR 12\nD 14\nR 3\nD 4\nU 8\nL 11\nU 9\nL 5\nU 1\nR 12\nD 6\nU 1\nR 1\nL 5\nU 5\nL 1\nD 5\nU 4\nD 13\nU 7\nR 5\nD 11\nU 9\nR 3\nD 11\nL 9\nD 8\nR 8\nU 8\nL 6\nR 3\nD 5\nL 10\nU 1\nL 4\nR 13\nL 5\nD 8\nL 5\nU 11\nL 8\nR 12\nL 6\nR 12\nU 5\nD 12\nR 12\nD 4\nU 9\nL 4\nR 11\nL 2\nR 11\nU 12\nD 14\nL 2\nU 5\nL 7\nD 8\nU 12\nD 4\nR 4\nL 13\nD 9\nU 11\nR 1\nD 2\nU 8\nD 10\nU 8\nL 6\nU 9\nR 8\nL 12\nU 9\nR 3\nU 14\nR 3\nU 9\nL 11\nU 2\nL 10\nD 6\nU 2\nL 4\nD 12\nL 8\nR 15\nD 11\nL 9\nR 6\nU 9\nR 11\nU 7\nR 13\nL 9\nD 9\nU 2\nR 9\nU 11\nR 15\nU 4\nL 4\nU 6\nD 3\nR 10\nL 5\nU 8\nD 6\nR 6\nD 6\nU 10\nL 7\nR 9\nD 6\nU 12\nR 15\nL 8\nD 9\nU 15\nD 6\nL 14\nD 2\nR 15\nU 14\nD 15\nU 13\nR 1\nU 11\nR 8\nU 13\nD 6\nL 2\nR 1\nU 7\nR 6\nD 13\nU 13\nR 15\nD 15\nR 1\nU 14\nD 9\nU 5\nL 6\nR 9\nL 13\nD 6\nU 2\nR 7\nD 3\nL 10\nR 7\nL 2\nU 4\nD 1\nL 9\nU 9\nR 7\nU 3\nD 7\nU 1\nR 12\nL 11\nR 7\nL 14\nR 3\nL 15\nR 15\nU 5\nR 12\nD 9\nR 5\nU 12\nL 12\nU 6\nL 4\nR 2\nU 2\nL 5\nD 3\nR 12\nD 8\nU 16\nD 16\nL 11\nD 7\nU 15\nR 13\nU 5\nD 6\nL 12\nD 2\nL 16\nD 16\nL 8\nU 9\nR 12\nD 16\nU 2\nR 1\nL 12\nU 9\nD 15\nU 16\nL 14\nD 4\nU 5\nL 2\nR 5\nD 9\nL 4\nR 13\nL 2\nU 2\nR 4\nL 15\nR 13\nD 11\nR 13\nL 13\nU 14\nR 8\nU 5\nD 10\nL 2\nU 15\nD 3\nL 8\nU 2\nL 14\nU 3\nR 16\nU 4\nD 1\nR 5\nL 3\nR 1\nL 16\nD 16\nL 12\nU 14\nR 12\nU 8\nR 1\nL 1\nR 9\nU 9\nR 12\nL 1\nU 9\nL 14\nU 11\nL 8\nU 10\nL 7\nU 1\nL 11\nR 2\nD 12\nU 3\nR 2\nL 14\nD 1\nL 12\nR 16\nD 16\nR 8\nL 15\nR 3\nL 10\nD 14\nR 9\nU 2\nD 4\nU 7\nD 2\nR 11\nD 6\nU 2\nR 4\nL 2\nR 6\nL 11\nR 9\nL 1\nR 8\nD 3\nR 4\nU 14\nD 7\nL 11\nR 14\nL 8\nD 9\nL 6\nD 15\nR 4\nD 9\nU 7\nR 6\nL 13\nD 11\nR 10\nL 17\nR 17\nD 17\nR 7\nU 15\nD 14\nR 6\nU 14\nR 5\nU 17\nR 7\nL 17\nU 14\nL 14\nR 13\nU 4\nR 14\nU 10\nL 16\nU 8\nR 2\nU 4\nD 16\nU 4\nL 14\nR 7\nD 13\nU 10\nL 10\nR 3\nL 6\nD 7\nR 13\nL 6\nU 7\nR 16\nL 10\nU 6\nL 6\nU 11\nD 6\nU 5\nL 4\nU 17\nR 6\nL 3\nD 5\nR 4\nU 1\nL 14\nR 10\nL 4\nU 9\nR 7\nD 2\nR 6\nU 12\nD 15\nR 15\nL 13\nU 5\nL 12\nD 3\nU 15\nL 9\nU 3\nD 12\nR 15\nU 7\nL 7\nR 11\nL 14\nR 2\nD 6\nR 6\nD 9\nR 2\nL 12\nR 2\nU 12\nR 8\nL 2\nU 12\nR 2\nD 17\nL 8\nD 1\nU 16\nD 1\nR 5\nL 9\nU 4\nL 1\nU 9\nL 11\nR 9\nD 7\nR 16\nD 12\nR 3\nU 7\nL 4\nR 7\nL 8\nD 9\nU 10\nD 7\nU 10\nD 5\nU 14\nD 5\nU 11\nR 15\nU 8\nD 12\nU 8\nL 18\nU 16\nD 16\nU 3\nR 5\nD 2\nU 10\nL 17\nR 5\nU 15\nR 9\nD 5\nU 9\nL 12\nD 17\nR 14\nL 4\nR 14\nL 17\nD 9\nL 10\nD 17\nR 1\nU 2\nR 7\nU 13\nR 1\nU 17\nR 4\nL 3\nD 14\nU 11\nL 15\nR 6\nU 4\nD 8\nL 17\nD 3\nR 13\nU 10\nR 4\nU 5\nR 3\nU 16\nD 6\nL 5\nR 18\nL 11\nD 16\nU 7\nR 7\nU 1\nR 14\nU 14\nR 4\nD 3\nR 12\nD 13\nU 5\nD 8\nR 17\nL 9\nD 4\nL 13\nU 8\nR 13\nD 5\nU 17\nL 11\nU 13\nD 9\nL 8\nR 14\nL 15\nD 10\nR 11\nD 8\nL 10\nU 3\nL 3\nR 12\nL 9\nR 17\nU 10\nL 17\nU 13\nL 12\nU 1\nD 2\nR 1\nL 16\nR 11\nD 15\nL 8\nR 10\nL 12\nU 3\nL 17\nU 7\nR 6\nU 16\nR 1\nL 3\nR 5\nL 11\nR 4\nD 10\nL 1\nR 4\nU 12\nL 18\nR 8\nL 7\nR 16\nU 19\nR 10\nU 11\nD 12\nR 6\nU 17\nL 16\nD 19\nL 9\nU 1\nR 12\nU 12\nR 15\nD 4\nL 15\nR 4\nL 9\nR 15\nL 10\nR 7\nL 16\nU 16\nL 19\nU 5\nL 4\nU 12\nL 6\nU 5\nR 17\nU 11\nR 6\nU 15\nL 9\nD 4\nR 2\nL 7\nR 16\nL 13\nU 19\nR 4\nU 13\nL 18\nD 19\nU 15\nR 13\nL 11\nU 18\nD 2\nU 9\nD 18\nL 13\nD 13\nL 11\nU 3\nD 11\nU 16\nR 14\nD 6\nL 12\nD 9\nR 2\nD 14\nL 12\nR 15\nD 2\nR 11\nU 7\nD 9\nL 16\nR 12\nL 12\nD 14\nU 2\nD 12\nR 8\nU 9\nD 10\nU 12\nL 17\nU 19\nL 4\nU 15\nR 12\nL 11\nD 12\nL 8\nU 3\nR 7\nL 2\nD 4\nU 17\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_09_questions.txt",
    "content": "--- Day 9: Rope Bridge ---\n\nThis rope bridge creaks as you walk along it. You aren't sure how\nold it is, or whether it can even support your weight.\n\nIt seems to support the Elves just fine, though.\nThe bridge spans a gorge which was carved out by the massive\nriver far below you.\n\nYou step carefully; as you do, the ropes stretch and twist.\nYou decide to distract yourself by modeling rope physics;\nmaybe you can even figure out where not to step.\n\nConsider a rope with a knot at each end; these knots mark\nthe head and the tail of the rope. If the head moves far enough\naway from the tail, the tail is pulled toward the head.\n\nDue to nebulous reasoning involving Planck lengths, you should\nbe able to model the positions of the knots on a two-dimensional grid.\nThen, by following a hypothetical series of motions (your puzzle input)\nfor the head, you can determine how the tail will move.\n\nDue to the aforementioned Planck lengths, the rope must be quite\nshort; in fact, the head (H) and tail (T) must always be touching\n(diagonally adjacent and even overlapping both count as touching):\n\n....\n.TH.\n....\n\n....\n.H..\n..T.\n....\n\n...\n.H. (H covers T)\n...\n\nIf the head is ever two steps directly up, down, left, or right\nfrom the tail, the tail must also move one step in that direction\nso it remains close enough:\n\n.....    .....    .....\n.TH.. -> .T.H. -> ..TH.\n.....    .....    .....\n\n...    ...    ...\n.T.    .T.    ...\n.H. -> ... -> .T.\n...    .H.    .H.\n...    ...    ...\n\nOtherwise, if the head and tail aren't touching and aren't in the same\nrow or column, the tail always moves one step diagonally to keep up:\n\n.....    .....    .....\n.....    ..H..    ..H..\n..H.. -> ..... -> ..T..\n.T...    .T...    .....\n.....    .....    .....\n\n.....    .....    .....\n.....    .....    .....\n..H.. -> ...H. -> ..TH.\n.T...    .T...    .....\n.....    .....    .....\n\nYou just need to work out where the tail goes as the head follows\na series of motions. Assume the head and the tail both start at\nthe same position, overlapping.\n\nFor example:\n\nR 4\nU 4\nL 3\nD 1\nR 4\nD 1\nL 5\nR 2\n\nThis series of motions moves the head right four steps, then up\nfour steps, then left three steps, then down one step, and so on.\nAfter each step, you'll need to update the position of the tail\nif the step means the head is no longer adjacent to the tail.\nVisually, these motions occur as follows (s marks the starting\nposition as a reference point):\n\n== Initial State ==\n\n......\n......\n......\n......\nH.....  (H covers T, s)\n\n== R 4 ==\n\n......\n......\n......\n......\nTH....  (T covers s)\n\n......\n......\n......\n......\nsTH...\n\n......\n......\n......\n......\ns.TH..\n\n......\n......\n......\n......\ns..TH.\n\n== U 4 ==\n\n......\n......\n......\n....H.\ns..T..\n\n......\n......\n....H.\n....T.\ns.....\n\n......\n....H.\n....T.\n......\ns.....\n\n....H.\n....T.\n......\n......\ns.....\n\n== L 3 ==\n\n...H..\n....T.\n......\n......\ns.....\n\n..HT..\n......\n......\n......\ns.....\n\n.HT...\n......\n......\n......\ns.....\n\n== D 1 ==\n\n..T...\n.H....\n......\n......\ns.....\n\n== R 4 ==\n\n..T...\n..H...\n......\n......\ns.....\n\n..T...\n...H..\n......\n......\ns.....\n\n......\n...TH.\n......\n......\ns.....\n\n......\n....TH\n......\n......\ns.....\n\n== D 1 ==\n\n......\n....T.\n.....H\n......\ns.....\n\n== L 5 ==\n\n......\n....T.\n....H.\n......\ns.....\n\n......\n....T.\n...H..\n......\ns.....\n\n......\n......\n..HT..\n......\ns.....\n\n......\n......\n.HT...\n......\ns.....\n\n......\n......\nHT....\n......\ns.....\n\n== R 2 ==\n\n......\n......\n.H....  (H covers T)\n......\ns.....\n\n......\n......\n.TH...\n......\ns.....\n\nAfter simulating the rope, you can count up all of the positions\nthe tail visited at least once. In this diagram, s again marks\nthe starting position (which the tail also visited) and # marks\nother positions the tail visited:\n\n..##..\n...##.\n.####.\n....#.\ns###..\n\nSo, there are 13 positions the tail visited at least once.\n\nSimulate your complete hypothetical series of motions.\nHow many positions does the tail of the rope visit at least once?\n\n--- Part Two ---\n\nA rope snaps! Suddenly, the river is getting a lot closer\nthan you remember. The bridge is still there, but some of the ropes\nthat broke are now whipping toward you as you fall through the air!\n\nThe ropes are moving too quickly to grab; you only have a few seconds\nto choose how to arch your body to avoid being hit.\nFortunately, your simulation can be extended to support longer ropes.\n\nRather than two knots, you now must simulate a rope consisting\nof ten knots. One knot is still the head of the rope and moves\naccording to the series of motions. Each knot further down the\nrope follows the knot in front of it using the same rules as\nbefore.\n\nUsing the same series of motions as the above example,\nbut with the knots marked H, 1, 2, ..., 9, the motions\nnow occur as follows:\n\n== Initial State ==\n\n......\n......\n......\n......\nH.....  (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)\n\n== R 4 ==\n\n......\n......\n......\n......\n1H....  (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s)\n\n......\n......\n......\n......\n21H...  (2 covers 3, 4, 5, 6, 7, 8, 9, s)\n\n......\n......\n......\n......\n321H..  (3 covers 4, 5, 6, 7, 8, 9, s)\n\n......\n......\n......\n......\n4321H.  (4 covers 5, 6, 7, 8, 9, s)\n\n== U 4 ==\n\n......\n......\n......\n....H.\n4321..  (4 covers 5, 6, 7, 8, 9, s)\n\n......\n......\n....H.\n.4321.\n5.....  (5 covers 6, 7, 8, 9, s)\n\n......\n....H.\n....1.\n.432..\n5.....  (5 covers 6, 7, 8, 9, s)\n\n....H.\n....1.\n..432.\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n== L 3 ==\n\n...H..\n....1.\n..432.\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n..H1..\n...2..\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n.H1...\n...2..\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n== D 1 ==\n\n..1...\n.H.2..\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n== R 4 ==\n\n..1...\n..H2..\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n..1...\n...H..  (H covers 2)\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n...1H.  (1 covers 2)\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n...21H\n..43..\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n== D 1 ==\n\n......\n...21.\n..43.H\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n== L 5 ==\n\n......\n...21.\n..43H.\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n...21.\n..4H..  (H covers 3)\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n...2..\n..H1..  (H covers 4; 1 covers 3)\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n...2..\n.H13..  (1 covers 4)\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n......\nH123..  (2 covers 4)\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n== R 2 ==\n\n......\n......\n.H23..  (H covers 1; 2 covers 4)\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\n......\n......\n.1H3..  (H covers 2, 4)\n.5....\n6.....  (6 covers 7, 8, 9, s)\n\nNow, you need to keep track of the positions the new tail, 9, visits.\nIn this example, the tail never moves, and so it only visits 1 position.\nHowever, be careful: more types of motion are possible than before,\nso you might want to visually compare your simulated rope\nto the one above.\n\nHere's a larger example:\n\nR 5\nU 8\nL 8\nD 3\nR 17\nD 10\nL 25\nU 20\n\nThese motions occur as follows (individual steps are not shown):\n\n== Initial State ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n...........H..............  (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)\n..........................\n..........................\n..........................\n..........................\n..........................\n\n== R 5 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n...........54321H.........  (5 covers 6, 7, 8, 9, s)\n..........................\n..........................\n..........................\n..........................\n..........................\n\n== U 8 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n................H.........\n................1.........\n................2.........\n................3.........\n...............54.........\n..............6...........\n.............7............\n............8.............\n...........9..............  (9 covers s)\n..........................\n..........................\n..........................\n..........................\n..........................\n\n== L 8 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n........H1234.............\n............5.............\n............6.............\n............7.............\n............8.............\n............9.............\n..........................\n..........................\n...........s..............\n..........................\n..........................\n..........................\n..........................\n..........................\n\n== D 3 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n.........2345.............\n........1...6.............\n........H...7.............\n............8.............\n............9.............\n..........................\n..........................\n...........s..............\n..........................\n..........................\n..........................\n..........................\n..........................\n\n== R 17 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n................987654321H\n..........................\n..........................\n..........................\n..........................\n...........s..............\n..........................\n..........................\n..........................\n..........................\n..........................\n\n== D 10 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n...........s.........98765\n.........................4\n.........................3\n.........................2\n.........................1\n.........................H\n\n== L 25 ==\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n...........s..............\n..........................\n..........................\n..........................\n..........................\nH123456789................\n\n== U 20 ==\n\nH.........................\n1.........................\n2.........................\n3.........................\n4.........................\n5.........................\n6.........................\n7.........................\n8.........................\n9.........................\n..........................\n..........................\n..........................\n..........................\n..........................\n...........s..............\n..........................\n..........................\n..........................\n..........................\n..........................\n\nNow, the tail (9) visits 36 positions (including s) at least once:\n\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n..........................\n#.........................\n#.............###.........\n#............#...#........\n.#..........#.....#.......\n..#..........#.....#......\n...#........#.......#.....\n....#......s.........#....\n.....#..............#.....\n......#............#......\n.......#..........#.......\n........#........#........\n.........########.........\n\nSimulate your complete series of motions on a larger rope\nwith ten knots. How many positions does the tail of the\nrope visit at least once?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_10.adb",
    "content": "--  Solution to Advent of Code 2022, Day 10\n-------------------------------------------\n--  Cathode-Ray Tube\n--\n--  https://adventofcode.com/2022/day/10\n--  Copy of questions in: aoc_2022_10_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_10 is\n  use HAT;\n\n  T0 : constant Time := Clock;\n  asm : String (1 .. 4);\n  arg : Integer;\n  f : File_Type;\n  add : array (1 .. 241) of Integer;\n  screen : array (0 .. 5, 0 .. 39) of Character;\n  sum, cycle, x, scr_i, scr_j : Integer;\n\nbegin\n  for i in add'Range loop\n    add (i) := 0;\n  end loop;\n\n  cycle := 1;\n  Open (f, \"aoc_2022_10.txt\");\n  while not End_Of_File (f) loop\n    Get (f, asm);\n    if asm = \"noop\" then\n      cycle := cycle + 1;\n    else\n      Get (f, arg);\n      cycle := cycle + 2;\n      add (cycle) := arg;\n    end if;\n  end loop;\n  Close (f);\n\n  for i in screen'Range (1) loop\n    for j in screen'Range (2) loop\n      --  We fill the screen with spaces.\n      --  In the end it should be full with '.' or '#'.\n      screen (i, j) := ' ';\n    end loop;\n  end loop;\n\n  --  Here we start the virtual machine.\n  x := 1;\n  sum := 0;\nVM_Run :\n  for cy in 1 .. cycle loop\n    x := x + add (cy);\n    if (cy - 20) mod 40 = 0 then\n      sum := sum + x * cy;\n    end if;\n    --\n    scr_i := (cy - 1) / 40;\n    scr_j := (cy - 1) mod 40;\n    if scr_i in screen'Range (1) then\n      if abs (scr_j - x) < 2 then\n        screen (scr_i, scr_j) := '#';\n      else\n        screen (scr_i, scr_j) := '.';\n      end if;\n    end if;\n  end loop VM_Run;\n\n  if Argument_Count >= 1 then\n    --  Compiler test mode.\n    if sum /= Integer'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: sum of signal strengths: \" & sum);\n    Put_Line (+\"Part 2:\");\n    for i in screen'Range (1) loop\n      for j in screen'Range (2) loop\n        Put (screen (i, j));\n      end loop;\n      New_Line;\n    end loop;\n    --  Part 1: validated by AoC: 12880\n    --  Part 2: validated by AoC: FCJAPJRE\n  end if;\nend AoC_2022_10;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_10.txt",
    "content": "addx 2\naddx 15\naddx -11\naddx 6\nnoop\nnoop\nnoop\naddx -1\naddx 5\naddx -1\naddx 5\nnoop\nnoop\nnoop\nnoop\nnoop\naddx 7\naddx -1\naddx 3\naddx 1\naddx 5\naddx 1\nnoop\naddx -38\nnoop\naddx 1\naddx 6\naddx 3\nnoop\naddx -8\nnoop\naddx 13\naddx 2\naddx 3\naddx -2\naddx 2\nnoop\naddx 3\naddx 9\naddx -2\naddx 2\naddx -10\naddx 11\naddx 2\naddx -14\naddx -21\naddx 2\nnoop\naddx 5\naddx 29\naddx -2\nnoop\naddx -19\nnoop\naddx 2\naddx 11\naddx -10\naddx 2\naddx 5\naddx -9\nnoop\naddx 14\naddx 2\naddx 3\naddx -2\naddx 3\naddx 1\nnoop\naddx -37\nnoop\naddx 13\naddx -8\nnoop\nnoop\nnoop\nnoop\naddx 13\naddx -5\naddx 3\naddx 3\naddx 3\nnoop\nnoop\nnoop\nnoop\nnoop\nnoop\nnoop\naddx 6\naddx 3\naddx 1\naddx 5\naddx -15\naddx 5\naddx -27\naddx 30\naddx -23\naddx 33\naddx -32\naddx 2\naddx 5\naddx 2\naddx -16\naddx 17\naddx 2\naddx -10\naddx 17\naddx 10\naddx -9\naddx 2\naddx 2\naddx 5\naddx -29\naddx -8\nnoop\nnoop\nnoop\naddx 19\naddx -11\naddx -1\naddx 6\nnoop\nnoop\naddx -1\naddx 3\nnoop\naddx 3\naddx 2\naddx -3\naddx 11\naddx -1\naddx 5\naddx -2\naddx 5\naddx 2\nnoop\nnoop\naddx 1\nnoop\nnoop\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_10_questions.txt",
    "content": "--- Day 10: Cathode-Ray Tube ---\n\nYou avoid the ropes, plunge into the river, and swim to shore.\n\nThe Elves yell something about meeting back up with them upriver,\nbut the river is too loud to tell exactly what they're saying.\nThey finish crossing the bridge and disappear from view.\n\nSituations like this must be why the Elves prioritized getting the\ncommunication system on your handheld device working. You pull it\nout of your pack, but the amount of water slowly draining from a\nbig crack in its screen tells you it probably won't be of much\nimmediate use.\n\nUnless, that is, you can design a replacement for the device's video\nsystem! It seems to be some kind of cathode-ray tube screen and\nsimple CPU that are both driven by a precise clock circuit.\nThe clock circuit ticks at a constant rate; each tick is called\na cycle.\n\nStart by figuring out the signal being sent by the CPU.\nThe CPU has a single register, X, which starts with the value 1.\nIt supports only two instructions:\n\n    addx V takes two cycles to complete. After two cycles, the X register is increased by the value V. (V can be negative.)\n    noop takes one cycle to complete. It has no other effect.\n\nThe CPU uses these instructions in a program (your puzzle input) to,\nsomehow, tell the screen what to draw.\n\nConsider the following small program:\n\nnoop\naddx 3\naddx -5\n\nExecution of this program proceeds as follows:\n\n    At the start of the first cycle, the noop instruction begins\n      execution. During the first cycle, X is 1. After the first\n      cycle, the noop instruction finishes execution, doing nothing.\n    At the start of the second cycle, the addx 3 instruction begins\n      execution. During the second cycle, X is still 1.\n    During the third cycle, X is still 1. After the third cycle,\n      the addx 3 instruction finishes execution, setting X to 4.\n    At the start of the fourth cycle, the addx -5 instruction begins\n      execution. During the fourth cycle, X is still 4.\n    During the fifth cycle, X is still 4. After the fifth cycle,\n      the addx -5 instruction finishes execution, setting X to -1.\n\nMaybe you can learn something by looking at the value of the X\nregister throughout execution. For now, consider the signal strength\n(the cycle number multiplied by the value of the X register) during\nthe 20th cycle and every 40 cycles after that (that is, during the\n20th, 60th, 100th, 140th, 180th, and 220th cycles).\n\nFor example, consider this larger program:\n\naddx 15\naddx -11\naddx 6\naddx -3\naddx 5\naddx -1\naddx -8\naddx 13\naddx 4\nnoop\naddx -1\naddx 5\naddx -1\naddx 5\naddx -1\naddx 5\naddx -1\naddx 5\naddx -1\naddx -35\naddx 1\naddx 24\naddx -19\naddx 1\naddx 16\naddx -11\nnoop\nnoop\naddx 21\naddx -15\nnoop\nnoop\naddx -3\naddx 9\naddx 1\naddx -3\naddx 8\naddx 1\naddx 5\nnoop\nnoop\nnoop\nnoop\nnoop\naddx -36\nnoop\naddx 1\naddx 7\nnoop\nnoop\nnoop\naddx 2\naddx 6\nnoop\nnoop\nnoop\nnoop\nnoop\naddx 1\nnoop\nnoop\naddx 7\naddx 1\nnoop\naddx -13\naddx 13\naddx 7\nnoop\naddx 1\naddx -33\nnoop\nnoop\nnoop\naddx 2\nnoop\nnoop\nnoop\naddx 8\nnoop\naddx -1\naddx 2\naddx 1\nnoop\naddx 17\naddx -9\naddx 1\naddx 1\naddx -3\naddx 11\nnoop\nnoop\naddx 1\nnoop\naddx 1\nnoop\nnoop\naddx -13\naddx -19\naddx 1\naddx 3\naddx 26\naddx -30\naddx 12\naddx -1\naddx 3\naddx 1\nnoop\nnoop\nnoop\naddx -9\naddx 18\naddx 1\naddx 2\nnoop\nnoop\naddx 9\nnoop\nnoop\nnoop\naddx -1\naddx 2\naddx -37\naddx 1\naddx 3\nnoop\naddx 15\naddx -21\naddx 22\naddx -6\naddx 1\nnoop\naddx 2\naddx 1\nnoop\naddx -10\nnoop\nnoop\naddx 20\naddx 1\naddx 2\naddx 2\naddx -6\naddx -11\nnoop\nnoop\nnoop\n\nThe interesting signal strengths can be determined as follows:\n\n    During the 20th cycle, register X has the value 21, so the\n      signal strength is 20 * 21 = 420. (The 20th cycle occurs in the\n      middle of the second addx -1, so the value of register X is the\n      starting value, 1, plus all of the other addx values up to\n      that point: 1 + 15 - 11 + 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.)\n    During the 60th cycle, register X has the value 19, so\n      the signal strength is 60 * 19 = 1140.\n    During the 100th cycle, register X has the value 18,\n      so the signal strength is 100 * 18 = 1800.\n    During the 140th cycle, register X has the value 21,\n      so the signal strength is 140 * 21 = 2940.\n    During the 180th cycle, register X has the value 16,\n      so the signal strength is 180 * 16 = 2880.\n    During the 220th cycle, register X has the value 18,\n      so the signal strength is 220 * 18 = 3960.\n\nThe sum of these signal strengths is 13140.\n\nFind the signal strength during the 20th, 60th, 100th, 140th, 180th,\nand 220th cycles. What is the sum of these six signal strengths?\n\n--- Part Two ---\n\nIt seems like the X register controls the horizontal position of\na sprite. Specifically, the sprite is 3 pixels wide, and the X register\nsets the horizontal position of the middle of that sprite. (In this\nsystem, there is no such thing as \"vertical position\": if the\nsprite's horizontal position puts its pixels where the CRT is\ncurrently drawing, then those pixels will be drawn.)\n\nYou count the pixels on the CRT: 40 wide and 6 high.\nThis CRT screen draws the top row of pixels left-to-right,\nthen the row below that, and so on.\nThe left-most pixel in each row is in position 0, and the right-most\npixel in each row is in position 39.\n\nLike the CPU, the CRT is tied closely to the clock circuit:\nthe CRT draws a single pixel during each cycle.\nRepresenting each pixel of the screen as a #, here are the cycles\nduring which the first and last pixel in each row are drawn:\n\nCycle   1 -> ######################################## <- Cycle  40\nCycle  41 -> ######################################## <- Cycle  80\nCycle  81 -> ######################################## <- Cycle 120\nCycle 121 -> ######################################## <- Cycle 160\nCycle 161 -> ######################################## <- Cycle 200\nCycle 201 -> ######################################## <- Cycle 240\n\nSo, by carefully timing the CPU instructions and the CRT drawing\noperations, you should be able to determine whether the sprite is\nvisible the instant each pixel is drawn. If the sprite is positioned\nsuch that one of its three pixels is the pixel currently being drawn,\nthe screen produces a lit pixel (#); otherwise, the screen leaves\nthe pixel dark (.).\n\nThe first few pixels from the larger example above are drawn as follows:\n\nSprite position: ###.....................................\n\nStart cycle   1: begin executing addx 15\nDuring cycle  1: CRT draws pixel in position 0\nCurrent CRT row: #\n\nDuring cycle  2: CRT draws pixel in position 1\nCurrent CRT row: ##\nEnd of cycle  2: finish executing addx 15 (Register X is now 16)\nSprite position: ...............###......................\n\nStart cycle   3: begin executing addx -11\nDuring cycle  3: CRT draws pixel in position 2\nCurrent CRT row: ##.\n\nDuring cycle  4: CRT draws pixel in position 3\nCurrent CRT row: ##..\nEnd of cycle  4: finish executing addx -11 (Register X is now 5)\nSprite position: ....###.................................\n\nStart cycle   5: begin executing addx 6\nDuring cycle  5: CRT draws pixel in position 4\nCurrent CRT row: ##..#\n\nDuring cycle  6: CRT draws pixel in position 5\nCurrent CRT row: ##..##\nEnd of cycle  6: finish executing addx 6 (Register X is now 11)\nSprite position: ..........###...........................\n\nStart cycle   7: begin executing addx -3\nDuring cycle  7: CRT draws pixel in position 6\nCurrent CRT row: ##..##.\n\nDuring cycle  8: CRT draws pixel in position 7\nCurrent CRT row: ##..##..\nEnd of cycle  8: finish executing addx -3 (Register X is now 8)\nSprite position: .......###..............................\n\nStart cycle   9: begin executing addx 5\nDuring cycle  9: CRT draws pixel in position 8\nCurrent CRT row: ##..##..#\n\nDuring cycle 10: CRT draws pixel in position 9\nCurrent CRT row: ##..##..##\nEnd of cycle 10: finish executing addx 5 (Register X is now 13)\nSprite position: ............###.........................\n\nStart cycle  11: begin executing addx -1\nDuring cycle 11: CRT draws pixel in position 10\nCurrent CRT row: ##..##..##.\n\nDuring cycle 12: CRT draws pixel in position 11\nCurrent CRT row: ##..##..##..\nEnd of cycle 12: finish executing addx -1 (Register X is now 12)\nSprite position: ...........###..........................\n\nStart cycle  13: begin executing addx -8\nDuring cycle 13: CRT draws pixel in position 12\nCurrent CRT row: ##..##..##..#\n\nDuring cycle 14: CRT draws pixel in position 13\nCurrent CRT row: ##..##..##..##\nEnd of cycle 14: finish executing addx -8 (Register X is now 4)\nSprite position: ...###..................................\n\nStart cycle  15: begin executing addx 13\nDuring cycle 15: CRT draws pixel in position 14\nCurrent CRT row: ##..##..##..##.\n\nDuring cycle 16: CRT draws pixel in position 15\nCurrent CRT row: ##..##..##..##..\nEnd of cycle 16: finish executing addx 13 (Register X is now 17)\nSprite position: ................###.....................\n\nStart cycle  17: begin executing addx 4\nDuring cycle 17: CRT draws pixel in position 16\nCurrent CRT row: ##..##..##..##..#\n\nDuring cycle 18: CRT draws pixel in position 17\nCurrent CRT row: ##..##..##..##..##\nEnd of cycle 18: finish executing addx 4 (Register X is now 21)\nSprite position: ....................###.................\n\nStart cycle  19: begin executing noop\nDuring cycle 19: CRT draws pixel in position 18\nCurrent CRT row: ##..##..##..##..##.\nEnd of cycle 19: finish executing noop\n\nStart cycle  20: begin executing addx -1\nDuring cycle 20: CRT draws pixel in position 19\nCurrent CRT row: ##..##..##..##..##..\n\nDuring cycle 21: CRT draws pixel in position 20\nCurrent CRT row: ##..##..##..##..##..#\nEnd of cycle 21: finish executing addx -1 (Register X is now 20)\nSprite position: ...................###..................\n\nAllowing the program to run to completion causes the CRT to\nproduce the following image:\n\n##..##..##..##..##..##..##..##..##..##..\n###...###...###...###...###...###...###.\n####....####....####....####....####....\n#####.....#####.....#####.....#####.....\n######......######......######......####\n#######.......#######.......#######.....\n\nRender the image given by your program. What eight capital\nletters appear on your CRT?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_11.adb",
    "content": "--  Solution to Advent of Code 2022, Day 11\n-------------------------------------------\n--  Monkey in the Middle\n--\n--  https://adventofcode.com/2022/day/1\n--  Copy of questions in: aoc_2022_11_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and another compiler, like GNAT.\n--  64-bit integer in Interfaces: Integer_64.\nwith Interfaces;\n\nprocedure AoC_2022_11 is\n  use HAT, Interfaces;\n\n  subtype Monkey_Range is Integer range 0 .. 9;\n  type Operation_Type is (plus, times, square);\n  type Item_Worry_List is array (1 .. 100) of Integer_64;\n\n  type Monkey_Data is record\n    top       : Natural;\n    s         : Item_Worry_List;\n    operation : Operation_Type;\n    operand   : Positive;\n    divisor   : Positive;\n    if_true   : Monkey_Range;\n    if_false  : Monkey_Range;\n    inspected : Natural;\n  end record;\n\n  mm : array (Monkey_Range) of Monkey_Data;\n\n  product_of_divisors : Integer_64;\n  last_id : Integer;\n\n  verbose : constant Boolean := False;\n\n  procedure Data_Acquisition is\n    c, space : Character;\n    idx, idx_comma : Integer;\n    starting_items_string : String (1 .. 18);  --  \"  Starting items: \"\n    operation_string      : String (1 .. 23);  --  \"  Operation: new = old \"\n    test_string           : String (1 .. 21);  --  \"  Test: divisible by\"\n    monkey_true_string    : String (1 .. 28);  --  \"    If true: throw to monkey\"\n    monkey_false_string   : String (1 .. 29);  --  \"    If false: throw to monkey\"\n    f : File_Type;\n    s : VString;\n  begin\n    product_of_divisors := 1;\n    last_id := -1;\n    Open (f, \"aoc_2022_11.txt\");\n  Read_Data :\n    loop\n      last_id := last_id + 1;\n      Skip_Line (f);  --  \"Monkey [last_id]:\"\n      mm (last_id).top := 0;\n      mm (last_id).inspected := 0;\n      Get (f, starting_items_string);\n      Get_Line (f, s);\n    Parse_Worries :\n      loop\n        idx_comma := Index (s, ',');\n        if idx_comma > 0 then\n          idx := idx_comma - 1;\n        else\n          idx := Length (s);\n        end if;\n        mm (last_id).top := mm (last_id).top + 1;\n        mm (last_id).s (mm (last_id).top) :=\n          Integer_64 (Integer_Value (Slice (s, 1, idx)));\n        exit Parse_Worries when idx_comma = 0;\n        Delete (s, 1, idx_comma);\n      end loop Parse_Worries;\n      Get (f, operation_string);\n      Get (f, c);\n      case c is\n        when '*' =>\n          Get (f, space);\n          Get (f, c);\n          if c = 'o' then\n            --  \"old * old\"\n            mm (last_id).operation := square;\n            Skip_Line (f);\n          else\n            mm (last_id).operation := times;\n            Get_Line (f, s);\n            mm (last_id).operand := Integer_Value (c & s);\n          end if;\n        when others =>\n          mm (last_id).operation := plus;\n          Get (f, mm (last_id).operand);\n      end case;\n      Get (f, test_string);\n      Get (f, mm (last_id).divisor);\n      product_of_divisors :=\n        product_of_divisors * Integer_64 (mm (last_id).divisor);\n      Get (f, monkey_true_string);\n      Get (f, mm (last_id).if_true);\n      Get (f, monkey_false_string);\n      Get (f, mm (last_id).if_false);\n      exit Read_Data when End_Of_File (f);\n      Skip_Line (f, 2);\n    end loop Read_Data;\n    Close (f);\n  end Data_Acquisition;\n\n  rounds : array (1 .. 2) of Positive;\n\n  function Simulation (part : Positive) return Integer_64 is\n    i : Integer_64;\n    dest : Monkey_Range;\n    top, top_1 : Positive;\n  begin\n    for round in 1 .. rounds (part) loop\n      for m in 0 .. last_id loop\n        if verbose then\n          Put_Line (+\"Monkey \" & m);\n        end if;\n        for o in 1 .. mm (m).top loop\n          if verbose then\n            Put (+\"  Worry:\" & Integer_64'Image (mm (m).s (o)));\n          end if;\n          i := mm (m).s (o);\n          case mm (m).operation is\n            when plus =>\n              i := i + Integer_64 (mm (m).operand);\n              if verbose then\n                Put (+\"  Plus \" & mm (m).operand);\n              end if;\n            when times =>\n              i := i * Integer_64 (mm (m).operand);\n              if verbose then\n                Put (+\"  Times \" & mm (m).operand);\n              end if;\n            when square =>\n              i := i * i;\n              if verbose then\n                Put (+\"  Square\");\n              end if;\n          end case;\n          if part = 1 then\n            i := i / 3;\n          else\n            i := i mod product_of_divisors;\n            --  ^ i mod divisor = (i mod product_of_divisors) mod divisor.\n          end if;\n          if i mod Integer_64 (mm (m).divisor) = 0 then\n            dest := mm (m).if_true;\n          else\n            dest := mm (m).if_false;\n          end if;\n          if verbose then\n            Put_Line (+\" throw\" & Integer_64'Image (i) & \" to \" & dest);\n          end if;\n          mm (dest).top := mm (dest).top + 1;\n          mm (dest).s (mm (dest).top) := i;\n        end loop;\n        mm (m).inspected := mm (m).inspected + mm (m).top;\n        mm (m).top := 0;\n      end loop;\n    end loop;\n    if verbose then\n      Put_Line (\"Inspected:\");\n      for m in 0 .. last_id loop\n        Put_Line (mm (m).inspected);\n      end loop;\n    end if;\n    top := 1;\n    top_1 := 1;\n    for m in 0 .. last_id loop\n      if mm (m).inspected >= top then\n        top_1 := top;\n        top := mm (m).inspected;\n      elsif mm (m).inspected > top_1 then\n        top_1 := mm (m).inspected;\n      end if;\n    end loop;\n    return Integer_64 (top) * Integer_64 (top_1);\n  end Simulation;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer_64;\n\nbegin\n  rounds (1) := 20;\n  rounds (2) := 10_000;\nParts :\n  for part in 1 .. 2 loop\n    Data_Acquisition;\n    r (part) := Simulation (part);\n    exit Parts when compiler_test_mode;  --  Skip part 2.\n  end loop Parts;\n\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Level of monkey business:\");\n    Put_Line (+\"  part 1: \" & Integer_64'Image (r (1)));\n    Put_Line (+\"  part 2: \" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 102399\n    --  Part 2: validated by AoC: 23641658401\n  end if;\nend AoC_2022_11;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_11.txt",
    "content": "Monkey 0:\n  Starting items: 50, 70, 54, 83, 52, 78\n  Operation: new = old * 3\n  Test: divisible by 11\n    If true: throw to monkey 2\n    If false: throw to monkey 7\n\nMonkey 1:\n  Starting items: 71, 52, 58, 60, 71\n  Operation: new = old * old\n  Test: divisible by 7\n    If true: throw to monkey 0\n    If false: throw to monkey 2\n\nMonkey 2:\n  Starting items: 66, 56, 56, 94, 60, 86, 73\n  Operation: new = old + 1\n  Test: divisible by 3\n    If true: throw to monkey 7\n    If false: throw to monkey 5\n\nMonkey 3:\n  Starting items: 83, 99\n  Operation: new = old + 8\n  Test: divisible by 5\n    If true: throw to monkey 6\n    If false: throw to monkey 4\n\nMonkey 4:\n  Starting items: 98, 98, 79\n  Operation: new = old + 3\n  Test: divisible by 17\n    If true: throw to monkey 1\n    If false: throw to monkey 0\n\nMonkey 5:\n  Starting items: 76\n  Operation: new = old + 4\n  Test: divisible by 13\n    If true: throw to monkey 6\n    If false: throw to monkey 3\n\nMonkey 6:\n  Starting items: 52, 51, 84, 54\n  Operation: new = old * 17\n  Test: divisible by 19\n    If true: throw to monkey 4\n    If false: throw to monkey 1\n\nMonkey 7:\n  Starting items: 82, 86, 91, 79, 94, 92, 59, 94\n  Operation: new = old + 7\n  Test: divisible by 2\n    If true: throw to monkey 5\n    If false: throw to monkey 3\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_11_questions.txt",
    "content": "--- Day 11: Monkey in the Middle ---\n\nAs you finally start making your way upriver, you realize your pack\nis much lighter than you remember. Just then, one of the items from\nyour pack goes flying overhead. Monkeys are playing Keep Away with\nyour missing things!\n\nTo get your stuff back, you need to be able to predict where the\nmonkeys will throw your items. After some careful observation, you\nrealize the monkeys operate based on how worried you are about each\nitem.\n\nYou take some notes (your puzzle input) on the items each monkey\ncurrently has, how worried you are about those items, and how the\nmonkey makes decisions based on your worry level. For example:\n\nMonkey 0:\n  Starting items: 79, 98\n  Operation: new = old * 19\n  Test: divisible by 23\n    If true: throw to monkey 2\n    If false: throw to monkey 3\n\nMonkey 1:\n  Starting items: 54, 65, 75, 74\n  Operation: new = old + 6\n  Test: divisible by 19\n    If true: throw to monkey 2\n    If false: throw to monkey 0\n\nMonkey 2:\n  Starting items: 79, 60, 97\n  Operation: new = old * old\n  Test: divisible by 13\n    If true: throw to monkey 1\n    If false: throw to monkey 3\n\nMonkey 3:\n  Starting items: 74\n  Operation: new = old + 3\n  Test: divisible by 17\n    If true: throw to monkey 0\n    If false: throw to monkey 1\n\nEach monkey has several attributes:\n\n    Starting items lists your worry level for each item the monkey\n      is currently holding in the order they will be inspected.\n    Operation shows how your worry level changes as that monkey\n      inspects an item. (An operation like new = old * 5 means that\n      your worry level after the monkey inspected the item is five\n      times whatever your worry level was before inspection.)\n    Test shows how the monkey uses your worry level to decide\n      where to throw an item next.\n        If true shows what happens with an item if the Test was true.\n        If false shows what happens with an item if the Test was false.\n\nAfter each monkey inspects an item but before it tests your worry\nlevel, your relief that the monkey's inspection didn't damage the\nitem causes your worry level to be divided by three and rounded\ndown to the nearest integer.\n\nThe monkeys take turns inspecting and throwing items. On a single\nmonkey's turn, it inspects and throws all of the items it is\nholding one at a time and in the order listed. Monkey 0 goes first,\nthen monkey 1, and so on until each monkey has had one turn.\nThe process of each monkey taking a single turn is called a round.\n\nWhen a monkey throws an item to another monkey, the item goes on\nthe end of the recipient monkey's list. A monkey that starts a round\nwith no items could end up inspecting and throwing many items by the\ntime its turn comes around. If a monkey is holding no items at the\nstart of its turn, its turn ends.\n\nIn the above example, the first round proceeds as follows:\n\nMonkey 0:\n  Monkey inspects an item with a worry level of 79.\n    Worry level is multiplied by 19 to 1501.\n    Monkey gets bored with item. Worry level is divided by 3 to 500.\n    Current worry level is not divisible by 23.\n    Item with worry level 500 is thrown to monkey 3.\n  Monkey inspects an item with a worry level of 98.\n    Worry level is multiplied by 19 to 1862.\n    Monkey gets bored with item. Worry level is divided by 3 to 620.\n    Current worry level is not divisible by 23.\n    Item with worry level 620 is thrown to monkey 3.\nMonkey 1:\n  Monkey inspects an item with a worry level of 54.\n    Worry level increases by 6 to 60.\n    Monkey gets bored with item. Worry level is divided by 3 to 20.\n    Current worry level is not divisible by 19.\n    Item with worry level 20 is thrown to monkey 0.\n  Monkey inspects an item with a worry level of 65.\n    Worry level increases by 6 to 71.\n    Monkey gets bored with item. Worry level is divided by 3 to 23.\n    Current worry level is not divisible by 19.\n    Item with worry level 23 is thrown to monkey 0.\n  Monkey inspects an item with a worry level of 75.\n    Worry level increases by 6 to 81.\n    Monkey gets bored with item. Worry level is divided by 3 to 27.\n    Current worry level is not divisible by 19.\n    Item with worry level 27 is thrown to monkey 0.\n  Monkey inspects an item with a worry level of 74.\n    Worry level increases by 6 to 80.\n    Monkey gets bored with item. Worry level is divided by 3 to 26.\n    Current worry level is not divisible by 19.\n    Item with worry level 26 is thrown to monkey 0.\nMonkey 2:\n  Monkey inspects an item with a worry level of 79.\n    Worry level is multiplied by itself to 6241.\n    Monkey gets bored with item. Worry level is divided by 3 to 2080.\n    Current worry level is divisible by 13.\n    Item with worry level 2080 is thrown to monkey 1.\n  Monkey inspects an item with a worry level of 60.\n    Worry level is multiplied by itself to 3600.\n    Monkey gets bored with item. Worry level is divided by 3 to 1200.\n    Current worry level is not divisible by 13.\n    Item with worry level 1200 is thrown to monkey 3.\n  Monkey inspects an item with a worry level of 97.\n    Worry level is multiplied by itself to 9409.\n    Monkey gets bored with item. Worry level is divided by 3 to 3136.\n    Current worry level is not divisible by 13.\n    Item with worry level 3136 is thrown to monkey 3.\nMonkey 3:\n  Monkey inspects an item with a worry level of 74.\n    Worry level increases by 3 to 77.\n    Monkey gets bored with item. Worry level is divided by 3 to 25.\n    Current worry level is not divisible by 17.\n    Item with worry level 25 is thrown to monkey 1.\n  Monkey inspects an item with a worry level of 500.\n    Worry level increases by 3 to 503.\n    Monkey gets bored with item. Worry level is divided by 3 to 167.\n    Current worry level is not divisible by 17.\n    Item with worry level 167 is thrown to monkey 1.\n  Monkey inspects an item with a worry level of 620.\n    Worry level increases by 3 to 623.\n    Monkey gets bored with item. Worry level is divided by 3 to 207.\n    Current worry level is not divisible by 17.\n    Item with worry level 207 is thrown to monkey 1.\n  Monkey inspects an item with a worry level of 1200.\n    Worry level increases by 3 to 1203.\n    Monkey gets bored with item. Worry level is divided by 3 to 401.\n    Current worry level is not divisible by 17.\n    Item with worry level 401 is thrown to monkey 1.\n  Monkey inspects an item with a worry level of 3136.\n    Worry level increases by 3 to 3139.\n    Monkey gets bored with item. Worry level is divided by 3 to 1046.\n    Current worry level is not divisible by 17.\n    Item with worry level 1046 is thrown to monkey 1.\n\nAfter round 1, the monkeys are holding items with these worry levels:\n\nMonkey 0: 20, 23, 27, 26\nMonkey 1: 2080, 25, 167, 207, 401, 1046\nMonkey 2: \nMonkey 3: \n\nMonkeys 2 and 3 aren't holding any items at the end of the round;\nthey both inspected items during the round and threw them\nall before the round ended.\n\nThis process continues for a few more rounds:\n\nAfter round 2, the monkeys are holding items with these worry levels:\nMonkey 0: 695, 10, 71, 135, 350\nMonkey 1: 43, 49, 58, 55, 362\nMonkey 2: \nMonkey 3: \n\nAfter round 3, the monkeys are holding items with these worry levels:\nMonkey 0: 16, 18, 21, 20, 122\nMonkey 1: 1468, 22, 150, 286, 739\nMonkey 2: \nMonkey 3: \n\nAfter round 4, the monkeys are holding items with these worry levels:\nMonkey 0: 491, 9, 52, 97, 248, 34\nMonkey 1: 39, 45, 43, 258\nMonkey 2: \nMonkey 3: \n\nAfter round 5, the monkeys are holding items with these worry levels:\nMonkey 0: 15, 17, 16, 88, 1037\nMonkey 1: 20, 110, 205, 524, 72\nMonkey 2: \nMonkey 3: \n\nAfter round 6, the monkeys are holding items with these worry levels:\nMonkey 0: 8, 70, 176, 26, 34\nMonkey 1: 481, 32, 36, 186, 2190\nMonkey 2: \nMonkey 3: \n\nAfter round 7, the monkeys are holding items with these worry levels:\nMonkey 0: 162, 12, 14, 64, 732, 17\nMonkey 1: 148, 372, 55, 72\nMonkey 2: \nMonkey 3: \n\nAfter round 8, the monkeys are holding items with these worry levels:\nMonkey 0: 51, 126, 20, 26, 136\nMonkey 1: 343, 26, 30, 1546, 36\nMonkey 2: \nMonkey 3: \n\nAfter round 9, the monkeys are holding items with these worry levels:\nMonkey 0: 116, 10, 12, 517, 14\nMonkey 1: 108, 267, 43, 55, 288\nMonkey 2: \nMonkey 3: \n\nAfter round 10, the monkeys are holding items with these worry levels:\nMonkey 0: 91, 16, 20, 98\nMonkey 1: 481, 245, 22, 26, 1092, 30\nMonkey 2: \nMonkey 3: \n\n...\n\nAfter round 15, the monkeys are holding items with these worry levels:\nMonkey 0: 83, 44, 8, 184, 9, 20, 26, 102\nMonkey 1: 110, 36\nMonkey 2: \nMonkey 3: \n\n...\n\nAfter round 20, the monkeys are holding items with these worry levels:\nMonkey 0: 10, 12, 14, 26, 34\nMonkey 1: 245, 93, 53, 199, 115\nMonkey 2: \nMonkey 3: \n\nChasing all of the monkeys at once is impossible; you're going to have\nto focus on the two most active monkeys if you want any hope of getting\nyour stuff back. Count the total number of times each monkey inspects\nitems over 20 rounds:\n\nMonkey 0 inspected items 101 times.\nMonkey 1 inspected items 95 times.\nMonkey 2 inspected items 7 times.\nMonkey 3 inspected items 105 times.\n\nIn this example, the two most active monkeys inspected items 101 and\n105 times. The level of monkey business in this situation can be found\nby multiplying these together: 10605.\n\nFigure out which monkeys to chase by counting how many items they\ninspect over 20 rounds. What is the level of monkey business after\n20 rounds of stuff-slinging simian shenanigans?\n\n--- Part Two ---\n\nYou're worried you might not ever get your items back. So worried,\nin fact, that your relief that a monkey's inspection didn't damage\nan item no longer causes your worry level to be divided by three.\n\nUnfortunately, that relief was all that was keeping your worry levels\nfrom reaching ridiculous levels. You'll need to find another way to\nkeep your worry levels manageable.\n\nAt this rate, you might be putting up with these monkeys for a very\nlong time - possibly 10000 rounds!\n\nWith these new rules, you can still figure out the monkey business\nafter 10000 rounds. Using the same example above:\n\n== After round 1 ==\nMonkey 0 inspected items 2 times.\nMonkey 1 inspected items 4 times.\nMonkey 2 inspected items 3 times.\nMonkey 3 inspected items 6 times.\n\n== After round 20 ==\nMonkey 0 inspected items 99 times.\nMonkey 1 inspected items 97 times.\nMonkey 2 inspected items 8 times.\nMonkey 3 inspected items 103 times.\n\n== After round 1000 ==\nMonkey 0 inspected items 5204 times.\nMonkey 1 inspected items 4792 times.\nMonkey 2 inspected items 199 times.\nMonkey 3 inspected items 5192 times.\n\n== After round 2000 ==\nMonkey 0 inspected items 10419 times.\nMonkey 1 inspected items 9577 times.\nMonkey 2 inspected items 392 times.\nMonkey 3 inspected items 10391 times.\n\n== After round 3000 ==\nMonkey 0 inspected items 15638 times.\nMonkey 1 inspected items 14358 times.\nMonkey 2 inspected items 587 times.\nMonkey 3 inspected items 15593 times.\n\n== After round 4000 ==\nMonkey 0 inspected items 20858 times.\nMonkey 1 inspected items 19138 times.\nMonkey 2 inspected items 780 times.\nMonkey 3 inspected items 20797 times.\n\n== After round 5000 ==\nMonkey 0 inspected items 26075 times.\nMonkey 1 inspected items 23921 times.\nMonkey 2 inspected items 974 times.\nMonkey 3 inspected items 26000 times.\n\n== After round 6000 ==\nMonkey 0 inspected items 31294 times.\nMonkey 1 inspected items 28702 times.\nMonkey 2 inspected items 1165 times.\nMonkey 3 inspected items 31204 times.\n\n== After round 7000 ==\nMonkey 0 inspected items 36508 times.\nMonkey 1 inspected items 33488 times.\nMonkey 2 inspected items 1360 times.\nMonkey 3 inspected items 36400 times.\n\n== After round 8000 ==\nMonkey 0 inspected items 41728 times.\nMonkey 1 inspected items 38268 times.\nMonkey 2 inspected items 1553 times.\nMonkey 3 inspected items 41606 times.\n\n== After round 9000 ==\nMonkey 0 inspected items 46945 times.\nMonkey 1 inspected items 43051 times.\nMonkey 2 inspected items 1746 times.\nMonkey 3 inspected items 46807 times.\n\n== After round 10000 ==\nMonkey 0 inspected items 52166 times.\nMonkey 1 inspected items 47830 times.\nMonkey 2 inspected items 1938 times.\nMonkey 3 inspected items 52013 times.\n\nAfter 10000 rounds, the two most active monkeys inspected\nitems 52166 and 52013 times. Multiplying these together, the level\nof monkey business in this situation is now 2713310158.\n\nWorry levels are no longer divided by three after each item is\ninspected; you'll need to find another way to keep your worry\nlevels manageable. Starting again from the initial state in\nyour puzzle input, what is the level of monkey business\nafter 10000 rounds?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_12.adb",
    "content": "--  Solution to Advent of Code 2022, Day 12\n-------------------------------------------\n--  Hill Climbing Algorithm\n--\n--  https://adventofcode.com/2022/day/12\n--  Copy of questions in: aoc_2022_12_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_12 is\n\n  type Point is record\n    x, y : Integer;\n  end record;\n\n  start, finish, n : Point;\n\n  inf : constant Natural := Integer'Last / 4;\n\n  nx_max : constant := 200;\n  ny_max : constant := 100;\n\n  subtype Range_x is Integer range 1 .. nx_max;\n  subtype Range_y is Integer range 1 .. ny_max;\n\n  map   : array (Range_x, Range_y) of Character;\n  best  : array (Range_x, Range_y) of Natural;\n\n  use HAT;\n\n  procedure Data_Acquisition is\n    c : Character;\n    f : File_Type;\n    x, y : Natural := 0;\n  begin\n    Open (f, \"aoc_2022_12.txt\");\n  Read_Data :\n    while not End_Of_File (f) loop\n      y := y + 1;\n      x := 0;\n      Get (f, c);\n      loop\n        x := x + 1;\n        case c is\n          when 'S' =>\n            start.x := x;\n            start.y := y;\n            map (x, y) := 'a';\n          when 'E' =>\n            finish.x := x;\n            finish.y := y;\n            map (x, y) := 'z';\n          when others =>\n            map (x, y) := c;\n        end case;\n        exit when End_Of_Line (f);\n        Get (f, c);\n      end loop;\n    end loop Read_Data;\n    n.x := x;\n    n.y := y;\n    Close (f);\n  end Data_Acquisition;\n\n  --  Dijkstra shortest path algorithm.\n  --  Code adapted from AoC_2021_15.\n  --\n  --  The following definitions belong to the Dijkstra algorithm, but\n  --  we keep them less local because of the visualization.\n\n  list_length_max : constant := 7500;\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  type Node is record\n    len  : Natural;\n    pt   : Point;\n    pred : Natural;  --  This is just for displaying the path.\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  function Dijkstra_Algorithm (start : Point; part : Positive) return Natural is\n\n    cur_len : Natural;\n    cur_c   : Character;\n\n    procedure Visit (x, y : Integer) is\n      len_to, ins : Integer;\n      ok_step : Boolean;\n    begin\n      if x in 1 .. n.x and then y in 1 .. n.y then\n        if part = 1 then\n          --  We avoid ascending more than one unit.\n          ok_step := map (x, y) <= Succ (cur_c);\n        else\n          --  We avoid descending more than one unit (reverse walk).\n          ok_step := map (x, y) >= Pred (cur_c);\n        end if;\n        if ok_step then\n          len_to := cur_len + 1;\n          if len_to < best (x, y) then\n            --  Improvement on cell (x, y).\n            best (x, y) := len_to;\n            --\n            --  Insert in a sorted way.\n            --\n            ins := explored + 1;\n            for i in current + 1 .. explored loop\n              if len_to < list (i).len then\n                ins := i;  --  Insert here.\n                --  Optional: remove another node\n                --  with the same (x, y) and a larger length.\n                exit;\n              end if;\n            end loop;\n            for i in reverse ins .. explored loop\n              list (i + 1) := list (i);\n            end loop;\n            list (ins).len := len_to;\n            list (ins).pt.x := x;\n            list (ins).pt.y := y;\n            list (ins).pred := current;\n            explored := explored + 1;\n          end if;\n        end if;\n      end if;\n    end Visit;\n    --\n    cur_pt  : Point;\n  begin\n    current  := 0;\n    explored := 0;\n\n    for x in 1 .. n.x loop\n      for y in 1 .. n.y loop\n        best (x, y) := inf;\n      end loop;\n    end loop;\n\n    best (start.x, start.y) := 0;\n    cur_pt := start;\n    loop\n      cur_len := best (cur_pt.x, cur_pt.y);\n      cur_c := map (cur_pt.x, cur_pt.y);\n      Visit (cur_pt.x - 1, cur_pt.y);\n      Visit (cur_pt.x + 1, cur_pt.y);\n      Visit (cur_pt.x, cur_pt.y - 1);\n      Visit (cur_pt.x, cur_pt.y + 1);\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_pt := list (current).pt;\n      if part = 1 then\n        exit when cur_pt.x = finish.x and then cur_pt.y = finish.y;\n      else\n        exit when map (cur_pt.x, cur_pt.y) = 'a';\n      end if;\n    end loop;\n    return best (cur_pt.x, cur_pt.y);\n  end Dijkstra_Algorithm;\n\n  ---------------\n  --  Display  --\n  ---------------\n\n  package Display is\n\n    subtype Color_Range is Natural range 0 .. 255;\n    type Pixel is record\n      R, G, B : Color_Range;\n    end record;\n\n    black, red, green, blue, yellow, pink, white : Pixel;\n\n    min_x : Range_x;\n    max_x : Range_x;\n    min_y : Range_y;\n    max_y : Range_y;\n    bitmap : array (Range_x, Range_y) of Pixel;\n\n    procedure Init;\n    procedure Show_Map;\n    procedure Show_Path (path_color : Pixel; part : Positive);\n    procedure Show_Ends;\n    procedure Dump_PPM (title : VString);\n\n  end Display;\n\n  package body Display is\n\n    procedure Init is\n    begin\n      Display.min_x := 1;\n      Display.max_x := n.x;  --  200;\n      Display.min_y := 1;    --  401;\n      Display.max_y := n.y;  --  990;\n      --\n      black.R := 0;\n      black.G := 0;\n      black.B := 0;\n      --\n      white.R := 16#ff#;\n      white.G := 16#ff#;\n      white.B := 16#ff#;\n      --\n      red   := black;\n      red.R := 16#ff#;\n      green   := black;\n      green.G := 16#ff#;\n      blue   := black;\n      blue.B := 16#ff#;\n      --\n      yellow := white;\n      yellow.B := 16#00#;\n      --\n      pink.R := 255;\n      pink.G := 174;\n      pink.B := 201;\n    end Init;\n\n    procedure Show_Map is\n      height, value : Real;\n      px : Pixel;\n    begin\n      --  Display the map on the RGB bitmap:\n      for y in min_y .. max_y loop\n        for x in min_x .. max_x loop\n          height := Real (Ord (map (x, y)) - Ord ('a')) / 25.0;\n          value := height ** 0.4;  --  Enhance low values.\n          px.R := 10 + Integer  (90.0 * value);\n          px.G := 80 + Integer (115.0 * value);\n          px.B := 50 + Integer (110.0 * value);\n          bitmap (x, y) := px;\n        end loop;\n      end loop;\n    end Show_Map;\n\n    procedure Show_Path (path_color : Pixel; part : Positive) is\n      px, path : Pixel;\n      i, j : Natural;\n      fall : Boolean;\n    begin\n      --  Display optimal path, back from the end (E).\n      i := current;\n      while i /= 0 loop\n        j := list (i).pred;\n        if i = current then\n          bitmap (list (i).pt.x, list (i).pt.y) := path_color;\n        elsif j /= 0 then\n          px := bitmap (list (i).pt.x, list (i).pt.y);\n          if part = 1 then\n            fall :=\n              map (list (i).pt.x, list (i).pt.y) <\n              map (list (j).pt.x, list (j).pt.y);\n          else\n            --  The path is walked in reverse, from the\n            --  hill's top to the plains.\n            fall :=\n              map (list (i).pt.x, list (i).pt.y) >\n              map (list (j).pt.x, list (j).pt.y);\n          end if;\n          if fall then\n            --  Show differently the point(s)\n            --  where the guy falls.\n            path := red;\n          else\n            path := path_color;\n          end if;\n          --  Blend current pixel with the color chose for the path:\n          px.R := (path.R + 2 * px.R) / 3;\n          px.G := (path.G + 2 * px.G) / 3;\n          px.B := (path.B + 2 * px.B) / 3;\n          bitmap (list (i).pt.x, list (i).pt.y) := px;\n        end if;\n        i := j;\n      end loop;\n    end Show_Path;\n\n    procedure Show_Ends is\n    begin\n      --  Display start (S) and end (E) points.\n      bitmap (start.x, start.y) := green;\n      bitmap (finish.x, finish.y) := blue;\n    end Show_Ends;\n\n    --  PPM output adapted from AoC_2022_09.\n    --\n    procedure Dump_PPM (title : VString) is\n      d : File_Type;\n    begin\n      Create (d, title & \".ppm\");\n      Put (d, \"P6\" & Chr (10));\n      Put (d, max_x - min_x + 1); Put (d, ' ');\n      Put (d, max_y - min_y + 1); Put (d, Chr (10));\n      Put (d, \"255\" & Chr (10));\n      for y in min_y .. max_y loop\n        for x in min_x .. max_x loop\n          Put (d, Chr (bitmap (x, y).R));\n          Put (d, Chr (bitmap (x, y).G));\n          Put (d, Chr (bitmap (x, y).B));\n        end loop;\n      end loop;\n      Close (d);\n    end Dump_PPM;\n\n  end Display;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := not compiler_test_mode;\n\nbegin\n  Data_Acquisition;\n  if verbose then\n    Display.Init;\n    Display.Show_Map;\n  end if;\n  r (1) := Dijkstra_Algorithm (start, 1);\n  if verbose then\n    Display.Show_Path (Display.yellow, 1);\n  end if;\n  r (2) := Dijkstra_Algorithm (finish, 2);\n  if verbose then\n    Display.Show_Path (Display.pink, 2);\n    Display.Show_Ends;\n    Display.Dump_PPM (+\"height_map\");\n  end if;\n\n  if compiler_test_mode then\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: shortest path from S to E . . . .  . . : \" & r (1));\n    Put_Line (+\"Part 2: shortest path from E to the ground . . : \" & r (2));\n    --  Part 1: validated by AoC: 440\n    --  Part 2: validated by AoC: 439\n  end if;\nend AoC_2022_12;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_12.txt",
    "content": "abccccccaaccaaccccaaaaacccccaaaaccccccccccccccccccccccccccccccccaaaaaaaaaaaaaaaaaaaccccccccccccccccaaaccccccccccccaacccccccccccccccccccccccccccccccccccccccccaaaa\nabaaaaccaaaaaccccaaaaaccccccaaaaccccccccccccccccccccaaacccccccccccaaaaaaaaaaaaaaaaaaccccccccccccccccaaaaccccccaaacaaccccccccccccccccccccccccccccccccccccccccaaaaa\nabaaacccaaaaaaaacaaaaaacccccaaaaccccccccccccccccccccaaaaacccccccccaaaaaaaaaaaaaaaaacccccccccaaccccaaaaaacccccccaaaaaccccaaccccccccccccccacccccccccccccccccccaaaaa\nabaaacccccaaaaaccccaaaaccccccaaacccccccccccccccccccaaaaaccccccccccaaaaaacacaaaaaacccccccccccaaccccaaaaacccccccccaaaaaaccaaaaaaccccccccccaaaccccacccccccccccaaaaaa\nabaacccccaaaaaccccaacccccccccccccccaaaaacccccccccccaaaaacccccccccaaaaaaaaccaaaaaaacccccccaaaaaaaaccaaaaacccccccaaaaaaaccaaaaacccccccccccaaacccaaaccccccccccccccaa\nabaaacccaaacaacccccccccccccccccccccaaaaaccccccccccccaaaaacccccccaaaaaaaaaccaaccaaacccccccaaaaaaaaccaacccccccccaaaaaaccaaaaaaccccccccccccaaaacaaaaccccccccccccccaa\nabaaacccccccaaccccccccccccccccccccaaaaaaccccccccccccaaccccccaacccaaaccaaaaccccccaacccccccccaaaacccccccccccccccaacaaaccaaaaaaaccccccccccccajjjjjjjcccccccccccccccc\nabcaacccccccccccccccccccccccccccccaaaaaaccccccccccccccccccccaaaaccccccaaaaccccccccccccccaacaaaaaccccccccccccccccccaaccccaaaaaacccccccccccjjjjjjjjjcccccaaaccccccc\nabccccccccccccccccccccccccccccccccaaaaaaccaaccccccccccccccaaaaaacccccccaaacccccccccccaacaaaaaaaaccccccccccccccccccccccccaaccaaccccccccaiijjjjojjjjcccccaaacaccccc\nabcccccccccccccccccccccccaaacccccccaaacacaaacccccccccccccccaaaaccccaaccccccccccccccccaaaaaaacccaccccccccccccccccccccccccaacccccccccccaiiijjooooojjkccaaaaaaaacccc\nabccccccccccccccccccccccaaaaccccccccccaaaaaccccccccccccccccaaaaacccaaaaaccccccccccccccaaaaaacccccccccccccccccccccccccccccccccccccciiiiiiiioooooookkkcaaaaaaaacccc\nabccccccccccccccccccccccaaaaccccccccccaaaaaaaacccccccccccccaacaaccaaaaacccccccaaacccaaaaaaaaccccccccccccccccccccccccccccccccccchiiiiiiiiooooouoookkkccaaaaaaccccc\nabcccccccccaaccccccccccccaaaccccccccccccaaaaacccccccccccccccccccccaaaaaccccccaaaacccaaaaacaacccccccccccccaacaacccccccccccccccchhhiiiinnnooouuuuoookkkccaaaaaccccc\nabcccccccccaaacccccccccccccccccccccccccaaaaacccccccccccccccccccccccaaaaacccccaaaaccccccaaccccccccccccccccaaaaacccccccccccccccchhhnnnnnnnnouuuuuuppkkkkaaaaaaccccc\nabccccccaaaaaaaacccaaccccccccccccccccccaacaaccaacaaccccccccccccccccaacccccccccaaaccccccaacccccccccccccccaaaaacccccccccccccccchhhnnnnnnnnntuuxuuupppkkkkkacccccccc\nabccccccaaaaaaaacacaaaacccccccccccccccccccaaccaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaacccccccaacccccchhhnnnnttttttuxxxuuppppkkkkkcccccccc\nabcccccccaaaaaaccaaaaaaccccccccccaaccccccccccaaaaaccccccccccccccccccccccccaaacccccccccccccccccccccccccccccaaaaccaaccaaacccaaahhhnnntttttttuxxxxuupppppllllccccccc\nabcccccccaaaaaacccaaaacccccccccaaaaaaccccccccaaaaaacccccccccccccccccccccccaaacccccccccccccccccccccccccccccacccccaaaaaaacaaaaahhhppntttxxxxxxxxuuuuvpppplllccccccc\nabcccccccaaaaaacccaaaacccccccccaaaaaacccccaaaaaaaaaccccccccccccccccccccaaaaaaaacccccccccccccccccccccaaaccccccaacaaaaaaccaaaaahhhpppttxxxxxxxxyuuvvvvvppplllcccccc\nabcccccccaaccaacccaacaccaaaaccccaaaaacccccaaaaaaaaaccccccccccccccccccccaaaaaaaacccccccccccccccccccccaaacaaaaaaaccaaaaaaaaaaaaahhppptttxxxxxxyyyyyyvvvppplllcccccc\nSbccccccccccccccccccccccaaaacccaaaaacccccccaaaaaaaaacaaaccccccccaacccccccaaaaaccccccccaaaaacccccccccaaaaaaaaaaaaaaaaaaaaaaaaacgggpppttxxxxEzzyyyyyvvvqqqlllcccccc\nabccccccccccccccccccccccaaaacccaaaaacccccccaaaaaaaaccaaaccccccccaaacaaccaaaaaaccccccccaaaaacccccccaaaaaaaaaaaaaaaaaaaaaaaaaaacgggpppsssxxxyyyyyyvvvvvqqlllccccccc\nabcccaaaccccccccccccccccaaaccccccccccccccccaaaaaaaaaaaaaccccccccaaaaaaccaaaaaacccccccaaaaaacccaaaccaaaaaccaaaaaaaaaaaacccccccccgggppssswwyyyyyyvvvvqqqqlllccccccc\nabcaaaaaccccccccccccccccccccccccccccccccccaaaaaaaaaaaaacccccccaaaaaaacccaccaaacccccccaaaaaacccaaacccaaaaaaaaaaaccccaaacccaaaaacgggppsswwwyyyyyyvvqqqqqlllcccccccc\nabcaaaaaaccccccccccccccccccccccccccccccccccaaccaaaaaaaaaaaccccaaaaaaacccccccccccccccccaaaaacccaaacaaaacaaaaaaaaccccaaacccaaaaacggpppsswwwywwyyyvvqqqmmmlccccccccc\nabcaaaaaacccccccaacaaccccccccccccccccccccccccccaaaaaaaaaaaccccccaaaaacccccccccccccccccaaaccaaaaaaaaaaacccccccaacccccccccaaaaaacggpppsswwwwwwwwyvvqqqmmmcccccccccc\nabcaaaaaccccccccaaaaaccccccccccccccccccccccccccccaaaaaaaacccccccaacaaacccccccccccccccccccccaaaaaaaaaccccccccccccccccccccaaaaaagggoossswwwwrrwwwvvqqmmmccccccccccc\nabcaaaaacccccccaaaaaccccccccccccccccccccccccccccaaaaaaacccccccccaaccccccccccccccccccccccccccaaaaaaacccccccccccaaaccccccccaaaaagggooosssssrrrrwwwvqqmmmcccaacccccc\nabcccccccccccccaaaaaaccccccccccccccccccccaacccccccccaaaccccccccccccccccccccccccccccccccccccccaaaaaaccccccccccccaaaaccccccaaaccgggooosssssrrrrrwwrrqmmmcccaacccccc\nabcccccccccccccccaaaacccccccccccccccccccaaaacccccccacaaacccccccccccccccccccccccccccccccccccccaaaaaaacccccccccaaaaaacccccccccccgffoooooosoonrrrrrrrrmmmccaaaaacccc\nabcccccccccccccccaccccccccccccccccccccccaaaacccccccaaaaacccccccccccccccccccccccccccccccccccccaaacaaacccccccccaaaaacccccccccccccfffoooooooonnnrrrrrmmmddcaaaaacccc\nabccccccccccccccccccccccccccccccccccccccaaaaccccccccaaaaacccccccccccccccccccccccccaaaccccccccaacccccccccccccccaaaaaccccccccccccffffoooooonnnnnnrnnmmmdddaaaaacccc\nabcccccccccccccccccccccccccccccccccccccccccccccccccaaaaaacccccccccccccccccaaaaaccaaaacccccccccccccccccccccccccaacccccccccccccccfffffffffeeeennnnnnmmdddaaaacccccc\nabcccccccaaaccccccccaccccccccccccccccccccccccccccccaaaaccccccccccccaaaccccaaaaaccaaaaccccccccccccccccccccccccccccccccccccccccccccfffffffeeeeennnnnmddddaaaaaccccc\nabcccaaccaaacccccaaaacccccaacccccccccccccccccccccccccaaacccccccccccaaacccaaaaaacccaaaccccccccccccccccccccccccccccccccccccccccccccccffffeeeeeeeedddddddcccaacccccc\nabcccaaaaaaacccccaaaaaaccaaacccccccccccccccccccccccccccacccccccccccaaaaccaaaaaaccccccccccccccccccccccccccaacccccccccaaaccccccccccccccaaaaaaeeeeedddddcccccccccccc\nabcccaaaaaacccccccaaaacccaaacaaaccccaaaacccccccccaaacaaaccccccaacccaaaacaaaaaaacccccccccccccccccccccccccaaaccccccccaaaacccccccccccccccccccaaaaeeddddccccccccccccc\nabccccaaaaaaaacccaaaaaaaaaaaaaaaccccaaaacccccccccaaaaaaacccccaaacccaaaaaaaaaacccccccccccccccccccccccaaacaaaccccccccaaaaccccccccccccccccccccaaaccccccccccccccaaaca\nabcccaaaaaaaaacccaacaaaaaaaaaaacccccaaaaccccccccccaaaaaacaaacaaacaaaaaaaaaacccccccccccccccaaacccccccaaaaaaaaaaccccccaaaccccccccccccccccccccaacccccccccccccccaaaaa\nabcccaaaaaaaacccccccccccaaaaaacccccccaacccccccccccaaaaaaaaaaaaaaaaaaaaaaaaccccccccccccccccaaaacccccccaaaaaaaaacccccccccccccccccccccccccccccaaacccccccccccccccaaaa\nabccaaaaaaacccccccccccccaaaaaaacccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaacccccccccccccccaaaacccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccaaaaa\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_12_questions.txt",
    "content": "--- Day 12: Hill Climbing Algorithm ---\n\nYou try contacting the Elves using your handheld device, but the\nriver you're following must be too low to get a decent signal.\n\nYou ask the device for a heightmap of the surrounding area\n(your puzzle input). The heightmap shows the local area from above\nbroken into a grid; the elevation of each square of the grid is\ngiven by a single lowercase letter, where a is the lowest elevation,\nb is the next-lowest, and so on up to the highest elevation, z.\n\nAlso included on the heightmap are marks for your current position (S)\nand the location that should get the best signal (E).\nYour current position (S) has elevation a, and the location\nthat should get the best signal (E) has elevation z.\n\nYou'd like to reach E, but to save energy, you should do it in as\nfew steps as possible. During each step, you can move exactly one\nsquare up, down, left, or right.\nTo avoid needing to get out your climbing gear, the elevation\nof the destination square can be at most one higher than the\nelevation of your current square; that is, if your current elevation\nis m, you could step to elevation n, but not to elevation o.\n(This also means that the elevation of the destination square\ncan be much lower than the elevation of your current square.)\n\nFor example:\n\nSabqponm\nabcryxxl\naccszExk\nacctuvwj\nabdefghi\n\nHere, you start in the top-left corner; your goal is near the middle.\nYou could start by moving down or right, but eventually you'll need\nto head toward the e at the bottom. From there, you can spiral around to the goal:\n\nv..v<<<<\n>v.vv<<^\n.>vv>E^^\n..v>>>^^\n..>>>>>^\n\nIn the above diagram, the symbols indicate whether the path exits\neach square moving up (^), down (v), left (<), or right (>).\nThe location that should get the best signal is still E, and . marks\nunvisited squares.\n\nThis path reaches the goal in 31 steps, the fewest possible.\n\nWhat is the fewest steps required to move from your current\nposition to the location that should get the best signal?\n\n--- Part Two ---\n\nAs you walk up the hill, you suspect that the Elves will want to turn\nthis into a hiking trail.\nThe beginning isn't very scenic, though; perhaps you can find a\nbetter starting point.\n\nTo maximize exercise while hiking, the trail should start as\nlow as possible: elevation a. The goal is still the square\nmarked E. However, the trail should still be direct, taking the\nfewest steps to reach its goal.\nSo, you'll need to find the shortest path from any square at\nelevation a to the square marked E.\n\nAgain consider the example from above:\n\nSabqponm\nabcryxxl\naccszExk\nacctuvwj\nabdefghi\n\nNow, there are six choices for starting position (five marked a, plus\nthe square marked S that counts as being at elevation a).\nIf you start at the bottom-left square, you can reach the goal\nmost quickly:\n\n...v<<<<\n...vv<<^\n...v>E^^\n.>v>>>^^\n>^>>>>>^\n\nThis path reaches the goal in only 29 steps, the fewest possible.\n\nWhat is the fewest steps required to move starting from any square\nwith elevation a to the location that should get the best signal?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_13.adb",
    "content": "--  Solution to Advent of Code 2022, Day 13\n-------------------------------------------\n--  Distress Signal\n--\n--  https://adventofcode.com/2022/day/13\n--  Copy of questions in: aoc_2022_13_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_13 is\n  use HAT;\n\n  type Order is (correct, wrong, undecided);\n\n  --  Here we compare a pair of recursive lists in the form:\n  --    [[1],[2,3,4]]\n  --    [[1],4]\n\n  function Compare_List (s1, s2 : VString) return Order;\n\n  function Compare_Elements (s1, s2 : VString) return Order is\n    i1, i2 : Integer;\n    h1, h2 : Character;\n  begin\n    h1 := Element (s1, 1);\n    h2 := Element (s2, 1);\n    if h1 in '0' .. '9' and then h2 in '0' .. '9' then\n      i1 := Integer_Value (Slice (s1, 1, Length (s1)));\n      i2 := Integer_Value (Slice (s2, 1, Length (s2)));\n      if i1 < i2 then\n        return correct;\n      elsif i1 > i2 then\n        return wrong;\n      else\n        return undecided;\n      end if;\n    elsif h1 = '[' and h2 = '[' then\n      return Compare_List (s1, s2);\n    elsif h1 = '[' then\n      return Compare_List (s1, '[' & s2 & ']');\n    else\n      return Compare_List ('[' & s1 & ']', s2);\n    end if;\n  end Compare_Elements;\n\n  function Element_End (s : VString) return Natural is\n    l : constant Natural :=  Length (s);\n    skip : Natural := 0;\n  begin\n    if l = 0 then\n      return 0;\n    end if;\n    for i in 1 .. l loop\n      case  Element (s, i) is\n        when ',' =>\n          if skip = 0 then\n            return i - 1;\n          end if;\n        when '[' =>\n          skip := skip + 1;\n        when ']' =>\n          skip := skip - 1;\n        when others =>\n          null;\n      end case;\n    end loop;\n    return l;\n  end Element_End;\n\n  --  Remove first element in \"a,b,c\"\n  procedure Delete_Head (s : in out VString; element_length : Natural) is\n  begin\n    Delete (s, 1, element_length);\n    if Length (s) > 0 and then Element (s, 1) = ',' then\n      Delete (s, 1, 1);\n    end if;\n  end Delete_Head;\n\n  --  Remove then '[' and ']' at both ends.\n  procedure Delete_Brackets (s : in out VString) is\n  begin\n    Delete (s, Length (s), Length (s));\n    Delete (s, 1, 1);\n  end Delete_Brackets;\n\n  function Compare_List (s1, s2 : VString) return Order is\n    e1, e2 : Integer;\n    v1, v2 : VString;\n    res : Order;\n  begin\n    v1 := s1;\n    v2 := s2;\n    --  Remove the outmost brackets around the list.\n    Delete_Brackets (v1);\n    Delete_Brackets (v2);\n    --  Process the elements, if any.\n    loop\n      e1 := Element_End (v1);\n      e2 := Element_End (v2);\n      if e1 = 0 and e2 = 0 then\n        return undecided;\n      elsif e1 = 0 then\n        --  \"If the left list runs out of items first,\n        --   the inputs are in the right order.\"\n        return correct;\n      elsif e2 = 0 then\n        --  \"If the right list runs out of items first,\n        --   the inputs are not in the right order.\"\n        return wrong;\n      end if;\n      res := Compare_Elements (Slice (v1, 1, e1), Slice (v2, 1, e2));\n      if res /= undecided then\n        return res;\n      end if;\n      --  Move to next element on both lists.\n      Delete_Head (v1, e1);\n      Delete_Head (v2, e2);\n    end loop;\n  end Compare_List;\n\n  function One_if_lesser (s1, s2 : VString) return Natural is\n  begin\n    if Compare_List (s1, s2) = correct then\n      return 1;\n    else\n      return 0;\n    end if;\n  end One_if_lesser;\n\n  f : File_Type;\n  s : array (1 .. 2) of VString;\n\n  pair_index, sum_correct_pair_indices, before_2, before_6 : Natural := 0;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\nbegin\n  Open (f, \"aoc_2022_13.txt\");\nRead_Data :\n  loop\n    for i in 1 .. 2 loop\n      Get_Line (f, s (i));\n      before_2 := before_2 + One_if_lesser (s (i), +\"[[2]]\");\n      before_6 := before_6 + One_if_lesser (s (i), +\"[[6]]\");\n    end loop;\n    pair_index := pair_index + 1;\n    if Compare_List (s (1), s (2)) = correct then\n      sum_correct_pair_indices := sum_correct_pair_indices + pair_index;\n    end if;\n    exit Read_Data when End_Of_File (f);\n    Skip_Line (f);\n  end loop Read_Data;\n  Close (f);\n\n  r (1) := sum_correct_pair_indices;\n  r (2) := (before_2 + 1) * (before_6 + 2);\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line\n      (+\"Part 1: sum of indices of list pairs in correct order  : \" & r (1));\n    Put_Line\n      (+\"Part 2: product of indices of [[2]] and [[6]] dividers : \" & r (2));\n    --  Part 1: validated by AoC: 6568\n    --  Part 2: validated by AoC: 19493\n  end if;\nend AoC_2022_13;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_13.txt",
    "content": "[[[],2,9,4],[],[[[],[0]],[[7,0,10,8],[10,5,5,4,1],0,6]],[]]\n[[[8],[3,6,9,[10,4,2],[4,5]],[10,[3],[7,10,7,2],[0,5]],2]]\n\n[[[3,6],[]],[[7,[7,9,1,8,2],[],[1],3],[[8,0,10],[5],0,8],[[6,4,5],[1,3,1,10,8],[],[8]],9,9]]\n[[[[5,0],[4,7,3],[4,5],[0,2]],9,0]]\n\n[]\n[[6,[4,8,0,[1,9]]],[[0,4,[8,10,8],[1,4,9,2,4]]]]\n\n[[8,4,8,8,1],[2,[1,8,[5,3,8]],[[3,2,2,9,8]]],[[[2,5,0,7],[6,8,8,8,2],1,7],2,8,[6,5,0]],[10],[[[2,6],[2],[0,7,8]],10]]\n[[],[6,10,[8]],[7,[[0,3,8],[7,0],9,[8,3],[2,7]],5,6],[2,[[7],[7,1,8,6]],0]]\n\n[[[[4,3,7],0],2,[3]],[2,0,[10,2,[4],1,0],9],[[10,9,[7]],0,4,[6],[10,[6,10,7,0,9],9]],[10,[8,[2],10,[7,10,9,6],6],5]]\n[[],[[9,10,1,[9]]],[9,[],[[],[2,1,8,4],[3,4,1,3]],0]]\n\n[[[[1,5,4],[0,9,6,4,9],[6,3,6,2],[1,4,10,4],5],0,[5]],[8]]\n[[[[6,4,9,3,1],[6,10,5,1,3],[3,10,8,4],3],7,3,10,3],[[5,[],0,6,4],8,[[7,8,5]],[6,[9,10,4,2,9],[6,7,4,6]]],[9,5,[[2,0,2,4,10],[2],4],[],9],[]]\n\n[[5,[[2],9],[5,7,[6,2,9,6],2]],[[2,5],4],[7,[2,4,[10],10],[0,2,9],[[],[6,4,10,8,0]],[]],[]]\n[[[10,4,7,4],3],[[[2,10,3,10],2,3,0],[[8,9,5,10,8]]],[[]],[3,[1,[5,5,9,2],[1],[],[5,3,4]],3,2],[3,4]]\n\n[[[[6],9],5,[1,1,[5,7,2,9,9],5,0],[3,[],[3,6],8]],[[4,[8,7],3],[[9],[4,5,3]]],[3,[],4,9,[3,[5,3,7]]]]\n[[3,3,0]]\n\n[[],[1],[]]\n[[[[0,3],[7,0,5,1]],[],[2,[4,3,3,6,4]]],[[],[10,[]],[5,[2,7,7,10],[9,8,2,10,4]]],[[],[[1],[4,4,6],10,[4]],[[1,1,7,7],[6,9],0]],[[3,[3,5,4],[8,2,4,0,3],5,[3,10]],10,[]],[[3],2,[],[[6,1,2,3],[7,7,9,1],7]]]\n\n[[]]\n[[3,8,5],[0,[[5,4,7,0,5],4]],[7,[[8,10,6,9,8],3]]]\n\n[[],[6,4,3,[8,[],1,[9,9,7],1],[[],[2,0,3],[4,5,5,8],5,[]]],[[2,2,2,[4,4,7]],8,[[4,9,4,10],8]]]\n[[[[2,3,0],[],[7],[3,8,5],2],[5,[]],8,[]],[],[],[7],[2]]\n\n[[[[2,4,5,2,9],9,7,[8,1,5,7,6]],[[10,9,9]],9],[[[],2,10],[9,4]],[8,9],[[[8,7,5]],1,[[1,7],[],[9,2,4],0],4],[3,3,5,4]]\n[[7,[8,[9,1,10,1],[8,7]],7,5],[[10,[4],[7,0]],0,5],[4,7,5],[],[9,[[9],[9,1]],5]]\n\n[[4,9,[8],[9,7,[0,7],0,0]]]\n[[4,0,0,2],[3,[[1,6],[5,4,7,1,9],9,5],[[9,1,3],5],8],[[[8,5,8],[],[10,10,0,9,0],[2,0,10]],[[6,3,8]],10,[[5,1,9,10],6]],[[]],[1,2,[[6,4,9,0,2]],8]]\n\n[[1,8,4],[6,[[2],4,3],10,1,[10,[8,8,7,3],1,2,7]],[8]]\n[[[0]]]\n\n[[5,[4,[3,7,6],[2,2,6,7]],[[5,8],3,2,[10,1,1,10,2],[3,2]],10],[8,[[],2,[]],[5,6,[3],0],1]]\n[[9,8,[],[[4,3,8,7,2],[0,5,7,2],8,1],7],[[[10,6],3]]]\n\n[[[2]],[[[7,2,8,9],[],2,[]],[6,9,[1,5,5,5],8],6],[[4,3,6,7],[[6,4,8],[0,6,2],6],[4,6],[[5,2,3,4,8]]]]\n[[[6],7,8,[7,[4],[1,10,0,3],[6]],[[8,10,9,1,2],[9,9,0,2],[2,7,0,2,9],8]],[[[8],0],9,5,[],7]]\n\n[[8],[[1,[],0,[10,3,0,8,6]],9,2,[8,[4,3,4],3]],[]]\n[[],[[[10,9,7],1,[6,3,7],[]],1,[[4,9,8,3,1],[9,8],[0,10,4,3],[0,0]],[6]],[[[5,7,10],10,[5,9,0,6],1,[0,0]],[10,[],[2,1,3]],[9,[5,1],[6,6,9],8]],[0,[],[2,[6,10,2,0],[3,2,9],[8,10,10],4]],[]]\n\n[[[[6,1,1,9,0],[2]],6,5,0,[[],[3,4]]],[[],[10,9,1],[2]],[2,[[8,5],5,[]],[1,8,[4],[0,4,4,4],[0,6]],6]]\n[[7,[9],[0,[4,0],3]],[[[],6,[6]],5,[[1,5,5],4,2],5,[0,1,[]]],[]]\n\n[[[4],[5],[9,8,9,1],1],[[[8,2,5]],[10,[9,0,0,6],6,[2,6,2],[4,8]],4,10],[],[[9,3,8,[10,10],4],[]]]\n[[5,2]]\n\n[[10],[0],[4,7,[[4,8],[2,4,8],[4,10,2,5,7],10],2,7],[[[7,0,0,1,0],[0,6,8,6,9],4,6]],[[[],7,[1,6],7],[[10,10,4,2]],[0,3,10,[6]]]]\n[[[[3],10,[7,3,2],[6,8,5,9]],[4,4,0,[8,6,9,2]]],[]]\n\n[[[2,[7,6],5,1,4]],[[8,0,10],[[2,8,6],9,[7],6,4]],[5]]\n[[4,4,[3,6,5,[10,8,9,5,4]]]]\n\n[[],[[9],3,[[6,10,10]],0,4],[[[10,10,10,8,1]],[9,[]]],[4,[8,5,[0],0,[7,6,6,3]],3,[7,0,5,7]]]\n[[[5,2,8,[1,6,10],5],[],[]],[[[]],[[0,1],5,0],[[8,2,9,1],[2,8,7],5],[[],9,0,6,0],4],[[[2]],[],[0,[3],[],5,6],0,[[7,3,0],1,[0,2,9,10]]]]\n\n[[9],[[[],0,9,0,2],5],[0,[10],[10,[8,0,5],5,9]]]\n[[],[[8],[],2,3],[1,[[10,2,7],6,[3,0,9,6],9,[9,5]],2,6,[3,5,[9,9,8]]],[6,[4,[8,7],4,[2,1,0]],[[10,1,7],10,[1,9,1,0]],9],[0]]\n\n[[2],[5,[1,[2,8,9],4,[4,1,7,8]],[],5],[9,9,[3,[10,2,9,0,4]],1],[5,[],8,[9,3,5,2]],[[[5],4,[0],[5],3],3,6]]\n[[2,2,6],[5,6,[2,10]]]\n\n[[[[6,10,5,10,8],[5,8]]],[[[6,4,8,4],[8,7,8],[8,9],3],5,2],[9,[5,9,[2,3]],[[],[7,1,4,4],[],10]],[]]\n[[6,5,[4,[8],[6,2],2,3],[2,1],10],[8,[8,[],[4,2,7,4]],[9,[5,2,2,0,9],[],[],[8,5]]],[[[4,3,9,6],[5,6,1],4,4,[6,8,1]],[[],9],[[2],6,2]],[7],[[[5,5,4]],3]]\n\n[[[[5],[0]],[5,10,[],5,4],[1,[1,9,2],8,[2]],8],[[[2,0,10,0]],5,3],[[[]],[5,1],[[0,2,4],5,10,[7,4]],0,[[5,8,2],[7,9,0],6]],[8,[[1,8],8,[3,0,4,10]],9]]\n[[],[],[[[5,8],8,[2,8,6,9]]],[9,9],[8,[9,[1,4,4,7,3],8],9,4]]\n\n[[10,[9,8],[[],[5,8,10,10,7],[7],4,[]],[0,3,[8,3,2],5]],[4,[0,[]]],[[[4]],[7,2,0,[3,0,7,6],3],[1,[0,9,7]],[5],[[0],3,2,8,2]],[6,[[6,10,6,0],[0],4,1,[5,8,5,3,10]]]]\n[[7,4,[[7,9],[6,1,7,9],[10],[9,4]],[[6,4],8,[9,3,8,10,1],[]],2]]\n\n[[[[1,0],[8,1,2,4,0]],2,[],5],[0,[]],[9,[],5]]\n[[[[10,0,9],8,[4,10],[8,3,10,6],4],10],[6,[[10,10,1,7],6],6],[[[10,7],3,6,4,[1,2]],10,[[8,3],[],5,1,0],[[],[0,7,0],5]],[]]\n\n[[9,3,2,[6,7,[10,5,7,3,2]],[[7,9,0,10],9,[10],[8,1,4,2]]],[10,9,8,[[9,4,10,3],2],[6]],[3,8,6,[[10,7,3,6]],[2,4,10,[3,3,0,5],[]]],[9,8,[2,9,10,[5]],[[],[3,7,10,10,9],[7,1,3,1,7],0,[]],[[2,1,10,7,9],[4],10]]]\n[[8,[[],[4,1,5,5,1]],6,9,5]]\n\n[[6],[[[3,6,10,8,9],1,[10,2,4,0,7],9]],[5,[6,1],[0],4],[],[[],[],[6,9,9],[],[]]]\n[[[7,[3,0,4,1],[2,9,10,6,4]]]]\n\n[[],[[],9,3,9]]\n[[[],[[8],[7,7,6,3],[],[9,7]],10,10]]\n\n[[[10,6]],[8,9,[7,9,6,[4],6],9,[[8],[7,1],[7,7],0]],[[10,6,[6]],7,7]]\n[[[[10,5,8],[8,1]],[[4,0,0,1,10],0,[8,10,2,9],[0,1,2,0],[4,0]],[8,[],0,2,[4,3,8,7,2]],[0,[0,3,6]],4],[[7,[3,8]],10,[]],[8]]\n\n[[[4,9,[3,5],9],10,7,5],[6,[5,[7,9,4,4,8],[0,3,3,5],10,6],[[]]]]\n[[9,[],[[6,3,2],9,3,5],7,[]]]\n\n[[[10,[],[5],[3],0],[6,[5,4,5,8,7]],5,2,5],[[5,8],[[]],0],[9,3,7,5],[7,[8,5,9],[3],[[],6,[4,5,8]],9],[[9],10,[[5,9,4,5],[]],2]]\n[[10],[5,10],[[9,9,[8]]],[[10,[],[5,10,6,2],[9],[]],[[0,8,10,10],[0,5,1,5,0],[2,2,5,1,9],9]],[3,7,[[3]],[[3,4,10,8],[2,3,10],3,[8]]]]\n\n[[3],[2,[],[[4,8,10],[7],3,[0,5,4]],3,3],[],[[],[[9,7,7]],[[8]]],[8,[],[[8],3],[]]]\n[[9,4,4],[[[1],9,6,[4,5]],[6,2,0],5],[[3,[6],9],7,[[],[6,0,2,4],[]],8,[6,[0,1],7,5]]]\n\n[[10,[],[[1],[8]],[],[[],5,[8],[3,8],[1]]],[[[],[4,8],[9,6,7,1]],3,5],[[[2,9,3,10,0],0,6,[3,7,5],[9,7]],10],[[8,0,[8,7]],6,5,5]]\n[[6,8]]\n\n[[],[],[]]\n[[[2,5,7],9,0,[1,10]],[8,[0,[2],5,[],[5,6]],6],[[[7,7],1,[6],[1,9],3]]]\n\n[[2,4,[[4,3,4,10],[7],6],[9]],[3,[],[[8,9,10,9],6,[2,3,2,4,10],6],[[4,8,4,8],2,6]],[3,[2],[7],4],[[2,[2,1],[9,3],[9,4,5]],[[1],[5,5,10]]],[1,[]]]\n[[[7,[3,6,6,6,2],[7,0,3,0],7,5]],[[4]],[],[3,9,1,4,[[1,7,0,10,8],0,5,[0]]],[[5,9,[4,5,5,10],[0,7]],0]]\n\n[[[2,8,2,8]],[]]\n[[],[6,9,[[8,7,7],[0],[4],[]],0,[[],[7,1,9,2],[2,5,9,4],2,[2]]]]\n\n[[7,3,[[8,9,3,7],[7,10,6,2],[4,0,7,0,8],[0]]],[[[],[4,3],8]],[]]\n[[[10,[9,9,4]],6],[4,[4,[],5,[3,1,8,6],0]],[5],[]]\n\n[[[],[4,0,[0,0,6,9],[8,0,3,7],[3]],9]]\n[[],[],[[[7,3,7,7],[5,8,3],6],10,4,[2,4]],[4,1,6,[]],[]]\n\n[[[[],4,4],4,6,9,[0,[1,10]]],[],[5],[6,[[8]],5],[[2,[6,3,1,10],[]],0,[[],[1,6,2,10,6],[8,10,6,2,1],1]]]\n[[[[0,9,8,3],1,0,5,[9,0]],[[5,8,3,4,9],[4,1,2,9,4],1,[],5]],[[[10,10,1,6],[5,10,3]],[[7,7,8,8,7],0,0,10]]]\n\n[[2,[[8,7,0,1,6],10,9],5],[]]\n[[[[3,9,9,2,4]],8,[],4,[[8,8,4],[],4,6,[5,6]]],[[[],0,7,3,[3,0,4,9,0]],[[4,5,6,7,0],5,0]],[2,[[0,1,5,6],[3,2,0,6]],[[6,7,1],4,[2,2],[4,10,9]],[9,2,[6]],[[7,7,9],1]],[[],[1,10,[7,9,2],2,10],2,[[]],[2,2,2,1,8]]]\n\n[[[7,8],[2,[7],[2,3,0]],1,[5,[6],5,[4,1,5,9]],[]],[0],[[[7,5,0],3,[6],8]],[6]]\n[[9,[[4,8],[1,4,8]],6],[[8,[3,6,2,2],[],[8,4,3],8],8,[[5,0],[],[4]],2,0],[[[7,6,1,6],[2,10,1,5,1],3]],[[[10,0,0],[8,1,4,3],[2,0,4],7,1],[8,9,[8,4,2,0,9]]],[[8,1],[[],[7,9,6],6,[10,0,8]]]]\n\n[[[8],1,2,[0,[4,4,8,7],[6,5,3]]],[],[[[5,7,10],4],[[10,10,4,6,5],0,[]],5,[[10,8],9,2],9]]\n[[],[],[[1],3,[[3,8,10],[9],4,[],[7,6]]],[[[7,5,4,7,5],[7,6]],[9],[[4,0],6,[2,0,5,6,7]],[[],9,[7,4,5,0,6]],[[8,0,2],[1,3,3,6]]]]\n\n[[6,7,4,8],[9],[8,[[3,6,6,5]]]]\n[[6,4,[[],10,2,[1,1],[7,2,2]]],[10,[10,[5,10,9,7,7]],7,[9,[0],9,10],10]]\n\n[[[0,[7,8,3]],7],[0,6,7,[8,[5,1],[7,6]]],[5],[[[],10],6]]\n[[8,[7,[8,9],8,9],3,[8,[2],6],2],[[[8,5],8,[0,4,10,4,5],[5],[4,4,2,6]],[],1,4,[10,4,[1,9,10,2,8],3,7]],[[[],4,[9,1,0,10,8],[6],[10,4,3,10,9]],4]]\n\n[[6],[],[6,9,[[6],5],[[5,8]],[[9,9,3,4,3],[0,5,6],[1,1,9]]]]\n[[6,5,10,[[]],1]]\n\n[[0,[0],[10,5,2,[9,0,10,4,0],5]]]\n[[7,2,3,[[1,10,7,1]]],[6,9,[[9,0,10,4,6],7,[1,8,6]],[[7,3]],3]]\n\n[[0,1,3,1],[3,6,[[0,1],9,[0,6,8,3,0],[1,10,10]]],[[],5,9],[4,[],[[8,6],[8,5,6,6,0],[2,6,5]],4],[10,[]]]\n[[],[8,[10]],[[10,[3,0,1,4],1],6,[[5,8,6],[10,10,6,4],[9,7,7]],[]],[]]\n\n[[0,3,[],[9,[7,2,4,9],[6,7],9,5],[]],[],[[7,[],[9,7,9,0,4],5],[6,[9,4,5,10,5],[1,4],[3,7,10,3],8],2],[]]\n[[8,6]]\n\n[[[[8,4,8,10,8],[7],[4,6,0],2,[1,1]],9,[[],0]]]\n[[2,[]]]\n\n[[[],2,10,2],[[[4,9],[4,8,9,9],[8,6,8],[1,1]],[7,3,[],[],2],[9,[6]],1],[[],[1,5,2,7,4]],[[[2],9,[7,7,2],8,6]]]\n[[],[9,9,[[],8],[[1,8],[10],9,[4,7,10,0],9],2],[]]\n\n[[[1,6,[9,3],9],[6,[4,7,9,2],[10],[4,10,8,1],[]]],[[[9,8],[4,9,1],9,[6,0,6,10]],[8,1,[8,3],2,6],9],[],[[6,[4,4,6,10],5,7,[2,0,8]],[[]],6]]\n[[8,8,[1,6,[9,4,8,3,7],[7,6]]],[9,7,4,[]]]\n\n[[2],[],[],[[[7,4,1,0,1],[0,9]],6,[[8,10,0,4,8]]]]\n[[1,9,9],[1,[[2],[0,5,9],2],[[9,7,7],6,6]],[[1,6,8,[]],[[0,1,5],3],5,[[9,2],2,6,5],5],[5,8,[4,4,[],[9]],1,7]]\n\n[[10,7,6],[[[],[4],4,5,10],1]]\n[[],[5],[0,[[5,3],1,10,[2,0],[8,1]],[1],4],[5,4,10,10,[[9,2,1,3],[2,10,10],[8,1,9],[3],[]]],[[0,2,[2,4,1],2,1],4,5,[[10],[7,5],[],1]]]\n\n[[7,[[8],2,[0,9,5,5,2],[5,3,4,2]]],[[[3,5,7,3,2],[5,10],8,9],4,7,8]]\n[[],[3,0,1,9,10]]\n\n[8,10,7,6,5]\n[8,10,7,6]\n\n[[[[6,5,4],[4,0,8,7,0],[1,9],5,[1,9,1,1,0]],[[4,6,6,2]],[8,[4,7],[8,2,7,9],[5],[]],1,[10,6,[1,5,8]]],[7,7,[8,[9],[2],4,[7,4,4,3,9]],[[],[3,7,3,1],3,[4,7]],2]]\n[[[9,5,[7],8],[[10,7,4,4],10,[3],8],10],[[[5,1,5,6],[2,2,5,4,5],0],[9,[10,9],8,8,7],3,[9],[[]]],[[8,5,8,6],4,[],[[]],9]]\n\n[[[0,7,7,5,9],[[],8,[2,2,7,3,7],6,[10,6]],[3,7,[8]]],[],[[],1,3,0,3],[]]\n[[3]]\n\n[[[[],[]],2,[8]],[],[0,[[0,3,3,7],1,[7,6,10]],7,1,[[3,0,8]]],[[[]],[[4,6,2,9,3]]],[[],[6,[2,8,6],4,7,[3,1,5,7,1]],1]]\n[[5,2,8,[[9,6,0]],10],[[[],[4,0,7,9],6,[9,0,7,5,9],[7,5,3]]],[5],[[1,10,7,[2,2]],[9,3]]]\n\n[[[],[[],[0,6]],10,7,[7,[],[2,5,2,10],[6,1],[2,0]]],[],[[2]]]\n[[6,[[10,6],4,3,[6,10]],[[7,6,9,10]],[7],10],[[5]],[[],[0,[8,3],5,[]],[[2]],0,[[2,8,3,7]]]]\n\n[[4],[2,[3,[10],[6,4,1,0],[],[1,9,9,2]],10],[3],[1,4,8],[7]]\n[[],[6,[],3,5]]\n\n[[],[5,[[3,1]],2,[],[[6,7,0,10],[7,8,6,4]]],[[[7,7,9,2],3,[1,1]],2,[10,[9,2,3],0],0,[[2],[10]]],[4,[[]],[4,6],[5,7],[3,[]]],[5,2]]\n[[8,[[],[9,2,8],[2,8,10,0],3,[10,10]],7],[[8],5,2,[10,1,[9,1],[4,0,0],2]],[9,2]]\n\n[[[[],[10,2]],9,7,[6,[9,6,8],8]]]\n[[[],0,10,0],[[[]]],[],[],[6,[],8,[],8]]\n\n[[[[4,8,6],9,[7,8],2,[1,3]],1,7,[[0]],8],[[0,[0,9],[9,1,2,8,3]],[]],[8,3,[7,[]],[2,[3,7,8],10],4],[10,[[9,2]],[[],4,10,9]],[[7,[9,5],[8,10],[8,2,5,6]],[9,[4,1,10,8],[3,7],2,9],[6],1]]\n[[],[],[],[]]\n\n[[8,1],[],[6,[[2,7,5,9],[4],7],[5,3,[1,7,1,2],3]]]\n[[2,5,7,[0,[7,4,0]]],[],[1,[7,3],9,9],[]]\n\n[[4,[],5,[[4,2,8],[7,2,8,9],[10,4,2,0],6,2]],[0,[[6],[7,0,6,7],8],[2,[2]],[],9]]\n[[1,[7,[2,0,7],8]],[8],[],[[[],0,6,[7,7,5,7],[6,7]],10],[0,[3,[8]],[3,[6],[9],[6],[4,5,0,1,1]],7]]\n\n[[[[],[2,8],[8],[1,6,3]],[6,[4,9,10,1],0],[[3,4,3],7,[9],[1,1,10,7]],3],[[[7,5,7,1],[7,5],6,5,[6,5,7,4,4]],4,2],[],[6,[],10]]\n[[5,[[1,4,1,6,9]],2],[[[],8],3,[[10,0,10]]],[[[4,7],4],4,[[7,3,2],[]]],[3]]\n\n[[1],[],[],[2,[[7,6],10,3,2],3,[[3,0,5,6],[1,8,9],[3,8,7]]]]\n[[2,[[6,10,6,7,8],[9,10,2,4,8],6],7],[[1]]]\n\n[[],[3,[6,[],7,9,[1]]]]\n[[[],5,7,[7,[10]],[8,10,7]],[[8],[6,[7,2,4,9]],[0,[10,1,8],8],[7,[10,0,8],[5,9,4],[],[5,1,1,7]]],[[[8],4,[],[]],1,3,8]]\n\n[[[7,[8,1,6,9],4],8,[[4,1,9,3,7],[9,7,8,4,10],8],8]]\n[[[3]],[9,1,4,[4,[7,1,1,6,0],4,[]]],[4,9,[6,[2,9,8],[4],6,[5,10,9,0]],1]]\n\n[[10,[],[[4]]],[[[4,4,3,2,9],6],1],[[6,[3],[3,6,2,5],1,[]],[[],[5,4,3,8],[2],8,[6]],8,8],[8,8]]\n[[],[1,[[2,0,10,0,8],[2,10,7,9,9],4,[7,9],[2,6,6,7]]]]\n\n[[4,[5],[],[[],[],0,1,10],2],[[0,7,[3],[7,4,7,4]],8],[[[6],[3,1],5,[],[1,1,7,0]],5],[[2,[10,3,4],[0,9,5,1,1],0,4],9,[5,[2,5,6,0],[2,5,3,3],4,7],3,[0,[10]]]]\n[[3,1,8,7,[7,0]],[[[5,4,4,10],2,[3,1,6,4]],[],10,9],[6,9,[4,[3,9]]]]\n\n[[],[[[]],[3,[8,4,4,4],3,2,[9,1,5,2]],10,[6,9,2,7,8],1]]\n[[10,[],2,0,7],[[8],4,[[1,5,3,1],1,[0,10],3,2],[[10,5,7,7],[7,8,8,6],[3,5,2,5],[8,0,7,2]]],[[],[4,[3,6,5,2]],[2,[8]]],[0,[10,1,3,[6],9],[6,3,[4,5,6],7],[1,[7,0,3,2],6,0]]]\n\n[[[[]],4,[[2,4,3,1,7],[4,5,8,0,0],[1,1,6,2,4]]],[[5,8,[7,2],4,[4,10,0,2,8]],9],[6,[]]]\n[[[6,[]],3,[0,[3,10,1,6],7,2]],[0]]\n\n[[7]]\n[[8,[[5],2,[2,10,9],[7,8,8]]]]\n\n[[[[9,9,0],8,[6,2,7,5,7]],3],[],[]]\n[[5,6,[9,2,[10,0,2],[5,9,6,10],[5,1,9,9,2]]],[[0,[4],[6,3]],2,[10],[2],7],[[],8,[],[2]],[0,[],[10]]]\n\n[[7,3],[[10,10,[],8,3],0,1,[],8],[1],[[5]],[9,9,8,8,[[10,10,3,10,0],9,6]]]\n[[[],[],2]]\n\n[[[8,10,0],1,[[4,6],[7,10,1],2,[8,2,8],[4,1,7]],7]]\n[[[2,[]],4,5,[4,[2],[]],5],[7,[9,[3,8]],[[10,7,3],8,10,4,8],[[4,10,8,4],7,0],[7,[3,9,9,5,10]]],[6],[0,[[0,8,7,1],7],4,[5]],[[[4,0]],[[10,2,8,5,10],5,4,[],2],1]]\n\n[[0,6,[[],9,6],3,[]],[[2,10,10,[3,9],8],[[1,8],6],3,2],[3,4,[9,[9],[3,6]],[5,2,[6],[10,10],[4,4,3,8,0]]]]\n[[[4],[[9,1,4,4],[],1,[6,10,7],[]]],[[],[8,5],[3,[3,0,0,9,1],[4,7,4,2,0]]],[[],[10,0,[6],[6,3,7],[5,0,10]]]]\n\n[[6,8],[3,9,[],[[1],[8],0,0]]]\n[[7],[],[8,[5,[3,5,6,4],[7,4],4,[10,9,2,1,6]],[9,[2,4],[7,8]]],[[[2,0,2],6,[5],[3,3,9,9],[4,8,8,0,7]],[6,[]],[],[10,[]]]]\n\n[[[[2,0,3],10],[7,[],[9,8,7,4,8],7,[4,10,6,10]],8],[7,9,[6,[],[]],2],[[5,1,[8],[10,8,10]],[10],[4,[],[1],6],[1,[],[1,9],[4]],3],[[[7,1,7,9,6]],[],2,[]],[[4],[[4,0,1,1,1],[5,9,10,7],0,[1]],[2,0]]]\n[[],[[],[[1,0,7,8,2],[4,6,8,10],[6],7,5]]]\n\n[[5],[[[1,8,7,5,1],2,7],8],[9,[[10]],[[7,1,0,6,1],[0],[6,9,2,6],[8],5],[5,9,9,[8,5,3,8],[]],2],[1,[5]],[[3,[8,9,8,6],1],[[],[1,8],[10,7,0,8],[5,9,7,8,8],[8,8,2,5,8]],[]]]\n[[[9,[4,6,0,10],[7],[1,4,1],[10,3]],[[10,10,7]],0],[[6,[0,8,3,1],[0,3],4,5],[4,0,[9,0,1],[0,4,9],7],[[8]],1,[]],[[[],3,2,[]],[9,[6,9,8,8]],5],[7,0,3,8,4],[10]]\n\n[[10,[8]],[6,0,[[7],2,0,1]],[[3,[1],[1,3],[1],[6]],8,[[6,8,4]]]]\n[[[9,[]],6,5,[9,0,[4]],[[1,4,1,8,10],9]],[[6,5,[8,1,7,3,0],[8,3],[]],1],[[[10,4,4],7,[4,8,2,10],[9,10]],1,4,5]]\n\n[[[[1,10,0,4,0],2],4,4,6,10],[[3],[0,[6],[0,5,2,1,5],6,[8,1,2,0,1]],[],[6],4],[[[]],[],[4],[9,[3],9],[9,6]],[1,4,6],[0]]\n[[[7,[2,5],[6,6,7],[9,9],[7,0,9]],0,6,[],[]],[[5,[1,7,10,0],[8,5],[2,5,6,4],7],8],[[[1,2,5,2,6],5],[[]],9,7],[[9,[2,3,9],9,[],[7,0,8,3,5]],[7,[3,2],[]],1,9,[]]]\n\n[[2,1],[5,[8,[]]],[]]\n[[0,2,2,[[4,9,8,10,0],3,5,7,[8,8,1]],[[3,7,8,1],[2,2,10,0,0],[4,5,3],[],6]],[5,[3],1,3],[[8,3,[9,9],[9,0],1],[5]],[[[4,9],1,[5,7,10],[8,7,4,2,2],2],[2,0,[6,1],9],4]]\n\n[[2,[3,8,[8],[10]],[[]]],[6]]\n[[7,[0]],[[7,[2,0],4,4]],[]]\n\n[[[[10,9],[3],[7,10,3]]],[]]\n[[[1,4,3,1,[]],[]],[]]\n\n[[],[[[],6,0,[3,4,4,2,10],[2,2,7,8]],[[4,8,3,4,9],0],[],[]],[]]\n[[3],[[6,2,[2]],3,4,7],[[2,[],[5,9,10],[3],[8]],[[4,2,0],8],4,10,[2]]]\n\n[[9,[[7,8,10,9],3,[3],[3,8,3,1,8]]],[[],4,[]]]\n[[5,6,8,[]],[[8],[],4,9]]\n\n[[[],[3]],[9],[],[[5],[],[2,8,10,[7,7,6,2],0],[[],[4,9],[3]]],[[[2,2,5]]]]\n[[],[[],[5,[4,3,6,7],9,2],[[4,1,8,10,5],6,7]],[[[0],7],[[6,9,2,6,5],7]],[[[0,10,3],[5],7,10],9,8,[[],4,0,[7,2,3]]]]\n\n[[3,4,0,[7,7]],[[[2,9],10,9,[2,10,7,0],[7,2,1]],10,0,[5,[],[7],[1,9,2]],[1,3,[],4]]]\n[[[3,5,6,[0,6,5]],[[],[],[2],1]],[5,[],[4,0,4,[]]],[4],[[[3,7,4,8,7],[0],[1,9,1],[7,9,8,0,6],4]],[[[7,10,5],[5,5,6],0,7,[9]]]]\n\n[[[[2,9,7,8,4],2],[8,2,[3],[5,5]],9,[[2],[7,8,9],4,6,[]]],[[],7,[[8,10,2],0],[[4,10,5,7],3,6,[2,6,3,4]],[5]],[10,10,[0,[4,7],[2,1,6,3]]],[9,[4]],[]]\n[[[3]],[7,[9,[],7,[8,3,1,1]],7]]\n\n[[10,[[0,1,4],8],[4],[],9],[5,[7,3,[10,8,4],9],[9,[4,3,8,3],2,[6,6,5,9,0],10],10,[[],[6,3,0,8,7],0,5]],[4,10,[1,[10,3],1,8]],[4,[[],[1,0,8,8,9],3,7],9,[[10,7,1,1],[],[8,2,6],5,[]]]]\n[[[5,[3,0,3,2],4],[1,[],7,[],[1]],[[10,10,4,0,2],9,[9,3,9,7,5],[4,2]],[7,1,[5,7,8],6,10]],[[[7,2],[9,3,0,6]],[[9,10],[],[10,7],[6,4,7,5]],1,4,[]],[[[7,6,3],5,[0,2]]],[[5,8,3],2,6,[]],[[[10],[],[],8,0],[],[8,6,[7,5,3],[2]],3,[[7,10],5,3]]]\n\n[[[[8,6,2,3],9]],[[1,7,1,5,[6,1,1,2]],[],[[4,1,1,9,9],[0,2,5,0,7]],9],[1,[[10,10],6,4,0,0],1,[8],[10,0,9,5,[4,7,3,5]]],[10,[[0,4,8,3,5]]]]\n[[0,[[5,6,6,7]],[6,3,[6],7,[3,0]],[8]],[2,10,9,5,10]]\n\n[[5,1],[7,[2,10,3,5,[10,4,6]]]]\n[[7,7,9,1,9],[]]\n\n[[[],[5,1,[],6,[4,2,2,6,6]],10,[[],[5,8,5],0,[3,2,0,7,8]]],[[[8,10,3,7]],[[2,1,6,1,9]]],[2,7,6,0,[[4,6],10,[3,2,7],0,[]]],[10,[[],3,[9,10]],9,5,[[]]],[[[],[10]],7,6,[[5,0,1,1,5],[]],3]]\n[[5],[6,[8,[10],4],[8,1],[[10],10,[7]],1]]\n\n[[2,[7,[],[],6],[[],3,[]]]]\n[[],[],[[9,[3,10,0],0,[8]]],[8,[[],5,0,[4,6,5,2,5],8]],[[7],[3],[[9,5],[7,6,7]]]]\n\n[[4,2,8],[[[],0,9],2,6,3],[],[[[2,3],[1,0,0,8],1,6],7,6]]\n[[[[3],10,2,8]],[6,3,[4,0,[7,7,2,9,9],[],5],[[0],3,6]],[8,[[6,7,10],[0,4],[2]],4,0,[]],[[9,[7,3],[0,0,5],4,4]],[1]]\n\n[[],[1],[1,[[10,9,2,0],[6,5,7]]],[10]]\n[[[5,[3,6],4,[]],8,2,10,[[7,0,0,7],7]]]\n\n[[[],[[],8,1],[1],8],[],[3],[1,10],[3,[],[[4,0,10,8],2,3,[5]]]]\n[[[[3,9,8]]],[[[0],9,[3,9,6,10],3]]]\n\n[[7,9,9,[],8],[[1,4]],[[1,[9,2,6,3],[1,4,6,0,2],4,[7,0]],9,[[3,2,1,9],[4,10,10],[7,7,5],[10,4,9,3,8],3],[[7,1,7,0,3],[10,2,7,0],5,[10,4,5]],[1,[8,3,2,0,0],7]],[2,[]],[]]\n[[[[5,5,1,8,5],[2,6,0],[3]],[1,3,[4,5,2,1],6],[[7,4,8,5],10,[10,3]],0]]\n\n[[[4,8],0,2,[[3]]],[[4,4,8],9,10],[3,3,4,[[],7],[[6]]]]\n[[8,[],[4,5,0,[1,5,5,6,6],[3,5,9,1,6]]],[[],6,8],[[2,9,[6,1,2,1,1]],[]],[9,6,3,1,2]]\n\n[[],[[[5,9,1,1,3],7,[10,0,5,7,5],[8,8]],4,7,[[2,10,8,4],[9,5,9,6],[]],8],[8,[[1,5,5,9]]],[5,6]]\n[[7,0],[[[5],[],7]],[5],[10],[6,0]]\n\n[[],[]]\n[[[],[],[7,4,7,[6,6,1]],[3,9,8,0,[5,2,3]],3],[[[1],1,7],[6,2,3],[1,[6,8,3,1,9],[]],[3,7,7,5,[2,2,3,5,9]],[4,5]]]\n\n[[4,[[8,6,3,10,0],2]],[9,[5,10,9,[3,1,0,8],3],1,8],[]]\n[[],[],[9,[[2,4,7,0],8,[],7,2],4,5,1]]\n\n[[2,[7,[3,8],[7,2,3],7,[7,6,7,4]]],[0],[6,[7,[10,10,5],8],[7,[10,7,6],[9],3,9],10],[[[10,7],[2]],[6,[7,5,8],1,6,[10,0]]],[[],[1],[],[10,[10,3,4,8],6,[7,0,3]]]]\n[[[[6,2,1]],2,1],[],[[1,[],0],0],[[8,[3,0,4,4],[7,7,10,9,1],2,[9]]]]\n\n[[3],[],[],[2,0,1],[10]]\n[[2,[10,[],[1,0,5,4],[],1]],[4,[2]],[[4,2,4],4,[2],7],[[],[[1,4,7,10,6],[3]],[],1,[2,6,6]]]\n\n[[],[],[],[0,[[2,0],[2,6,10,0],5,[0,3,7,6,4]],[10,7],3,5],[2,2,[2,1,[5,2,2,8]]]]\n[[[5],7,[5,[9,7,9],1]],[3]]\n\n[[[5,[5,8,0,2]],[10,6],1,6,[7,2,[],3,8]]]\n[[[7,5,3,6],[6,[3],4,[]],[[3],[],[5,5],[0]],[[10,0,3,8,7],[5,3,6],[8,4,5],8,4]],[[7,7],[10,[10,7,6],[9,7,5,5],[4],9],0,[2],[]],[[],4,4,[1,0,[],0],[[5,4],0,[0],8,1]],[8,[4,[7,0]],[8,10,0,7],[[6,6],10,[8,1],4]]]\n\n[[],[[[],3,8],[4,8,9,[3]]],[],[2,1,10,[],[5]]]\n[[[[3],1,[9,5],5,7],9,2],[2],[[0]],[],[[[7],10,9,[9,6,2]],[[10,1],8]]]\n\n[[],[],[[10],[[],[4],[0,2,1,4],[8,7,4,3],6],[9,[2]],[]],[[[10,5,3,1,9],0],[2,1,[7,7,8,9,1],5,[7,3,1,9]]]]\n[[10,[5]],[]]\n\n[[7,2,[[],[2,1,0,1,9],6,[10,6,7,1]],[[],[6,6,1,2],[6],6,[8,2,2,10,8]],9],[6,[6,[3,5,0],[1,0,0,2],[5,9,8,1]]],[],[[[],8,0,[0,5,1,0,6]],[[3,5,9],8,0,0,[10,3]],[]],[8,[],[[2],10,8,[1,10,10,10]]]]\n[[1,[[8,5,10,0,3],8,8],6]]\n\n[[[],[],5,9,[[],3]],[[[],[],[10,3,2,6]]],[[6]]]\n[[[[0]],1,2,[[0],[10,6,7],[8,2,9,4,9],[6],[0,7,6,6]]],[6,3,[[8,6,8,9],[8],8,9],[2]]]\n\n[[6,[],5],[10],[5,3,8,[[7,1,2,1],[7,7,2],3]],[[4],[9,[5,6],10,3]]]\n[[[1,7],0]]\n\n[[5,[]],[],[],[],[6,[[],0,[6,10,7,5],9],[[3],6,2,[7,8,8,1,6],7]]]\n[[[2],0,[8,[5,6,2],1,3],[[7],10,[8,8]],[[8,5,4,7],9,[7,3,2,7,0]]],[1,[[2,6]],[5,6,8,[8,1,7,0,7]]],[3,7]]\n\n[[8,1],[0,5],[],[]]\n[[8,6,[5]],[],[[],4,[[9,2]],4,[[9,10],[9,7,7],[6,6,5]]],[[[9,7,9,10],3,[1,5,2,6]],0],[[[10,1,7],[5,3,0],[]],1,[8,0,[9,6,7,5,0],[],[6,1]],[[8,7,2,1],7,1,4,10],[[5,6,8,5],[8,10,7,6,9],9,1,[]]]]\n\n[[[],[],7,6,3],[6,3,6,10],[[],[],[6,1,[7,9,8,2],[10]],3],[[]]]\n[[2,[9,2],[[0,0,8,5]],7]]\n\n[[[7,5,2,5,3],1,[[],2,[],9],[[4,0,10,6,6],2],2],[[],[]]]\n[[4],[]]\n\n[[[4,6,[7,9],9],6,[[0,10],[10,8,1],[6],[3,10,9]],3],[10,[[]]],[8,9,7]]\n[[[8,8,[9,4,4,5],[8],3]],[],[10,10,3],[[[1],[5,0,2],0],3,[[4,1]],[[4,7,5],5,[]]]]\n\n[[[1,0,[],[10,2,7,5,3]],1],[[8,[7,6,3,5,6],[8,5,3,8]],9,[3,10],[1,2,[],5,1],[]],[[3,2,[],[1,4],[10]]],[]]\n[[],[[0,2,9,7],5],[9]]\n\n[[5],[[]],[[[0,7,2],[5,6,6],[6,10,9,9,7],8],[],10]]\n[[[[0],[6,2,8],[1,0,8,9],[]],[9],1],[10,4],[5,7,6,1],[]]\n\n[[[[6,10,7],[2],[3,0,2,9]],9,[[5,8,1,1,4],5,4,[0,2,4],[2,3,6,4]],[[10],[10,0,1]]]]\n[[[6],5],[[2,1]]]\n\n[[10,[5,[1]],5],[[[1,4,6,6,7],[2,5],4,[5,3,5,3,7]]]]\n[[9,[3,[],[],[3]],7,1],[[6,9,0,2,[8,8,10]],10,8,[]],[]]\n\n[[[6],[[10,9],5,[7],[7],[10,5,9]],0,[[10],[4,9],6,[0,1,4,10]],8]]\n[[0,[0],[],5],[],[[[9,8],[6,3,1,3],7,8,[]],2,[[4,0,3]],[6]],[7,[[10,2,0,1],9,2],[[9,7,0,4,10],10,[3,10],5,6]]]\n\n[[0,0],[1,[],2],[6,4,5],[5]]\n[[7,[[0],5],5],[5,[[4,3,8,4,0],[8,7,0],7],[],[[],10,5]]]\n\n[[],[5,2,[[5,2,4,8,5],9,6],[],[[8,5,5,4,10],8]],[[],[[1,7,4],[6,4,7],[10,1,10,7,3],[1,4,10,4],[]],[9,[5,0,10,5,9]]],[],[6,3,[10,[0,10,0,10]],2]]\n[[],[[[8,7,10],1],[[5,2,8],[8,8,10],10],[[],8,[7,10,4]]],[[],[3,10,[7,0,8,4,6],2],10,[[6,6,5]],2]]\n\n[[],[1,[[],9,3,[1,2],[]],[10,1,7,[7,9,0,1,2]],3,3],[1,8,[[5,1,7]],6,[[9,1,3],[7]]],[7]]\n[[[[],5],3,[],3],[[[],5],[[2,3,0,8,5],8],[[],3],3,0],[[[9,9,2,2]],7,5,2],[2,[],[8,6,[5,1,2],[9,0,7],[10,2,0]]]]\n\n[[[10,2,7]]]\n[[4,[6],[[8,1]],[]],[[3],2],[[[],[7,0],[],[9,1],[4,2]],10,5],[7],[2]]\n\n[[[10,[10,3],[],4,[]],6],[[],0,[[],[8,7,8,2],3,[2,6,8,8],3],8,[[4,5,5,5,1],[1,4,6],[5,8,0],9]]]\n[[],[5,[[4,4]],[[8,3,3,9]],[]],[1,2],[5,1,[[8,9,7,0,8],[10,2,0,4],0,7],1]]\n\n[[6,[[1,6,0,0],1],[8,9,5],4,0],[[[3,7,10,3]]]]\n[[7,[6,[5,0],10,8],[0,9,[7,10,5,7,4],6],[7,[8,0,0,4,3],[7,10,8]],2],[[1,1,4],[[10]]]]\n\n[[[9,[6,2,5,1,1],5],6,10,9,9]]\n[[[2,7,3]]]\n\n[[],[],[7],[2,[[2],[1,1,2]],4,[3,2]],[6,[10,1,9,3],9]]\n[[3,2],[],[[[],[4,6],[7,1,10,4],3,9],[8,[8],[1,7],[4,5,1,1],[]],9,0,9],[1,[[1,9],[0,4,1],[2,8],[],0],[[0,0,3],[9,8,1],[5],4]],[[4,[4,10,2],[]]]]\n\n[4,6,9,10]\n[4,6,9,10,4]\n\n[[],[],[2,9],[]]\n[[7,9,10],[2,[[8,2,3],[1,4,1,4,10],7],5,[[6,8,0,5,1],[8,10,9],1],2],[9],[[]]]\n\n[[[[],[9],[],[7]],[0,0],5]]\n[[],[3,8,[5,5,9]],[7,1,[10,[]]],[[1,5]]]\n\n[[],[9,10,10],[6,[[5,0,0],9]],[0]]\n[[[],4]]\n\n[[4,10,10]]\n[[5],[9,8,10,[[2,1,8,7,4],[],7,9,[]]],[9,[],[4]],[],[[10]]]\n\n[[3,3,[],0],[],[[1,7,0],[],[7,5,[7,6]],[[3],[7,8]]],[4],[7]]\n[[[6,[7,7,5,1,4],2,10]],[],[[7,10,[],5],[8],10],[4,[[5,1]],[]]]\n\n[[1,2,4,10],[],[[10,[7,10,7,10],[8],6],[[0,6,7,6,1],2,8,8,7]],[],[]]\n[[9,10],[7]]\n\n[[[7,6,[9,9,3,3]]]]\n[[0,3],[[],8,4],[1],[[[],8,[6,1,3,0]]],[[0,1,7,0,[6,2,8,5]],[[7,7,7],[2,7],3,10,6],0,[[9,5,2,5],6,[4]],6]]\n\n[[4,6,4,10,[]],[],[]]\n[[],[[],[[3,8,7],1,[6,0,3,3],[6,9],[9,7,10,6]],10,[0,7,2]],[[[9,6,6],1,[],[6,9,4,0]]],[[[6,5,3,7,4]],[],[7],[8,8,[1,5,2,7,7]]]]\n\n[[[[5,1,2,2,9]],[3,5,6,[7,10]],7,[8,[9,10,3],[3,10,4,2,1]],[[5,3,4,10,3],[10,1],7,1,[]]],[[[8,8,8],9,[],3,[2,9]],9,[5,5,[10,9,5,1,1],[],4]]]\n[[[9,10,[4],[]],[10]],[[],9,4,[[9],[1],[5,10,4],2,[0,4,7,10]]],[2,2,5,[[6,0],2,[8,7]]]]\n\n[[],[],[6,9,7],[1,[[8],[],5,[3,1]],[[2,5],10,[],3]]]\n[[[5,[7,0,7,10,5],5,0],1,6],[0,8],[1,0,[[3],[9],[1,3,4,5,3],10],[],5]]\n\n[[6,3,[[3,2,9,3]],[]],[[],2,5],[],[1,6,3],[9]]\n[[9]]\n\n[[2,4,[6,[6],[2,8]],[[7,10,7,3]]],[9,4,[],7,2]]\n[[9],[],[8,[[5,10,6],1],7,0,2]]\n\n[[1,5,[5,9,[3,0]],[9,[5,6],[8],[8,1,8,0]],10],[9,[0]]]\n[[4,5,[3,8]]]\n\n[[],[[[]],[[6,5,7],2,[0,0,3,0]]]]\n[[6,[],1,2],[[[10,4,1,6,9],[8,8,1,7,8],[]],1,10,2]]\n\n[[2,[10,0,1,[5,7,9,10,10],[10]]],[0,[9,0,6,6],4,0],[2,[10,[],[],1],[[2,10],[9,7],[5,4,10]],7,[[8,10,1],5,9,[8,3,2,1]]],[2,[[6,8,3]]],[0,1]]\n[[8,[4,[5,1,5]],5,5,9],[],[[4,4,[]]]]\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_13_questions.txt",
    "content": "--- Day 13: Distress Signal ---\n\nYou climb the hill and again try contacting the Elves.\nHowever, you instead receive a signal you weren't expecting:\na distress signal.\n\nYour handheld device must still not be working properly; the packets\nfrom the distress signal got decoded out of order.\nYou'll need to re-order the list of received packets (your puzzle input)\nto decode the message.\n\nYour list consists of pairs of packets; pairs are separated by a\nblank line. You need to identify how many pairs of packets are\nin the right order.\n\nFor example:\n\n[1,1,3,1,1]\n[1,1,5,1,1]\n\n[[1],[2,3,4]]\n[[1],4]\n\n[9]\n[[8,7,6]]\n\n[[4,4],4,4]\n[[4,4],4,4,4]\n\n[7,7,7,7]\n[7,7,7]\n\n[]\n[3]\n\n[[[]]]\n[[]]\n\n[1,[2,[3,[4,[5,6,7]]]],8,9]\n[1,[2,[3,[4,[5,6,0]]]],8,9]\n\nPacket data consists of lists and integers.\nEach list starts with [, ends with ], and contains zero or more\ncomma-separated values (either integers or other lists).\nEach packet is always a list and appears on its own line.\n\nWhen comparing two values, the first value is called left and the\nsecond value is called right. Then:\n\n    If both values are integers, the lower integer should come first.\n      If the left integer is lower than the right integer,\n      the inputs are in the right order.\n      If the left integer is higher than the right integer,\n      the inputs are not in the right order.\n      Otherwise, the inputs are the same integer;\n      continue checking the next part of the input.\n\n    If both values are lists, compare the first value of each list,\n      then the second value, and so on.\n      If the left list runs out of items first, the inputs are in\n      the right order.\n      If the right list runs out of items first, the inputs are\n      not in the right order.\n      If the lists are the same length and no comparison makes a\n      decision about the order, continue checking the next part\n      of the input.\n\n    If exactly one value is an integer, convert the integer to\n      a list which contains that integer as its only value, then\n      retry the comparison. For example, if comparing [0,0,0] and 2,\n      convert the right value to [2] (a list containing 2);\n      the result is then found by instead comparing [0,0,0] and [2].\n\nUsing these rules, you can determine which of the pairs in\nthe example are in the right order:\n\n== Pair 1 ==\n- Compare [1,1,3,1,1] vs [1,1,5,1,1]\n  - Compare 1 vs 1\n  - Compare 1 vs 1\n  - Compare 3 vs 5\n    - Left side is smaller, so inputs are in the right order\n\n== Pair 2 ==\n- Compare [[1],[2,3,4]] vs [[1],4]\n  - Compare [1] vs [1]\n    - Compare 1 vs 1\n  - Compare [2,3,4] vs 4\n    - Mixed types; convert right to [4] and retry comparison\n    - Compare [2,3,4] vs [4]\n      - Compare 2 vs 4\n        - Left side is smaller, so inputs are in the right order\n\n== Pair 3 ==\n- Compare [9] vs [[8,7,6]]\n  - Compare 9 vs [8,7,6]\n    - Mixed types; convert left to [9] and retry comparison\n    - Compare [9] vs [8,7,6]\n      - Compare 9 vs 8\n        - Right side is smaller, so inputs are not in the right order\n\n== Pair 4 ==\n- Compare [[4,4],4,4] vs [[4,4],4,4,4]\n  - Compare [4,4] vs [4,4]\n    - Compare 4 vs 4\n    - Compare 4 vs 4\n  - Compare 4 vs 4\n  - Compare 4 vs 4\n  - Left side ran out of items, so inputs are in the right order\n\n== Pair 5 ==\n- Compare [7,7,7,7] vs [7,7,7]\n  - Compare 7 vs 7\n  - Compare 7 vs 7\n  - Compare 7 vs 7\n  - Right side ran out of items, so inputs are not in the right order\n\n== Pair 6 ==\n- Compare [] vs [3]\n  - Left side ran out of items, so inputs are in the right order\n\n== Pair 7 ==\n- Compare [[[]]] vs [[]]\n  - Compare [[]] vs []\n    - Right side ran out of items, so inputs are not in the right order\n\n== Pair 8 ==\n- Compare [1,[2,[3,[4,[5,6,7]]]],8,9] vs [1,[2,[3,[4,[5,6,0]]]],8,9]\n  - Compare 1 vs 1\n  - Compare [2,[3,[4,[5,6,7]]]] vs [2,[3,[4,[5,6,0]]]]\n    - Compare 2 vs 2\n    - Compare [3,[4,[5,6,7]]] vs [3,[4,[5,6,0]]]\n      - Compare 3 vs 3\n      - Compare [4,[5,6,7]] vs [4,[5,6,0]]\n        - Compare 4 vs 4\n        - Compare [5,6,7] vs [5,6,0]\n          - Compare 5 vs 5\n          - Compare 6 vs 6\n          - Compare 7 vs 0\n            - Right side is smaller, so inputs are not in the right order\n\nWhat are the indices of the pairs that are already in the right order?\n(The first pair has index 1, the second pair has index 2, and so on.)\nIn the above example, the pairs in the right order are 1, 2, 4, and 6;\nthe sum of these indices is 13.\n\nDetermine which pairs of packets are already in the right order.\nWhat is the sum of the indices of those pairs?\n\n--- Part Two ---\n\nNow, you just need to put all of the packets in the right order.\nDisregard the blank lines in your list of received packets.\n\nThe distress signal protocol also requires that you include two\nadditional divider packets:\n\n[[2]]\n[[6]]\n\nUsing the same rules as before, organize all packets - the ones\nin your list of received packets as well as the two divider packets\n- into the correct order.\n\nFor the example above, the result of putting the packets in the\ncorrect order is:\n\n[]\n[[]]\n[[[]]]\n[1,1,3,1,1]\n[1,1,5,1,1]\n[[1],[2,3,4]]\n[1,[2,[3,[4,[5,6,0]]]],8,9]\n[1,[2,[3,[4,[5,6,7]]]],8,9]\n[[1],4]\n[[2]]\n[3]\n[[4,4],4,4]\n[[4,4],4,4,4]\n[[6]]\n[7,7,7]\n[7,7,7,7]\n[[8,7,6]]\n[9]\n\nAfterward, locate the divider packets. To find the decoder key for\nthis distress signal, you need to determine the indices of the two\ndivider packets and multiply them together.\n(The first packet is at index 1, the second packet is at index 2,\nand so on.) In this example, the divider packets are 10th and 14th,\nand so the decoder key is 140.\n\nOrganize all of the packets into the correct order.\nWhat is the decoder key for the distress signal?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_14.adb",
    "content": "--  Solution to Advent of Code 2022, Day 14\n-------------------------------------------\n--  Regolith Reservoir\n--\n--  https://adventofcode.com/2022/day/14\n--  Copy of questions in: aoc_2022_14_questions.txt\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_14 is\n  use HAT, AoC_Toolbox;\n\n  subtype Range_x is Integer range 300 .. 800;\n  subtype Range_y is Integer range   0 .. 200;\n\n  map : array (Range_x, Range_y) of Character;\n\n  m, n : Point;\n\n  procedure Adapt_Top_Left_Corner (using : Point) is\n  begin\n    m.x := Min (m.x, using.x);\n    m.y := Min (m.y, using.y);\n  end Adapt_Top_Left_Corner;\n\n  procedure Adapt_Bottom_Right_Corner (using : Point) is\n  begin\n    n.x := Max (n.x, using.x);\n    n.y := Max (n.y, using.y);\n  end Adapt_Bottom_Right_Corner;\n\n  procedure Show (title : VString) is\n  begin\n    New_Line;\n    Put_Line (title);\n    New_Line;\n    Put_Line (+\"  x is in range: \" & m.x & \" .. \" & n.x);\n    Put_Line (+\"  y is in range: \" & m.y & \" .. \" & n.y);\n    New_Line;\n    for y in m.y .. n.y loop\n      Put (\"  \");\n      for x in m.x .. n.x loop\n        Put (map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  procedure Data_Acquisition (enhanced : Boolean) is\n    p1, p2, p : Point;\n    arrow : String (1 .. 4) := \" -> \";\n    sep : Character;\n    f : File_Type;\n  begin\n    m.x := Range_x'Last;\n    m.y := 0;\n    n.x := Range_x'First;\n    n.y := Range_y'First;\n    for x in Range_x loop\n      for y in Range_y loop\n        map (x, y) := '.';\n      end loop;\n    end loop;\n    Open (f, \"aoc_2022_14.txt\");\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get (f, p1.x);\n      Get (f, sep);\n      Get (f, p1.y);\n      Adapt_Top_Left_Corner (p1);\n      Adapt_Bottom_Right_Corner (p1);\n      map (p1.x, p1.y) := '#';\n      loop\n        Get (f, arrow);\n        Get (f, p2.x);\n        Get (f, sep);\n        Get (f, p2.y);\n        Adapt_Top_Left_Corner (p2);\n        Adapt_Bottom_Right_Corner (p2);\n        p := p1;\n        for count in 1 .. Dist_L1 (p1, p2) loop\n          p.x := p.x + Sgn (p2.x - p1.x);\n          p.y := p.y + Sgn (p2.y - p1.y);\n          map (p.x, p.y) := '#';\n        end loop;\n        exit when End_Of_Line (f);\n        p1 := p2;\n      end loop;\n    end loop Read_Data;\n    Close (f);\n    if enhanced then\n      --  Added a layer of rock 2 units below:\n      p.y := n.y + 2;\n      p.x := m.x - p.y;\n      Adapt_Top_Left_Corner (p);\n      p.x := n.x + p.y;\n      Adapt_Bottom_Right_Corner (p);\n      for x in m.x .. n.x loop\n        map (x, p.y) := '@';\n      end loop;\n    end if;\n  end Data_Acquisition;\n\n  pouring_point : Point;\n  full_or_blocked : Boolean;\n\n  procedure Simulate_Sand_Unit is\n    p : Point := pouring_point;\n  begin\n    full_or_blocked := False;\n    if map (p.x, p.y) = 'o' then\n      --  Source is blocked!\n      full_or_blocked := True;\n      return;\n    end if;\n    loop\n      if map (p.x, p.y + 1) = '.' then\n        --  Cell below is free -> fall further.\n        p.y := p.y + 1;\n      else\n        --  Obstacle.\n        if map (p.x - 1, p.y + 1) = '.' then\n          --  Move diagonally (left).\n          p.x := p.x - 1;\n          p.y := p.y + 1;\n        elsif map (p.x + 1, p.y + 1) = '.' then\n          --  Move diagonally (right).\n          p.x := p.x + 1;\n          p.y := p.y + 1;\n        else\n          --  Sand unit cannot move anymore.\n          map (p.x, p.y) := 'o';\n          --  Displayed portion of the map may increase:\n          Adapt_Top_Left_Corner (p);\n          exit;\n        end if;\n      end if;\n      if p.y = n.y then\n        --  Reach floor level: will \"fall into the endless void\".\n        full_or_blocked := True;\n        exit;\n      end if;\n    end loop;\n  end Simulate_Sand_Unit;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  verbose : constant Boolean := False;\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\nbegin\n  pouring_point.x := 500;\n  pouring_point.y :=   0;\nParts :\n  for part in 1 .. 2 loop\n    Data_Acquisition (part = 2);\n    if verbose then\n      Show (+\"Initial:\");\n    end if;\n    for step in Positive loop\n      Simulate_Sand_Unit;\n      if verbose and then n.y < 100 then\n        Show (+\"Sand unit #\" & step & ':');\n      end if;\n      if full_or_blocked then\n        r (part) := step - 1;\n        --  ^ \"- 1\" is because \"How many units of sand come to rest\n        --    *before* sand starts flowing into the abyss below\"\n        exit;\n      end if;\n    end loop;\n    if verbose then\n      Show (+\"Final:\");\n    end if;\n    exit Parts when compiler_test_mode;  --  Skip part 2.\n  end loop Parts;\n\n  if compiler_test_mode then\n    if r (1) /= Integer'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Number of sand units for...\");\n    Put_Line (+\"  (part 1): original map: \" & r (1));\n    Put_Line (+\"  (part 2): enhanced map: \" & r (2));\n    --  Part 1: validated by AoC: 964\n    --  Part 2: validated by AoC: 32041\n  end if;\nend AoC_2022_14;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_14.txt",
    "content": "490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n534,94 -> 538,94\n519,92 -> 523,92\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n499,27 -> 499,28 -> 515,28\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n525,88 -> 529,88\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n533,116 -> 537,116\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n523,70 -> 528,70\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n540,126 -> 540,127 -> 543,127 -> 543,126\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n560,161 -> 565,161\n540,94 -> 544,94\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n554,167 -> 559,167\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n533,122 -> 533,123 -> 541,123\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n543,164 -> 548,164\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n525,92 -> 529,92\n525,119 -> 537,119 -> 537,118\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n530,70 -> 535,70\n516,94 -> 520,94\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n525,119 -> 537,119 -> 537,118\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n528,90 -> 532,90\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n533,67 -> 538,67\n546,161 -> 551,161\n537,70 -> 542,70\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n532,61 -> 537,61\n499,27 -> 499,28 -> 515,28\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n534,90 -> 538,90\n531,88 -> 535,88\n556,158 -> 561,158\n525,61 -> 530,61\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n533,122 -> 533,123 -> 541,123\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n557,164 -> 562,164\n552,155 -> 557,155\n531,92 -> 535,92\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n547,167 -> 552,167\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n561,167 -> 566,167\n522,64 -> 527,64\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n519,67 -> 524,67\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n550,164 -> 555,164\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n516,70 -> 521,70\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n536,64 -> 541,64\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n539,110 -> 543,110\n529,64 -> 534,64\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n528,86 -> 532,86\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n540,126 -> 540,127 -> 543,127 -> 543,126\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n545,116 -> 549,116\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n568,167 -> 573,167\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n553,161 -> 558,161\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n540,67 -> 545,67\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n546,141 -> 546,144 -> 541,144 -> 541,152 -> 554,152 -> 554,144 -> 550,144 -> 550,141\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n522,90 -> 526,90\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n528,58 -> 533,58\n549,158 -> 554,158\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n523,44 -> 523,48 -> 517,48 -> 517,55 -> 530,55 -> 530,48 -> 525,48 -> 525,44\n526,67 -> 531,67\n540,167 -> 545,167\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n544,170 -> 544,174 -> 536,174 -> 536,182 -> 554,182 -> 554,174 -> 549,174 -> 549,170\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n541,130 -> 541,133 -> 537,133 -> 537,138 -> 548,138 -> 548,133 -> 545,133 -> 545,130\n540,126 -> 540,127 -> 543,127 -> 543,126\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n542,113 -> 546,113\n528,94 -> 532,94\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n522,94 -> 526,94\n539,116 -> 543,116\n544,70 -> 549,70\n542,107 -> 542,104 -> 542,107 -> 544,107 -> 544,101 -> 544,107 -> 546,107 -> 546,100 -> 546,107\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n536,113 -> 540,113\n537,92 -> 541,92\n507,41 -> 507,39 -> 507,41 -> 509,41 -> 509,35 -> 509,41 -> 511,41 -> 511,34 -> 511,41 -> 513,41 -> 513,40 -> 513,41 -> 515,41 -> 515,38 -> 515,41 -> 517,41 -> 517,31 -> 517,41 -> 519,41 -> 519,33 -> 519,41 -> 521,41 -> 521,32 -> 521,41 -> 523,41 -> 523,39 -> 523,41\n513,83 -> 513,76 -> 513,83 -> 515,83 -> 515,73 -> 515,83 -> 517,83 -> 517,80 -> 517,83 -> 519,83 -> 519,82 -> 519,83 -> 521,83 -> 521,80 -> 521,83 -> 523,83 -> 523,73 -> 523,83 -> 525,83 -> 525,81 -> 525,83 -> 527,83 -> 527,81 -> 527,83 -> 529,83 -> 529,74 -> 529,83\n564,164 -> 569,164\n490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,14 -> 492,23 -> 494,23 -> 494,20 -> 494,23 -> 496,23 -> 496,18 -> 496,23 -> 498,23 -> 498,19 -> 498,23 -> 500,23 -> 500,20 -> 500,23 -> 502,23 -> 502,17 -> 502,23 -> 504,23 -> 504,14 -> 504,23 -> 506,23 -> 506,18 -> 506,23 -> 508,23 -> 508,15 -> 508,23\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_14_questions.txt",
    "content": "--- Day 14: Regolith Reservoir ---\n\nThe distress signal leads you to a giant waterfall! Actually, hang on -\nthe signal seems like it's coming from the waterfall itself, and that\ndoesn't make any sense. However, you do notice a little path that leads\nbehind the waterfall.\n\nCorrection: the distress signal leads you behind a giant waterfall!\nThere seems to be a large cave system here, and the signal definitely\nleads further inside.\n\nAs you begin to make your way deeper underground, you feel the ground\nrumble for a moment. Sand begins pouring into the cave! If you don't\nquickly figure out where the sand is going, you could quickly become\ntrapped!\n\nFortunately, your familiarity with analyzing the path of falling\nmaterial will come in handy here. You scan a two-dimensional vertical\nslice of the cave above you (your puzzle input) and discover that it\nis mostly air with structures made of rock.\n\nYour scan traces the path of each solid rock structure and reports\nthe x,y coordinates that form the shape of the path, where x represents\ndistance to the right and y represents distance down. Each path appears\nas a single line of text in your scan. After the first point of each\npath, each point indicates the end of a straight horizontal or vertical\nline to be drawn from the previous point. For example:\n\n498,4 -> 498,6 -> 496,6\n503,4 -> 502,4 -> 502,9 -> 494,9\n\nThis scan means that there are two paths of rock; the first path\nconsists of two straight lines, and the second path consists of\nthree straight lines. (Specifically, the first path consists of a\nline of rock from 498,4 through 498,6 and another line of rock\nfrom 498,6 through 496,6.)\n\nThe sand is pouring into the cave from point 500,0.\n\nDrawing rock as #, air as ., and the source of the sand as +,\nthis becomes:\n\n\n  4     5  5\n  9     0  0\n  4     0  3\n0 ......+...\n1 ..........\n2 ..........\n3 ..........\n4 ....#...##\n5 ....#...#.\n6 ..###...#.\n7 ........#.\n8 ........#.\n9 #########.\n\nSand is produced one unit at a time, and the next unit of sand is not\nproduced until the previous unit of sand comes to rest. A unit of sand\nis large enough to fill one tile of air in your scan.\n\nA unit of sand always falls down one step if possible. If the tile\nimmediately below is blocked (by rock or sand), the unit of sand\nattempts to instead move diagonally one step down and to the left.\nIf that tile is blocked, the unit of sand attempts to instead move\ndiagonally one step down and to the right. Sand keeps moving as long\nas it is able to do so, at each step trying to move down, then\ndown-left, then down-right. If all three possible destinations are\nblocked, the unit of sand comes to rest and no longer moves, at\nwhich point the next unit of sand is created back at the source.\n\nSo, drawing sand that has come to rest as o, the first unit of sand\nsimply falls straight down and then stops:\n\n......+...\n..........\n..........\n..........\n....#...##\n....#...#.\n..###...#.\n........#.\n......o.#.\n#########.\n\nThe second unit of sand then falls straight down, lands on the first\none, and then comes to rest to its left:\n\n......+...\n..........\n..........\n..........\n....#...##\n....#...#.\n..###...#.\n........#.\n.....oo.#.\n#########.\n\nAfter a total of five units of sand have come to rest, they\nform this pattern:\n\n......+...\n..........\n..........\n..........\n....#...##\n....#...#.\n..###...#.\n......o.#.\n....oooo#.\n#########.\n\nAfter a total of 22 units of sand:\n\n......+...\n..........\n......o...\n.....ooo..\n....#ooo##\n....#ooo#.\n..###ooo#.\n....oooo#.\n...ooooo#.\n#########.\n\nFinally, only two more units of sand can possibly come to rest:\n\n......+...\n..........\n......o...\n.....ooo..\n....#ooo##\n...o#ooo#.\n..###ooo#.\n....oooo#.\n.o.ooooo#.\n#########.\n\nOnce all 24 units of sand shown above have come to rest, all further\nsand flows out the bottom, falling into the endless void. Just for fun,\nthe path any new sand takes before falling forever is shown here with ~:\n\n.......+...\n.......~...\n......~o...\n.....~ooo..\n....~#ooo##\n...~o#ooo#.\n..~###ooo#.\n..~..oooo#.\n.~o.ooooo#.\n~#########.\n~..........\n~..........\n~..........\n\nUsing your scan, simulate the falling sand.\nHow many units of sand come to rest before sand starts flowing\ninto the abyss below?\n\n--- Part Two ---\n\nYou realize you misread the scan. There isn't an endless void at the\nbottom of the scan - there's floor, and you're standing on it!\n\nYou don't have time to scan the floor, so assume the floor is an\ninfinite horizontal line with a y coordinate equal to two plus the\nhighest y coordinate of any point in your scan.\n\nIn the example above, the highest y coordinate of any point is 9,\nand so the floor is at y=11. (This is as if your scan contained one\nextra rock path like -infinity,11 -> infinity,11.)\nWith the added floor, the example above now looks like this:\n\n        ...........+........\n        ....................\n        ....................\n        ....................\n        .........#...##.....\n        .........#...#......\n        .......###...#......\n        .............#......\n        .............#......\n        .....#########......\n        ....................\n<-- etc #################### etc -->\n\nTo find somewhere safe to stand, you'll need to simulate falling sand\nuntil a unit of sand comes to rest at 500,0, blocking the source\nentirely and stopping the flow of sand into the cave.\nIn the example above, the situation finally looks like\nthis after 93 units of sand come to rest:\n\n............o............\n...........ooo...........\n..........ooooo..........\n.........ooooooo.........\n........oo#ooo##o........\n.......ooo#ooo#ooo.......\n......oo###ooo#oooo......\n.....oooo.oooo#ooooo.....\n....oooooooooo#oooooo....\n...ooo#########ooooooo...\n..ooooo.......ooooooooo..\n#########################\n\nUsing your scan, simulate the falling sand until the source of the\nsand becomes blocked. How many units of sand come to rest?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_15.adb",
    "content": "--  Solution to Advent of Code 2022, Day 15\n-------------------------------------------\n--  Beacon Exclusion Zone\n--\n--  https://adventofcode.com/2022/day/15\n--  Copy of questions in: aoc_2022_15_questions.txt\n--\n--  Note: this solution takes an insane amount of time with HAC.\n--  Fortunately, you can compile it with GNAT and\n--  the total run-time is there 1.17 seconds on an i7 machine.\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and GNAT (64-bit integer: Integer_64):\nwith Interfaces;\n\nprocedure AoC_2022_15 is\n  use AoC_Toolbox, HAT, Interfaces;\n\n  lowest, highest : Point;\n\n  procedure Adapt_Lowest_Value_Point (using : Point) is\n  begin\n    lowest.x := Min (lowest.x, using.x);\n    lowest.y := Min (lowest.y, using.y);\n  end Adapt_Lowest_Value_Point;\n\n  procedure Adapt_Highest_Value_Point (using : Point) is\n  begin\n    highest.x := Max (highest.x, using.x);\n    highest.y := Max (highest.y, using.y);\n  end Adapt_Highest_Value_Point;\n\n  type Observation is record\n    sensor, beacon : Point;\n    d : Natural;\n  end record;\n\n  type Storage is array (1 .. 100) of Observation;\n\n  top : Natural;\n  k   : Storage;\n\n  --  If (x, y) is within topological disc (which is a square,\n  --  geometrically, due to the distance used, L1) around any\n  --  sensor delimited by the distance to the next beacon, then\n  --  it is beacon-free [2] unless it is the point where\n  --  the beacon is [1].\n  --  NB: the puzzle kindly excludes *two* beacons\n  --  at the same distance of a sensor (\"There is never a tie where\n  --  two beacons are the same distance to a sensor\").\n  --\n  function Beacon_Free (x, y : Integer) return Boolean is\n    p : Point;\n  begin\n    p.x := x;\n    p.y := y;\n    for i in 1 .. top loop\n      if k (i).beacon.x = x and then k (i).beacon.y = y then\n        return False;  --  [1]\n      end if;\n      if Dist_L1 (p, k (i).sensor) <= k (i).d then\n        return True;   --  [2]\n      end if;\n    end loop;\n    return False;\n  end Beacon_Free;\n\n  --  Count for x in a given range, and a given y,\n  --  the number of beacon-free points.\n  function Scan_for_Beacon_Free_Range (mx, nx, y : Integer) return Natural is\n    t : Natural := 0;\n  begin\n    for x in mx .. nx loop\n      if Beacon_Free (x, y) then\n        t := t + 1;\n      end if;\n    end loop;\n    return t;\n  end Scan_for_Beacon_Free_Range;\n\n  --  Count for \"any\" value of x, and a given y,\n  --  the number of beacon-free points.\n  function Scan_for_Beacon_Free (y : Integer) return Natural is\n  begin\n    return\n      Scan_for_Beacon_Free_Range\n        (lowest.x  - (highest.x - lowest.x),\n         highest.x + (highest.x - lowest.x), y);\n  end Scan_for_Beacon_Free;\n\n  --  name : constant VString := +\"mini.txt\";\n  --  y_p1 : constant := 10;\n  --  lim_p2 : constant := 20;\n\n  name : constant VString := +\"aoc_2022_15.txt\";\n  y_p1 : constant := 2_000_000;\n  lim_p2 : constant := 4_000_000;\n\n  tuning_frequency : Integer_64;\n\n  procedure Search_Undetected_Beacon is\n    sensor_i : Point;\n    distance_i : Integer;\n\n    procedure Check (x, y : Integer) is\n    begin\n      if x in 0 .. lim_p2\n        and then y in 0 .. lim_p2\n        and then not Beacon_Free (x, y)\n      then\n        tuning_frequency := Integer_64 (x) * 4_000_000 + Integer_64 (y);\n      end if;\n    end Check;\n\n  begin\n    tuning_frequency := 0;\n    --\n    --  Since there is only one possible point where the beacon is,\n    --  it is surrounded by beacon-free zones, which are the topological\n    --  discs (geometrically, squares with diagonally-oriented edges)\n    --  around a sensor.\n    --  So it is sufficient to search the point right outside the squares.\n    --\n    --  Idea from Maxim Reznik,\n    --  https://forum.ada-lang.io/t/2022-day-15-beacon-exclusion-zone/254/2\n    --\n    --  The brute force method would check more than 16 trillion points!\n    --\n    for i in 1 .. top loop\n      sensor_i   := k (i).sensor;\n      distance_i := k (i).d;\n      for dx in 0 .. distance_i loop\n        --  Check one unit above the top-right side\n        --  of the square around sensor_i #i.\n        Check (sensor_i.x + dx, sensor_i.y + (distance_i - dx) + 1);\n        --  NB: we should scan the other sides for the special\n        --      case where the searched point is on the edge of\n        --      the given search area, but in the example and our\n        --      data, the point is inside the area, so it is surrounded\n        --      by four squares with one kind edge each touching the point.\n        --\n        --  12222233\n        --  11222333\n        --  1112*433   <--- the point *. The check above will detect it for\n        --  11114443                     square #1.\n        --  11144444\n        exit when tuning_frequency > 0;\n      end loop;\n      exit when tuning_frequency > 0;\n    end loop;\n  end Search_Undetected_Beacon;\n\n  s1 : String (1 .. 12) := \"Sensor at x=\";\n  s2 : String (1 ..  4) := \", y=\";\n  s3 : String (1 .. 25) := \": closest beacon is at x=\";\n  s4 : String (1 ..  4) := \", y=\";\n  f : File_Type;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer_64;\n\nbegin\n  top := 0;\n  lowest.x := Integer'Last;\n  lowest.y := Integer'Last;\n  highest.x := Integer'First;\n  highest.y := Integer'First;\n  Open (f, name);\nRead_Data :\n  while not End_Of_File (f) loop\n    top := top + 1;\n    Get (f, s1);\n    Get (f, k (top).sensor.x);\n    Get (f, s2);\n    Get (f, k (top).sensor.y);\n    Get (f, s3);\n    Get (f, k (top).beacon.x);\n    Get (f, s4);\n    Get (f, k (top).beacon.y);\n    k (top).d := Dist_L1 (k (top).beacon, k (top).sensor);\n    Adapt_Lowest_Value_Point (k (top).beacon);\n    Adapt_Highest_Value_Point (k (top).beacon);\n    Adapt_Lowest_Value_Point (k (top).sensor);\n    Adapt_Highest_Value_Point (k (top).sensor);\n  end loop Read_Data;\n  Close (f);\n\n  Search_Undetected_Beacon;\n\n  r (1) := Integer_64 (Scan_for_Beacon_Free (y_p1));\n  r (2) := tuning_frequency;\n\n  Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n  Put_Line (+\"Part 1 answer:\" & Integer_64'Image (r (1)));\n  Put_Line (+\"Part 2 answer:\" & Integer_64'Image (r (2)));\n  --  Part 1: validated by AoC: 5240818\n  --  Part 2: validated by AoC: 13213086906101\nend AoC_2022_15;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_15.txt",
    "content": "Sensor at x=2899860, y=3122031; closest beacon is at x=2701269, y=3542780\nSensor at x=1836719, y=1116779; closest beacon is at x=2037055, y=2000000\nSensor at x=3995802, y=2706630; closest beacon is at x=3944538, y=3053285\nSensor at x=2591204, y=2008272; closest beacon is at x=2597837, y=2509170\nSensor at x=2546593, y=1538222; closest beacon is at x=2037055, y=2000000\nSensor at x=252214, y=61954; closest beacon is at x=1087565, y=-690123\nSensor at x=950, y=1106672; closest beacon is at x=-893678, y=1276864\nSensor at x=1349445, y=1752783; closest beacon is at x=2037055, y=2000000\nSensor at x=3195828, y=3483667; closest beacon is at x=3334657, y=3531523\nSensor at x=2057761, y=2154359; closest beacon is at x=2037055, y=2000000\nSensor at x=2315350, y=3364640; closest beacon is at x=2701269, y=3542780\nSensor at x=327139, y=2426600; closest beacon is at x=-88420, y=3646947\nSensor at x=3943522, y=2854345; closest beacon is at x=3944538, y=3053285\nSensor at x=3358620, y=516881; closest beacon is at x=3260516, y=2246079\nSensor at x=1788376, y=8679; closest beacon is at x=1087565, y=-690123\nSensor at x=3344883, y=3537985; closest beacon is at x=3334657, y=3531523\nSensor at x=2961064, y=2697125; closest beacon is at x=2597837, y=2509170\nSensor at x=3780090, y=2093546; closest beacon is at x=3260516, y=2246079\nSensor at x=3291917, y=3398703; closest beacon is at x=3334657, y=3531523\nSensor at x=3999864, y=2998005; closest beacon is at x=3944538, y=3053285\nSensor at x=2919272, y=3732950; closest beacon is at x=2701269, y=3542780\nSensor at x=2057404, y=2947435; closest beacon is at x=2037055, y=2000000\nSensor at x=1072126, y=645784; closest beacon is at x=1087565, y=-690123\nSensor at x=3549465, y=2554712; closest beacon is at x=3260516, y=2246079\nSensor at x=3550313, y=3121694; closest beacon is at x=3944538, y=3053285\nSensor at x=3405149, y=3483630; closest beacon is at x=3334657, y=3531523\nSensor at x=2600212, y=3961193; closest beacon is at x=2701269, y=3542780\nSensor at x=1102632, y=3932527; closest beacon is at x=-88420, y=3646947\nSensor at x=67001, y=3506079; closest beacon is at x=-88420, y=3646947\nSensor at x=3994250, y=3975025; closest beacon is at x=3944538, y=3053285\nSensor at x=3019750, y=2125144; closest beacon is at x=3260516, y=2246079\nSensor at x=3282319, y=3656404; closest beacon is at x=3334657, y=3531523\nSensor at x=2797371, y=3645126; closest beacon is at x=2701269, y=3542780\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_15_questions.txt",
    "content": "--- Day 15: Beacon Exclusion Zone ---\n\nYou feel the ground rumble again as the distress signal leads you to\na large network of subterranean tunnels.\nYou don't have time to search them all, but you don't need to:\nyour pack contains a set of deployable sensors that you imagine\nwere originally built to locate lost Elves.\n\nThe sensors aren't very powerful, but that's okay; your handheld\ndevice indicates that you're close enough to the source of the\ndistress signal to use them. You pull the emergency sensor system\nout of your pack, hit the big button on top, and the sensors zoom\noff down the tunnels.\n\nOnce a sensor finds a spot it thinks will give it a good reading,\nit attaches itself to a hard surface and begins monitoring for the\nnearest signal source beacon. Sensors and beacons always exist at\ninteger coordinates. Each sensor knows its own position and can\ndetermine the position of a beacon precisely; however, sensors can\nonly lock on to the one beacon closest to the sensor as measured\nby the Manhattan distance. (There is never a tie where two beacons\nare the same distance to a sensor.)\n\nIt doesn't take long for the sensors to report back their positions\nand closest beacons (your puzzle input).\nFor example:\n\nSensor at x=2, y=18: closest beacon is at x=-2, y=15\nSensor at x=9, y=16: closest beacon is at x=10, y=16\nSensor at x=13, y=2: closest beacon is at x=15, y=3\nSensor at x=12, y=14: closest beacon is at x=10, y=16\nSensor at x=10, y=20: closest beacon is at x=10, y=16\nSensor at x=14, y=17: closest beacon is at x=10, y=16\nSensor at x=8, y=7: closest beacon is at x=2, y=10\nSensor at x=2, y=0: closest beacon is at x=2, y=10\nSensor at x=0, y=11: closest beacon is at x=2, y=10\nSensor at x=20, y=14: closest beacon is at x=25, y=17\nSensor at x=17, y=20: closest beacon is at x=21, y=22\nSensor at x=16, y=7: closest beacon is at x=15, y=3\nSensor at x=14, y=3: closest beacon is at x=15, y=3\nSensor at x=20, y=1: closest beacon is at x=15, y=3\n\nSo, consider the sensor at 2,18; the closest beacon to it is at -2,15.\nFor the sensor at 9,16, the closest beacon to it is at 10,16.\n\nDrawing sensors as S and beacons as B, the above arrangement of\nsensors and beacons looks like this:\n\n               1    1    2    2\n     0    5    0    5    0    5\n 0 ....S.......................\n 1 ......................S.....\n 2 ...............S............\n 3 ................SB..........\n 4 ............................\n 5 ............................\n 6 ............................\n 7 ..........S.......S.........\n 8 ............................\n 9 ............................\n10 ....B.......................\n11 ..S.........................\n12 ............................\n13 ............................\n14 ..............S.......S.....\n15 B...........................\n16 ...........SB...............\n17 ................S..........B\n18 ....S.......................\n19 ............................\n20 ............S......S........\n21 ............................\n22 .......................B....\n\nThis isn't necessarily a comprehensive map of all beacons in the\narea, though. Because each sensor only identifies its closest beacon,\nif a sensor detects a beacon, you know there are no other beacons\nthat close or closer to that sensor. There could still be beacons that\njust happen to not be the closest beacon to any sensor.\nConsider the sensor at 8,7:\n\n               1    1    2    2\n     0    5    0    5    0    5\n-2 ..........#.................\n-1 .........###................\n 0 ....S...#####...............\n 1 .......#######........S.....\n 2 ......#########S............\n 3 .....###########SB..........\n 4 ....#############...........\n 5 ...###############..........\n 6 ..#################.........\n 7 .#########S#######S#........\n 8 ..#################.........\n 9 ...###############..........\n10 ....B############...........\n11 ..S..###########............\n12 ......#########.............\n13 .......#######..............\n14 ........#####.S.......S.....\n15 B........###................\n16 ..........#SB...............\n17 ................S..........B\n18 ....S.......................\n19 ............................\n20 ............S......S........\n21 ............................\n22 .......................B....\n\nThis sensor's closest beacon is at 2,10, and so you know there are no\nbeacons that close or closer (in any positions marked #).\n\nNone of the detected beacons seem to be producing the distress signal,\nso you'll need to work out where the distress beacon is by working out\nwhere it isn't. For now, keep things simple by counting the positions\nwhere a beacon cannot possibly be along just a single row.\n\nSo, suppose you have an arrangement of beacons and sensors like in the\nexample above and, just in the row where y=10, you'd like to count the\nnumber of positions a beacon cannot possibly exist. The coverage from\nall sensors near that row looks like this:\n\n                 1    1    2    2\n       0    5    0    5    0    5\n 9 ...#########################...\n10 ..####B######################..\n11 .###S#############.###########.\n\nIn this example, in the row where y=10, there are 26 positions where\na beacon cannot be present.\n\nConsult the report from the sensors you just deployed.\nIn the row where y=2000000, how many positions cannot contain a beacon?\n\n--- Part Two ---\n\nYour handheld device indicates that the distress signal is coming\nfrom a beacon nearby. The distress beacon is not detected by any\nsensor, but the distress beacon must have x and y coordinates each\nno lower than 0 and no larger than 4000000.\n\nTo isolate the distress beacon's signal, you need to determine its\ntuning frequency, which can be found by multiplying its x coordinate\nby 4000000 and then adding its y coordinate.\n\nIn the example above, the search space is smaller: instead, the\nx and y coordinates can each be at most 20.\nWith this reduced search area, there is only a single position that\ncould have a beacon: x=14, y=11.\nThe tuning frequency for this distress beacon is 56000011.\n\nFind the only possible position for the distress beacon.\nWhat is its tuning frequency?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_16.adb",
    "content": "--  Solution to Advent of Code 2022, Day 16\n-------------------------------------------\n--  Proboscidea Volcanium\n--\n--  https://adventofcode.com/2022/day/16\n--  Copy of questions in: aoc_2022_16_questions.txt\n--\n--  Note: this solution takes an insane amount of time with HAC.\n--  Fortunately, you can compile it with GNAT and\n--  the total run-time is there 0.94 seconds on an i7 machine.\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_16 is\n  use HAT;\n\n  type Valve is\n    (nil,\n     AA, AB, AC, AD, AE, AF, AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS,     AU, AV, AW, AX, AY, AZ,\n     BA, BB, BC, BD, BE, BF, BG, BH, BI, BJ, BK, BL, BM, BN, BO, BP, BQ, BR, BS, BT, BU, BV, BW, BX, BY, BZ,\n     CA, CB, CC, CD, CE, CF, CG, CH, CI, CJ, CK, CL, CM, CN, CO, CP, CQ, CR, CS, CT, CU, CV, CW, CX, CY, CZ,\n     DA, DB, DC, DD, DE, DF, DG, DH, DI, DJ, DK, DL, DM, DN,     DP, DQ, DR, DS, DT, DU, DV, DW, DX, DY, DZ,\n     EA, EB, EC, ED, EE, EF, EG, EH, EI, EJ, EK, EL, EM, EN, EO, EP, EQ, ER, ES, ET, EU, EV, EW, EX, EY, EZ,\n     FA, FB, FC, FD, FE, FF, FG, FH, FI, FJ, FK, FL, FM, FN, FO, FP, FQ, FR, FS, FT, FU, FV, FW, FX, FY, FZ,\n     GA, GB, GC, GD, GE, GF, GG, GH, GI, GJ, GK, GL, GM, GN, GO, GP, GQ, GR, GS, GT, GU, GV, GW, GX, GY, GZ,\n     HA, HB, HC, HD, HE, HF, HG, HH, HI, HJ, HK, HL, HM, HN, HO, HP, HQ, HR, HS, HT, HU, HV, HW, HX, HY, HZ,\n     IA, IB, IC, ID, IE,     IG, IH, II, IJ, IK, IL, IM,     IO, IP, IQ, IR,     IT, IU, IV, IW, IX, IY, IZ,\n     JA, JB, JC, JD, JE, JF, JG, JH, JI, JJ, JK, JL, JM, JN, JO, JP, JQ, JR, JS, JT, JU, JV, JW, JX, JY, JZ,\n     KA, KB, KC, KD, KE, KF, KG, KH, KI, KJ, KK, KL, KM, KN, KO, KP, KQ, KR, KS, KT, KU, KV, KW, KX, KY, KZ,\n     LA, LB, LC, LD, LE, LF, LG, LH, LI, LJ, LK, LL, LM, LN, LO, LP, LQ, LR, LS, LT, LU, LV, LW, LX, LY, LZ,\n     MA, MB, MC, MD, ME, MF, MG, MH, MI, MJ, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ,\n     NA, NB, NC, ND, NE, NF, NG, NH, NI, NJ, NK, NL, NM, NN, NO, NP, NQ, NR, NS, NT, NU, NV, NW, NX, NY, NZ,\n     OA, OB, OC, OD, OE,     OG, OH, OI, OJ, OK, OL, OM, ON, OO, OP, OQ,     OS, OT, OU, OV, OW, OX, OY, OZ,\n     PA, PB, PC, PD, PE, PF, PG, PH,     PJ, PK, PL, PM, PN, PO, PP, PQ, PR, PS, PT, PU, PV, PW, PX, PY, PZ,\n     QA, QB, QC, QD, QE, QF, QG, QH, QI, QJ, QK, QL, QM, QN, QO, QP, QQ, QR, QS, QT, QU, QV, QW, QX, QY, QZ,\n     RA, RB, RC, RD, RE, RF, RG, RH, RI, RJ, RK, RL, RM, RN, RO, RP, RQ, RR, RS, RT, RU, RV, RW, RX, RY, RZ,\n     SA, SB, SC, SD, SE, SF, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SP, SQ, SR, SS, ST, SU, SV, SW, SX, SY, SZ,\n     TA, TB, TC, TD, TE, TF, TG, TH, TI, TJ, TK, TL, TM, TN, TO, TP, TQ, TR, TS, TT, TU, TV, TW, TX, TY, TZ,\n     UA, UB, UC, UD, UE, UF, UG, UH, UI, UJ, UK, UL, UM, UN, UO, UP, UQ, UR, US, UT, UU, UV, UW, UX, UY, UZ,\n     VA, VB, VC, VD, VE, VF, VG, VH, VI, VJ, VK, VL, VM, VN, VO, VP, VQ, VR, VS, VT, VU, VV, VW, VX, VY, VZ,\n     WA, WB, WC, WD, WE, WF, WG, WH, WI, WJ, WK, WL, WM, WN, WO, WP, WQ, WR, WS, WT, WU, WV, WW, WX, WY, WZ,\n     XA, XB, XC, XD, XE, XF, XG, XH, XI, XJ, XK, XL, XM, XN, XO, XP, XQ, XR, XS, XT, XU, XV, XW, XX, XY, XZ,\n     YA, YB, YC, YD, YE, YF, YG, YH, YI, YJ, YK, YL, YM, YN, YO, YP, YQ, YR, YS, YT, YU, YV, YW, YX, YY, YZ,\n     ZA, ZB, ZC, ZD, ZE, ZF, ZG, ZH, ZI, ZJ, ZK, ZL, ZM, ZN, ZO, ZP, ZQ, ZR, ZS, ZT, ZU, ZV, ZW, ZX, ZY, ZZ);\n\n  flow : array (Valve) of Integer;\n\n  next : array (Valve, 1 .. 5) of Valve;\n\n  verbosity_level : constant Natural := 0;\n\n  procedure Data_Acquisition is\n    c1, c2, sep : Character;\n    valve_nr        : String (1 ..  6) := \"Valve \";\n    has_flow_rate   : String (1 .. 15) := \" has flow rate=\";\n    tunnels_lead_to : String (1 .. 24) := \"; tunnel lead to valves \";  --  \"tunnel\" can be with or without 's'\n    f : File_Type;\n    val : Valve;\n  begin\n    for i in Valve loop\n      flow (i) := 0;\n      for j in next'Range (2) loop\n        next (i, j) := nil;\n      end loop;\n    end loop;\n    Open (f, \"aoc_2022_16.txt\");\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get (f, valve_nr);\n      Get (f, c1);\n      Get (f, c2);\n      val := Valve'Value (c1 & c2);\n      if verbosity_level > 0 then\n        Put (val'Image & \": \");\n      end if;\n      Get (f, has_flow_rate);\n      Get (f, flow (val));\n      if verbosity_level > 0 then\n        Put (flow (val), 3);\n        Put (\"  -> \");\n      end if;\n      Get (f, tunnels_lead_to);\n      for j in next'Range (2) loop\n        Get (f, sep);\n        if sep = ' ' then\n          Get (f, c1);\n        else\n          c1 := sep;\n        end if;\n        Get (f, c2);\n        next (val, j) := Valve'Value (c1 & c2);\n        if verbosity_level > 0 then\n          Put (\"  \" & next (val, j)'Image);\n        end if;\n        exit when End_Of_Line (f);\n        Get (f, sep);\n      end loop;\n      if verbosity_level > 0 then\n        New_Line;\n      end if;\n    end loop Read_Data;\n    Close (f);\n  end Data_Acquisition;\n\n  --  The following \"laziness filter\" is very efficient at\n  --  cutting the recursion for paths that are obviously\n  --  unefficient. For solving part 2 (man + elephant), the\n  --  run time goes from 12+ hours to 6 seconds on a lame\n  --  laptop even if the filter is filled in a very rough way.\n  --  The run-time for part 1 & 2 is less than one second\n  --  on an i7 machine.\n  --\n  --  TBD: fill the filter in a non-arbitrary way, using\n  --  for instance the ditance of a valve to the AA point\n  --  and its potential score.\n\n  laziness_filter : array (0 .. 30) of Integer;\n\n  procedure Fill_Laziness_Filter_Affine_Function\n    (floor_final_score         : Natural;\n     --  ^ Final score must be at least that value.\n     max_time_left_for_0_score : Natural)\n     --  ^ Allow score to be still 0 when time left if that amount or more\n  is\n  begin\n    for t in laziness_filter'Range loop\n      --  Here we have an unsophisticated affine function.\n      --  Score increments are small for small values of time left.\n      --  Score increments must be large at the beginning of\n      --  the journey in order to maximize the result and compensate\n      --  for the first lazy steps where no valve is opened.\n      --  So on both ends the affine function is on the safer side.\n      --  However, it is empirical and we have no proof that the optimal\n      --  is not filtered out by this function.\n      laziness_filter (t) :=\n        floor_final_score\n          - t * (floor_final_score / max_time_left_for_0_score);\n    end loop;\n  end Fill_Laziness_Filter_Affine_Function;\n\n  function Visit_One_Agent (v, from : Valve; time_left, score : Natural) return Natural is\n    mem_flow : Positive;\n    result_opening, result_moving : Natural := 0;\n    next_valve : Valve;\n  begin\n    if time_left = 0 then\n      if verbosity_level > 1 then\n        Put_Line (\"Time exhausted!\");\n        for v in Valve loop\n          if flow (v) > 0 then\n            Put (v'Image & \": \");\n            Put (flow (v), 3);\n            New_Line;\n          end if;\n        end loop;\n      end if;\n      --  No time left.\n      return 0;\n    end if;\n    if score < laziness_filter (time_left) then\n      return 0;\n    end if;\n    if flow (v) > 0 then\n      --  Try a variant where we open the valve v.\n      mem_flow := flow (v);\n      result_opening := flow (v) * (time_left - 1);\n      --  ^ The flow begins only after one minute for\n      --    opening the valve.\n      flow (v) := 0;\n      result_opening :=\n        result_opening + Visit_One_Agent (v, nil, time_left - 1, score + result_opening);\n      --  ^ The recursive visit includes moving further.\n      --    We forget the previous node's location since\n      --    it is meaningful to walk back in that case:\n      --    purpose was for opening a valve.\n      --\n      --  Restore previous state:\n      flow (v) := mem_flow;\n    end if;\n    --  Move to adjacent nodes:\n    for j in next'Range (2) loop\n      next_valve := next (v, j);\n      exit when next_valve = nil;\n      if next_valve /= from then\n        --  ^ Avoid hesitant moves (going back right\n        --    after coming and having done nothing).\n        result_moving :=\n          Max (result_moving, Visit_One_Agent (next_valve, v, time_left - 1, score));\n      end if;\n    end loop;\n    return Max (result_opening, result_moving);\n  end Visit_One_Agent;\n\n  function Visit_Two_Agents\n    (v_m, from_m, v_e, from_e : Valve;\n    time_left, score          : Natural)\n    return Natural\n  is\n    mem_flow_m, mem_flow_e : Positive;\n    result_opening_m, result_opening_e, result_opening_2,\n    result_moving_m, result_moving_e, result_moving_2 : Natural := 0;\n    next_valve_m, next_valve_e : Valve;\n  begin\n    if time_left = 0 or else score < laziness_filter (time_left) then\n      return 0;\n    end if;\n    if flow (v_m) > 0 and then flow (v_e) > 0 and then v_m /= v_e then\n      --  Man and Elephant open valves\n      mem_flow_m := flow (v_m);\n      mem_flow_e := flow (v_e);\n      result_opening_2 := (flow (v_m) + flow (v_e)) * (time_left - 1);\n      flow (v_m) := 0;\n      flow (v_e) := 0;\n      result_opening_2 :=\n        result_opening_2 +\n          Visit_Two_Agents\n            (v_m, nil, v_e, nil, time_left - 1, score + result_opening_2);\n      flow (v_m) := mem_flow_m;\n      flow (v_e) := mem_flow_e;\n    end if;\n    if flow (v_m) > 0 then\n      --  Man opens valve\n      mem_flow_m := flow (v_m);\n      result_opening_m := flow (v_m) * (time_left - 1);\n      flow (v_m) := 0;\n      --  Elephant moves\n      for j_e in next'Range (2) loop\n        next_valve_e := next (v_e, j_e);\n        exit when next_valve_e = nil;\n        if next_valve_e /= from_e then\n          result_moving_e :=\n            Max\n              (result_moving_e,\n               Visit_Two_Agents\n                 (v_m, nil, next_valve_e, v_e, time_left - 1, score + result_opening_m));\n        end if;\n      end loop;\n      flow (v_m) := mem_flow_m;\n      result_opening_m := result_opening_m + result_moving_e;\n    end if;\n    if flow (v_e) > 0 then\n      --  Elephant opens valve\n      mem_flow_e := flow (v_e);\n      result_opening_e := flow (v_e) * (time_left - 1);\n      flow (v_e) := 0;\n      --  Man moves\n      for j_m in next'Range (2) loop\n        next_valve_m := next (v_m, j_m);\n        exit when next_valve_m = nil;\n        if next_valve_m /= from_m then\n          result_moving_m :=\n            Max\n              (result_moving_m,\n               Visit_Two_Agents\n                 (next_valve_m, v_m, v_e, nil, time_left - 1, score + result_opening_e));\n        end if;\n      end loop;\n      flow (v_e) := mem_flow_e;\n      result_opening_e := result_opening_e + result_moving_m;\n    end if;\n    --  Man and Elephant move\n    for j_m in next'Range (2) loop\n      next_valve_m := next (v_m, j_m);\n      exit when next_valve_m = nil;\n      if next_valve_m /= from_m then\n        for j_e in next'Range (2) loop\n          next_valve_e := next (v_e, j_e);\n          exit when next_valve_e = nil;\n          if next_valve_e /= from_e\n            and then not (v_m = v_e and then next_valve_m >= next_valve_e)\n            --  If Man and Elephant are in the same room,\n            --  we skip symmetrical movements.\n          then\n            result_moving_2 :=\n              Max\n                (result_moving_2,\n                 Visit_Two_Agents\n                   (next_valve_m, v_m, next_valve_e, v_e, time_left - 1, score));\n          end if;\n        end loop;\n      end if;\n    end loop;\n    return\n      Max\n        (Max (result_opening_2, result_opening_m),\n         Max (result_opening_e, result_moving_2));\n  end Visit_Two_Agents;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\nbegin\n  Data_Acquisition;\n\n  Fill_Laziness_Filter_Affine_Function (1700, 25);\n  r (1) := Visit_One_Agent (AA, nil, 30, 0);\n  Fill_Laziness_Filter_Affine_Function (2270, 20);\n  r (2) := Visit_Two_Agents (AA, nil, AA, nil, 26, 0);\n\n  Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n  Put_Line (+\"Part 1: maximum pressure release . . . . . . . . : \" & r (1));\n  Put_Line (+\"Part 2: maximum pressure release (2 players) . . : \" & r (2));\n  --  Part 1: validated by AoC: 1728\n  --  Part 2: validated by AoC: 2304\nend AoC_2022_16;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_16.txt",
    "content": "Valve GJ has flow rate=14; tunnels lead to valves UV, AO, MM, UD, GM\nValve HE has flow rate=0; tunnels lead to valves QE, SV\nValve ET has flow rate=0; tunnels lead to valves LU, SB\nValve SG has flow rate=0; tunnels lead to valves FF, SB\nValve LC has flow rate=0; tunnels lead to valves QJ, GM\nValve EE has flow rate=13; tunnels lead to valves RE, BR\nValve AA has flow rate=0; tunnels lead to valves QC, ZR, NT, JG, FO\nValve TF has flow rate=0; tunnels lead to valves LU, MM\nValve GO has flow rate=0; tunnels lead to valves LB, AH\nValve QE has flow rate=24; tunnels lead to valves LG, HE\nValve MI has flow rate=0; tunnels lead to valves KU, FF\nValve BR has flow rate=0; tunnels lead to valves HY, EE\nValve UV has flow rate=0; tunnels lead to valves GP, GJ\nValve EH has flow rate=0; tunnels lead to valves UU, FF\nValve WK has flow rate=0; tunnels lead to valves HY, EL\nValve NT has flow rate=0; tunnels lead to valves FF, AA\nValve KI has flow rate=0; tunnels lead to valves OQ, AO\nValve AH has flow rate=22; tunnels lead to valves GO, RE\nValve EL has flow rate=0; tunnels lead to valves WK, SQ\nValve GP has flow rate=0; tunnels lead to valves SB, UV\nValve GM has flow rate=0; tunnels lead to valves LC, GJ\nValve LU has flow rate=9; tunnels lead to valves UU, DW, TF, ET, ML\nValve LB has flow rate=0; tunnels lead to valves GO, VI\nValve QC has flow rate=0; tunnels lead to valves ML, AA\nValve JJ has flow rate=0; tunnels lead to valves QJ, DV\nValve MM has flow rate=0; tunnels lead to valves TF, GJ\nValve VI has flow rate=18; tunnel leads to valve LB\nValve NV has flow rate=0; tunnels lead to valves SB, KU\nValve VT has flow rate=0; tunnels lead to valves HY, JG\nValve RE has flow rate=0; tunnels lead to valves AH, EE\nValve FO has flow rate=0; tunnels lead to valves SB, AA\nValve DV has flow rate=10; tunnels lead to valves JH, UD, JJ\nValve SQ has flow rate=12; tunnels lead to valves EL, QA\nValve OQ has flow rate=23; tunnels lead to valves KI, IV, JS\nValve FF has flow rate=3; tunnels lead to valves EU, NT, SG, MI, EH\nValve IV has flow rate=0; tunnels lead to valves LG, OQ\nValve HY has flow rate=8; tunnels lead to valves VT, BR, WK\nValve ML has flow rate=0; tunnels lead to valves LU, QC\nValve JS has flow rate=0; tunnels lead to valves EM, OQ\nValve KU has flow rate=5; tunnels lead to valves MI, VL, NV, HU, DW\nValve QA has flow rate=0; tunnels lead to valves OS, SQ\nValve EU has flow rate=0; tunnels lead to valves FF, OS\nValve SV has flow rate=0; tunnels lead to valves QJ, HE\nValve JG has flow rate=0; tunnels lead to valves AA, VT\nValve DW has flow rate=0; tunnels lead to valves LU, KU\nValve UD has flow rate=0; tunnels lead to valves DV, GJ\nValve QJ has flow rate=17; tunnels lead to valves JJ, SV, LC, EM, YA\nValve HU has flow rate=0; tunnels lead to valves JH, KU\nValve ZR has flow rate=0; tunnels lead to valves AA, VL\nValve YA has flow rate=0; tunnels lead to valves QJ, OS\nValve JH has flow rate=0; tunnels lead to valves HU, DV\nValve OS has flow rate=15; tunnels lead to valves EU, YA, QA\nValve LG has flow rate=0; tunnels lead to valves QE, IV\nValve SB has flow rate=4; tunnels lead to valves FO, SG, NV, GP, ET\nValve UU has flow rate=0; tunnels lead to valves EH, LU\nValve VL has flow rate=0; tunnels lead to valves ZR, KU\nValve AO has flow rate=0; tunnels lead to valves GJ, KI\nValve EM has flow rate=0; tunnels lead to valves QJ, JS\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_16_questions.txt",
    "content": "--- Day 16: Proboscidea Volcanium ---\n\nThe sensors have led you to the origin of the distress signal: yet\nanother handheld device, just like the one the Elves gave you.\nHowever, you don't see any Elves around; instead, the device is\nsurrounded by elephants! They must have gotten lost in these tunnels,\nand one of the elephants apparently figured out how to turn on the\ndistress signal.\n\nThe ground rumbles again, much stronger this time. What kind of cave\nis this, exactly? You scan the cave with your handheld device; it\nreports mostly igneous rock, some ash, pockets of pressurized gas,\nmagma... this isn't just a cave, it's a volcano!\n\nYou need to get the elephants out of here, quickly. Your device\nestimates that you have 30 minutes before the volcano erupts,\nso you don't have time to go back out the way you came in.\n\nYou scan the cave for other options and discover a network of pipes\nand pressure-release valves. You aren't sure how such a system got\ninto a volcano, but you don't have time to complain; your device\nproduces a report (your puzzle input) of each valve's flow rate if\nit were opened (in pressure per minute) and the tunnels you could use\nto move between the valves.\n\nThere's even a valve in the room you and the elephants are currently\nstanding in labeled AA. You estimate it will take you one minute to\nopen a single valve and one minute to follow any tunnel from one valve\nto another. What is the most pressure you could release?\n\nFor example, suppose you had the following scan output:\n\nValve AA has flow rate=0; tunnels lead to valves DD, II, BB\nValve BB has flow rate=13; tunnels lead to valves CC, AA\nValve CC has flow rate=2; tunnels lead to valves DD, BB\nValve DD has flow rate=20; tunnels lead to valves CC, AA, EE\nValve EE has flow rate=3; tunnels lead to valves FF, DD\nValve FF has flow rate=0; tunnels lead to valves EE, GG\nValve GG has flow rate=0; tunnels lead to valves FF, HH\nValve HH has flow rate=22; tunnel leads to valve GG\nValve II has flow rate=0; tunnels lead to valves AA, JJ\nValve JJ has flow rate=21; tunnel leads to valve II\n\nAll of the valves begin closed. You start at valve AA, but it must be\ndamaged or jammed or something: its flow rate is 0, so there's no\npoint in opening it. However, you could spend one minute moving to\nvalve BB and another minute opening it; doing so would release\npressure during the remaining 28 minutes at a flow rate of 13,\na total eventual pressure release of 28 * 13 = 364.\nThen, you could spend your third minute moving to valve CC and your\nfourth minute opening it, providing an additional 26 minutes\nof eventual pressure release at a flow rate of 2, or 52 total\npressure released by valve CC.\n\nMaking your way through the tunnels like this, you could probably\nopen many or all of the valves by the time 30 minutes have elapsed.\nHowever, you need to release as much pressure as possible,\nso you'll need to be methodical.\nInstead, consider this approach:\n\n== Minute 1 ==\nNo valves are open.\nYou move to valve DD.\n\n== Minute 2 ==\nNo valves are open.\nYou open valve DD.\n\n== Minute 3 ==\nValve DD is open, releasing 20 pressure.\nYou move to valve CC.\n\n== Minute 4 ==\nValve DD is open, releasing 20 pressure.\nYou move to valve BB.\n\n== Minute 5 ==\nValve DD is open, releasing 20 pressure.\nYou open valve BB.\n\n== Minute 6 ==\nValves BB and DD are open, releasing 33 pressure.\nYou move to valve AA.\n\n== Minute 7 ==\nValves BB and DD are open, releasing 33 pressure.\nYou move to valve II.\n\n== Minute 8 ==\nValves BB and DD are open, releasing 33 pressure.\nYou move to valve JJ.\n\n== Minute 9 ==\nValves BB and DD are open, releasing 33 pressure.\nYou open valve JJ.\n\n== Minute 10 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve II.\n\n== Minute 11 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve AA.\n\n== Minute 12 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve DD.\n\n== Minute 13 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve EE.\n\n== Minute 14 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve FF.\n\n== Minute 15 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve GG.\n\n== Minute 16 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou move to valve HH.\n\n== Minute 17 ==\nValves BB, DD, and JJ are open, releasing 54 pressure.\nYou open valve HH.\n\n== Minute 18 ==\nValves BB, DD, HH, and JJ are open, releasing 76 pressure.\nYou move to valve GG.\n\n== Minute 19 ==\nValves BB, DD, HH, and JJ are open, releasing 76 pressure.\nYou move to valve FF.\n\n== Minute 20 ==\nValves BB, DD, HH, and JJ are open, releasing 76 pressure.\nYou move to valve EE.\n\n== Minute 21 ==\nValves BB, DD, HH, and JJ are open, releasing 76 pressure.\nYou open valve EE.\n\n== Minute 22 ==\nValves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.\nYou move to valve DD.\n\n== Minute 23 ==\nValves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.\nYou move to valve CC.\n\n== Minute 24 ==\nValves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.\nYou open valve CC.\n\n== Minute 25 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n== Minute 26 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n== Minute 27 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n== Minute 28 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n== Minute 29 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n== Minute 30 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\nThis approach lets you release the most pressure possible in 30\nminutes with this valve layout, 1651.\n\nWork out the steps to release the most pressure in 30 minutes.\nWhat is the most pressure you can release?\n\n--- Part Two ---\n\nYou're worried that even with an optimal approach, the pressure\nreleased won't be enough. What if you got one of the elephants\nto help you?\n\nIt would take you 4 minutes to teach an elephant how to open\nthe right valves in the right order, leaving you with only 26\nminutes to actually execute your plan.\nWould having two of you working together be better, even if\nit means having less time?\n(Assume that you teach the elephant before opening any valves\nyourself, giving you both the same full 26 minutes.)\n\nIn the example above, you could teach the elephant\nto help you as follows:\n\n== Minute 1 ==\nNo valves are open.\nYou move to valve II.\nThe elephant moves to valve DD.\n\n== Minute 2 ==\nNo valves are open.\nYou move to valve JJ.\nThe elephant opens valve DD.\n\n== Minute 3 ==\nValve DD is open, releasing 20 pressure.\nYou open valve JJ.\nThe elephant moves to valve EE.\n\n== Minute 4 ==\nValves DD and JJ are open, releasing 41 pressure.\nYou move to valve II.\nThe elephant moves to valve FF.\n\n== Minute 5 ==\nValves DD and JJ are open, releasing 41 pressure.\nYou move to valve AA.\nThe elephant moves to valve GG.\n\n== Minute 6 ==\nValves DD and JJ are open, releasing 41 pressure.\nYou move to valve BB.\nThe elephant moves to valve HH.\n\n== Minute 7 ==\nValves DD and JJ are open, releasing 41 pressure.\nYou open valve BB.\nThe elephant opens valve HH.\n\n== Minute 8 ==\nValves BB, DD, HH, and JJ are open, releasing 76 pressure.\nYou move to valve CC.\nThe elephant moves to valve GG.\n\n== Minute 9 ==\nValves BB, DD, HH, and JJ are open, releasing 76 pressure.\nYou open valve CC.\nThe elephant moves to valve FF.\n\n== Minute 10 ==\nValves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.\nThe elephant moves to valve EE.\n\n== Minute 11 ==\nValves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.\nThe elephant opens valve EE.\n\n(At this point, all valves are open.)\n\n== Minute 12 =\n\n=\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n...\n\n== Minute 20 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\n...\n\n== Minute 26 ==\nValves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.\n\nWith the elephant helping, after 26 minutes, the best you could do\nwould release a total of 1707 pressure.\n\nWith you and an elephant working together for 26 minutes,\nwhat is the most pressure you could release?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_17.adb",
    "content": "--  Solution to Advent of Code 2022, Day 17\n-------------------------------------------\n--  Pyroclastic Flow\n--\n--  A giant and deterministic Tetris without rotations.\n--\n--  https://adventofcode.com/2022/day/17\n--  Copy of questions in: aoc_2022_17_questions.txt\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and GNAT (64-bit integer: Integer_64):\nwith Interfaces;\n\nprocedure AoC_2022_17 is\n  use AoC_Toolbox, HAT, Interfaces;\n\n  verbosity_level : constant Natural := 0;\n\n  subtype Range_x is Integer range 0 ..    8;\n  subtype Range_y is Integer range 0 .. 8000;\n\n  map   : array (Range_x, Range_y) of Character;\n\n  lowest, highest : Point;\n\n  procedure Adapt_Highest_Value_Point (using : Point) is\n  begin\n    highest.x := Max (highest.x, using.x);\n    highest.y := Max (highest.y, using.y);\n  end Adapt_Highest_Value_Point;\n\n  procedure Show is\n  begin\n    for y in reverse lowest.y .. highest.y loop\n      for x in lowest.x .. highest.x loop\n        Put (map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  type Rock_Type is (minus, plus, L, I, square);\n\n  --  ####\n  --\n  --  .#.\n  --  ###\n  --  .#.\n  --\n  --  ..#\n  --  ..#\n  --  ###\n  --\n  --  #\n  --  #\n  --  #\n  --  #\n  --\n  --  ##\n  --  ##\n\n  rock : Rock_Type;\n\n  --  pattern_mini : String (1 .. 40) := \">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>\";\n\n  pattern : VString;\n\n  jet : Positive;\n\n  old_n_rock, old_height : Integer_64;\n  rocks_per_cycle, height_per_cycle : Integer_64;\n  target_rock : Integer_64 := 0;\n  cycles : Integer_64;\n\n  tera : constant := 1e12;\n\n  procedure Simulate_Rock (n_rock : Integer_64) is\n    lb   : Point;    --  Left, Bottom point of the \"sprite\".\n    w, h : Integer;  --  Width, Height\n    rt   : Point;    --  Right, Top\n    fits, fit_px : Boolean;\n    rest : Integer_64;\n  begin\n    --  Start position:\n    lb.x := 3;\n    lb.y := highest.y + 4;\n    case rock is\n      when minus  => w := 4; h := 1;\n      when plus   => w := 3; h := 3;\n      when L      => w := 3; h := 3;\n      when I      => w := 1; h := 4;\n      when square => w := 2; h := 2;\n    end case;\n    loop\n      --  Gas jet:\n      if Element (pattern, jet) = '<' then\n        case rock is\n          when plus =>\n            fits := map (lb.x,     lb.y)     = '.' and then\n                    map (lb.x - 1, lb.y + 1) = '.' and then\n                    map (lb.x,     lb.y + 2) = '.';\n          when L =>\n            fits := map (lb.x - 1, lb.y)     = '.' and then\n                    map (lb.x + 1, lb.y + 1) = '.' and then\n                    map (lb.x + 1, lb.y + 2) = '.';\n          when others =>\n            fits := True;\n            for y in 0 .. h - 1 loop\n              fit_px := map (lb.x - 1, lb.y + y) = '.';\n              fits := fits and then fit_px;\n              exit when not fit_px;\n            end loop;\n        end case;\n        if fits then\n          lb.x := lb.x - 1;\n        end if;\n      else\n        case rock is\n          when plus =>\n            fits := map (lb.x + 2, lb.y)     = '.' and then\n                    map (lb.x + 3, lb.y + 1) = '.' and then\n                    map (lb.x + 2, lb.y + 2) = '.';\n          when others =>\n            fits := True;\n            for y in 0 .. h - 1 loop\n              fit_px := map (lb.x + w, lb.y + y) = '.';\n              fits := fits and then fit_px;\n              exit when not fit_px;\n            end loop;\n        end case;\n        if fits then\n          lb.x := lb.x + 1;\n        end if;\n      end if;\n      if jet = Length (pattern) then\n        jet := 1;\n        if old_n_rock /= 0 then\n          --  We observe a cycle (the pattern having a prime\n          --  number of symbols does the magic).\n          --  Every rocks_per_cycle after n_rock - 1 + (any n >= 0),\n          --  the tower is height_per_cycle higher.\n          --\n          --  We decompose tera = 1e12 falling rocks as:\n          --\n          --      tera = n_rock + rocks_per_cycle * cycles + rest\n          --\n          --  Hence, the relation\n          --\n          --     (tera - n_rock) = rocks_per_cycle * cycles + rest\n          --\n          --  allow us to calculate cycles and rest.\n          --  Now we can see the decomposition like this:\n          --\n          --      tera = (n_rock + rest) + (rocks_per_cycle * cycles)\n          --\n          --  So, we can let falling (target_rock := n_rock + rest),\n          --  measure the height h, let (rocks_per_cycle * cycles) more\n          --  rocks falling. Then the total rocks is 1e12 and the total\n          --  height is: h + height_per_cycle * cycles.\n          --\n          rocks_per_cycle  := n_rock - old_n_rock;\n          height_per_cycle := Integer_64 (highest.y) - old_height;\n          rest := (tera - n_rock) mod rocks_per_cycle;\n          target_rock := n_rock + rest;\n          cycles := (tera - n_rock) / rocks_per_cycle;\n          if verbosity_level > 0 then\n            Put_Line\n              (+\"After rock nb \" & Integer_64'Image (n_rock - 1) &\n                \" heap is height \" & highest.y &\n                \" cycle rock \" & Integer_64'Image (rocks_per_cycle) &\n                \"; cycle height: \" & Integer_64'Image (height_per_cycle));\n            Put_Line\n              (+\"Must reach rock nb \" & Integer_64'Image (target_rock));\n          end if;\n        end if;\n        old_n_rock := n_rock;\n        old_height := Integer_64 (highest.y);\n      else\n        jet := jet + 1;\n      end if;\n      --  Simulate falling:\n      case rock is\n        when plus =>\n          fits := map (lb.x,     lb.y)     = '.' and then\n                  map (lb.x + 1, lb.y - 1) = '.' and then\n                  map (lb.x + 2, lb.y)     = '.';\n        when others =>\n          fits := True;\n          for x in 0 .. w - 1 loop\n            fit_px := map (lb.x + x, lb.y - 1) = '.';\n            fits := fits and then fit_px;\n            exit when not fit_px;\n          end loop;\n      end case;\n      if fits then\n        lb.y := lb.y - 1;\n      else\n        --  \"Write\" the sprite\n        case rock is\n          when minus =>\n            for x in 0 .. 3 loop\n              map (lb.x + x, lb.y) := '#';\n            end loop;\n          when plus =>\n            map (lb.x + 1, lb.y + 2) := '#';\n            for x in 0 .. 2 loop\n              map (lb.x + x, lb.y + 1) := '#';\n            end loop;\n            map (lb.x + 1, lb.y) := '#';\n          when L =>\n            map (lb.x + 2, lb.y + 2) := '#';\n            map (lb.x + 2, lb.y + 1) := '#';\n            for x in 0 .. 2 loop\n              map (lb.x + x, lb.y) := '#';\n            end loop;\n          when I =>\n            for y in 0 .. 3 loop\n              map (lb.x, lb.y + y) := '#';\n            end loop;\n          when square =>\n            for x in 0 .. 1 loop\n              for y in 0 .. 1 loop\n                map (lb.x + x, lb.y + y) := '#';\n              end loop;\n            end loop;\n        end case;\n        exit;\n      end if;\n    end loop;\n    --  Calculate Right-Top corner.\n    rt.x := lb.x + w - 1;\n    rt.y := lb.y + h - 1;\n    Adapt_Highest_Value_Point (rt);\n\n    if rock = square then\n      rock := minus;\n    else\n      rock := Rock_Type'Succ (rock);\n    end if;\n  end Simulate_Rock;\n\n  f : File_Type;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer_64;\n\nbegin\n  r (1) := 0;\n  r (2) := 0;\n  Open (f, \"aoc_2022_17.txt\");\n  Get_Line (f, pattern);\n  --  pattern := + pattern_mini;\n  Close (f);\n  lowest.x  := Range_x'First;\n  highest.x := Range_x'Last;\n  lowest.y  := Range_y'First;\n  highest.y := 0;\n  map (0, 0) := '+';\n  map (0, 8) := '+';\n  for x in 1 .. 7 loop\n    map (x, 0) := '-';\n  end loop;\n  for y in 1 .. Range_y'Last loop\n    map (0, y) := '|';\n    for x in 1 .. 7 loop\n      map (x, y) := '.';\n    end loop;\n    map (8, y) := '|';\n  end loop;\n  rock := minus;\n  jet := 1;\n  old_n_rock := 0;\n  for rock_count in 1 .. 6000 loop\n    Simulate_Rock (Integer_64 (rock_count));\n    if verbosity_level > 0 and then rock_count <= 5 then\n      Put_Line (rock_count, 0);\n      Show;\n    end if;\n    if rock_count = 2022 then\n      r (1) := Integer_64 (highest.y);\n    elsif Integer_64 (rock_count) = target_rock then\n      r (2) := Integer_64 (highest.y) + cycles * height_per_cycle;\n      exit;\n    end if;\n  end loop;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Height of the tower of...\");\n    Put_Line (+\"  (part 1): 2022 rocks . . . . . . . . :\" & Integer_64'Image (r (1)));\n    Put_Line (+\"  (part 2): 1_000_000_000_000 rocks  . :\" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 3193\n    --  Part 2: validated by AoC: 1577650429835\n  end if;\nend AoC_2022_17;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_17.txt",
    "content": "><<<>>><<<><<<>>><<>>>><<<>>>><>>>><<<>>><<<<>>><<>>>><<<>>><<<<>>><<<<>>><<<<>>>><<<<>>>><<<<>><<<<><<<<><<<>>>><<<>><<>>><<<>><<>>><<>>><>><<<>><<<<>>><<>><>>><<<<>>><>><>>><<<<>>>><<<>>><<<><<<<>>><><>>>><<<><<<<>><<<>><<<>>>><><<<><<>>>><<>>>><<<><<>>>><<>><<><<<>><>>>><<<>>>><<<>><>><<<>>>><<<<><<><<<>><<>>>><<<<>><<<<><<<<><<<<><>><<><<>>><>><<<<>>><>>><>>>><<<<>>><><<>><<<<><<<>>><>>><<<><<<<><<<<><<<<>><>>><><><<<<>><>>>><<<<><>><<<<>>><<<>>><<>>>><<<<><>>>><<>><<<<>>>><<>>><<<>>><><<>>>><<<<>><<>>><<<>><><<<<>>>><<<<>>><>>>><<>>>><<<>>><>>>><<<>>>><<><<>>><>>><<<>>><<<>><>>><<<<>><<<><<>>><>>>><<<<>>><<<>>><<<<>>><<<<>><<>><><<<<>><<<>>><<<<><<<<>>>><<<>><<<><>>><<>>>><<<>>>><<>>><<<<>>><<<>>>><<<>><<<<>>><<<<>>><<>>>><<<>>>><>>><<<>>>><<>><>>>><<>>>><<<>>>><<<<><<<><<>><<<>><<<>>>><<>>>><<<<>><>>>><<<<><<<<>><<>><<>><<<<>>><<>><<><>>>><<<>><>><<>><<>><>><<<>><<<<><<<>>>><<<>>>><<<<>><>><<<<><<<>><<<<>>><>>><<<<><<<>><<<<>><<>>>><<<>>>><<<<>><<<>><><<<<>>><>><<><<<<>><<<><<<><<<<>>>><<<<>>>><><>><<<>>>><<<<>><>>><<<<><<>>><<<>>>><<>><<<>>><>>><<><<<>>><<<><<<>>><<<<><<<<>><<><<>><><<<<>><<<<>>>><><<<>>>><<<>><>>>><<>>>><<<<>>>><<<>>><<<<><<>>>><<<><<<>>>><<><<<>>>><><<<><>>>><>>>><<<>>><>><>>>><>><<>>><>>>><<<>>><<>>>><<>>>><<><<<<>>>><<>>><>><<<<>>><<<>>>><<<>>>><<>>><>><>><<<<>>>><<><<><>>>><<>>>><>>><<<<>>>><<<<>>><<><<<><<>>>><<>>><>>><>>><<<><<<>>>><<<>><<>>><><<<<>>><<<<>><<<>>>><<>><<<<><<<><<<<>><<<<>>>><<><<<><<<<>>>><<<<><<<<>>><<<>>>><<<>>><><<<<>>>><<<>><<<<><>><<<><<>>><>>>><<<><<<<>><<<<><<<<>><<>>>><>><<<>>>><<<<><<<>><<<>>>><><<<>><<<><<<<>>>><><<>><<>>><<<<><<<<><<<<><<>>>><<>>>><<><<<<>><<<<>><<<><>><<<<><<<>>>><<<>><>>>><<<<><<<<><<>><<>><<<<>><<<<>><><><<>><<<<>>>><<<>>>><>>><<<>>>><<>>><><><<><>>><<<<>>>><<>>><<<>>>><<<>>>><>><<<<>>>><<<<>>><<>>>><>>><<<<>>>><<<>>>><<<<>><><>><<<>>>><<>><<<>>><>>>><<<>>>><>><<<>>><<<<>><<<>><<<<>>>><>>>><><><<>><<<<>><<<>><<><<<<>><<>>><>><<><<>><<<<>>><>>>><<<>>>><<>>><>>>><<<><<<<>>>><<<><<<><<<>><<>>>><<<><<<<><<<<>>>><<<<>>>><<<><<<<>>><<>>>><<<>><<<>><<>>>><<>><<<>>>><><<<<>><><<<<>><<<>>><<<>>>><<<>>>><<>>><<<>><<<><>><><<<><>>>><<><<<<>>>><>>><<>>><>>>><<<<>>>><<>><<<<>><<<>><><<<<>><<>>>><<>>>><<<>><<<<>>><<><<<<>>><<>>>><<>><<<<>><<><<<><>><>>><>><<<>>><<<<>>><<>>>><<<><<<<><<<<>><<<<>>>><<<<>>><<>><<<><>>>><<<><<>>>><<<>><>>>><<<<>><<<<>><<>>>><<><<<><>>><<<>>><<>>><<>><<<<>>>><<<<>><<<<>><<<>>>><<<<>>><<>>><<<<><<<>>><<<><<>><<<<>><>>><<><<>>><<<<>>>><<<>>><<<>><<<<>>>><<>><<<<>><><<>>>><>><<<>><<<>><<<<>><>><>><<<>>>><<>><<><<>>><<>>>><<<<>>><<>>>><><<<>>><<>><<<<><<<<>><<>>>><<<<>>>><>>><>>><<<>><><<<>>><<<<>>><>>>><<<>><<<<><<<>>><<<<>>>><<<>>>><<<<>>><<<>><<<<>>><<<>>>><<<<>>>><>>><<<<><><<><<><<>>>><>>>><<<>>><<><><><<<<><<<<>>><<<>>>><<<<>>>><>>><<>>><<>><<<>>>><<><<>><<>>><<<><<<><<<>>>><>><>>><>>>><<<<>>><>><<<><>>>><<<>>>><<<><<<<>>><<<<><<>>><>>>><><<><<<<>>><>>><>><<>>><<<>>>><<<>>>><<<<><<<>>><<<<><<<>>>><<<>>>><>>><<>>>><<>>><<<<><>>><<<><<>><>>><>><<>><<>><<<>>>><<<<>><<<>>><<<<>>>><<>><>>><>>><<<>><<<><<>><>><><<<>>>><<<><<>><<<>>><<<<>><<<>>>><<<<>><>>>><>><<<><>>>><<<<><<<><>>>><<<>>>><><>>><><>>><<<>>>><<>>><<>><<>><>><>>>><<<>>>><><>>><<<<>>><<<>><<><>><<<<>>><<>>>><<<>>><<<>>><<<><<<>><<<<>>><><>>>><<>><<<>>><<<<>><<<>><><<<>>><<<><>>>><><<>><<<><<<>>><<<>>><<>>>><<<>>><<<<>>>><<>>>><<>>><<<<>><>>>><<>>>><><<>><><<<<>><<>>><<>>><<<><<>>><<<>><<<>>>><<>>><>>>><<<><<<><<>>>><><<<<>>><<>>><<<<>>>><<<>>><<<<>>>><<<<>><<>><<>>><<<>>><<<><<<<>>>><<>><<<><<<<>><<<<>>>><<><<<<><>><><<<>><<><<<>>>><<><<<><>>>><<<>>>><<<<><<>>><<<>>><<>>><<><<<<><>>><<>><<<<><<<>><<><><<<><<<><><>>><<><>>>><<><<<><<<<>>>><><<>>>><<><<><<<>>><<<<>><<<><<<>>><<<>>>><<<<>>><<>>>><<<><<<<>><<<<><<<>>>><<<>>>><<<>>>><<<>><<>>>><>><<<><<>>><<<<>>>><><<<<>>><<>><<>><<<<>><<<<><<<<>><<<<>><<<<>>><<>>>><<<<>>>><<<<>>><<<><><<<<>>><<<>>><<>><<><<<>>>><<>><<<><>><<<<>>><<<<><<<<><<><>><<>>><<<><<><<<<>>><<<>>><<<<>><<<<>>>><>>>><><<>><<>><>><<<><<>>>><<<>><<<><<>><<><<<<>>><<>>><<<<>>>><>><<>>>><<<>>><>><<<<>>><<<<>>>><<<>>><<>>><<<<><<<><>>><>><<<>>>><><<<>><<><>><<<><<<>><<>>>><<>>>><<<>><<<>>>><>>><><>>><<<>>>><<<>>><<<><<<<>><<<<><><<<><<><<<<>><><<<<>>><<<>><<<<>>>><<<>>>><<<>>><<<>>><<>>>><<>>>><<<>>>><<<>>><<<>><>>><>>><<<>>>><<>>>><<><>>>><<<><<<>>>><<><<<>><<>><<<<><<<<>>>><<<<><>>><<<<>>>><<<>>>><><<><<<>>>><<<><<>><<>>>><>>><>>>><<>>><<>><<>>><>>><<<>>>><<<>>><<<<>>><<<>>>><<<<>><><<>>>><<<<><>>><<><<<>>>><>>>><<>>>><<<><<><<<<>>>><>>><<<>>>><<<>><><<>>><<<><<>><><<<>>><<<<><<><<<>>><<>>><>>>><>>><<>>><>><><<<<>>>><<<<>>>><><<<<><<<<><<<<>>>><<<<>>><<<<><<<>><<>>>><<><<<>>><<><<<>><>>><<<<>>><<><<>>><<<><<><<<>><<<<><<>>><><<>><><><<<><<>>><<>>>><<<<>>><<<>><<<<><<>>>><>>>><<<<><<<<>>>><<>>><<<<>>><<>>><<<>>><>>><<<>>>><<<>><<><<<<><>>>><<>><<>>>><<<>>><<<>>><>>><<<<>><<<<>><<><<<<>>><<>>>><>>>><>>><<<<>>>><><<<>>>><<<<>>>><<<>>>><<<>>>><<<<><<<>>>><<<>>><<<<>>>><<<><>>><><>>>><<<<>><<>>><<<><<<<><<>><<<<>><><<><<<>>><<<<>><<<>>>><<<>>>><<><>>><<>>><<<>>><<<<><<<<>>><<<<>><>>>><<<<>>>><<<><<<<>>><<>>>><<<>>>><<><>>>><<>>>><<>><<<>><<>>><<<<>>>><<><>>><<><<<>>>><<<<>><>>><><>>>><<<>><<<<>>>><<<<><<>>>><<<<>><<<>>><><<<<>>><<>>>><<>>>><<<><<><<<<>>><<<<>>>><<<><<<<><><<<<>>>><<<<>>><<<<><<<><<<>><><<<<><<>>><<<>><<<>>>><<>>>><<>>>><<>>>><<><<<<>><<<<><<<<>>><<><>>>><>>><><>><<><<>>>><<<<><>><<<<><<>><<>>><>><<<>><>><>><<<>>><<>>>><<<>>>><<>>><<>>>><<>>><<<<>>><<<<>>><<<<><<>>>><<<<>>>><<<>>><>>><<>>>><<<>>>><>>>><>><<<<>>>><<<<><<>>>><<<<><>>>><<<>><<<<>>>><>>><<<<>>>><<>>><<<<>><<<<><<<>><<<>><<>><>>>><>><<<<>>>><<<>><<>><<>>><<<>>>><>>>><<>>><>>><<><<>><<<<>><<<>>><<<><<<>>><<<<>>><<<><<<>>>><<<<><<>>><<<>>>><>>>><<<<><><<<<>>>><<>>><>>><<<<>>>><<<<>><<>><<<>>>><<<>><>>>><>>>><><<<>>>><<<<><<<>>><<>>><><<<<>><<<<>><>>><>><<<>>>><<<>>>><<<<>><<>>><<<><<<>><<<>><<<>><<>>><<<<>><<<>>>><<>>>><<<>><>>><>>>><<<<>>>><<<>><>>><<>><><<<>>>><>><<<<>>>><<<<><>>>><<<<><<><<<<>>>><<>><<<>>>><<<><<>>><<<<><<<<>><<>>><<<<>>><<><<<<>>><<><<>>><<>><<<<><>>><<<<>>><<>><<<<>>><<<><>>>><><<><><<<>><>>><>><>>><<<>>>><>><<<<>><<<>><<<<>>><<<>>><<<>>>><><<><<<>><<<<>><<><<<<>><<<<>>>><<<<>><<<>>><<<<>>>><<>>>><<<><<<>>>><<>>><<>>>><<<<>>><<>>>><>>>><<<<>>>><<<>>><<<>>><<<><>>>><>>>><<<<>>><<<>>>><>>>><<>>><<>>><><<<<>><<>><<>><<<<>>><<<<>>>><<<>>>><<<>><>><<<<><>><>>>><<<<>>>><<<>>>><<<>>>><<>>>><>>>><<<<>>><>>>><<<<>><<><<<>><<<<>><<<>><<<<><<<>>>><<>><>><>><<<>>>><>><<<><<><<<<>>><<<<><>>>><<><>><<<>><>><<<>>>><<<><<<<>>>><<<<><>>>><<<<>><<<<>><<<<><>>>><>>><<<<>>>><<<><<<>>><<<>><<>><<<<>>>><<<>><<<<>>><<>>>><<>><<>>>><<><<><<<<>>>><<<>>><<<><>>>><<>>>><><<<>><>><<><<>>>><><>>>><<<>>>><<<<>><<>><<<>>>><>>><<>>><>>><><<><<<<>><>><<<>>><<<>><><<<<>><<<>>><><<<<><>>><<<><><<<<>>><<>>><>>><>>>><<<>><<<<>>>><>>><<>>>><<>>><<<>>>><>>><<<>>>><<<<>>><<<<>>><<><<><<>>><<<<>>>><<<><>><>>>><<>>>><<<>>>><>>><<<><<><>>>><<>>><<<>>>><<>>>><<<><<<<>>>><>><<<>>><<<><<<>>><><<<<>>>><>><>>>><<<<><<<<>>>><<>>>><><<<>><>>><<<<>><<<<>>><<<<>>>><<<>><<<<>>>><<><>><<<>>><><<<<>>>><<<<><<<>><>><<>>><<<><<<<>><<>>>><<<>>>><<>>>><<<<>><<>><>>><<<<>>><<<>>>><<<<>>>><<>><<><<>><<<<>>><<<<>>><<<<>>>><><<<>>><<<<>>><<<<><><<<<><>><<<<>>><<<>>><<<<>>>><<<<>>><>>><<>>><<<<>><<<>><>><<>>>><>>>><>><<<>>>><<<<>>>><<<>>>><<<><<<><<<>><>>><<<<>>>><<<>>>><<<<>>><<<<>><<>><<<<><<<><>><>>><><<<><<<>>>><<<>>><<<<>>>><<<<><<>>>><<<<><<<>>><<>><<<<>><>>><<>>>><<<><<>>><>>><<>>><<<>>>><>><><<<<>>><><<<<>>><<<>>>><<><><<><<>>><>><<<<>>><<<>>>><<<><<<>><<<<>>><><>><<>>>><<<><<<<><>>><>><<<<>>>><<>>><<<<>>>><<<<>>><<>>><<<<><<>>>><<<>>>><<>>><>>><<>>><<<><<<>><<<<>>>><<<<>>><<>><>>>><<<<>>>><<<><>>>><<<<><<<<>><<>>><<<<>>>><><<>><<<<><>>>><<<<>><>>><><>>><<>>>><<<><><<<<>><<<><<<<>>>><><>>><<>>><<<>>><<<<>>><<<<>><<>>>><<<>>><>>><<<<>>>><<><>>><<<><<<>>>><<<>>>><<<><>>>><<<<>>><>>>><<<>>><<<><<<<>>><<<<><<<<>>><<>>>><<<>>><<<<><<><<<<>>>><<<>><<<<>><>>><<<<><<>>>><<>><>>>><<<<><<<>><<>>>><<>>>><<<<>><<<<>>>><<>>>><<<>>>><<>>><><<<>>><<><<>>>><<<>>>><<>>>><>><<<<>>>><<<<>>>><<><<><<<<><<>>><<>>><<<<>>>><<<>><<<<><<<<>>><<<<>>><<<>>><<<<><<>>>><<<<>>>><<<>><<<>><>>>><<<><><<<<><><<<>>><<<<>>>><<<><<<<>>>><<<>>>><>><<<<>>>><<>>>><<<>>>><<<<><<<>>>><>>>><><<<><<<>><>>>><<<>><<<<><<<<>><<>>><>>>><<>><>><>><<<>>><<<>>><<<>>><<>>><<>><<<>>>><<<<>>><<<>><>>>><<<<><<><>>>><<>>><<><<<<>><<<<>>>><<>><<<><<>>><<<<>><<<>><<><<<<>>>><<<>>>><<<<>>><>><<<<>><<<><>><<>>><<<<><<<<>>>><<<>><<<>>>><<<<>>>><<<>>><<>><>>><>>><<<>>><><<<<>>><>>><>>>><>>><<<<>>>><<<><<><><<<>>>><<<><<<>><<<<>>><<<><<><<<<>>>><<><<<<>>><>>>><>>>><>><<<<>>>><<<<>>><>>><<<>><>>>><<<<>><<<<>>>><>>><>>><<<<>><<<>>>><<<><<<<><>>><<<<>>><<<>>>><><<<><>><<<<>><<<><<<<>>>><>><><<<<><<<<>>>><<<>>>><<>><<<<><<>>><<<<><<<><<<<>><<<><<>>>><<<<>><>>>><<<>>><<>><<<>><><<<<>>>><<<>><<>><>>>><<<>>><<>>><<<>>><<>>><<<><<<<>>><>><<<>>>><<<<>>>><<<>><<<<>>>><>><<<><><<<<>><<<>>>><>>>><<<<>>>><<>>><<>>><><>>><<<><>><<>>>><>>><<<>>>><><>><>>>><<>>><>><<<<>><<>>><<>>>><><<><<<>><<>>>><<<>>><<><<<>>>><<<><><<>><<<>><<<><<<>>>><<<>>><>><<<>>><>>><>>><<>>><<<<><<<<>><<<>>><<<><>>><<<<>><>><<<>>><<>><>><<><>>><<<<>><>>><<<<><<<><<<><<<>>><<>>>><<<<>><<>><<>>><<>><<>><<<<>>><<><<<><>>><>><<><<>>>><<>>><<<<>>><<<>>>><>>><>>><<>>><><<<><<><<>>><>>>><>>>><<<<>>><>><<<>>>><>><<<>><<>>><>><<><<<><<<>>><<>>><<<<>>><><<<<>>><<<>><>>>><<<>>>><<<<><<<<>>>><<>><><<>>><<<><<>>><<>>>><<>><<<><<<><<<>>><<>><<<>>>><><<<<>>>><<>>><<>><<>>><<>>><<>>>><<<><<<<>><<>>>><<<>>><><<><<><<>>><<<<><<<><<><<>>>><<>>><><<<<>><<>><><<><>>><>>><<>>><<<<>>><<<<><>><<>>>><<<<>>>><>><<<<>><<><<<>>>><>><<<<>>>><<<><<<>><><<<<>>>><><<<<>><<<><<>>>><<><<<>><<<>><<<>><<<>>><<><<<>>>><>><<>>>><<>>><>>>><>>><><>><<<>>><<<><><<>><<<>>><<<<>>><<<>>>><><>>><<><>><<<>><<>><<>>><<<<>>><<<><<<<><>><<<>>><<<>>><<>>>><<<<>>><<>>><<<><<>>><<<>><<<>>><>>>><<<<>>>><<<<>><<<<>>><<>><<<<>><<<>>><<<>><><<<>>>><<>>>><<<<>>>><<>><>>>><<<<>>><>>>><>><<<<>>><>>><<>>>><<<<><<<><<<>><<>>><<><>>><<<<>>><>>>><<>>><<<<>>><>><<<>><<><<<><<<<>>><><<<<>>><<<<>>><<><<<<>><<>>>><>>>><<><><<<>>><>><>><>>>><><<<<>>><<<<>>>><<>><<>\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_17_questions.txt",
    "content": "--- Day 17: Pyroclastic Flow ---\n\nYour handheld device has located an alternative exit from the cave for\nyou and the elephants. The ground is rumbling almost continuously now,\nbut the strange valves bought you some time.\nIt's definitely getting warmer in here, though.\n\nThe tunnels eventually open into a very tall, narrow chamber.\nLarge, oddly-shaped rocks are falling into the chamber from above,\npresumably due to all the rumbling. If you can't work out where the\nrocks will fall next, you might be crushed!\n\nThe five types of rocks have the following peculiar shapes,\nwhere # is rock and . is empty space:\n\n####\n\n.#.\n###\n.#.\n\n..#\n..#\n###\n\n#\n#\n#\n#\n\n##\n##\n\nThe rocks fall in the order shown above: first the - shape, then\nthe + shape, and so on. Once the end of the list is reached, the\nsame order repeats: the - shape falls first, sixth, 11th, 16th, etc.\n\nThe rocks don't spin, but they do get pushed around by jets of hot\ngas coming out of the walls themselves. A quick scan reveals the\neffect the jets of hot gas will have on the rocks\nas they fall (your puzzle input).\n\nFor example, suppose this was the jet pattern in your cave:\n\n>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>\n\nIn jet patterns, < means a push to the left, while > means a push\nto the right. The pattern above means that the jets will push a\nfalling rock right, then right, then right, then left, then left,\nthen right, and so on. If the end of the list is reached, it repeats.\n\nThe tall, vertical chamber is exactly seven units wide.\nEach rock appears so that its left edge is two units away from the\nleft wall and its bottom edge is three units above the highest rock\nin the room (or the floor, if there isn't one).\n\nAfter a rock appears, it alternates between being pushed by a jet\nof hot gas one unit (in the direction indicated by the next symbol\nin the jet pattern) and then falling one unit down.\nIf any movement would cause any part of the rock to move into the\nwalls, floor, or a stopped rock, the movement instead does not occur.\nIf a downward movement would have caused a falling rock to move into\nthe floor or an already-fallen rock, the falling rock stops where it\nis (having landed on something) and a new rock immediately begins\nfalling.\n\nDrawing falling rocks with @ and stopped rocks with #, the jet\npattern in the example above manifests as follows:\n\nThe first rock begins falling:\n|..@@@@.|\n|.......|\n|.......|\n|.......|\n+-------+\n\nJet of gas pushes rock right:\n|...@@@@|\n|.......|\n|.......|\n|.......|\n+-------+\n\nRock falls 1 unit:\n|...@@@@|\n|.......|\n|.......|\n+-------+\n\nJet of gas pushes rock right, but nothing happens:\n|...@@@@|\n|.......|\n|.......|\n+-------+\n\nRock falls 1 unit:\n|...@@@@|\n|.......|\n+-------+\n\nJet of gas pushes rock right, but nothing happens:\n|...@@@@|\n|.......|\n+-------+\n\nRock falls 1 unit:\n|...@@@@|\n+-------+\n\nJet of gas pushes rock left:\n|..@@@@.|\n+-------+\n\nRock falls 1 unit, causing it to come to rest:\n|..####.|\n+-------+\n\nA new rock begins falling:\n|...@...|\n|..@@@..|\n|...@...|\n|.......|\n|.......|\n|.......|\n|..####.|\n+-------+\n\nJet of gas pushes rock left:\n|..@....|\n|.@@@...|\n|..@....|\n|.......|\n|.......|\n|.......|\n|..####.|\n+-------+\n\nRock falls 1 unit:\n|..@....|\n|.@@@...|\n|..@....|\n|.......|\n|.......|\n|..####.|\n+-------+\n\nJet of gas pushes rock right:\n|...@...|\n|..@@@..|\n|...@...|\n|.......|\n|.......|\n|..####.|\n+-------+\n\nRock falls 1 unit:\n|...@...|\n|..@@@..|\n|...@...|\n|.......|\n|..####.|\n+-------+\n\nJet of gas pushes rock left:\n|..@....|\n|.@@@...|\n|..@....|\n|.......|\n|..####.|\n+-------+\n\nRock falls 1 unit:\n|..@....|\n|.@@@...|\n|..@....|\n|..####.|\n+-------+\n\nJet of gas pushes rock right:\n|...@...|\n|..@@@..|\n|...@...|\n|..####.|\n+-------+\n\nRock falls 1 unit, causing it to come to rest:\n|...#...|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\nA new rock begins falling:\n|....@..|\n|....@..|\n|..@@@..|\n|.......|\n|.......|\n|.......|\n|...#...|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\nThe moment each of the next few rocks begins falling,\nyou would see this:\n\n|..@....|\n|..@....|\n|..@....|\n|..@....|\n|.......|\n|.......|\n|.......|\n|..#....|\n|..#....|\n|####...|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|..@@...|\n|..@@...|\n|.......|\n|.......|\n|.......|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|..@@@@.|\n|.......|\n|.......|\n|.......|\n|....##.|\n|....##.|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|...@...|\n|..@@@..|\n|...@...|\n|.......|\n|.......|\n|.......|\n|.####..|\n|....##.|\n|....##.|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|....@..|\n|....@..|\n|..@@@..|\n|.......|\n|.......|\n|.......|\n|..#....|\n|.###...|\n|..#....|\n|.####..|\n|....##.|\n|....##.|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|..@....|\n|..@....|\n|..@....|\n|..@....|\n|.......|\n|.......|\n|.......|\n|.....#.|\n|.....#.|\n|..####.|\n|.###...|\n|..#....|\n|.####..|\n|....##.|\n|....##.|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|..@@...|\n|..@@...|\n|.......|\n|.......|\n|.......|\n|....#..|\n|....#..|\n|....##.|\n|....##.|\n|..####.|\n|.###...|\n|..#....|\n|.####..|\n|....##.|\n|....##.|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\n|..@@@@.|\n|.......|\n|.......|\n|.......|\n|....#..|\n|....#..|\n|....##.|\n|##..##.|\n|######.|\n|.###...|\n|..#....|\n|.####..|\n|....##.|\n|....##.|\n|....#..|\n|..#.#..|\n|..#.#..|\n|#####..|\n|..###..|\n|...#...|\n|..####.|\n+-------+\n\nTo prove to the elephants your simulation is accurate, they want to\nknow how tall the tower will get after 2022 rocks have stopped (but\nbefore the 2023rd rock begins falling). In this example, the tower\nof rocks will be 3068 units tall.\n\nHow many units tall will the tower of rocks be after 2022 rocks have\nstopped falling?\n\n--- Part Two ---\n\nThe elephants are not impressed by your simulation.\nThey demand to know how tall the tower will be after 1000000000000 rocks\nhave stopped! Only then will they feel confident enough to proceed\nthrough the cave.\n\nIn the example above, the tower would be 1514285714288 units tall!\n\nHow tall will the tower be after 1000000000000 rocks have stopped?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_18.adb",
    "content": "--  Solution to Advent of Code 2022, Day 18\n-------------------------------------------\n--  Boiling Boulders\n--\n--  https://adventofcode.com/2022/day/18\n--  Copy of questions in: aoc_2022_18_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\nwith HAT;\n\nprocedure AoC_2022_18 is\n  use HAT;\n\n  subtype The_Range is Integer range -1 .. 20;\n\n  type Big_Cube is array (The_Range, The_Range, The_Range) of Natural;\n\n  space : Big_Cube;\n\n  air   : constant := 0;\n  lava  : constant := 1;\n\n  procedure Flood_Fill (x, y, z : Integer) is\n  begin\n    if x in The_Range\n      and then y in The_Range\n      and then z in The_Range\n      and then space (x, y, z) = air\n    then\n      space (x, y, z) := lava;\n      Flood_Fill (x - 1, y, z);\n      Flood_Fill (x + 1, y, z);\n      Flood_Fill (x, y - 1, z);\n      Flood_Fill (x, y + 1, z);\n      Flood_Fill (x, y, z - 1);\n      Flood_Fill (x, y, z + 1);\n    end if;\n  end Flood_Fill;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n  f : File_Type;\n  c1, c2 : Character;\n  x, y, z : Natural;\n  cubes_lava, contacts_lava, cubes_air, inner_faces_air : Natural := 0;\n  surface_area_lava, surface_area_air : Natural;\n\nbegin\n  for x in Big_Cube'Range (1) loop\n    for y in Big_Cube'Range (2) loop\n      for z in Big_Cube'Range (3) loop\n        space (x, y, z) := air;\n      end loop;\n    end loop;\n  end loop;\n\n  Open (f, \"aoc_2022_18.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    Get (f, x);\n    Get (f, c1);\n    Get (f, y);\n    Get (f, c2);\n    Get (f, z);\n    space (x, y, z) := lava;\n    cubes_lava := cubes_lava + 1;\n    --  Count the faces of each lava cube that is\n    --  connected to the new lava cube.\n    --  Each square is counted once.\n    contacts_lava := contacts_lava +\n      space (x - 1, y, z) + space (x + 1, y, z) +\n      space (x, y - 1, z) + space (x, y + 1, z) +\n      space (x, y, z - 1) + space (x, y, z + 1);\n  end loop Read_Data;\n  Close (f);\n  surface_area_lava := 6 * cubes_lava - 2 * contacts_lava;\n  r (1) := surface_area_lava;\n\n  Flood_Fill (-1, -1, -1);\n  --  Now the only air remaining is trapped inside the lava droplet.\n  for x in Big_Cube'Range (1) loop\n    for y in Big_Cube'Range (2) loop\n      for z in Big_Cube'Range (3) loop\n        if space (x, y, z) = air then\n          cubes_air := cubes_air + 1;\n          --  Count the faces of each air cube that is\n          --  connected to another air cube.\n          --  Each square is counted twice.\n          inner_faces_air := inner_faces_air + 6 -\n            (space (x - 1, y, z) + space (x + 1, y, z) +\n             space (x, y - 1, z) + space (x, y + 1, z) +\n             space (x, y, z - 1) + space (x, y, z + 1));\n        end if;\n      end loop;\n    end loop;\n  end loop;\n  surface_area_air := (6 * cubes_air - inner_faces_air);\n  r (2) :=  surface_area_lava  - surface_area_air;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: surface area of lava . . . . . : \" & r (1));\n    Put_Line (+\"Part 2: exterior surface area of lava  : \" & r (2));\n    --  Part 1: validated by AoC: 3374\n    --  Part 2: validated by AoC: 2010\n  end if;\nend AoC_2022_18;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_18.txt",
    "content": "13,4,13\n13,7,5\n4,6,14\n11,17,11\n7,5,16\n10,11,2\n5,14,7\n12,5,4\n12,17,7\n16,9,5\n10,8,17\n17,9,11\n11,10,16\n2,12,7\n8,4,15\n15,9,15\n18,7,9\n5,10,15\n9,3,8\n9,3,7\n15,8,15\n12,1,10\n7,4,14\n17,11,10\n13,2,9\n6,15,4\n2,13,11\n17,10,9\n9,5,16\n5,2,8\n16,15,9\n10,2,8\n2,11,11\n12,16,14\n7,4,13\n12,16,9\n13,9,3\n6,2,9\n16,8,14\n9,3,13\n15,8,4\n7,7,2\n11,16,12\n4,13,15\n8,7,17\n6,15,15\n1,6,9\n3,7,6\n14,6,3\n11,13,2\n16,6,10\n5,3,9\n6,12,16\n12,14,4\n2,6,11\n13,3,4\n11,7,2\n12,4,4\n11,7,17\n8,8,17\n15,4,14\n3,10,11\n9,6,2\n15,5,8\n4,14,8\n5,6,6\n10,18,12\n4,11,5\n11,2,10\n14,12,4\n12,7,16\n9,14,16\n11,16,13\n14,10,15\n5,5,13\n15,4,8\n6,11,3\n10,12,3\n3,6,8\n12,14,3\n8,4,13\n9,2,12\n7,6,2\n10,15,15\n14,7,15\n6,3,8\n16,8,7\n8,5,4\n7,4,8\n12,5,16\n3,11,15\n12,16,12\n12,16,13\n17,12,10\n8,16,7\n9,11,3\n6,11,18\n4,4,10\n11,2,12\n16,9,14\n4,5,7\n17,12,8\n3,12,14\n14,2,9\n7,17,9\n10,9,3\n14,12,16\n3,6,11\n9,18,11\n16,13,4\n12,11,17\n5,5,10\n4,14,5\n17,5,6\n15,6,6\n7,5,3\n8,18,8\n3,14,9\n10,16,6\n12,12,17\n12,13,14\n4,13,6\n5,8,3\n5,12,17\n8,17,8\n8,11,18\n2,9,13\n3,6,7\n8,11,16\n12,5,15\n4,4,8\n5,16,11\n10,17,5\n6,5,15\n13,10,16\n12,3,13\n6,9,2\n1,12,10\n8,4,4\n11,12,2\n4,9,3\n14,6,15\n15,4,13\n9,6,1\n3,5,12\n10,10,18\n6,1,10\n3,7,13\n18,11,10\n6,18,11\n17,13,8\n5,6,16\n10,17,10\n5,13,6\n16,11,5\n16,8,8\n10,6,4\n12,9,3\n14,7,4\n15,3,12\n4,5,12\n3,10,14\n4,6,12\n16,9,7\n15,13,5\n9,4,4\n7,15,5\n18,9,12\n16,7,3\n15,14,14\n3,7,14\n17,9,9\n9,16,8\n2,7,8\n9,4,15\n8,5,14\n13,13,17\n12,7,3\n13,7,15\n5,5,15\n14,7,16\n14,13,15\n6,5,5\n7,12,17\n17,9,7\n9,5,1\n6,12,4\n14,12,14\n4,4,7\n10,8,2\n17,9,6\n5,4,5\n7,6,5\n3,13,7\n16,10,11\n18,8,10\n17,7,9\n3,10,12\n17,10,6\n8,5,17\n5,11,17\n2,8,13\n4,12,4\n13,17,6\n12,14,16\n8,5,15\n12,15,14\n16,10,5\n5,5,5\n3,8,6\n15,10,8\n9,6,17\n17,11,6\n5,6,10\n7,16,10\n4,6,5\n14,14,14\n6,8,16\n17,6,11\n9,15,14\n5,14,15\n9,8,17\n14,3,12\n10,1,11\n13,12,3\n7,6,3\n16,11,13\n10,17,7\n3,5,10\n4,13,13\n5,6,4\n5,14,5\n16,7,11\n15,3,9\n16,14,5\n4,8,6\n12,2,8\n9,4,5\n7,11,2\n16,6,11\n9,8,1\n8,12,16\n12,4,14\n7,9,3\n10,4,5\n3,6,13\n5,4,12\n14,16,11\n10,17,13\n15,5,14\n6,4,6\n5,17,9\n12,10,2\n4,2,9\n13,5,3\n15,14,10\n10,5,3\n8,2,7\n3,7,11\n8,15,4\n9,15,4\n9,16,16\n11,8,18\n2,13,13\n5,5,14\n9,17,6\n4,4,11\n14,8,16\n14,14,3\n9,17,13\n16,8,11\n13,6,16\n9,9,18\n15,15,10\n6,10,2\n5,5,12\n6,4,15\n2,5,7\n10,18,9\n5,15,15\n10,1,7\n17,13,13\n6,17,13\n7,12,2\n14,7,3\n10,11,17\n16,12,14\n14,14,13\n2,10,12\n5,10,3\n13,16,13\n4,4,9\n9,17,11\n5,13,14\n7,2,8\n14,15,7\n7,3,5\n10,3,14\n17,6,9\n5,4,11\n17,8,11\n10,9,18\n13,15,7\n10,13,3\n8,3,7\n5,8,16\n5,16,5\n13,11,15\n6,11,16\n2,7,6\n17,11,9\n10,6,16\n5,3,8\n15,13,4\n4,9,15\n12,15,7\n11,3,9\n12,1,8\n14,10,4\n6,2,7\n13,16,12\n2,7,5\n1,8,10\n6,6,16\n12,17,11\n10,14,4\n12,13,4\n10,2,6\n13,14,14\n3,12,7\n15,13,9\n12,12,3\n10,2,10\n9,18,7\n10,15,6\n14,17,12\n6,8,8\n14,14,4\n9,15,7\n4,6,6\n5,7,15\n12,16,11\n5,17,13\n13,17,10\n8,1,10\n13,6,4\n6,17,7\n4,3,7\n2,5,6\n11,19,11\n12,16,7\n2,7,7\n6,5,16\n7,11,16\n7,16,8\n9,15,16\n5,6,14\n15,10,3\n2,5,11\n13,3,12\n9,5,17\n8,3,14\n5,9,17\n17,10,14\n7,11,15\n8,3,12\n10,5,2\n7,3,13\n15,6,5\n5,7,2\n10,10,3\n14,2,12\n9,16,14\n15,12,16\n7,4,4\n7,14,3\n5,9,3\n8,11,2\n16,5,13\n10,4,4\n7,9,16\n10,2,13\n17,15,7\n5,13,4\n11,2,8\n1,10,7\n5,14,14\n17,6,10\n14,15,15\n14,9,2\n12,3,6\n11,18,8\n17,10,13\n15,6,13\n8,17,11\n3,4,6\n17,9,8\n6,3,6\n8,15,8\n17,8,8\n15,5,5\n12,4,8\n7,6,16\n2,11,12\n9,17,8\n12,14,5\n2,11,7\n14,6,4\n13,12,17\n6,16,15\n11,9,2\n7,15,15\n9,12,1\n2,9,5\n10,9,17\n1,9,7\n2,13,9\n4,10,15\n16,14,13\n15,10,5\n14,15,6\n7,14,11\n2,8,7\n8,4,16\n10,6,1\n1,8,9\n4,14,4\n13,4,6\n8,2,14\n6,10,16\n8,18,9\n9,14,4\n7,17,6\n3,5,13\n13,12,16\n9,6,16\n3,11,5\n9,12,15\n3,10,5\n5,15,14\n17,7,14\n6,4,5\n5,9,16\n6,14,3\n1,11,11\n14,11,3\n8,14,15\n2,8,9\n17,8,9\n11,14,15\n18,8,11\n10,2,9\n14,4,14\n14,5,6\n7,10,17\n3,12,8\n16,4,10\n4,8,8\n9,5,4\n16,12,12\n14,9,4\n3,11,7\n10,12,2\n4,9,12\n8,3,5\n11,14,4\n15,6,4\n7,16,12\n11,17,7\n11,17,8\n15,14,13\n14,16,13\n13,6,17\n6,16,9\n14,16,10\n11,15,13\n3,11,16\n15,6,14\n13,8,16\n3,6,6\n16,9,6\n14,13,4\n16,5,11\n4,11,13\n9,15,3\n5,10,7\n8,16,8\n15,5,15\n7,13,3\n8,12,3\n7,10,2\n3,9,15\n8,7,2\n17,9,10\n11,3,10\n9,3,14\n12,7,18\n4,6,13\n4,12,3\n11,10,2\n11,1,9\n15,13,6\n7,18,10\n4,14,11\n10,16,10\n10,3,13\n8,16,6\n11,1,8\n5,15,11\n5,9,4\n8,6,3\n8,10,2\n11,5,7\n10,2,12\n9,12,3\n15,14,7\n4,6,10\n5,11,15\n14,4,7\n2,12,12\n8,17,7\n14,17,11\n1,7,10\n4,5,13\n7,3,4\n15,5,11\n7,2,11\n9,18,8\n14,9,3\n15,13,7\n17,7,11\n10,13,17\n10,10,17\n16,13,7\n16,14,7\n5,17,11\n7,11,17\n3,13,4\n15,12,4\n4,14,7\n14,16,5\n7,4,12\n14,5,15\n2,12,13\n5,4,4\n13,10,17\n15,14,8\n12,6,14\n5,15,5\n12,4,7\n3,5,6\n13,5,4\n13,13,4\n10,8,1\n6,13,3\n2,10,6\n9,16,5\n10,12,17\n3,9,10\n11,3,5\n11,1,12\n10,4,3\n8,2,9\n9,13,16\n11,5,16\n17,8,6\n5,8,2\n9,11,18\n15,8,16\n10,16,7\n6,4,8\n15,4,7\n9,12,2\n16,7,13\n12,6,16\n7,13,2\n11,5,15\n6,13,17\n2,14,8\n9,17,14\n6,3,11\n17,13,10\n3,9,14\n12,4,15\n14,10,3\n8,10,16\n13,3,7\n7,12,15\n8,17,13\n9,10,1\n17,8,7\n5,14,6\n4,9,4\n13,7,2\n7,14,4\n7,16,13\n3,12,11\n12,4,9\n8,8,1\n7,4,16\n9,7,18\n16,13,9\n13,7,16\n5,15,13\n6,2,10\n9,7,3\n17,7,10\n7,7,18\n15,12,6\n12,10,3\n15,5,13\n5,12,2\n15,6,15\n14,8,3\n12,18,9\n2,12,11\n5,16,13\n6,3,9\n4,4,12\n6,13,16\n14,4,9\n16,4,11\n2,7,10\n8,17,9\n13,6,15\n13,5,6\n6,5,4\n9,2,11\n9,8,2\n2,13,8\n15,16,10\n4,8,14\n7,13,5\n7,1,10\n18,11,11\n11,3,7\n14,5,5\n8,2,6\n16,14,6\n13,5,5\n5,12,3\n8,2,10\n18,10,8\n16,14,14\n13,17,9\n3,9,12\n7,13,4\n3,8,14\n14,8,17\n16,4,9\n3,10,4\n1,7,8\n11,15,15\n8,12,13\n2,8,5\n1,9,8\n4,17,9\n15,9,17\n6,6,5\n11,10,18\n16,12,7\n15,17,8\n1,8,6\n12,9,2\n3,4,7\n14,13,16\n14,15,8\n15,14,5\n4,9,8\n5,17,10\n12,7,2\n16,9,8\n4,11,14\n16,9,4\n4,15,11\n13,3,11\n13,8,2\n7,7,4\n13,6,2\n17,8,14\n17,12,12\n4,9,14\n16,13,11\n16,16,11\n17,11,7\n10,2,4\n13,13,3\n5,12,4\n6,11,2\n17,9,5\n13,14,7\n11,15,3\n13,16,11\n5,10,2\n8,13,2\n4,15,6\n18,9,6\n17,13,9\n14,15,12\n15,7,4\n14,13,11\n14,12,15\n12,11,15\n9,15,15\n16,12,11\n4,16,11\n14,4,12\n12,16,6\n4,8,16\n12,12,2\n10,3,5\n16,6,7\n13,3,8\n15,12,12\n16,16,6\n8,4,5\n12,15,11\n14,15,13\n16,4,7\n4,5,8\n3,3,7\n10,15,4\n12,16,10\n4,14,13\n3,11,13\n13,6,14\n13,16,6\n2,9,9\n4,9,16\n5,11,4\n8,4,14\n5,12,14\n10,16,5\n7,8,2\n17,14,10\n14,3,6\n17,15,10\n4,14,9\n11,7,1\n3,14,6\n10,14,15\n12,6,17\n9,2,8\n17,7,7\n17,14,6\n15,8,5\n7,7,5\n9,0,11\n4,3,10\n10,13,16\n9,17,10\n2,10,7\n16,8,13\n14,3,10\n9,14,3\n14,9,16\n11,10,3\n9,14,15\n5,16,6\n15,9,16\n2,15,9\n12,10,17\n13,16,7\n15,3,8\n16,7,6\n3,9,5\n13,3,14\n13,14,5\n3,8,16\n6,8,17\n3,10,16\n13,7,4\n13,15,14\n15,6,7\n2,10,9\n11,0,9\n16,5,8\n14,15,10\n6,10,15\n16,6,13\n3,15,13\n3,5,11\n14,4,15\n4,6,11\n5,5,16\n13,10,2\n3,5,9\n14,12,3\n5,4,14\n10,5,16\n6,13,15\n12,5,3\n5,5,3\n14,14,6\n9,8,16\n13,4,4\n3,14,12\n4,7,5\n12,13,2\n7,5,4\n13,14,16\n16,4,8\n6,2,6\n16,11,14\n15,15,14\n9,11,17\n11,15,5\n2,14,9\n16,14,8\n12,15,15\n14,9,17\n13,5,13\n11,1,11\n18,11,9\n12,4,5\n16,13,13\n8,14,16\n7,15,14\n3,14,13\n16,9,11\n11,15,4\n3,6,10\n15,12,7\n5,14,13\n3,7,12\n10,3,9\n8,2,12\n15,15,12\n10,16,4\n16,8,12\n15,15,13\n17,6,8\n13,3,13\n11,16,6\n10,9,1\n12,12,18\n5,12,13\n9,10,3\n3,11,6\n16,14,9\n7,15,16\n14,3,9\n13,2,8\n10,16,13\n12,16,5\n14,5,4\n11,17,13\n4,11,15\n2,7,11\n13,5,11\n6,4,10\n12,17,12\n10,14,16\n10,17,9\n1,10,11\n17,10,8\n9,7,2\n10,6,2\n4,15,9\n17,12,15\n9,17,12\n15,9,4\n6,15,6\n12,4,13\n10,2,11\n15,4,4\n4,8,4\n6,17,11\n6,3,7\n12,4,3\n16,4,6\n9,1,11\n9,3,4\n9,1,9\n14,6,13\n8,16,11\n7,8,4\n9,16,12\n11,2,13\n11,3,14\n6,4,13\n16,15,8\n13,1,9\n5,14,16\n6,10,3\n6,16,10\n12,4,12\n5,10,4\n9,11,2\n11,6,5\n11,16,14\n9,5,5\n12,3,9\n10,3,15\n14,8,13\n10,17,11\n16,7,5\n14,16,7\n12,14,15\n5,15,8\n17,13,6\n12,17,9\n5,12,12\n13,12,2\n10,3,12\n7,17,11\n6,3,14\n10,5,1\n9,18,12\n5,16,10\n4,4,5\n11,18,14\n8,8,18\n2,5,8\n7,8,17\n7,17,10\n7,3,7\n14,8,2\n16,6,9\n14,3,8\n8,10,3\n1,12,11\n15,4,5\n11,18,11\n3,10,9\n12,15,16\n7,13,16\n14,11,15\n8,15,3\n3,8,7\n16,12,13\n3,12,15\n10,15,14\n12,6,4\n11,6,3\n2,6,7\n2,8,8\n8,5,3\n17,10,12\n8,16,13\n5,15,6\n13,16,9\n7,3,6\n10,6,15\n3,14,10\n11,2,7\n1,8,12\n14,13,5\n7,13,17\n9,2,9\n11,7,3\n11,2,6\n2,9,12\n6,16,7\n8,13,15\n15,5,6\n4,3,12\n9,6,12\n7,2,13\n16,4,12\n3,4,10\n3,12,9\n10,16,8\n8,1,12\n11,17,6\n14,8,4\n14,15,9\n7,3,9\n17,9,12\n8,9,3\n16,10,15\n15,6,11\n2,10,14\n11,6,14\n14,6,14\n11,13,3\n16,9,13\n11,4,5\n17,8,12\n3,9,6\n15,4,12\n10,17,8\n5,10,17\n8,7,16\n6,8,2\n16,10,8\n13,11,17\n13,10,3\n2,11,4\n12,17,13\n13,4,12\n13,17,7\n14,11,13\n9,6,3\n15,15,6\n4,3,13\n13,2,12\n11,11,17\n14,13,14\n13,6,3\n14,6,5\n17,14,8\n9,12,17\n15,14,6\n7,3,10\n16,13,12\n12,10,15\n7,4,15\n9,10,18\n8,1,11\n7,8,18\n8,3,11\n11,8,17\n5,3,6\n16,11,9\n17,12,7\n11,16,15\n15,15,8\n5,4,8\n6,11,15\n15,6,8\n7,11,3\n5,15,12\n4,7,11\n5,15,10\n10,18,11\n17,10,5\n4,14,14\n3,12,12\n2,6,9\n13,5,14\n16,13,10\n8,16,10\n13,3,15\n16,9,12\n4,15,7\n11,3,11\n15,14,11\n10,13,4\n13,18,9\n13,9,4\n6,16,12\n16,12,5\n15,11,6\n3,8,13\n11,1,10\n15,7,5\n15,4,9\n10,5,15\n8,6,2\n12,9,18\n10,3,6\n17,12,11\n9,6,18\n11,4,14\n14,8,15\n8,2,8\n4,7,16\n2,10,4\n8,5,16\n4,14,6\n8,14,3\n14,13,3\n2,10,13\n12,4,11\n13,4,14\n2,9,10\n9,17,7\n12,17,10\n3,7,5\n11,2,14\n12,15,5\n7,8,1\n7,3,11\n17,7,6\n14,4,11\n7,12,16\n15,5,12\n6,16,11\n6,6,4\n8,15,5\n7,2,7\n9,10,17\n14,2,10\n11,8,4\n3,11,12\n6,9,16\n15,7,3\n3,15,10\n3,8,5\n12,10,16\n8,8,2\n12,13,3\n6,15,12\n11,5,3\n16,6,6\n4,5,9\n5,13,15\n18,9,10\n15,13,13\n6,2,11\n6,16,6\n13,8,3\n9,5,3\n10,12,16\n1,10,9\n15,5,10\n13,4,11\n4,7,4\n12,3,14\n11,9,16\n10,14,3\n2,10,8\n9,16,6\n13,16,10\n17,10,7\n10,16,14\n13,13,5\n3,12,5\n4,14,10\n3,12,13\n6,14,8\n13,4,7\n5,6,9\n14,4,5\n11,13,15\n16,15,10\n7,17,8\n18,9,8\n12,11,16\n16,14,10\n12,4,16\n10,12,14\n7,3,12\n8,11,3\n4,3,9\n10,6,3\n11,16,4\n14,12,6\n7,5,6\n12,3,7\n13,13,15\n13,15,15\n3,8,3\n13,10,4\n14,13,6\n12,3,5\n7,7,16\n17,14,9\n13,15,4\n16,6,12\n6,14,4\n12,6,15\n10,1,9\n7,8,16\n4,15,10\n14,12,11\n8,9,16\n2,13,7\n13,14,3\n6,12,3\n16,12,9\n17,5,8\n5,7,8\n11,2,11\n10,9,4\n8,2,11\n11,15,14\n6,18,12\n16,12,4\n3,6,12\n7,14,16\n3,5,7\n5,2,10\n4,12,14\n15,11,3\n15,7,14\n10,17,14\n12,2,6\n3,13,11\n2,8,10\n18,14,9\n2,6,6\n2,5,9\n5,8,5\n15,15,11\n11,18,10\n13,5,16\n9,9,2\n15,7,16\n7,6,17\n12,11,2\n2,12,14\n10,18,7\n8,5,2\n11,9,1\n11,8,2\n6,9,3\n15,2,9\n6,17,8\n4,7,3\n10,3,7\n2,12,10\n2,6,13\n7,9,1\n6,15,14\n8,10,1\n11,16,5\n5,15,7\n9,2,13\n18,8,8\n17,13,12\n16,9,15\n17,10,10\n14,5,3\n13,15,13\n14,10,1\n7,9,17\n13,16,8\n4,15,8\n17,11,13\n10,17,15\n3,6,5\n13,6,6\n4,8,15\n5,5,6\n12,5,14\n6,8,18\n12,2,9\n16,6,5\n10,7,16\n3,10,7\n13,13,14\n18,12,8\n13,8,15\n6,2,12\n14,15,14\n4,13,8\n15,5,9\n4,12,6\n2,8,14\n2,12,9\n4,12,12\n3,14,5\n7,5,10\n11,4,15\n6,13,2\n9,1,13\n14,7,12\n2,11,13\n6,3,12\n11,7,5\n14,13,13\n7,10,18\n13,11,16\n18,10,7\n6,15,8\n10,7,2\n6,15,16\n15,13,11\n6,4,14\n15,8,3\n7,16,7\n1,10,10\n9,13,1\n4,11,8\n12,2,10\n9,12,18\n7,5,17\n3,13,13\n5,13,5\n15,7,15\n6,14,13\n9,16,11\n8,3,15\n6,15,11\n12,13,15\n12,12,16\n7,6,15\n4,15,13\n11,18,7\n18,10,9\n11,16,9\n15,5,7\n9,1,7\n5,5,4\n10,1,10\n8,13,17\n13,17,11\n10,4,14\n10,10,1\n9,16,15\n13,4,15\n16,15,11\n7,2,5\n8,11,1\n12,3,11\n16,10,6\n12,3,4\n13,16,5\n16,12,6\n7,14,15\n9,1,14\n6,11,5\n4,10,14\n11,15,17\n3,10,8\n11,17,10\n12,5,13\n17,8,5\n2,11,6\n2,9,8\n4,9,13\n13,9,17\n9,7,1\n4,13,4\n3,9,8\n16,8,6\n16,11,6\n12,8,3\n13,13,16\n13,6,5\n13,11,4\n15,12,8\n16,11,11\n6,14,14\n12,17,6\n17,10,11\n15,3,10\n13,7,3\n4,8,13\n9,3,12\n16,5,12\n14,11,6\n9,13,17\n15,4,10\n14,15,11\n14,11,16\n7,2,6\n12,14,17\n8,14,4\n5,16,9\n7,16,6\n10,13,15\n15,10,15\n16,11,7\n8,8,4\n10,15,16\n14,14,15\n7,5,14\n0,9,8\n13,9,16\n7,12,3\n16,12,15\n9,13,3\n16,3,12\n4,10,13\n15,11,14\n18,8,12\n3,5,14\n7,17,14\n14,12,5\n8,17,6\n16,10,9\n8,18,10\n4,14,12\n14,5,10\n11,6,16\n7,8,3\n12,6,3\n16,13,6\n10,7,1\n17,6,6\n15,17,9\n14,16,8\n4,6,8\n3,10,6\n8,11,17\n4,16,8\n5,3,10\n4,16,7\n6,11,4\n9,9,19\n6,4,7\n18,10,6\n15,15,9\n8,12,2\n12,2,13\n8,13,1\n3,4,11\n8,9,18\n5,4,7\n14,6,8\n10,2,15\n8,17,10\n7,5,2\n9,4,14\n6,5,3\n14,8,6\n3,13,14\n2,11,9\n6,5,14\n6,15,5\n6,14,5\n4,13,5\n7,17,12\n3,13,9\n14,14,11\n11,4,13\n3,12,6\n11,17,14\n2,13,10\n15,13,10\n12,1,12\n12,7,1\n15,10,16\n13,12,4\n16,3,10\n7,4,6\n2,9,6\n5,9,2\n13,4,10\n5,13,7\n3,7,9\n7,3,8\n3,11,14\n16,5,9\n5,4,13\n11,14,16\n7,8,15\n5,14,11\n12,2,14\n0,8,11\n8,13,3\n13,5,15\n10,18,10\n11,3,6\n4,7,15\n3,16,9\n4,4,13\n9,7,16\n8,3,4\n11,1,5\n6,10,17\n10,15,12\n4,16,12\n7,4,5\n1,10,6\n12,17,14\n6,16,4\n4,7,9\n2,9,7\n8,15,16\n5,3,7\n14,16,12\n4,11,17\n10,10,16\n12,9,17\n6,7,2\n8,9,17\n12,15,4\n11,18,12\n9,16,13\n6,13,5\n6,17,9\n1,10,8\n5,16,8\n2,7,12\n15,12,9\n13,14,13\n5,10,16\n11,8,16\n15,4,6\n12,14,12\n15,10,4\n5,7,3\n15,9,2\n8,17,5\n1,11,12\n18,6,9\n11,12,17\n2,12,4\n4,9,5\n5,14,4\n11,4,17\n11,4,4\n13,17,8\n11,14,2\n11,4,16\n11,10,1\n10,12,18\n5,10,5\n11,11,3\n9,8,18\n16,5,5\n9,5,15\n10,6,5\n13,11,3\n12,8,17\n16,8,15\n9,8,3\n16,5,10\n6,8,5\n12,1,11\n14,5,8\n9,11,16\n12,9,16\n9,7,17\n5,17,12\n12,7,17\n10,9,2\n19,9,9\n13,13,2\n6,14,15\n2,8,11\n15,12,3\n8,4,6\n3,8,9\n4,7,14\n8,2,13\n9,1,12\n13,2,6\n6,16,14\n13,3,9\n7,16,14\n14,6,12\n5,12,16\n12,13,17\n12,5,12\n13,11,14\n14,12,2\n4,5,5\n18,13,9\n3,5,8\n7,10,4\n15,5,4\n11,15,7\n17,7,13\n1,11,10\n18,12,10\n12,17,8\n5,17,8\n3,10,13\n4,10,3\n6,9,14\n15,12,15\n7,16,5\n6,3,13\n17,14,12\n9,3,16\n4,9,6\n5,3,13\n1,10,12\n15,12,17\n3,7,8\n12,11,1\n7,14,5\n14,16,6\n14,17,9\n4,8,3\n14,15,4\n6,6,14\n18,8,9\n5,2,9\n16,10,12\n10,5,17\n14,4,13\n2,7,9\n15,14,15\n5,8,15\n5,5,11\n7,1,9\n15,3,13\n15,12,5\n3,7,7\n15,11,5\n13,9,18\n8,6,15\n11,12,16\n13,8,13\n5,4,15\n15,10,6\n2,10,10\n18,7,6\n13,17,12\n16,10,10\n15,12,14\n2,9,4\n14,4,8\n7,1,7\n16,11,15\n6,6,18\n11,5,4\n9,3,6\n17,7,5\n16,15,13\n19,10,10\n3,12,10\n11,13,16\n12,11,3\n4,7,17\n5,4,9\n4,10,16\n9,19,8\n13,1,10\n15,4,11\n2,8,12\n8,13,4\n12,9,4\n12,10,18\n10,1,6\n4,10,12\n3,11,9\n5,12,15\n4,4,6\n6,4,4\n7,7,17\n12,8,16\n17,11,11\n9,5,7\n7,5,5\n9,4,16\n16,13,8\n8,8,3\n11,5,2\n13,2,11\n11,10,15\n8,10,17\n6,13,4\n14,14,5\n15,7,6\n16,16,7\n8,6,17\n8,5,6\n2,4,9\n14,6,16\n5,6,5\n4,6,9\n16,7,8\n4,13,3\n15,11,4\n11,7,16\n16,8,5\n5,4,10\n5,11,3\n17,13,7\n13,14,15\n5,6,15\n9,4,6\n16,7,15\n16,11,12\n10,17,12\n6,8,3\n4,5,6\n13,3,10\n8,15,17\n3,15,9\n1,7,9\n5,10,14\n17,5,9\n14,7,2\n5,9,12\n15,15,5\n4,3,8\n13,12,5\n14,14,12\n4,12,5\n9,16,9\n13,16,14\n11,6,17\n5,16,12\n4,13,7\n2,5,12\n17,11,12\n2,8,6\n12,7,14\n7,16,9\n11,16,7\n17,11,8\n3,3,10\n8,15,13\n12,16,8\n11,17,9\n6,9,1\n10,7,17\n2,6,8\n11,10,17\n16,12,10\n14,13,12\n1,10,5\n8,7,3\n14,3,7\n6,7,16\n7,5,15\n0,11,12\n7,2,9\n10,18,8\n14,7,5\n15,8,6\n7,1,11\n8,1,9\n10,11,16\n9,1,10\n16,5,6\n12,3,8\n1,12,7\n2,11,10\n18,12,9\n13,15,10\n11,16,10\n5,9,5\n10,11,3\n18,13,10\n13,11,2\n2,14,10\n11,5,18\n10,8,3\n11,7,18\n17,14,11\n10,15,3\n10,4,16\n1,11,9\n8,1,8\n13,13,12\n16,5,4\n8,8,16\n7,13,14\n9,17,5\n4,7,7\n17,11,3\n2,6,12\n3,14,7\n6,7,3\n9,17,9\n12,8,18\n16,11,4\n10,17,6\n3,4,8\n7,14,13\n6,17,10\n5,11,16\n11,8,1\n6,2,8\n16,16,9\n4,7,6\n10,2,7\n18,11,7\n11,6,18\n15,11,2\n4,6,15\n12,10,5\n3,9,7\n13,3,6\n10,4,15\n16,6,8\n3,13,5\n5,16,7\n12,15,10\n18,12,7\n17,8,13\n3,14,8\n14,14,8\n4,3,11\n9,16,7\n6,10,1\n10,3,10\n8,16,9\n11,7,4\n9,3,5\n7,1,13\n13,15,6\n13,15,11\n8,16,4\n16,6,4\n7,15,4\n8,2,5\n4,12,15\n9,9,16\n14,2,7\n6,5,6\n8,12,17\n13,15,5\n8,18,12\n7,7,3\n13,12,15\n3,4,9\n6,12,17\n17,6,7\n6,6,15\n17,13,11\n11,8,14\n7,6,18\n15,14,4\n15,13,12\n4,5,10\n4,11,16\n11,4,3\n16,14,11\n1,9,12\n7,17,13\n9,3,15\n14,5,2\n13,7,14\n14,2,6\n9,15,11\n7,15,11\n16,12,8\n15,11,11\n15,9,13\n7,9,19\n12,6,5\n4,5,14\n13,8,17\n11,14,3\n13,15,16\n6,3,15\n9,12,16\n2,12,8\n15,7,10\n13,2,7\n4,10,7\n17,6,13\n13,15,12\n4,6,7\n11,5,14\n10,15,5\n15,16,11\n9,13,2\n9,2,14\n2,14,12\n10,16,17\n9,14,17\n10,3,8\n10,16,15\n15,9,3\n5,5,8\n16,7,9\n3,15,8\n9,16,10\n17,6,12\n1,6,11\n5,9,15\n7,11,18\n18,6,7\n7,15,13\n9,13,4\n10,8,18\n1,9,10\n4,6,3\n7,2,10\n11,9,17\n16,6,14\n18,9,9\n1,12,9\n3,6,9\n3,6,14\n12,11,18\n12,12,15\n13,4,3\n16,8,9\n14,11,11\n3,8,15\n5,14,12\n6,7,14\n13,5,9\n15,14,12\n7,2,12\n4,13,12\n6,5,12\n3,9,13\n17,8,10\n17,7,12\n9,2,10\n12,18,11\n12,8,15\n2,12,5\n7,15,6\n17,12,13\n5,9,14\n2,11,8\n6,5,8\n14,16,14\n16,10,13\n5,12,6\n18,11,8\n4,4,14\n5,4,6\n15,11,16\n15,13,14\n4,5,11\n10,4,6\n11,11,2\n9,18,9\n9,9,17\n14,7,13\n8,7,1\n4,13,14\n6,15,3\n8,15,14\n11,14,5\n15,15,7\n15,11,15\n7,10,16\n14,10,17\n2,10,5\n3,13,12\n6,7,15\n9,5,2\n12,2,12\n7,9,18\n4,8,5\n8,5,7\n7,9,4\n7,14,10\n14,11,4\n10,6,17\n8,15,10\n13,5,2\n9,10,2\n8,16,15\n11,12,18\n8,4,12\n5,7,4\n2,12,6\n6,15,13\n15,7,9\n5,14,8\n8,13,16\n12,13,16\n12,4,6\n9,2,7\n16,14,12\n11,17,12\n16,7,7\n1,13,9\n12,9,15\n10,7,18\n8,14,13\n4,16,13\n7,15,8\n4,16,10\n14,5,13\n10,4,13\n13,16,4\n8,12,4\n11,4,6\n14,6,6\n6,3,5\n3,9,4\n12,8,4\n14,5,7\n13,7,17\n4,12,16\n16,8,3\n12,10,1\n6,14,16\n10,13,2\n10,7,3\n8,3,6\n10,11,1\n9,11,1\n7,4,7\n15,6,12\n6,6,3\n4,13,16\n14,3,11\n8,16,5\n13,1,11\n7,3,15\n3,13,8\n13,15,9\n6,16,13\n4,10,8\n15,14,9\n4,6,16\n1,13,10\n6,3,10\n6,12,14\n6,3,4\n9,10,16\n18,11,12\n1,8,7\n2,13,12\n16,7,14\n12,14,14\n9,15,17\n8,9,2\n12,7,4\n8,4,3\n5,15,9\n16,13,14\n15,12,13\n15,12,11\n11,3,12\n13,9,15\n8,3,9\n6,6,2\n18,7,11\n7,16,4\n16,7,12\n7,17,4\n5,8,13\n13,7,7\n14,14,7\n7,15,3\n10,2,14\n1,13,8\n3,8,11\n15,8,12\n14,14,10\n14,10,16\n5,11,2\n14,6,10\n15,8,14\n3,7,16\n14,10,12\n4,11,4\n17,6,5\n13,18,10\n13,4,9\n7,9,2\n10,9,16\n6,6,13\n10,10,2\n14,3,13\n4,12,13\n11,15,10\n11,3,8\n11,4,7\n4,7,13\n2,11,15\n6,7,4\n6,5,11\n1,9,11\n2,6,10\n8,12,1\n7,2,14\n5,14,3\n17,7,8\n6,16,8\n16,10,7\n18,6,10\n12,2,7\n15,3,11\n16,5,7\n4,13,11\n13,5,7\n6,9,17\n2,7,14\n8,7,5\n13,2,10\n10,15,11\n6,17,6\n17,12,9\n15,7,7\n13,9,2\n12,7,15\n12,15,13\n1,6,10\n15,16,9\n6,15,10\n7,16,15\n13,4,5\n14,15,5\n3,9,16\n11,15,16\n6,8,4\n18,10,12\n17,12,6\n12,2,5\n18,13,11\n11,6,2\n15,10,13\n12,2,11\n11,14,14\n10,7,4\n12,14,9\n10,2,5\n14,10,5\n5,13,3\n12,3,12\n8,16,14\n8,3,8\n14,16,9\n4,12,10\n8,13,14\n12,3,10\n3,14,4\n0,9,11\n3,13,6\n16,8,10\n11,9,18\n18,12,11\n14,12,7\n9,15,12\n15,8,2\n7,4,3\n4,10,10\n12,8,1\n3,12,4\n15,2,7\n9,13,14\n14,2,11\n16,10,4\n12,15,6\n1,10,13\n15,6,10\n3,11,3\n8,8,5\n17,4,12\n3,14,14\n3,11,11\n16,10,14\n13,14,4\n8,6,16\n9,7,5\n15,13,8\n8,15,15\n10,12,1\n11,2,9\n10,12,4\n5,8,14\n17,11,4\n12,8,2\n12,1,7\n9,16,3\n11,18,9\n8,16,12\n15,10,7\n9,18,10\n10,8,16\n14,10,2\n11,13,18\n6,5,7\n2,14,11\n7,11,14\n10,5,14\n6,8,15\n6,15,7\n9,6,15\n18,10,10\n8,14,2\n9,2,6\n9,9,1\n1,11,7\n15,9,6\n6,12,15\n17,15,11\n7,13,15\n10,3,11\n9,4,3\n5,13,16\n15,11,12\n17,14,13\n5,5,7\n3,3,8\n9,19,10\n5,17,7\n1,8,11\n9,19,9\n11,11,18\n14,14,9\n5,8,9\n3,3,9\n7,15,7\n15,10,17\n14,2,8\n10,11,18\n9,15,10\n18,6,11\n3,8,4\n8,6,4\n9,16,4\n9,2,5\n13,16,15\n4,10,4\n5,8,17\n8,14,5\n5,16,14\n8,12,18\n9,15,5\n6,7,17\n6,11,17\n4,3,5\n14,3,14\n5,1,11\n14,12,17\n12,13,12\n5,8,4\n16,9,17\n1,8,8\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_18_questions.txt",
    "content": "--- Day 18: Boiling Boulders ---\n\nYou and the elephants finally reach fresh air.\nYou've emerged near the base of a large volcano that seems\nto be actively erupting! Fortunately, the lava seems to be\nflowing away from you and toward the ocean.\n\nBits of lava are still being ejected toward you, so you're sheltering\nin the cavern exit a little longer. Outside the cave, you can see the\nlava landing in a pond and hear it loudly hissing as it solidifies.\n\nDepending on the specific compounds in the lava and speed at which it\ncools, it might be forming obsidian! The cooling rate should be based\non the surface area of the lava droplets, so you take a quick scan of\na droplet as it flies past you (your puzzle input).\n\nBecause of how quickly the lava is moving, the scan isn't very good;\nits resolution is quite low and, as a result, it approximates the shape\nof the lava droplet with 1x1x1 cubes on a 3D grid, each given as its\nx,y,z position.\n\nTo approximate the surface area, count the number of sides of each\ncube that are not immediately connected to another cube.\nSo, if your scan were only two adjacent cubes like 1,1,1 and 2,1,1,\neach cube would have a single side covered and five sides exposed,\na total surface area of 10 sides.\n\nHere's a larger example:\n\n2,2,2\n1,2,2\n3,2,2\n2,1,2\n2,3,2\n2,2,1\n2,2,3\n2,2,4\n2,2,6\n1,2,5\n3,2,5\n2,1,5\n2,3,5\n\nIn the above example, after counting up all the sides that aren't\nconnected to another cube, the total surface area is 64.\n\nWhat is the surface area of your scanned lava droplet?\n\n--- Part Two ---\n\nSomething seems off about your calculation.\nThe cooling rate depends on exterior surface area,\nbut your calculation also included the surface area\nof air pockets trapped in the lava droplet.\n\nInstead, consider only cube sides that could be reached\nby the water and steam as the lava droplet tumbles into the pond.\nThe steam will expand to reach as much as possible, completely\ndisplacing any air on the outside of the lava droplet\nbut never expanding diagonally.\n\nIn the larger example above, exactly one cube of air is\ntrapped within the lava droplet (at 2,2,5), so the exterior\nsurface area of the lava droplet is 58.\n\nWhat is the exterior surface area of your scanned lava droplet?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_19.adb",
    "content": "--  Solution to Advent of Code 2022, Day 19\n-------------------------------------------\n--  Not Enough Minerals\n--\n--  https://adventofcode.com/2022/day/19\n--  Copy of questions in: aoc_2022_19_questions.txt\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  Note: this solution takes a large amount of time\n--  with GNAT and an even larger one with HAC.\n--  See AoC_2022_19_Full_Ada for a fast solution.\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\nprocedure AoC_2022_19 is\n  use AoC_Toolbox, HAT;\n\n  verbosity_level : constant Natural := 1;\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\n  f : File_Type;\n\n  --  Parseable copy of the example (part after column with '|'):\n  --\n  --  |Blueprint 1:\n  --  | Each ore robot costs 4 ore.\n  --  | Each clay robot costs 2 ore.\n  --  | Each obsidian robot costs 3 ore and 14 clay.\n  --  | Each geode robot costs 2 ore and 7 obsidian.\n  --  |\n  --  |Blueprint 2:\n  --  | Each ore robot costs 2 ore.\n  --  | Each clay robot costs 3 ore.\n  --  | Each obsidian robot costs 3 ore and 8 clay.\n  --  | Each geode robot costs 3 ore and 12 obsidian.\n\n  type Resource_Type is (ore, clay, obsidian, geode);\n\n  type Portfolio_Type is array (Resource_Type) of Natural;\n\n  type State_Type is record\n    resource : Portfolio_Type;\n    robot    : Portfolio_Type;\n  end record;\n\n  subtype Cost_Type is Portfolio_Type;\n\n  --  Costs of a robot producing a certain resource.\n  type Blueprint_Type is array (Resource_Type) of Cost_Type;\n\n  function Best_Geode_Opening\n    (blueprint : Blueprint_Type; total_time : Positive) return Natural\n  is\n    initial : State_Type;\n\n    obsidian_cost_geode_robot, clay_cost_obsidian_robot : Positive;\n\n    greedy : constant Boolean := True;\n\n    procedure Visit (state : State_Type; time_left : Natural; geodes : out Natural) is\n      robot_creation_possible, any_possible : Boolean;\n      score_build_robot : array (Resource_Type) of Natural;\n      score_same_robots : Natural;\n      new_state : State_Type;\n      result : Natural;\n    begin\n      case time_left is\n        when 0 =>\n          geodes := state.resource (geode);\n          return;\n\n        --  Some recursion breakers on desperately unefficient scenarios\n        when 1 =>\n          if state.robot (geode) = 0 then\n            --  There is not even a single geode-breaking robot in the last minute.\n            geodes := 0;\n            return;\n          end if;\n        when 2 =>\n          if state.robot (obsidian) = 0 then\n            --  There is not even a single obsidian-collecting robot\n            --  in the needed time to construct the first geode-breaking robot\n            --  and produce the first geode.\n            geodes := 0;\n            return;\n          end if;\n          if state.robot (geode) = 0 then\n            --  No geode-breaking robot? Fair enough, we contruct one.\n            if state.resource (obsidian) < obsidian_cost_geode_robot then\n              --  There is not enough obsidian to construct the\n              --  first geode-breaking robot.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n        when 3 =>\n          if state.robot (clay) = 0 then\n            --  Too late for the first clay robot.\n            geodes := 0;\n            return;\n          end if;\n          if state.robot (obsidian) = 0 then\n            if state.resource (clay) < clay_cost_obsidian_robot then\n              --  Not enough clay to construct the first obsidian-collecting robot.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n          if state.robot (geode) = 0 then\n            if state.resource (obsidian) + state.robot (obsidian) < obsidian_cost_geode_robot then\n              --  There won't be not enough obsidian on next step to construct the\n              --  first geode-breaking robot.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n        when 4 =>\n          if state.robot (obsidian) = 0 then\n            if state.resource (clay) + state.robot (clay) < clay_cost_obsidian_robot then\n              --  Not enough clay to construct the first obsidian-collecting\n              --  robot in the last possible minute.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n          if state.robot (geode) = 0 then\n            case state.robot (obsidian) is\n              when 0 =>\n                if state.resource (obsidian) < obsidian_cost_geode_robot - 1 then\n                  geodes := 0;\n                  return;\n                end if;\n              when 1 =>\n                if state.resource (obsidian) < obsidian_cost_geode_robot - 3 then\n                  geodes := 0;\n                  return;\n                end if;\n              when 2 =>\n                if state.resource (obsidian) < obsidian_cost_geode_robot - 6 then\n                  geodes := 0;\n                  return;\n                end if;\n              when others =>\n                null;\n            end case;\n          end if;\n        when 5 =>\n          if state.robot (geode) = 0 then\n            case state.robot (obsidian) is\n              when 0 =>\n                --  Best case : one more obsidian robot is constructed at each\n                --  subsequent time step, allowing for constructin a geode robot.\n                if state.resource (obsidian) < obsidian_cost_geode_robot - 3 then\n                  geodes := 0;\n                  return;\n                end if;\n              when 1 =>\n                if state.resource (obsidian) < obsidian_cost_geode_robot - 7 then\n                  geodes := 0;\n                  return;\n                end if;\n              when others =>\n                null;\n            end case;\n          end if;\n        when 6 =>\n          if state.robot (geode) = 0\n            and then state.robot (obsidian) = 0\n            and then state.resource (obsidian) < obsidian_cost_geode_robot - 6\n          then\n            geodes := 0;\n            return;\n          end if;\n        when others =>\n          null;\n      end case;\n\n      any_possible := False;\n      for new_robot in Resource_Type loop\n        score_build_robot (new_robot) := 0;\n        robot_creation_possible := False;\n        if state.resource (ore) >= blueprint (new_robot)(ore) then\n          case new_robot is\n            when ore | clay =>\n              new_state := state;\n              new_state.resource (ore) := new_state.resource (ore) - blueprint (new_robot)(ore);\n              robot_creation_possible := True;\n            when obsidian =>\n              if state.resource (clay) >= blueprint (obsidian)(clay) then\n                new_state := state;\n                new_state.resource (ore) := new_state.resource (ore) - blueprint (obsidian)(ore);\n                new_state.resource (clay) := new_state.resource (clay) - blueprint (obsidian)(clay);\n                robot_creation_possible := True;\n              end if;\n            when geode =>\n              if state.resource (obsidian) >= blueprint (geode)(obsidian) then\n                new_state := state;\n                new_state.resource (ore) := new_state.resource (ore) - blueprint (geode)(ore);\n                new_state.resource (obsidian) := new_state.resource (obsidian) - blueprint (geode)(obsidian);\n                robot_creation_possible := True;\n              end if;\n          end case;\n        end if;\n        if robot_creation_possible then\n          --  Earn new resources\n          for res in Resource_Type loop\n            new_state.resource (res) := new_state.resource (res) + new_state.robot (res);\n          end loop;\n          new_state.robot (new_robot) := new_state.robot (new_robot) + 1;\n          Visit (new_state, time_left - 1, score_build_robot (new_robot));\n        end if;\n        any_possible := any_possible or robot_creation_possible;\n      end loop;\n      --  Variant without constructing a new robot.\n      if greedy and then any_possible then\n        --  We ignore this variant if it is possible to construct a robot.\n        score_same_robots := 0;\n      else\n        new_state := state;\n        --  Earn new resources\n        for res in Resource_Type loop\n          new_state.resource (res) := new_state.resource (res) + new_state.robot (res);\n        end loop;\n        Visit (new_state, time_left - 1, score_same_robots);\n      end if;\n      --  Find max:\n      result := score_same_robots;\n      for res in Resource_Type loop\n        result := Max (result, score_build_robot (res));\n      end loop;\n      geodes := result;\n    end Visit;\n\n    max_geodes : Natural;\n\n  begin\n    for r in Resource_Type loop\n      initial.robot (r) := 0;\n      initial.resource (r) := 0;\n    end loop;\n    initial.robot (ore) := 1;\n    obsidian_cost_geode_robot := blueprint (geode)(obsidian);\n    clay_cost_obsidian_robot  := blueprint (obsidian)(clay);\n\n    --  put(min_time_to_collect_enough_obsidian);\n    --  put(min_time_to_collect_enough_clay);\n    --  new_line;\n    Visit (initial, total_time, max_geodes);\n    return max_geodes;\n  end Best_Geode_Opening;\n\n  last : Natural := 0;\n\n  blueprint : array (1 .. 30) of Blueprint_Type;\n\n  best : Natural;\n\nbegin\n  Open (f, \"aoc_2022_19.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    Skip_till_Space (f, 6);\n    exit Read_Data when End_Of_File (f);\n    last := last + 1;\n    for robot in Resource_Type loop\n      for cost in Resource_Type loop\n        blueprint (last)(robot)(cost) := 0;\n      end loop;\n    end loop;\n    Get (f, blueprint (last)(ore)(ore));\n    Skip_till_Space (f, 6);\n    Get (f, blueprint (last)(clay)(ore));\n    Skip_till_Space (f, 6);\n    Get (f, blueprint (last)(obsidian)(ore));\n    Skip_till_Space (f, 3);\n    Get (f, blueprint (last)(obsidian)(clay));\n    Skip_till_Space (f, 6);\n    Get (f, blueprint (last)(geode)(ore));\n    Skip_till_Space (f, 3);\n    Get (f, blueprint (last)(geode)(obsidian));\n    Skip_till_Space (f, 1);\n  end loop Read_Data;\n  Close (f);\n\n  r (1) := 0;\n  r (2) := 1;\n  for b in 1 .. last loop\n    best := Best_Geode_Opening (blueprint (b), 24);\n    if verbosity_level > 0 then\n      Put_Line\n        (+\"In 24 steps (minutes), blueprint #\" & b & \": \" & best & \" geodes cracked, T = \" & (Clock - T0));\n    end if;\n    r (1) := r (1) + b * best;\n    if b <= 3 then\n      best := Best_Geode_Opening (blueprint (b), 32);\n      if verbosity_level > 0 then\n        Put_Line\n          (+\"In 32 steps (minutes), blueprint #\" & b & \": \" & best & \" geodes cracked, T = \" & (Clock - T0));\n      end if;\n      r (2) := r (2) * best;\n    end if;\n  end loop;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1 (24 minutes):\" & r (1)'Image);\n    Put_Line (+\"Part 2 (32 minutes):\" & r (2)'Image);\n    --  Part 1: validated by AoC: 1192\n    --  Part 2: validated by AoC: 14725\n  end if;\nend AoC_2022_19;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_19_full_ada.adb",
    "content": "--  Solution to Advent of Code 2022, Day 19\n-------------------------------------------\n--  Not Enough Minerals\n--\n--  https://adventofcode.com/2022/day/19\n--  Copy of questions in: aoc_2022_19_questions.txt\n\nwith AoC_Toolbox;\n\n--  Note: this solution uses a cache for \"memoizing\"\n--  the nodes which were already computed.\n--  Total run time with GNAT: 58 seconds.\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\nwith Ada.Containers.Hashed_Maps;\n\nprocedure AoC_2022_19_Full_Ada is\n  use AoC_Toolbox, HAT;\n\n  verbosity_level : constant Natural := 1;\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer;\n\n  f : File_Type;\n\n  --  Parseable copy of the example (part after column with '|'):\n  --\n  --  |Blueprint 1:\n  --  | Each ore robot costs 4 ore.\n  --  | Each clay robot costs 2 ore.\n  --  | Each obsidian robot costs 3 ore and 14 clay.\n  --  | Each geode robot costs 2 ore and 7 obsidian.\n  --  |\n  --  |Blueprint 2:\n  --  | Each ore robot costs 2 ore.\n  --  | Each clay robot costs 3 ore.\n  --  | Each obsidian robot costs 3 ore and 8 clay.\n  --  | Each geode robot costs 3 ore and 12 obsidian.\n\n  type Resource_Type is (ore, clay, obsidian, geode);\n\n  type Portfolio_Type is array (Resource_Type) of Natural;\n\n  type State_Type is record\n    resource  : Portfolio_Type;\n    robot     : Portfolio_Type;\n    time_left : Natural;\n  end record;\n\n  function State_Hash (s : State_Type) return Ada.Containers.Hash_Type with Inline is\n    use Ada.Containers;\n    x : Hash_Type := 0;\n    multiplier : constant := 37;  --  Can be any value: Hash_Type does not overflow.\n  begin\n    for res in Resource_Type loop\n      x := x * multiplier + Hash_Type (s.robot (res));\n      x := x * multiplier + Hash_Type (s.resource (res));\n    end loop;\n    return x * multiplier + Hash_Type (s.time_left);\n  end State_Hash;\n\n  package State_Maps is\n    new Ada.Containers.Hashed_Maps (State_Type, Natural, State_Hash, \"=\");\n\n  subtype Cost_Type is Portfolio_Type;\n\n  --  Costs of a robot producing a certain resource.\n  type Blueprint_Type is array (Resource_Type) of Cost_Type;\n\n  function Best_Geode_Opening\n    (blueprint : Blueprint_Type; total_time : Positive) return Natural\n  is\n    initial : State_Type;\n\n    obsidian_cost_geode_robot, clay_cost_obsidian_robot : Positive;\n\n    greedy : constant Boolean := True;\n\n    cache : State_Maps.Map;\n\n    procedure Visit (state : State_Type; geodes : out Natural) is\n      robot_creation_possible, any_possible : Boolean;\n      score_build_robot : array (Resource_Type) of Natural;\n      score_same_robots : Natural;\n      new_state : State_Type;\n      result : Natural;\n      cursor : State_Maps.Cursor;\n      use State_Maps;\n    begin\n      case state.time_left is\n        when 0 =>\n          geodes := state.resource (geode);\n          return;\n        --  Some recursion breakers on desperately unefficient scenarios\n        when 1 =>\n          if state.robot (geode) = 0 then\n            --  There is not even a single geode-breaking robot in the last minute.\n            geodes := 0;\n            return;\n          end if;\n        when 2 =>\n          if state.robot (obsidian) = 0 then\n            --  There is not even a single obsidian-collecting robot\n            --  in the needed time to construct the first geode-breaking robot\n            --  and produce the first geode.\n            geodes := 0;\n            return;\n          end if;\n          if state.robot (geode) = 0 then\n            --  No geode-breaking robot? Fair enough, we contruct one.\n            if state.resource (obsidian) < obsidian_cost_geode_robot then\n              --  There is not enough obsidian to construct the\n              --  first geode-breaking robot.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n        when 3 =>\n          if state.robot (clay) = 0 then\n            --  Too late for the first clay robot.\n            geodes := 0;\n            return;\n          end if;\n          if state.robot (obsidian) = 0 then\n            if state.resource (clay) < clay_cost_obsidian_robot then\n              --  Not enough clay to construct the first obsidian-collecting robot.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n          if state.robot (geode) = 0 then\n            if state.resource (obsidian) + state.robot (obsidian) < obsidian_cost_geode_robot then\n              --  There won't be not enough obsidian on next step to construct the\n              --  first geode-breaking robot.\n              geodes := 0;\n              return;\n            end if;\n          end if;\n        when others =>\n          null;\n      end case;\n\n      cursor := cache.Find (state);\n      if cursor /= No_Element then\n        geodes := Element (cursor);\n        return;\n      end if;\n\n      any_possible := False;\n      for new_robot in Resource_Type loop\n        score_build_robot (new_robot) := 0;\n        robot_creation_possible := False;\n        if state.resource (ore) >= blueprint (new_robot)(ore) then\n          case new_robot is\n            when ore | clay =>\n              new_state := state;\n              new_state.resource (ore) := new_state.resource (ore) - blueprint (new_robot)(ore);\n              robot_creation_possible := True;\n            when obsidian =>\n              if state.resource (clay) >= blueprint (obsidian)(clay) then\n                new_state := state;\n                new_state.resource (ore) := new_state.resource (ore) - blueprint (obsidian)(ore);\n                new_state.resource (clay) := new_state.resource (clay) - blueprint (obsidian)(clay);\n                robot_creation_possible := True;\n              end if;\n            when geode =>\n              if state.resource (obsidian) >= blueprint (geode)(obsidian) then\n                new_state := state;\n                new_state.resource (ore) := new_state.resource (ore) - blueprint (geode)(ore);\n                new_state.resource (obsidian) := new_state.resource (obsidian) - blueprint (geode)(obsidian);\n                robot_creation_possible := True;\n              end if;\n          end case;\n        end if;\n        if robot_creation_possible then\n          --  Earn new resources\n          for res in Resource_Type loop\n            new_state.resource (res) := new_state.resource (res) + new_state.robot (res);\n          end loop;\n          new_state.robot (new_robot) := new_state.robot (new_robot) + 1;\n          new_state.time_left := new_state.time_left - 1;\n          Visit (new_state, score_build_robot (new_robot));\n        end if;\n        any_possible := any_possible or robot_creation_possible;\n      end loop;\n      --  Variant without constructing a new robot.\n      if greedy and then any_possible then\n        --  We ignore this variant if it is possible to construct a robot.\n        score_same_robots := 0;\n      else\n        new_state := state;\n        --  Earn new resources\n        for res in Resource_Type loop\n          new_state.resource (res) := new_state.resource (res) + new_state.robot (res);\n        end loop;\n        new_state.time_left := new_state.time_left - 1;\n        Visit (new_state, score_same_robots);\n      end if;\n      --  Find max:\n      result := score_same_robots;\n      for res in Resource_Type loop\n        result := Max (result, score_build_robot (res));\n      end loop;\n      geodes := result;\n      cache.Insert (state, result);\n    end Visit;\n\n    max_geodes : Natural;\n\n  begin\n    for r in Resource_Type loop\n      initial.robot (r) := 0;\n      initial.resource (r) := 0;\n    end loop;\n    initial.robot (ore) := 1;\n    initial.time_left := total_time;\n    obsidian_cost_geode_robot := blueprint (geode)(obsidian);\n    clay_cost_obsidian_robot  := blueprint (obsidian)(clay);\n\n    --  put(min_time_to_collect_enough_obsidian);\n    --  put(min_time_to_collect_enough_clay);\n    --  new_line;\n    Visit (initial, max_geodes);\n    return max_geodes;\n  end Best_Geode_Opening;\n\n  last : Natural := 0;\n\n  blueprint : array (1 .. 30) of Blueprint_Type;\n\n  best : Natural;\n\nbegin\n  Open (f, \"aoc_2022_19.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    Skip_till_Space (f, 6);\n    exit Read_Data when End_Of_File (f);\n    last := last + 1;\n    for robot in Resource_Type loop\n      for cost in Resource_Type loop\n        blueprint (last)(robot)(cost) := 0;\n      end loop;\n    end loop;\n    Get (f, blueprint (last)(ore)(ore));\n    Skip_till_Space (f, 6);\n    Get (f, blueprint (last)(clay)(ore));\n    Skip_till_Space (f, 6);\n    Get (f, blueprint (last)(obsidian)(ore));\n    Skip_till_Space (f, 3);\n    Get (f, blueprint (last)(obsidian)(clay));\n    Skip_till_Space (f, 6);\n    Get (f, blueprint (last)(geode)(ore));\n    Skip_till_Space (f, 3);\n    Get (f, blueprint (last)(geode)(obsidian));\n    Skip_till_Space (f, 1);\n  end loop Read_Data;\n  Close (f);\n\n  r (1) := 0;\n  r (2) := 1;\n  for b in 1 .. last loop\n    best := Best_Geode_Opening (blueprint (b), 24);\n    if verbosity_level > 0 then\n      Put_Line\n        (+\"In 24 steps (minutes), blueprint #\" & b & \": \" & best & \" geodes cracked, T = \" & (Clock - T0));\n    end if;\n    r (1) := r (1) + b * best;\n    if b <= 3 then\n      best := Best_Geode_Opening (blueprint (b), 32);\n      if verbosity_level > 0 then\n        Put_Line\n          (+\"In 32 steps (minutes), blueprint #\" & b & \": \" & best & \" geodes cracked, T = \" & (Clock - T0));\n      end if;\n      r (2) := r (2) * best;\n    end if;\n  end loop;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer'Value (To_String (Argument (1))) or\n       r (2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1 (24 minutes):\" & r (1)'Image);\n    Put_Line (+\"Part 2 (32 minutes):\" & r (2)'Image);\n    --  Part 1: validated by AoC: 1192\n    --  Part 2: validated by AoC: 14725\n  end if;\nend AoC_2022_19_Full_Ada;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_19_questions.txt",
    "content": "--- Day 19: Not Enough Minerals ---\n\nYour scans show that the lava did indeed form obsidian!\n\nThe wind has changed direction enough to stop sending\nlava droplets toward you, so you and the elephants exit the cave.\n As you do, you notice a collection of geodes around the pond.\n Perhaps you could use the obsidian to create some geode-cracking\n robots and break them open?\n\nTo collect the obsidian from the bottom of the pond, you'll need\nwaterproof obsidian-collecting robots. Fortunately, there is an\nabundant amount of clay nearby that you can use to make them waterproof.\n\nIn order to harvest the clay, you'll need special-purpose\nclay-collecting robots. To make any type of robot, you'll\nneed ore, which is also plentiful but in the opposite\ndirection from the clay.\n\nCollecting ore requires ore-collecting robots with big drills.\nFortunately, you have exactly one ore-collecting robot in your\npack that you can use to kickstart the whole operation.\n\nEach robot can collect 1 of its resource type per minute.\nIt also takes one minute for the robot factory (also\nconveniently from your pack) to construct any type of robot,\nalthough it consumes the necessary resources available when\nconstruction begins.\n\nThe robot factory has many blueprints (your puzzle input)\nyou can choose from, but once you've configured it with a\nblueprint, you can't change it. You'll need to work out\nwhich blueprint is best.\n\nFor example:\n\nBlueprint 1:\n  Each ore robot costs 4 ore.\n  Each clay robot costs 2 ore.\n  Each obsidian robot costs 3 ore and 14 clay.\n  Each geode robot costs 2 ore and 7 obsidian.\n\nBlueprint 2:\n  Each ore robot costs 2 ore.\n  Each clay robot costs 3 ore.\n  Each obsidian robot costs 3 ore and 8 clay.\n  Each geode robot costs 3 ore and 12 obsidian.\n\n(Blueprints have been line-wrapped here for legibility.\nThe robot factory's actual assortment of blueprints are\nprovided one blueprint per line.)\n\nThe elephants are starting to look hungry, so you shouldn't\ntake too long; you need to figure out which blueprint would\nmaximize the number of opened geodes after 24 minutes by\nfiguring out which robots to build and when to build them.\n\nUsing blueprint 1 in the example above, the largest number\nof geodes you could open in 24 minutes is 9.\nOne way to achieve that is:\n\n== Minute 1 ==\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\n\n== Minute 2 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n\n== Minute 3 ==\nSpend 2 ore to start building a clay-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\nThe new clay-collecting robot is ready; you now have 1 of them.\n\n== Minute 4 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n1 clay-collecting robot collects 1 clay; you now have 1 clay.\n\n== Minute 5 ==\nSpend 2 ore to start building a clay-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\n1 clay-collecting robot collects 1 clay; you now have 2 clay.\nThe new clay-collecting robot is ready; you now have 2 of them.\n\n== Minute 6 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n2 clay-collecting robots collect 2 clay; you now have 4 clay.\n\n== Minute 7 ==\nSpend 2 ore to start building a clay-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\n2 clay-collecting robots collect 2 clay; you now have 6 clay.\nThe new clay-collecting robot is ready; you now have 3 of them.\n\n== Minute 8 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n3 clay-collecting robots collect 3 clay; you now have 9 clay.\n\n== Minute 9 ==\n1 ore-collecting robot collects 1 ore; you now have 3 ore.\n3 clay-collecting robots collect 3 clay; you now have 12 clay.\n\n== Minute 10 ==\n1 ore-collecting robot collects 1 ore; you now have 4 ore.\n3 clay-collecting robots collect 3 clay; you now have 15 clay.\n\n== Minute 11 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n3 clay-collecting robots collect 3 clay; you now have 4 clay.\nThe new obsidian-collecting robot is ready; you now have 1 of them.\n\n== Minute 12 ==\nSpend 2 ore to start building a clay-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\n3 clay-collecting robots collect 3 clay; you now have 7 clay.\n1 obsidian-collecting robot collects 1 obsidian; you now have 1 obsidian.\nThe new clay-collecting robot is ready; you now have 4 of them.\n\n== Minute 13 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n4 clay-collecting robots collect 4 clay; you now have 11 clay.\n1 obsidian-collecting robot collects 1 obsidian; you now have 2 obsidian.\n\n== Minute 14 ==\n1 ore-collecting robot collects 1 ore; you now have 3 ore.\n4 clay-collecting robots collect 4 clay; you now have 15 clay.\n1 obsidian-collecting robot collects 1 obsidian; you now have 3 obsidian.\n\n== Minute 15 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\n4 clay-collecting robots collect 4 clay; you now have 5 clay.\n1 obsidian-collecting robot collects 1 obsidian; you now have 4 obsidian.\nThe new obsidian-collecting robot is ready; you now have 2 of them.\n\n== Minute 16 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n4 clay-collecting robots collect 4 clay; you now have 9 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 6 obsidian.\n\n== Minute 17 ==\n1 ore-collecting robot collects 1 ore; you now have 3 ore.\n4 clay-collecting robots collect 4 clay; you now have 13 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 8 obsidian.\n\n== Minute 18 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n4 clay-collecting robots collect 4 clay; you now have 17 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 3 obsidian.\nThe new geode-cracking robot is ready; you now have 1 of them.\n\n== Minute 19 ==\n1 ore-collecting robot collects 1 ore; you now have 3 ore.\n4 clay-collecting robots collect 4 clay; you now have 21 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 5 obsidian.\n1 geode-cracking robot cracks 1 geode; you now have 1 open geode.\n\n== Minute 20 ==\n1 ore-collecting robot collects 1 ore; you now have 4 ore.\n4 clay-collecting robots collect 4 clay; you now have 25 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 7 obsidian.\n1 geode-cracking robot cracks 1 geode; you now have 2 open geodes.\n\n== Minute 21 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n1 ore-collecting robot collects 1 ore; you now have 3 ore.\n4 clay-collecting robots collect 4 clay; you now have 29 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 2 obsidian.\n1 geode-cracking robot cracks 1 geode; you now have 3 open geodes.\nThe new geode-cracking robot is ready; you now have 2 of them.\n\n== Minute 22 ==\n1 ore-collecting robot collects 1 ore; you now have 4 ore.\n4 clay-collecting robots collect 4 clay; you now have 33 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 4 obsidian.\n2 geode-cracking robots crack 2 geodes; you now have 5 open geodes.\n\n== Minute 23 ==\n1 ore-collecting robot collects 1 ore; you now have 5 ore.\n4 clay-collecting robots collect 4 clay; you now have 37 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 6 obsidian.\n2 geode-cracking robots crack 2 geodes; you now have 7 open geodes.\n\n== Minute 24 ==\n1 ore-collecting robot collects 1 ore; you now have 6 ore.\n4 clay-collecting robots collect 4 clay; you now have 41 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 8 obsidian.\n2 geode-cracking robots crack 2 geodes; you now have 9 open geodes.\n\nHowever, by using blueprint 2 in the example above, you could do even better:\nthe largest number of geodes you could open in 24 minutes is 12.\n\nDetermine the quality level of each blueprint by multiplying that\nblueprint's ID number with the largest number of geodes that\ncan be opened in 24 minutes using that blueprint. In this example,\nthe first blueprint has ID 1 and can open 9 geodes, so its\nquality level is 9. The second blueprint has ID 2 and can open\n12 geodes, so its quality level is 24. Finally, if you add up\nthe quality levels of all of the blueprints in the list, you get 33.\n\nDetermine the quality level of each blueprint using the largest\nnumber of geodes it could produce in 24 minutes. What do you get\nif you add up the quality level of all of the blueprints in your list?\n\n--- Part Two ---\n\nWhile you were choosing the best blueprint, the elephants found some\nfood on their own, so you're not in as much of a hurry; you figure\nyou probably have 32 minutes before the wind changes direction again\nand you'll need to get out of range of the erupting volcano.\n\nUnfortunately, one of the elephants ate most of your blueprint list!\nNow, only the first three blueprints in your list are intact.\n\nIn 32 minutes, the largest number of geodes blueprint 1\n(from the example above) can open is 56.\nOne way to achieve that is:\n\n== Minute 1 ==\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\n\n== Minute 2 ==\n1 ore-collecting robot collects 1 ore; you now have 2 ore.\n\n== Minute 3 ==\n1 ore-collecting robot collects 1 ore; you now have 3 ore.\n\n== Minute 4 ==\n1 ore-collecting robot collects 1 ore; you now have 4 ore.\n\n== Minute 5 ==\nSpend 4 ore to start building an ore-collecting robot.\n1 ore-collecting robot collects 1 ore; you now have 1 ore.\nThe new ore-collecting robot is ready; you now have 2 of them.\n\n== Minute 6 ==\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n\n== Minute 7 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\nThe new clay-collecting robot is ready; you now have 1 of them.\n\n== Minute 8 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n1 clay-collecting robot collects 1 clay; you now have 1 clay.\nThe new clay-collecting robot is ready; you now have 2 of them.\n\n== Minute 9 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n2 clay-collecting robots collect 2 clay; you now have 3 clay.\nThe new clay-collecting robot is ready; you now have 3 of them.\n\n== Minute 10 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n3 clay-collecting robots collect 3 clay; you now have 6 clay.\nThe new clay-collecting robot is ready; you now have 4 of them.\n\n== Minute 11 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n4 clay-collecting robots collect 4 clay; you now have 10 clay.\nThe new clay-collecting robot is ready; you now have 5 of them.\n\n== Minute 12 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n5 clay-collecting robots collect 5 clay; you now have 15 clay.\nThe new clay-collecting robot is ready; you now have 6 of them.\n\n== Minute 13 ==\nSpend 2 ore to start building a clay-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n6 clay-collecting robots collect 6 clay; you now have 21 clay.\nThe new clay-collecting robot is ready; you now have 7 of them.\n\n== Minute 14 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 2 ore.\n7 clay-collecting robots collect 7 clay; you now have 14 clay.\nThe new obsidian-collecting robot is ready; you now have 1 of them.\n\n== Minute 15 ==\n2 ore-collecting robots collect 2 ore; you now have 4 ore.\n7 clay-collecting robots collect 7 clay; you now have 21 clay.\n1 obsidian-collecting robot collects 1 obsidian; you now have 1 obsidian.\n\n== Minute 16 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n7 clay-collecting robots collect 7 clay; you now have 14 clay.\n1 obsidian-collecting robot collects 1 obsidian; you now have 2 obsidian.\nThe new obsidian-collecting robot is ready; you now have 2 of them.\n\n== Minute 17 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 2 ore.\n7 clay-collecting robots collect 7 clay; you now have 7 clay.\n2 obsidian-collecting robots collect 2 obsidian; you now have 4 obsidian.\nThe new obsidian-collecting robot is ready; you now have 3 of them.\n\n== Minute 18 ==\n2 ore-collecting robots collect 2 ore; you now have 4 ore.\n7 clay-collecting robots collect 7 clay; you now have 14 clay.\n3 obsidian-collecting robots collect 3 obsidian; you now have 7 obsidian.\n\n== Minute 19 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n7 clay-collecting robots collect 7 clay; you now have 7 clay.\n3 obsidian-collecting robots collect 3 obsidian; you now have 10 obsidian.\nThe new obsidian-collecting robot is ready; you now have 4 of them.\n\n== Minute 20 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 3 ore.\n7 clay-collecting robots collect 7 clay; you now have 14 clay.\n4 obsidian-collecting robots collect 4 obsidian; you now have 7 obsidian.\nThe new geode-cracking robot is ready; you now have 1 of them.\n\n== Minute 21 ==\nSpend 3 ore and 14 clay to start building an obsidian-collecting robot.\n2 ore-collecting robots collect 2 ore; you now have 2 ore.\n7 clay-collecting robots collect 7 clay; you now have 7 clay.\n4 obsidian-collecting robots collect 4 obsidian; you now have 11 obsidian.\n1 geode-cracking robot cracks 1 geode; you now have 1 open geode.\nThe new obsidian-collecting robot is ready; you now have 5 of them.\n\n== Minute 22 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 2 ore.\n7 clay-collecting robots collect 7 clay; you now have 14 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 9 obsidian.\n1 geode-cracking robot cracks 1 geode; you now have 2 open geodes.\nThe new geode-cracking robot is ready; you now have 2 of them.\n\n== Minute 23 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 2 ore.\n7 clay-collecting robots collect 7 clay; you now have 21 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 7 obsidian.\n2 geode-cracking robots crack 2 geodes; you now have 4 open geodes.\nThe new geode-cracking robot is ready; you now have 3 of them.\n\n== Minute 24 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 2 ore.\n7 clay-collecting robots collect 7 clay; you now have 28 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 5 obsidian.\n3 geode-cracking robots crack 3 geodes; you now have 7 open geodes.\nThe new geode-cracking robot is ready; you now have 4 of them.\n\n== Minute 25 ==\n2 ore-collecting robots collect 2 ore; you now have 4 ore.\n7 clay-collecting robots collect 7 clay; you now have 35 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 10 obsidian.\n4 geode-cracking robots crack 4 geodes; you now have 11 open geodes.\n\n== Minute 26 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 4 ore.\n7 clay-collecting robots collect 7 clay; you now have 42 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 8 obsidian.\n4 geode-cracking robots crack 4 geodes; you now have 15 open geodes.\nThe new geode-cracking robot is ready; you now have 5 of them.\n\n== Minute 27 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 4 ore.\n7 clay-collecting robots collect 7 clay; you now have 49 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 6 obsidian.\n5 geode-cracking robots crack 5 geodes; you now have 20 open geodes.\nThe new geode-cracking robot is ready; you now have 6 of them.\n\n== Minute 28 ==\n2 ore-collecting robots collect 2 ore; you now have 6 ore.\n7 clay-collecting robots collect 7 clay; you now have 56 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 11 obsidian.\n6 geode-cracking robots crack 6 geodes; you now have 26 open geodes.\n\n== Minute 29 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 6 ore.\n7 clay-collecting robots collect 7 clay; you now have 63 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 9 obsidian.\n6 geode-cracking robots crack 6 geodes; you now have 32 open geodes.\nThe new geode-cracking robot is ready; you now have 7 of them.\n\n== Minute 30 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 6 ore.\n7 clay-collecting robots collect 7 clay; you now have 70 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 7 obsidian.\n7 geode-cracking robots crack 7 geodes; you now have 39 open geodes.\nThe new geode-cracking robot is ready; you now have 8 of them.\n\n== Minute 31 ==\nSpend 2 ore and 7 obsidian to start building a geode-cracking robot.\n2 ore-collecting robots collect 2 ore; you now have 6 ore.\n7 clay-collecting robots collect 7 clay; you now have 77 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 5 obsidian.\n8 geode-cracking robots crack 8 geodes; you now have 47 open geodes.\nThe new geode-cracking robot is ready; you now have 9 of them.\n\n== Minute 32 ==\n2 ore-collecting robots collect 2 ore; you now have 8 ore.\n7 clay-collecting robots collect 7 clay; you now have 84 clay.\n5 obsidian-collecting robots collect 5 obsidian; you now have 10 obsidian.\n9 geode-cracking robots crack 9 geodes; you now have 56 open geodes.\n\nHowever, blueprint 2 from the example above is still better;\nusing it, the largest number of geodes you could open in 32 minutes is 62.\n\nYou no longer have enough blueprints to worry about quality levels.\nInstead, for each of the first three blueprints, determine the largest\nnumber of geodes you could open; then, multiply these three values together.\n\nDon't worry about quality levels; instead, just determine the largest\nnumber of geodes you could open using each of the first three blueprints.\nWhat do you get if you multiply these numbers together?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_20.adb",
    "content": "--  Solution to Advent of Code 2022, Day 20\n-------------------------------------------\n--  Grove Positioning System\n--\n--  https://adventofcode.com/2022/day/20\n--  Copy of questions in: aoc_2022_20_questions.txt\n--\n--  This problem resembles to the Crab Cups puzzle (AoC_2020_23).\n\n--\n--  Note: this solution takes a large amount of time\n--  with HAC (62 seconds).\n--  Fortunately, you can compile it with GNAT and\n--  the total run-time is there 0.29 seconds on an i7 machine.\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and GNAT (64-bit integer: Integer_64):\nwith Interfaces;\n\nprocedure AoC_2022_20 is\n  use HAT, Interfaces;\n\n  verbosity_level : constant Natural := 0;\n\n  info_max : constant := 5000;\n\n  subtype Extended_Info_Range is Integer range -1 .. info_max;\n  subtype Info_Range is Integer range 0 .. info_max;\n\n  type Info is record\n    label : Integer;\n    prev  : Extended_Info_Range;\n    next  : Info_Range;\n  end record;\n\n  type Info_Array is array (Info_Range) of Info;\n\n  data, o : Info_Array;\n  last : Extended_Info_Range := -1;\n\n  procedure Show is\n    cursor : Info_Range;\n  begin\n    cursor := 0;\n    for count in 0 .. last loop\n      Put (o (cursor).label, 0);\n      if count < last then\n        Put (\", \");\n      end if;\n      cursor := o (cursor).next;\n    end loop;\n    New_Line;\n  end Show;\n\n  f : File_Type;\n\n  new_prev, new_next, total, zero_position, cursor : Info_Range;\n  rounds : Positive;\n  skip, decryption_key : Integer_64;\n\n  r : array (1 .. 2) of Integer_64;\n  T0 : constant Time := Clock;\n\nbegin\n  Open (f, \"aoc_2022_20.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    last := last + 1;\n    Get (f, data (last).label);\n    if data (last).label = 0 then\n      zero_position := last;\n    end if;\n    data (last).prev := last - 1;\n    data (last).next := last + 1;\n  end loop Read_Data;\n  Close (f);\n  data (0).prev := last;\n  data (last).next := 0;\n  total := last + 1;\n  if verbosity_level > 0 then\n    Show;\n  end if;\n\nParts :\n  for part in 1 .. 2 loop\n    o := data;\n    --  Play:\n    case part is\n      when 1 =>\n        rounds := 1;\n        decryption_key := 1;\n      when 2 =>\n        rounds := 10;\n        decryption_key := 811589153;\n    end case;\n  Multiple_Rounds :\n    for round in 1 .. rounds loop\n    Single_Round :\n      for i in 0 .. last loop\n        --  Remove node i:\n        o (o (i).prev).next := o (i).next;\n        o (o (i).next).prev := o (i).prev;\n        --  Find the new neighbours for node i:\n        new_prev := o (i).prev;\n        skip := Integer_64 (o (i).label);\n        if part = 2 then\n          skip := skip * decryption_key;\n        end if;\n        skip := skip mod Integer_64 (total - 1);\n        --  ^ Banana skin here: \"mod (total - 1)\" and not\n        --    \"mod total\", because we have one node less!\n        for count in 1 .. skip loop\n          new_prev := o (new_prev).next;\n        end loop;\n        new_next := o (new_prev).next;\n        --  Relink node i:\n        o (i).next := new_next;\n        o (i).prev := new_prev;\n        --  Insert node i:\n        o (new_prev).next := i;\n        o (new_next).prev := i;\n        --  Display:\n        if verbosity_level > 0 then\n          Show;\n        end if;\n      end loop Single_Round;\n    end loop Multiple_Rounds;\n    cursor := zero_position;\n    r (part) := 0;\n    for thousands in 1 .. 3 loop\n      for count in 1 .. 1000 mod total loop\n        cursor := o (cursor).next;\n      end loop;\n      r (part) := r (part) + Integer_64 (o (cursor).label) * decryption_key;\n    end loop;\n  end loop Parts;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2:\" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 2215\n    --  Part 2: validated by AoC: 8927480683\n  end if;\nend AoC_2022_20;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_20.txt",
    "content": "-2312\n5492\n793\n-773\n5453\n-2076\n-1728\n-7702\n4318\n8316\n-3366\n-3814\n9182\n-673\n-8201\n7847\n9691\n4044\n802\n-8114\n8944\n-2438\n-3460\n-6923\n-4847\n-7341\n2063\n-9848\n6702\n2560\n6058\n-7669\n7315\n-6427\n5165\n3147\n-1320\n4789\n6296\n-806\n1185\n-1445\n-982\n2759\n-8506\n-5959\n5683\n-6623\n-8571\n-5834\n-9022\n8729\n-7420\n-9812\n-9162\n-240\n7302\n2221\n-4352\n-4248\n5177\n9037\n-6880\n-2117\n9569\n-1037\n726\n2866\n-4587\n3384\n998\n9665\n3982\n3169\n4547\n612\n2857\n-2601\n-982\n-4267\n-740\n2817\n-818\n-8005\n-3697\n497\n-8039\n-116\n8438\n-8460\n2609\n709\n3590\n1323\n2202\n-1246\n-736\n-3992\n7811\n127\n-2609\n8314\n-5668\n-6449\n-6512\n3972\n-5998\n-7462\n4542\n-6350\n8424\n5046\n-3554\n6481\n-4521\n1307\n-172\n-7391\n79\n-179\n-7320\n9750\n-5916\n8531\n5522\n5133\n-1506\n4151\n-2793\n5448\n-2267\n998\n-6216\n3894\n-1297\n7112\n8486\n-6030\n-1815\n-1451\n4165\n828\n8678\n-1751\n-9528\n5056\n-9702\n9288\n8683\n-1924\n-6171\n-7050\n-9968\n-3909\n-9834\n-8325\n-2528\n-2247\n-1075\n6684\n6038\n-6309\n-3562\n2333\n3593\n-18\n-9857\n-4318\n6923\n-5266\n1408\n-7781\n2037\n-519\n4085\n7054\n-4111\n2817\n-5375\n870\n-8252\n4142\n3500\n-9371\n-2040\n-7381\n6216\n7143\n-6814\n673\n3104\n-1693\n6050\n-2416\n7112\n4114\n5367\n4566\n2560\n4361\n4131\n4337\n7876\n-3000\n-8724\n-2088\n6785\n-5326\n-7107\n3739\n-302\n9519\n-5331\n8759\n6867\n-9267\n4816\n-749\n-1980\n1830\n9715\n1634\n-6922\n-288\n4436\n63\n-156\n1185\n-5004\n-9093\n-8661\n8447\n233\n-854\n3154\n-5589\n-5490\n2321\n-1006\n3688\n6313\n4704\n6598\n430\n-7073\n-6571\n-3768\n6203\n8453\n8735\n-4070\n8059\n-4734\n-1827\n1330\n586\n-8858\n1938\n1366\n6031\n3744\n-7191\n8032\n3586\n-3196\n-460\n3032\n2387\n450\n1391\n-3905\n-2774\n6690\n-9103\n8220\n-6594\n8834\n-3559\n-9337\n2199\n-9026\n2904\n-8552\n499\n7727\n6519\n-17\n-3625\n-302\n4611\n9129\n9756\n6869\n-2262\n-4677\n3533\n19\n5877\n5224\n3783\n5992\n-2218\n-5097\n3956\n9335\n-5586\n-9441\n3252\n-4307\n-1111\n6509\n-116\n-4926\n-7394\n1270\n-1773\n6658\n3317\n-8704\n-3692\n6482\n2451\n7241\n-350\n-5042\n-9182\n2602\n9752\n-8475\n-5018\n-267\n-9360\n599\n917\n5210\n4388\n909\n-1063\n8311\n1831\n8235\n-9129\n-7420\n-284\n-1940\n4079\n-7284\n-4893\n4913\n-8602\n-59\n6105\n-4934\n1196\n-6947\n-1508\n-8961\n2112\n-6739\n-8401\n9750\n-3697\n85\n2240\n-5882\n-1900\n3783\n5747\n4388\n5225\n6858\n-3799\n6119\n8592\n-3328\n4716\n-6391\n-7721\n4813\n3223\n6303\n8780\n4400\n-7964\n8810\n8247\n8776\n-5738\n-2655\n-2036\n9906\n-6834\n92\n6695\n1740\n29\n-9758\n-7016\n-8170\n-7780\n4243\n-3391\n2989\n-7678\n2154\n-4515\n4475\n8011\n-3785\n-3518\n5532\n8387\n806\n-9546\n655\n804\n-5420\n4138\n8495\n8975\n-2559\n8202\n8268\n-6923\n1671\n-9892\n6337\n6205\n6024\n6038\n-3289\n4626\n4356\n-3104\n7633\n9404\n-3630\n-4041\n106\n-4493\n3651\n6983\n-5958\n819\n6105\n1910\n4645\n-1293\n-8747\n8655\n-6928\n9025\n1984\n-9959\n-9290\n-7834\n3588\n2967\n3048\n4730\n-8653\n-4434\n6105\n8028\n-4909\n-7865\n-6832\n-1267\n8129\n4131\n-9615\n-7137\n3956\n464\n-588\n5260\n2181\n-3581\n649\n8992\n-6427\n-3292\n-5641\n-8274\n-2283\n-3455\n1417\n7054\n3937\n-1797\n-615\n-2526\n6210\n6222\n-6007\n-3764\n-1743\n-3123\n9495\n8269\n3675\n1085\n-1859\n8578\n-1240\n-4734\n1196\n1332\n-3507\n-6268\n3380\n-6530\n3264\n-4958\n-7533\n8869\n2666\n-6780\n7739\n-4128\n-8229\n9624\n-8005\n-1897\n-9773\n8000\n-419\n269\n5048\n-5962\n4319\n6834\n-9624\n-5247\n-2683\n-9050\n-5335\n5244\n-3052\n929\n-3922\n-4806\n-7085\n4186\n-5127\n7790\n527\n-222\n4043\n9900\n4630\n5056\n-9425\n-2369\n-1442\n-7949\n5228\n7449\n3945\n726\n-1722\n-3439\n-1037\n-4998\n-5130\n5158\n-227\n-8075\n3917\n5228\n9382\n-7582\n787\n-2895\n-7385\n9750\n-8872\n-1263\n5877\n4398\n9200\n4061\n8059\n9960\n5756\n-3241\n-2283\n9568\n-5852\n-3630\n-2336\n-3596\n4649\n-7203\n4473\n-8025\n-9991\n-8721\n1307\n-5487\n4632\n1799\n2468\n2834\n2571\n-3894\n7319\n8466\n-7831\n-7428\n5475\n6296\n9191\n6193\n-843\n8566\n9398\n7317\n-3984\n-1886\n-5012\n4014\n-3554\n6002\n-5254\n8412\n-4059\n7761\n-7363\n9025\n-1960\n1905\n-304\n-2877\n7707\n-3120\n8969\n-545\n-9237\n885\n3830\n7085\n-8779\n9198\n4123\n517\n480\n-6380\n9713\n-2029\n-947\n-5205\n-9126\n-4653\n5254\n3153\n2067\n7872\n-3545\n1864\n9068\n4516\n6440\n-9167\n4281\n4859\n-6318\n-3155\n8699\n-5310\n-38\n-4889\n-1805\n-9405\n-1235\n3285\n1579\n1265\n-850\n259\n1513\n-1490\n7916\n-9000\n-7515\n2756\n831\n2387\n-6922\n-6299\n8992\n3336\n4473\n1728\n1366\n-2893\n-8891\n7818\n-3140\n2972\n1088\n2718\n9495\n64\n7527\n8638\n-8670\n6740\n-2971\n1849\n5365\n7997\n2941\n5528\n8065\n6973\n-5858\n1355\n6359\n-7757\n-3968\n-1985\n-3194\n1425\n-6928\n4616\n-1912\n-5892\n-9337\n-4007\n-1299\n5042\n3825\n-5517\n5056\n-9180\n-4646\n-843\n6038\n7750\n-7705\n1294\n8809\n6888\n-1634\n-8823\n-2995\n-7983\n-7333\n-7315\n2240\n-4881\n497\n-4026\n-6921\n714\n4513\n-2134\n-4600\n-4863\n7388\n-6344\n-8589\n9381\n-7674\n-9967\n-9237\n2679\n-8598\n-6741\n7739\n-7720\n-1899\n-5265\n-5665\n-2580\n-8820\n8550\n9121\n-1218\n8832\n-1776\n-4814\n-1570\n-7969\n-6529\n8232\n-4867\n-638\n-1263\n3918\n8720\n-6378\n-7501\n3894\n-663\n3894\n1264\n555\n-1139\n9538\n-7029\n4909\n1751\n-6800\n7761\n6810\n6708\n-3571\n7994\n9707\n5187\n-3084\n5458\n-5274\n-8246\n5730\n2425\n7931\n-6800\n-6008\n-2705\n-5151\n-6268\n-1054\n6176\n-6809\n7683\n-4342\n-7797\n-6430\n4127\n-3148\n7294\n6188\n8729\n3463\n3375\n5648\n788\n3996\n7650\n8952\n-7078\n-8155\n-6166\n-3726\n-2742\n3845\n1103\n-5164\n6507\n-2219\n4131\n9421\n-8277\n7068\n-8046\n833\n-684\n-6160\n-8604\n-6384\n-2081\n940\n3239\n1962\n3502\n3576\n-3320\n-335\n5644\n-200\n823\n8320\n-7803\n6209\n-7565\n1042\n769\n-5705\n7494\n-4419\n5726\n5198\n-6879\n3377\n-6890\n-6072\n-3633\n-100\n-8584\n2961\n-5839\n8191\n9055\n-5330\n-3082\n-8589\n-7126\n-9861\n7624\n8486\n-272\n-1092\n-3047\n9349\n6014\n8554\n-2986\n1425\n-2615\n-1855\n5442\n-8509\n9775\n-8855\n6313\n-8060\n-102\n8809\n2374\n5400\n7789\n-6100\n-1473\n-916\n-6715\n-1828\n-5649\n6314\n-1946\n-895\n8774\n5894\n-8284\n3825\n8737\n500\n-1468\n2542\n-7925\n7775\n9221\n-2916\n-9878\n-6427\n9800\n-468\n-8699\n9798\n9424\n8910\n8582\n-8806\n-4157\n8620\n-5136\n-952\n-9019\n-6947\n-601\n-5789\n-9535\n6028\n-8930\n8466\n-5689\n3254\n-4709\n4394\n2281\n3362\n2813\n-5808\n3420\n6002\n-9398\n9653\n5728\n9204\n-4846\n-7691\n-8087\n6772\n-451\n-2286\n2826\n5945\n-7702\n9713\n5468\n4660\n672\n-1854\n-3970\n1905\n3685\n6425\n5102\n-7462\n1913\n6360\n-8581\n6604\n9384\n9117\n2574\n4436\n-6263\n8516\n-2059\n6378\n-6492\n4242\n-9681\n-6126\n436\n5520\n9528\n3885\n1227\n-8501\n1230\n-6933\n-5230\n-9432\n-1313\n-2136\n-1379\n1439\n-2864\n2839\n3340\n-226\n-4206\n9121\n-9572\n8567\n-8298\n7244\n9526\n-8506\n-7922\n-901\n-523\n-6310\n2811\n2324\n-7384\n8812\n-916\n2580\n-2966\n9885\n-3400\n-6277\n-5818\n-663\n-7179\n7344\n6022\n2865\n-676\n1375\n8622\n1965\n-9990\n-4255\n5796\n-3903\n8008\n-78\n-4997\n-460\n8437\n-6563\n-5517\n-1827\n6257\n-5413\n-6169\n6869\n5890\n9791\n5425\n-7310\n7249\n1175\n4417\n-527\n4115\n-834\n9427\n6924\n731\n-1537\n-4632\n-1218\n3677\n-8488\n-946\n-5430\n580\n4976\n5132\n8448\n-3109\n4014\n-4493\n-5671\n6507\n3688\n-9214\n-2641\n3508\n7581\n-9640\n-2308\n3598\n4940\n-3843\n-7364\n-1693\n2367\n2589\n9435\n-7914\n-5655\n7388\n379\n6022\n1899\n2607\n-6226\n8992\n1231\n-8751\n-4158\n1888\n-2145\n-5874\n-5713\n-9526\n1060\n-3324\n-834\n8534\n-1807\n9906\n1217\n9946\n1892\n8556\n6182\n-2868\n7988\n-1555\n-9400\n2212\n1311\n6349\n-9405\n3703\n9120\n5284\n4672\n-8397\n-7984\n-5319\n-7955\n-1570\n6475\n-2479\n266\n-3865\n3550\n1313\n5476\n3052\n9659\n2696\n-8760\n6568\n-5512\n-4938\n7835\n-6933\n1821\n5033\n3504\n7070\n-2016\n1147\n-2652\n-4622\n-4126\n-9118\n6462\n1563\n3285\n8275\n-8593\n-4833\n-1318\n-6620\n-2818\n4893\n5076\n356\n-4435\n6210\n9037\n6929\n-6950\n-6710\n-1735\n3541\n-5278\n-1451\n8176\n885\n-9108\n-2591\n-1165\n660\n2387\n1829\n3490\n3048\n7244\n-6423\n3571\n-5055\n-1272\n-84\n6388\n2320\n-4569\n2382\n5900\n-7482\n7915\n5668\n9089\n9963\n-6007\n6337\n-5863\n-6139\n-1803\n-1863\n8283\n-8654\n-7952\n-6938\n-5541\n484\n-8487\n-3356\n-2433\n-9859\n-1960\n7112\n8010\n-7200\n9261\n5926\n-2610\n-7854\n6988\n-4258\n-9209\n-3029\n6578\n-1779\n-6575\n9899\n4561\n7564\n-6399\n-7750\n-1276\n-1242\n9793\n-1650\n400\n-4830\n-9533\n6806\n2157\n-5517\n-9506\n-1925\n-519\n5650\n-8327\n4683\n788\n7457\n-4476\n6695\n-4255\n7292\n760\n-8423\n1603\n-4258\n6097\n-567\n5582\n1323\n-3113\n9303\n-3025\n-8242\n6039\n8692\n2309\n-5558\n-916\n-7193\n5906\n-9774\n8231\n491\n8404\n-9325\n-9261\n4790\n-5419\n4394\n-2174\n-8130\n6327\n7412\n6495\n-5814\n6741\n-6791\n9147\n-828\n-619\n1841\n1120\n-9057\n123\n430\n-3828\n6360\n5831\n-5059\n-7599\n-6946\n-9640\n4733\n2834\n524\n-5316\n8832\n-1566\n-5477\n-4370\n1991\n6716\n8755\n-3455\n7821\n-90\n-8899\n-7101\n1785\n-2925\n1299\n9571\n-8319\n8304\n-1690\n-6509\n-5792\n4825\n6801\n-1638\n-4783\n4784\n-5668\n4170\n7228\n-2326\n9793\n-4041\n-9295\n7134\n-4845\n528\n3199\n-1632\n3372\n-5856\n-2582\n7039\n-7775\n-6401\n5747\n-6986\n2608\n5091\n-8261\n-8431\n-1591\n-6165\n4835\n6467\n312\n9873\n-6425\n-9224\n1633\n8856\n5961\n-4968\n8583\n-268\n-6396\n6791\n8721\n-2141\n-2248\n-9119\n4338\n-9103\n-3693\n-706\n-975\n3854\n-1136\n8930\n6511\n-445\n917\n-1024\n-3782\n8406\n2624\n-9544\n-4830\n-5255\n-9561\n-2948\n-1011\n9056\n8291\n3320\n-5316\n1148\n-8261\n1330\n-2145\n-9226\n-1257\n1905\n-3227\n-6728\n-6107\n7278\n-9645\n879\n-3758\n4980\n-7956\n6640\n4053\n-7842\n-6749\n363\n-6904\n-3055\n-768\n7220\n-5118\n6750\n7737\n-3422\n6328\n4844\n-2690\n1113\n-7072\n3528\n-4331\n-5164\n-4056\n-4821\n-982\n2502\n7885\n-8553\n9740\n5105\n-5824\n2693\n5459\n2462\n-3001\n9783\n6766\n-9286\n-6516\n2307\n-908\n-1325\n904\n-84\n-1526\n278\n7384\n655\n-4468\n1264\n4952\n-5002\n5700\n-9261\n-966\n-438\n-466\n-3756\n-9867\n-2088\n4125\n1930\n9294\n-1243\n-5604\n-2422\n-2385\n9296\n9426\n6767\n-6467\n8846\n-1315\n7568\n4391\n85\n-2167\n-9427\n-6613\n-2586\n2008\n4540\n9421\n-7046\n8466\n-2939\n6699\n-8174\n3384\n-2700\n3199\n-4011\n-8991\n-1129\n2216\n8273\n7977\n-3962\n-2334\n-2747\n7765\n1765\n-4471\n1863\n-6768\n-7752\n-5945\n8593\n-2225\n2550\n9650\n8842\n465\n6133\n-952\n7479\n5645\n4520\n-8873\n4429\n9857\n-4567\n-124\n6193\n-7916\n-1299\n1811\n-5195\n8974\n-8604\n6126\n-7579\n-7828\n8882\n-5002\n-6102\n3891\n-589\n-5697\n7519\n-1335\n-311\n-6777\n5704\n1962\n-4950\n9814\n5400\n610\n-2093\n7898\n-6492\n-1165\n-1063\n1658\n-7184\n-3384\n5101\n4733\n1231\n9255\n-712\n4122\n4402\n5443\n3877\n7541\n4473\n-3633\n-9959\n9260\n9177\n1788\n-5986\n-5165\n8969\n6031\n741\n-7417\n7002\n6992\n-4374\n-8995\n2832\n2250\n2221\n-2791\n-2287\n-9125\n-1692\n4930\n-443\n4349\n-8602\n3553\n9117\n8304\n209\n6650\n745\n1058\n-3994\n-7437\n8476\n-7390\n-6864\n2467\n1798\n-292\n-6487\n2954\n-3029\n1192\n-1955\n4256\n5615\n4335\n7948\n-7963\n-831\n8499\n-1778\n5063\n2069\n610\n6032\n1447\n6898\n2154\n-6397\n7996\n-7809\n-3279\n6789\n7245\n8794\n-7078\n-1434\n-3953\n-3029\n7262\n-4640\n4742\n-1063\n7790\n2320\n-1721\n6128\n-4219\n7482\n3385\n-2949\n-6830\n-1522\n-3530\n-9002\n-4798\n7347\n7847\n-8651\n9432\n1612\n-5705\n-9216\n-5384\n-2064\n7739\n7113\n6250\n7192\n2927\n7901\n-2990\n-736\n3892\n-2641\n7870\n5061\n4500\n278\n3569\n5059\n-8721\n9991\n1219\n-1289\n-6273\n-8618\n-9085\n6235\n-7551\n-2850\n-7188\n-9828\n2381\n-1298\n-5671\n-2114\n-3312\n-5589\n-394\n8484\n-4008\n3378\n-9841\n-3357\n6888\n4421\n-5959\n-2719\n-5031\n1945\n5058\n1732\n8774\n-9907\n9240\n3189\n-8103\n8526\n-7588\n6113\n-9506\n1096\n-7420\n5688\n-3131\n-8204\n4321\n1860\n-3439\n5902\n5484\n-7310\n7544\n-9184\n3579\n-8311\n9400\n-2046\n3613\n2834\n-3828\n4483\n-3687\n2474\n9175\n5682\n2134\n8178\n4669\n-8999\n4089\n3745\n6187\n-3255\n4496\n-4086\n-5667\n-4719\n-9530\n57\n-5557\n-1809\n4683\n-6874\n9649\n238\n-5274\n2548\n-1610\n2406\n6760\n3829\n-6658\n-7076\n-8907\n-8252\n4473\n-6559\n9751\n9946\n-1815\n-4719\n6440\n-3154\n-4584\n-8861\n5988\n-6730\n5975\n-6449\n3127\n6406\n7501\n-4504\n-5805\n-8832\n3352\n-3961\n-3453\n9800\n-8757\n-9250\n5575\n-1894\n-1130\n2529\n2060\n819\n8152\n-6329\n-6967\n-451\n-3261\n1670\n4090\n-6879\n-638\n-5435\n2187\n3891\n5504\n4337\n3137\n-9570\n2350\n9955\n5628\n8522\n-165\n-7442\n-5330\n8494\n-8458\n5667\n-3922\n-5440\n-7066\n7265\n-8704\n490\n-5609\n-768\n1537\n-7702\n5884\n-1198\n4784\n1935\n-9959\n3985\n-1213\n-518\n-7078\n-9683\n-4973\n-2189\n9598\n-4616\n7220\n3335\n8211\n7294\n-5295\n4813\n-3329\n2697\n5383\n-2611\n4052\n-9056\n5442\n-5822\n8230\n2860\n2797\n2893\n1320\n7805\n9598\n-6575\n1307\n-3383\n7434\n7853\n-6166\n2096\n-2921\n-8558\n2689\n-2719\n9225\n-2812\n-7176\n6243\n-7995\n-7186\n8770\n-953\n-3986\n9430\n-9280\n5951\n254\n9268\n1664\n6491\n8121\n-6876\n2805\n-265\n8954\n5634\n-4938\n-6880\n7449\n-9839\n6036\n4772\n-5325\n3763\n-3455\n-8766\n1458\n-605\n-6746\n7846\n-8180\n8340\n9269\n7054\n-5084\n-98\n9491\n2893\n-8571\n3179\n2972\n-9473\n1502\n9398\n-621\n1562\n-1657\n1670\n9896\n7344\n-9187\n-2085\n-2781\n342\n-9159\n6214\n802\n-2429\n-7600\n4489\n-7485\n-4674\n2709\n-446\n-8240\n9394\n8159\n-4058\n5910\n-1281\n9760\n-6626\n5440\n4697\n-5100\n6509\n4256\n-4904\n244\n1154\n-7067\n-4251\n-4759\n5617\n-8546\n8747\n5770\n-4909\n1447\n612\n-8622\n2866\n-2947\n-1800\n-8985\n-3800\n-6839\n-1256\n-8119\n6427\n8187\n-4392\n-2980\n-7103\n-2337\n5830\n-3644\n4052\n4591\n-2181\n6072\n6905\n5783\n-3905\n-9064\n-3083\n4615\n-3437\n1133\n3153\n-1922\n-4065\n-8069\n-6436\n7889\n4440\n-7021\n-638\n-5127\n8977\n2839\n6777\n7054\n-5443\n3666\n-9640\n-1863\n-2244\n-8397\n6744\n9748\n5783\n7727\n-6548\n7052\n-4846\n-7240\n8565\n-6165\n-9038\n2975\n-6850\n-8567\n-7842\n4297\n-474\n-5606\n-4723\n-203\n-4902\n6313\n92\n-784\n-5997\n-2915\n-6920\n-8873\n-5885\n85\n-3035\n8715\n3763\n-4255\n6210\n5214\n3284\n-5662\n-585\n2621\n3569\n8826\n-9532\n-9323\n1430\n159\n-1831\n-373\n-5837\n-6559\n2129\n-6731\n2932\n-9463\n7930\n-5585\n9567\n2601\n-6215\n-4804\n9927\n-8269\n-9660\n6692\n7859\n855\n-3444\n-545\n-1924\n3776\n6273\n7774\n400\n5129\n6999\n-8423\n-243\n8011\n7236\n-555\n9279\n2752\n4931\n4728\n8293\n6421\n4497\n3458\n-8929\n9792\n-1333\n-4216\n1379\n-6254\n8851\n9346\n8174\n5712\n1899\n4115\n4437\n-7151\n6917\n9104\n-5838\n-1454\n779\n8637\n7494\n-7076\n7365\n3931\n-2719\n8075\n-5323\n-7745\n9761\n-5792\n5746\n5575\n9704\n-9334\n-8704\n9364\n-4196\n4914\n3552\n-6741\n-7272\n3199\n6427\n-3097\n-2195\n-3535\n-5885\n-7161\n-4290\n-5912\n5957\n9337\n-6472\n9037\n5573\n2384\n2474\n5497\n5889\n-9663\n-5332\n5913\n-48\n3398\n6039\n-1025\n4567\n-1689\n-7643\n8403\n6422\n2666\n4681\n7571\n9306\n-4140\n8668\n5961\n1728\n9600\n4567\n-9947\n7947\n2311\n7683\n4036\n-9118\n-1440\n7701\n-718\n7252\n-5748\n8074\n9077\n1430\n309\n7223\n7241\n6924\n-1726\n2580\n323\n9592\n-147\n9734\n-6509\n-2141\n9899\n8912\n-9095\n-1534\n-1722\n-6731\n-4674\n-5668\n9543\n2181\n-5971\n-4285\n-5435\n8785\n6022\n3483\n3442\n-4311\n-9718\n491\n-234\n-6505\n-2233\n1054\n1843\n-8170\n3725\n9367\n-9708\n2884\n575\n1466\n-4904\n-7163\n-6509\n-9898\n-1035\n4218\n-3782\n-7972\n4094\n-4022\n7344\n3528\n6745\n-8677\n-564\n599\n-1588\n-638\n-2547\n7384\n-3223\n-8978\n-3131\n2367\n38\n4294\n2227\n-4687\n-8416\n-7749\n-901\n5156\n5381\n7208\n9451\n-1072\n-6165\n4274\n-9330\n-5692\n-976\n8507\n-4214\n3267\n-693\n4016\n-4859\n4131\n2624\n-2195\n-5747\n-3433\n-5309\n4909\n-1789\n1970\n1113\n6654\n9294\n580\n2701\n-3072\n-1058\n-450\n-3553\n8842\n-6902\n5849\n-8210\n3129\n-4568\n7319\n9289\n1953\n-2772\n3176\n7831\n-5215\n-7078\n-269\n-9613\n-5990\n140\n-3349\n-1868\n-6378\n7029\n3786\n9495\n4946\n-3908\n5746\n7246\n6543\n3375\n-6525\n3179\n4829\n-5690\n-4458\n-5067\n3563\n-9505\n8886\n-6046\n8975\n-9892\n4232\n-3386\n6748\n5560\n-5068\n-4307\n8256\n-4803\n6559\n-726\n7262\n3603\n-6032\n-1753\n1072\n-3515\n1160\n-4265\n8809\n7319\n-2341\n-4621\n-5593\n4672\n-7252\n7876\n-2824\n-2708\n151\n6484\n2609\n2708\n-9044\n-7454\n4473\n-3075\n-5664\n1659\n9212\n-8951\n-3382\n8762\n7569\n-2142\n-3045\n-7361\n110\n6810\n1104\n-373\n-4500\n-9051\n-3242\n2221\n5025\n-4297\n-6710\n7853\n-6452\n7998\n-9213\n-7520\n-6727\n5334\n1096\n678\n-4395\n7679\n-4022\n6257\n-3939\n9591\n8016\n-4342\n8010\n5402\n1423\n8834\n6389\n9001\n5102\n3868\n-7905\n8265\n-2083\n6772\n-8806\n-1136\n-5612\n-5127\n-7981\n-5655\n480\n-3419\n368\n-2090\n5293\n7052\n4686\n3386\n-708\n3991\n-684\n-2381\n4228\n-9954\n-9993\n4285\n-6467\n6787\n-3366\n-4653\n-3731\n-4257\n-1246\n3925\n2320\n1536\n-3196\n-1374\n-5465\n-7690\n-716\n1929\n859\n3442\n3500\n-6460\n7761\n5628\n-4119\n4069\n9037\n105\n9498\n8235\n-2437\n3472\n-5420\n-6518\n3972\n-7627\n-8503\n6050\n4393\n-8440\n1986\n2187\n-5589\n2686\n3888\n-9356\n-543\n2822\n5302\n-7034\n-7778\n9334\n-5462\n-267\n-6891\n-2707\n7407\n8805\n7388\n6184\n3346\n6847\n-5971\n-417\n-3326\n-1592\n5544\n-6800\n7034\n-5441\n-9441\n-6987\n1815\n5783\n6926\n-4314\n-9892\n-1500\n2904\n-1946\n-9074\n-7659\n-4333\n-3553\n-916\n3237\n-7151\n-6030\n-8337\n418\n-9384\n1192\n2558\n7496\n-7729\n8273\n9305\n3827\n7519\n2133\n1879\n1001\n258\n-3963\n119\n4186\n5239\n-7204\n7704\n9534\n-8682\n-4772\n-7978\n5929\n6107\n506\n1760\n5782\n5895\n-3687\n-78\n-7125\n-534\n-4774\n6218\n9585\n8200\n-5340\n-9302\n3559\n8846\n3552\n1671\n-5477\n-9118\n7790\n-3757\n8365\n7394\n8465\n7245\n3956\n-592\n2205\n-5882\n6476\n-5732\n-6477\n6713\n4709\n4714\n7356\n-1080\n-983\n-9975\n-8190\n-7574\n828\n-6316\n3515\n451\n1098\n5400\n238\n480\n-5998\n-4376\n1974\n9915\n-7151\n-128\n-5130\n-4423\n8491\n3122\n7110\n-9930\n-7341\n-1882\n-3439\n8231\n1407\n-6444\n-4772\n-8872\n-2853\n8031\n6313\n-9629\n4347\n-5487\n-1799\n-1225\n8026\n6920\n4427\n3467\n-2158\n909\n8977\n-5982\n3825\n-718\n7908\n4464\n-1220\n693\n8293\n-8873\n5243\n3511\n8604\n-5990\n-4492\n-4091\n5688\n1240\n664\n3712\n3048\n-9240\n-5267\n247\n-2010\n5327\n-2030\n8030\n-5240\n-3302\n480\n4323\n-8323\n-4590\n2769\n8506\n-1556\n-1827\n-6216\n-4879\n-156\n-1447\n5967\n-1840\n-5838\n7409\n8444\n-5008\n-7949\n6069\n284\n-9103\n-8612\n797\n5615\n-2375\n-9861\n2789\n5978\n-59\n4821\n7116\n4054\n2816\n-8543\n-1099\n9062\n5718\n9635\n6353\n-3312\n1227\n2144\n5770\n9824\n-2918\n-7958\n4640\n1036\n7693\n-951\n5293\n-4364\n6883\n-4395\n7615\n1097\n8269\n-9907\n5813\n-5369\n4001\n-4965\n-4567\n8939\n-145\n3003\n-6977\n8293\n1299\n9247\n-2988\n7170\n6638\n431\n-8887\n3279\n-946\n-4148\n6039\n2067\n-282\n-71\n8031\n425\n-6890\n878\n-1532\n820\n-8918\n-5336\n1989\n-7692\n-1915\n-684\n7818\n254\n7294\n7865\n4192\n-6782\n-6593\n-9534\n-6708\n7805\n-6548\n-5502\n-6471\n-3453\n-736\n-60\n450\n-2995\n4978\n3135\n1408\n7241\n-4262\n-1352\n1200\n5332\n-3276\n-8900\n3210\n317\n1659\n-8895\n-68\n1728\n7241\n-5572\n8605\n2181\n7379\n5184\n3720\n-7081\n-906\n8125\n-4793\n-387\n-9056\n-6572\n5129\n9554\n-206\n3680\n-1500\n8300\n9128\n-6752\n1001\n8338\n-2893\n3567\n314\n4180\n-7983\n5575\n4745\n-302\n5910\n5877\n9130\n-4624\n490\n-6477\n508\n-2262\n5063\n9995\n5492\n-8571\n-2076\n-7245\n7531\n-4395\n5668\n-8525\n9198\n5457\n5282\n-9627\n-8023\n-4275\n-6099\n-9415\n5771\n3678\n-6865\n417\n-1681\n-9044\n8269\n610\n-7461\n-7621\n-4022\n5225\n-4529\n9988\n-2569\n9810\n1996\n1283\n9364\n-7877\n6015\n-7076\n-352\n-9273\n-3114\n-9044\n8524\n1634\n6057\n-5687\n1947\n4940\n2461\n-5043\n-4571\n-5986\n4391\n-9838\n6912\n-5398\n-318\n-5024\n1465\n3817\n8656\n4389\n-4034\n4052\n7988\n-8598\n9693\n7317\n4356\n783\n-5211\n-1854\n3219\n-3521\n-6814\n-4709\n6055\n1394\n-10\n3384\n403\n9590\n4927\n1524\n1098\n-9975\n9585\n6222\n499\n148\n-5770\n-4801\n-8148\n-7928\n3359\n-7612\n3226\n-4709\n1527\n-2568\n-5296\n3739\n-9003\n-806\n1984\n2059\n7955\n7818\n5364\n793\n6822\n3946\n151\n-9630\n9630\n2324\n662\n3333\n-8448\n6754\n437\n-2029\n-4255\n6568\n8500\n-3622\n810\n9004\n8653\n1164\n-8115\n-1858\n-2642\n611\n-7246\n-8085\n-6299\n-4599\n5226\n-4384\n-1024\n-4938\n-1431\n-6083\n2496\n6922\n4660\n1912\n-8991\n-8297\n-6895\n-9607\n1696\n6072\n-3326\n-5078\n1355\n7649\n1118\n-3072\n-5738\n-4741\n3892\n-647\n-6566\n-2195\n3768\n-1397\n-4046\n-3118\n-8531\n4909\n-6367\n5292\n-3083\n151\n-591\n3367\n-8325\n6439\n-6505\n-7330\n2456\n8503\n-5579\n5852\n-7902\n-667\n-3492\n-6341\n7979\n8307\n-29\n-8265\n-2614\n-4590\n-7186\n-3785\n-3744\n3300\n5701\n3678\n-2580\n527\n-120\n-7978\n-5319\n7443\n-5475\n-1506\n-7191\n-9281\n-7356\n-2628\n7251\n-1997\n3924\n-5266\n-8651\n9217\n5305\n9111\n-2939\n7519\n-8554\n-5596\n-3718\n-9826\n5615\n-3270\n7568\n-901\n-7112\n-7598\n7930\n-1075\n2380\n-9192\n-9157\n-9773\n-9061\n-4003\n2896\n4243\n7496\n3191\n4741\n9293\n-8230\n9568\n5013\n-7046\n-9040\n-3302\n2822\n-3767\n-6571\n2286\n9978\n-5369\n-3987\n321\n-9841\n-9334\n-4786\n1332\n2154\n350\n-1841\n-397\n238\n-1815\n-8499\n-4930\n8627\n3968\n1148\n-2153\n-4273\n279\n119\n-3390\n-4077\n-7011\n-2595\n140\n7960\n-6277\n6223\n4957\n-3939\n6988\n-5028\n-9901\n1603\n-5892\n-775\n-9280\n3171\n-1522\n5108\n4891\n3685\n4661\n-7643\n-552\n8337\n-5832\n8644\n3003\n-9386\n6223\n8612\n787\n-3622\n9641\n3003\n-9341\n-7802\n9602\n-3767\n-8598\n7949\n723\n-4998\n-6073\n-5646\n4880\n-2046\n7167\n1100\n6188\n-2993\n5320\n-4615\n-5113\n2264\n6658\n1364\n8910\n-8873\n-9623\n-1256\n5575\n7718\n-8815\n-8254\n4073\n2488\n-7385\n-9406\n-1283\n-2330\n439\n-2260\n-3460\n-1411\n1800\n-1868\n8900\n2905\n-7883\n-8724\n-6531\n7876\n6834\n9389\n8247\n-1522\n-2524\n7145\n-8339\n5056\n7401\n-8273\n3776\n-6665\n8064\n8148\n2243\n-7815\n1924\n-3212\n-6806\n4323\n904\n-4695\n9209\n-6907\n1291\n1529\n-4561\n-7375\n-1211\n2558\n-2141\n5043\n6989\n-5202\n-2176\n-5916\n2884\n-6187\n-3430\n-2237\n-1213\n5977\n-6300\n3245\n8531\n-4257\n-9381\n802\n-78\n-4860\n7008\n-4722\n1110\n9955\n3907\n1910\n8930\n-2195\n-3785\n5610\n5135\n3491\n7948\n3403\n-338\n1694\n-8961\n-3504\n-8033\n-9811\n6823\n6748\n8362\n-5673\n5260\n5914\n-809\n4578\n-2719\n2755\n-42\n1258\n1601\n767\n-347\n7552\n4349\n5549\n-9012\n-4066\n-3864\n6657\n-4258\n7015\n5905\n3870\n-7769\n3896\n3956\n1996\n8506\n-1060\n-5314\n6853\n-7459\n-5834\n-9179\n9981\n-5594\n3705\n-799\n1788\n6874\n-4405\n2345\n-5994\n-9878\n425\n3474\n323\n-4786\n-7819\n-5507\n-8999\n1683\n-5020\n-8423\n-9015\n-1037\n909\n-1304\n9494\n-4815\n7341\n2170\n4724\n-9026\n-5085\n-4041\n-4282\n8747\n2902\n5352\n3576\n-8931\n1536\n-8880\n376\n6995\n1446\n2811\n4310\n9204\n-6879\n-9143\n-78\n-2334\n5345\n3317\n-9839\n-8793\n-833\n4699\n-2420\n-3265\n-8066\n3885\n-7660\n-7341\n13\n8711\n-2510\n-8420\n-3856\n9808\n1921\n-2644\n-6183\n-6786\n7739\n4036\n-5541\n-9182\n4427\n7008\n-4938\n-228\n-3505\n7569\n1683\n5763\n-728\n2236\n-943\n5351\n-8467\n101\n-7916\n-9075\n1983\n-8025\n5674\n9528\n-2621\n6098\n8770\n4600\n6519\n-8724\n-3047\n6462\n5293\n-9484\n8464\n106\n-2368\n-2455\n9659\n-3489\n8326\n7198\n5617\n-1513\n-2437\n3380\n7835\n-517\n-4778\n-6895\n-7224\n3200\n2324\n4704\n-7740\n4029\n-4071\n723\n3889\n-5732\n-1338\n-7655\n9258\n-4148\n-8233\n4544\n804\n9968\n-6880\n5772\n-6405\n3637\n2752\n-5041\n6317\n1884\n-2007\n-2908\n-8629\n-5600\n9867\n-421\n-6378\n-5810\n7684\n3456\n-7571\n-9877\n-5828\n-2763\n9288\n491\n8692\n-5648\n4501\n-4434\n-569\n-3339\n1118\n-961\n516\n5412\n-9462\n8219\n2882\n7319\n-4920\n-7027\n-3528\n1097\n4900\n8282\n4135\n4658\n8008\n-8843\n9656\n7044\n-3992\n-5136\n-3968\n-4330\n-3265\n9567\n-2542\n497\n-5318\n-18\n-6056\n-3651\n9104\n-6477\n-2719\n5268\n5570\n703\n8809\n-4719\n7949\n-2175\n3009\n6939\n9709\n4264\n-7758\n5746\n-9630\n4579\n4909\n3571\n8199\n8743\n6349\n-5785\n1889\n1893\n4256\n-2987\n4089\n2112\n-4104\n1333\n-3443\n-7134\n77\n4963\n4908\n-9050\n-7842\n7564\n-9229\n-6378\n2975\n-7823\n6418\n269\n522\n-6300\n6174\n7005\n-5378\n-7981\n-9356\n-9072\n2569\n8999\n-6390\n-5935\n-5057\n2360\n-8700\n-3348\n-90\n3191\n1789\n-8654\n7768\n-6404\n-8873\n-6821\n4562\n1085\n4429\n-9579\n-7957\n7294\n-427\n-7934\n2968\n1508\n-6905\n-5993\n-1688\n-8417\n1780\n9540\n-4450\n1536\n5184\n8111\n9877\n3466\n2279\n-5254\n-6850\n6936\n-5318\n-7691\n-6390\n5400\n6108\n8351\n-9275\n-6229\n-5441\n-9950\n-5475\n1480\n5686\n-8082\n-128\n9648\n5982\n9904\n1974\n-4077\n-9764\n-4525\n-5834\n6285\n6559\n-6806\n1577\n-7459\n7276\n839\n9633\n-7440\n9191\n4709\n-7421\n-5043\n-2217\n-5419\n8031\n9873\n4658\n-2961\n-3223\n3226\n2189\n6134\n1939\n-4390\n-1323\n-240\n-8850\n6122\n7885\n1991\n2271\n6261\n-8012\n-6213\n-3041\n4125\n6966\n-5882\n-6915\n-5345\n-3925\n709\n978\n6321\n7461\n2433\n7315\n-4675\n-656\n-8237\n-7938\n-340\n-5314\n-4571\n1699\n1525\n-6613\n-2064\n4562\n6285\n4192\n-173\n7710\n-7469\n-3785\n-2248\n4375\n8399\n-833\n-427\n5295\n-7999\n7236\n-5517\n-5989\n-6017\n965\n-3883\n-7937\n7707\n-1892\n-2085\n8111\n-7516\n9569\n8043\n532\n-1663\n8001\n-1162\n9170\n-7059\n-8235\n-6865\n-9272\n6119\n-3662\n3870\n1339\n6589\n-4588\n-4322\n1549\n-9520\n6393\n7102\n621\n9389\n-4111\n5768\n-3700\n3018\n-5154\n-8234\n8634\n-2928\n-6425\n1709\n3657\n-9595\n-8276\n-844\n-4257\n770\n-4722\n-3718\n5091\n-8724\n7964\n5288\n8921\n-4719\n527\n-6946\n5186\n3598\n5259\n4359\n4147\n9435\n5992\n-6929\n1058\n-9752\n-4909\n4756\n-1902\n837\n6293\n6326\n7847\n-8692\n-9016\n8851\n8842\n8743\n1989\n-3991\n-6232\n-9571\n425\n2666\n9009\n4745\n-1197\n2866\n-2479\n8453\n-6310\n9490\n-1892\n-1313\n-2941\n-5062\n-4521\n-4219\n6337\n-2011\n7727\n-205\n2094\n2780\n6791\n3547\n-9513\n7262\n-9526\n-1306\n8873\n342\n6483\n376\n1897\n9068\n-5133\n1822\n-6727\n-3922\n-2009\n3515\n4391\n-3029\n2778\n7117\n8232\n6898\n-1425\n7289\n1346\n462\n-5431\n3643\n-7627\n8974\n-5687\n-7501\n5783\n132\n1799\n-6425\n-8416\n-8904\n8380\n-6216\n-6391\n-5792\n-5770\n4126\n-9622\n8842\n-2096\n2929\n-1438\n-3156\n-2796\n-7415\n1924\n6898\n6991\n-4968\n-8032\n998\n-3780\n1969\n8453\n2515\n-1596\n-6004\n3195\n-5012\n4594\n141\n1449\n2834\n-5076\n5824\n34\n3463\n-736\n-5096\n691\n3876\n5463\n6703\n-1072\n3853\n-7937\n-8593\n9037\n-2492\n1952\n2293\n-4422\n-2151\n5214\n5234\n5988\n-8011\n4501\n8970\n8678\n8386\n4525\n8340\n-7246\n-2570\n-5829\n2271\n-6614\n-8375\n-4515\n9674\n-2724\n-7871\n3973\n594\n3875\n1614\n-8339\n1879\n-7555\n5093\n6353\n-5309\n-9118\n-7390\n0\n-7598\n-4177\n8634\n7534\n1556\n349\n-9441\n3579\n-4653\n-2416\n-2194\n-4484\n-6483\n-5383\n-78\n-5205\n-1242\n813\n3590\n6240\n-3736\n-7390\n-7632\n5321\n-6299\n-4615\n-2210\n6188\n2372\n7060\n-5986\n-1632\n3032\n-5612\n-5336\n-8543\n3502\n1695\n4391\n2387\n4547\n1110\n-3353\n-545\n804\n-1809\n-5353\n7904\n8120\n5855\n1657\n-6626\n-6422\n-4870\n-1404\n-6229\n-3968\n2585\n2060\n-1821\n1577\n810\n-8408\n-7540\n7897\n279\n6039\n6656\n-9330\n2591\n8567\n-5495\n7354\n7443\n8697\n-9959\n925\n3180\n-6647\n8556\n-1018\n-1293\n9569\n-2128\n-1431\n7483\n-3984\n-649\n-8978\n4285\n262\n-5191\n-2759\n4835\n-5834\n1294\n-3856\n3084\n-8885\n-2708\n-1693\n-8948\n-6021\n1629\n3961\n2760\n2861\n-6797\n5184\n8419\n-9162\n6810\n-8473\n9899\n9844\n-2044\n-9103\n-3183\n-8697\n5303\n7412\n8344\n5003\n5957\n6327\n-8799\n2425\n-5159\n1732\n7934\n5728\n-7328\n-605\n-8552\n-6232\n-9200\n-3586\n6145\n8498\n-2780\n649\n5957\n3744\n-9775\n7645\n7354\n1335\n4195\n-5747\n6484\n8567\n7851\n1910\n8259\n-3384\n-9657\n2189\n-7643\n-5612\n-3674\n-6521\n-4128\n2187\n-3000\n-9708\n3052\n6262\n-4863\n8010\n3371\n5220\n-38\n3744\n-3828\n-6773\n-2962\n2887\n497\n425\n7873\n4140\n8657\n2461\n-7654\n8640\n6365\n4225\n6829\n4186\n2301\n-2793\n-6554\n7241\n-7102\n659\n-7999\n9335\n-1223\n-7090\n6542\n-2019\n-873\n-9624\n6293\n6039\n-6108\n8204\n2860\n5098\n-7132\n9694\n-1973\n-1217\n-3264\n-7112\n8296\n-8850\n4014\n-1837\n480\n-7667\n8005\n4750\n1059\n-4798\n-187\n4728\n7007\n-2369\n505\n-590\n-1827\n9692\n-6294\n9115\n9756\n2380\n4533\n-8557\n6450\n9019\n9514\n-6594\n7060\n2477\n2259\n-5578\n-85\n7356\n6055\n7649\n-2742\n29\n-5146\n-7621\n-2829\n-2427\n-3827\n6197\n9143\n-9622\n-4062\n-6232\n-1470\n2591\n7104\n-206\n9517\n-8918\n4658\n-7199\n-48\n2662\n6782\n-4705\n-9459\n-3950\n-9057\n-2526\n4866\n5611\n-7128\n4238\n1706\n-9179\n-6611\n5615\n-3148\n5074\n-9463\n-4435\n266\n4733\n-1242\n4407\n5334\n-2856\n-3600\n2666\n9396\n-1224\n-7132\n1957\n-3651\n-8843\n-8699\n-6879\n-9957\n-648\n-8212\n6511\n-2657\n5351\n7541\n8556\n7344\n-3734\n-4679\n-9580\n8416\n-8\n3976\n-8397\n-2827\n3666\n-3230\n-9044\n-9821\n-3836\n-8100\n-1502\n-4011\n-4569\n9761\n-8261\n4533\n9424\n-9374\n-6630\n4941\n2496\n-1902\n1491\n-9374\n3398\n2018\n-9983\n-6165\n1750\n-5885\n-383\n-2319\n9426\n5058\n8016\n-8079\n-576\n7192\n5003\n-5885\n-414\n-6455\n2511\n662\n-2997\n9240\n2670\n6145\n-6745\n-3414\n-6450\n-2425\n-335\n2475\n3671\n-4809\n-5888\n-3508\n4522\n-2626\n2970\n9659\n4590\n-4730\n-4722\n-5018\n-916\n4268\n-7102\n-2070\n-5414\n3533\n-6170\n-2247\n-6590\n-7211\n5153\n1360\n-2995\n-9954\n-7684\n-2668\n-335\n9352\n-698\n-133\n-3571\n-3419\n-4821\n-4222\n1603\n-4835\n-2259\n1547\n-2244\n8811\n-151\n-1201\n1008\n2212\n-739\n-9308\n-3766\n8964\n-240\n4044\n8368\n1944\n6672\n7953\n3481\n-4273\n-3961\n-6222\n-9274\n5345\n5834\n-4737\n9009\n-7920\n1128\n8227\n6031\n-4925\n-1714\n-6649\n-460\n183\n9207\n-6046\n2196\n-5435\n2797\n9783\n5909\n1103\n-6800\n9507\n-9967\n7643\n-7489\n4104\n-8978\n8732\n8582\n8013\n-2724\n-9453\n645\n-5489\n-3939\n-5242\n3400\n6392\n3355\n-2111\n-6056\n-8164\n-3053\n-6399\n1921\n-9171\n-68\n-4051\n-5292\n-2462\n-4215\n4733\n-1397\n47\n-5508\n425\n-1883\n-4273\n-8058\n-3972\n7223\n5112\n2154\n-5770\n7949\n8859\n-6140\n876\n7153\n4082\n-1025\n4462\n3629\n7006\n-1790\n2221\n-4133\n-5881\n259\n720\n-6333\n-953\n-749\n1092\n-1037\n4657\n8842\n4075\n-163\n9342\n558\n-5932\n-2319\n-5168\n-8259\n4266\n1592\n2389\n6351\n8556\n6039\n-248\n-6163\n-116\n7369\n-5998\n-2572\n-5181\n-8613\n372\n-8880\n-9597\n4453\n-9775\n-2547\n9640\n-1404\n9001\n8351\n5364\n3377\n-5316\n7518\n1801\n7070\n-4133\n5740\n1146\n-5307\n-9975\n-3460\n7818\n-1809\n-6152\n-1204\n3292\n3734\n-7803\n4001\n-5202\n5747\n1526\n-3045\n-5540\n6697\n2618\n7086\n4230\n1282\n2755\n-5638\n-5562\n-108\n2600\n-4321\n-2492\n-9473\n5957\n-1133\n-892\n5765\n3675\n-6046\n5497\n-773\n7607\n1526\n-9037\n1789\n1944\n-4342\n-5042\n-7299\n-9663\n-472\n-6905\n-4902\n7109\n-6946\n-9443\n1957\n-1247\n3834\n1904\n4014\n9367\n-5834\n4013\n-3265\n-9544\n7826\n-5557\n3747\n1848\n-2747\n1763\n7110\n9740\n-6326\n1550\n-8806\n886\n-1692\n621\n-2318\n-2134\n8851\n-9455\n6829\n6212\n4231\n-9032\n5475\n1265\n-266\n-266\n-7812\n831\n6041\n-787\n178\n7112\n-753\n1676\n6785\n-3034\n-7140\n-6678\n1425\n3896\n-8604\n-4845\n-3478\n6291\n70\n8512\n-1011\n-6948\n4547\n8822\n9089\n-3883\n8273\n6755\n2170\n-7420\n8031\n-1800\n837\n-485\n-8679\n-3348\n5730\n9397\n-2344\n3651\n5514\n1688\n-5743\n8640\n-8667\n-9101\n372\n-2657\n-3782\n7262\n6058\n-7034\n-7193\n6004\n-1135\n-2223\n-7027\n-4662\n-1242\n2456\n-6222\n6197\n6695\n4025\n-7363\n3533\n9713\n-6273\n-7379\n1355\n-383\n-1882\n-9203\n7521\n-8303\n-4640\n-240\n4398\n-3756\n5300\n2396\n9107\n6837\n9589\n-8655\n-3455\n7931\n5288\n6212\n8644\n-4086\n-5556\n-3605\n6591\n8482\n-7391\n7898\n821\n-9683\n-2569\n-7078\n4879\n9921\n-9772\n-1675\n5588\n1058\n-860\n-7392\n-3218\n5499\n6216\n4473\n6210\n-5278\n132\n-1231\n2585\n-7112\n-3865\n4741\n1892\n4073\n4142\n3887\n-8210\n4239\n-3057\n-1247\n-197\n-8115\n-1883\n2029\n6337\n-5321\n-798\n7434\n2029\n-4894\n-7469\n5746\n3214\n-2885\n9598\n-3215\n-4772\n4645\n5263\n6055\n3744\n7774\n3461\n-4734\n6680\n-5585\n1891\n1542\n-7905\n-2908\n-425\n9432\n1695\n-8178\n3503\n-1293\n2028\n-9261\n-8178\n-8058\n8489\n-7812\n-3736\n-3056\n-6157\n8653\n-5405\n1096\n-333\n-9319\n3339\n1335\n4123\n4547\n-4432\n4946\n-3545\n3156\n2462\n9946\n51\n-1134\n6576\n-3436\n5617\n-6425\n-1506\n3201\n2905\n4238\n-5132\n5409\n6349\n2760\n491\n6999\n-6552\n4265\n-9103\n6039\n-9163\n-9496\n7860\n-3785\n13\n8842\n-4772\n-9622\n3261\n271\n-7660\n4662\n5858\n-8431\n-8779\n-559\n9284\n9303\n8780\n3892\n-7479\n8794\n-4622\n-5606\n3466\n-4134\n7344\n-2691\n3375\n-1133\n-2429\n-448\n3443\n-8201\n-3057\n6113\n-5562\n2311\n6427\n-5692\n403\n7459\n1549\n-1563\n1954\n-9166\n-5462\n2189\n853\n8443\n-9894\n-4630\n-2070\n-7034\n-2206\n723\n-1228\n-2484\n2467\n7607\n5293\n870\n-2064\n2329\n-873\n9483\n-6800\n353\n2028\n8549\n8964\n9408\n9007\n-8406\n-2484\n3870\n9519\n-5874\n5176\n-919\n-5452\n-1890\n-9887\n3275\n2816\n7647\n-1376\n742\n5574\n2305\n-9003\n9633\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_20_questions.txt",
    "content": "--- Day 20: Grove Positioning System ---\n\nIt's finally time to meet back up with the Elves.\nWhen you try to contact them, however, you get no reply.\nPerhaps you're out of range?\n\nYou know they're headed to the grove where the star fruit grows,\nso if you can figure out where that is, you should be able to meet\nback up with them.\n\nFortunately, your handheld device has a file (your puzzle input)\nthat contains the grove's coordinates!\nUnfortunately, the file is encrypted - just in case the device\nwere to fall into the wrong hands.\n\nMaybe you can decrypt it?\n\nWhen you were still back at the camp, you overheard some Elves\ntalking about coordinate file encryption.\nThe main operation involved in decrypting the file is called mixing.\n\nThe encrypted file is a list of numbers.\nTo mix the file, move each number forward or backward in the file\na number of positions equal to the value of the number being moved.\nThe list is circular, so moving a number off one end of the list\nwraps back around to the other end as if the ends were connected.\n\nFor example, to move the 1 in a sequence like 4, 5, 6, 1, 7, 8, 9,\nthe 1 moves one position forward: 4, 5, 6, 7, 1, 8, 9.\nTo move the -2 in a sequence like 4, -2, 5, 6, 7, 8, 9,\nthe -2 moves two positions backward, wrapping around: 4, 5, 6, 7, 8, -2, 9.\n\nThe numbers should be moved in the order they originally\nappear in the encrypted file. Numbers moving around during\nthe mixing process do not change the order in which the numbers are moved.\n\nConsider this encrypted file:\n\n1\n2\n-3\n3\n-2\n0\n4\n\nMixing this file proceeds as follows:\n\nInitial arrangement:\n1, 2, -3, 3, -2, 0, 4\n\n1 moves between 2 and -3:\n2, 1, -3, 3, -2, 0, 4\n\n2 moves between -3 and 3:\n1, -3, 2, 3, -2, 0, 4\n\n-3 moves between -2 and 0:\n1, 2, 3, -2, -3, 0, 4\n\n3 moves between 0 and 4:\n1, 2, -2, -3, 0, 3, 4\n\n-2 moves between 4 and 1:\n1, 2, -3, 0, 3, 4, -2\n\n0 does not move:\n1, 2, -3, 0, 3, 4, -2\n\n4 moves between -3 and 0:\n1, 2, -3, 4, 0, 3, -2\n\nThen, the grove coordinates can be found by looking at the 1000th,\n2000th, and 3000th numbers after the value 0, wrapping around the\nlist as necessary. In the above example, the 1000th number after 0\nis 4, the 2000th is -3, and the 3000th is 2;\nadding these together produces 3.\n\nMix your encrypted file exactly once.\nWhat is the sum of the three numbers that form the grove coordinates?\n\n--- Part Two ---\n\nThe grove coordinate values seem nonsensical.\nWhile you ponder the mysteries of Elf encryption, you suddenly\nremember the rest of the decryption routine you overheard back at camp.\n\nFirst, you need to apply the decryption key, 811589153.\nMultiply each number by the decryption key before you begin;\nthis will produce the actual list of numbers to mix.\n\nSecond, you need to mix the list of numbers ten times.\nThe order in which the numbers are mixed does not change during mixing;\nthe numbers are still moved in the order they appeared in the original,\npre-mixed list. (So, if -3 appears fourth in the original list of numbers\nto mix, -3 will be the fourth number to move during each round of mixing.)\n\nUsing the same example as above:\n\nInitial arrangement:\n811589153, 1623178306, -2434767459, 2434767459, -1623178306, 0, 3246356612\n\nAfter 1 round of mixing:\n0, -2434767459, 3246356612, -1623178306, 2434767459, 1623178306, 811589153\n\nAfter 2 rounds of mixing:\n0, 2434767459, 1623178306, 3246356612, -2434767459, -1623178306, 811589153\n\nAfter 3 rounds of mixing:\n0, 811589153, 2434767459, 3246356612, 1623178306, -1623178306, -2434767459\n\nAfter 4 rounds of mixing:\n0, 1623178306, -2434767459, 811589153, 2434767459, 3246356612, -1623178306\n\nAfter 5 rounds of mixing:\n0, 811589153, -1623178306, 1623178306, -2434767459, 3246356612, 2434767459\n\nAfter 6 rounds of mixing:\n0, 811589153, -1623178306, 3246356612, -2434767459, 1623178306, 2434767459\n\nAfter 7 rounds of mixing:\n0, -2434767459, 2434767459, 1623178306, -1623178306, 811589153, 3246356612\n\nAfter 8 rounds of mixing:\n0, 1623178306, 3246356612, 811589153, -2434767459, 2434767459, -1623178306\n\nAfter 9 rounds of mixing:\n0, 811589153, 1623178306, -2434767459, 3246356612, 2434767459, -1623178306\n\nAfter 10 rounds of mixing:\n0, -2434767459, 1623178306, 3246356612, -1623178306, 2434767459, 811589153\n\nThe grove coordinates can still be found in the same way. Here, the 1000th\nnumber after 0 is 811589153, the 2000th is 2434767459, and the 3000th\nis -1623178306; adding these together produces 1623178306.\n\nApply the decryption key and mix your encrypted file ten times.\nWhat is the sum of the three numbers that form the grove coordinates?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_21.adb",
    "content": "--  Solution to Advent of Code 2022, Day 21\n-------------------------------------------\n--  Monkey Math\n--\n--  https://adventofcode.com/2022/day/21\n--  Copy of questions in: aoc_2022_21_questions.txt\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_2022_21_Pkg;\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and GNAT (64-bit integer: Integer_64):\nwith Interfaces;\n\nprocedure AoC_2022_21 is\n\n  use AoC_2022_21_Pkg, AoC_Toolbox;\n  use HAT, Interfaces;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbose : constant Boolean := not compiler_test_mode;\n\n  T0 : constant Time := Clock;\n  r : array (1 .. 2) of Integer_64;\n\n  function Search (choice : Data_Type) return Integer_64 is\n\n    function f (x : Integer_64) return Integer_64 is\n    begin\n      case choice is\n        when mini  => return Compute_Mini (part_2, x);\n        when input => return Compute (part_2, x);\n      end case;\n    end f;\n\n    x1, x2, x, y1, y2, y : Integer_64;\n\n    procedure Show is\n    begin\n      Put_Line\n        (+\"   x in [\" &\n         Integer_64'Image (x1) & \" ..\" &\n         Integer_64'Image (x2) & \"] : \" &\n         Integer_64'Image (y1) & \", \" &\n         Integer_64'Image (y2));\n    end Show;\n\n  begin\n    x := 1;\n    if verbose then\n      Put_Line (\"Range extension phase:\");\n    end if;\n    loop\n      x1 := -x;\n      x2 := +x;\n      y1 := f (x1);\n      y2 := f (x2);\n      if verbose then\n        Show;\n      end if;\n      exit when Sgn_64 (y1) /= Sgn_64 (y2);\n      x := x * 2;\n    end loop;\n    if y1 = 0 then\n      return x1;\n    elsif y2 = 0 then\n      return x2;\n    end if;\n    --  From here, y1 and y2 are non-zero, with different signs.\n    if verbose then\n      Put_Line (\"Range narrowing phase:\");\n    end if;\n    loop\n      x := (x1 + x2) / 2;\n      y := f (x);\n      if y = 0 then\n        return x;\n      end if;\n      if Sgn_64 (y) = Sgn_64 (y1) then\n        --  The zero is *not* between x1 and x.\n        x1 := x;\n        y1 := y;\n      else\n        x2 := x;\n        y2 := y;\n      end if;\n      if verbose then\n        Show;\n      end if;\n      exit when x1 = x2;\n    end loop;\n    Put_Line (\"Non-integer zero...\");\n    return 666;\n  end Search;\n\nbegin\n  if verbose then\n    Put_Line\n      (\"Example: simple computation: \" &\n       Integer_64'Image (Compute_Mini (part_1, 0)));\n  end if;\n  r (1) := Compute (part_1, 0);\n\n  if verbose then\n    for i in 300 .. 303 loop\n      Put_Line\n        (+\"Example: difference at root, human = \" & i & \" : \" &\n         Integer_64'Image (Compute_Mini (part_2, Integer_64 (i))));\n    end loop;\n    Put_Line\n      (+\"Example: search minimum: \" & Integer_64'Image (Search (mini)));\n  end if;\n  r (2) := Search (input);\n\n  if verbose then\n    Put_Line (\"Some values around the zero:\");\n    for i in r (2) - 3 .. r (2) + 2 loop\n      Put_Line\n        (\"   x = \" &\n         Integer_64'Image (i) & \" : \" &\n         Integer_64'Image (Compute (part_2, i)));\n    end loop;\n    New_Line;\n  end if;\n\n  if compiler_test_mode then\n    if r (1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: evaluation . . . . :\" & Integer_64'Image (r (1)));\n    Put_Line (+\"Part 2: search of zero . . :\" & Integer_64'Image (r (2)));\n    --  Part 1: validated by AoC: 286698846151845\n    --  Part 2: validated by AoC: 3759566892641\n  end if;\nend AoC_2022_21;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_21_pkg.adb",
    "content": "package body AoC_2022_21_Pkg is\n\n  function Compute_Mini (part : Part_Type; human : Integer_64) return Integer_64\n  is\n    function Eval (m : Monkey_Mini) return Integer_64 is\n    begin\n      case m is\n        when root_m =>\n          case part is\n            when part_1 => return Eval (pppw) + Eval (sjmn);\n            when part_2 => return Eval (pppw) - Eval (sjmn);\n          end case;\n        when dbpl   => return 5;\n        when cczh   => return Eval (sllz) + Eval (lgvd);\n        when zczc   => return 2;\n        when ptdq   => return Eval (humn_m) - Eval (dvpt);\n        when dvpt   => return 3;\n        when lfqf   => return 4;\n        when humn_m =>\n          case part is\n            when part_1 => return 5;\n            when part_2 => return human;\n          end case;\n        when ljgn   => return 2;\n        when sjmn   => return Eval (drzm) * Eval (dbpl);\n        when sllz   => return 4;\n        when pppw   => return Eval (cczh) / Eval (lfqf);\n        when lgvd   => return Eval (ljgn) * Eval (ptdq);\n        when drzm   => return Eval (hmdt) - Eval (zczc);\n        when hmdt   => return 32;\n      end case;\n    end Eval;\n  begin\n    return Eval (root_m);\n  end Compute_Mini;\n\n  function Compute (part : Part_Type; human : Integer_64) return Integer_64 is\n    function Eval (m : Monkey) return Integer_64 is\n    begin\n      case m is\n        when rmmz => return 2;\n        when vdjz => return 4;\n        when rqbd => return 3;\n        when zvqw => return 4;\n        when sshm => return Eval (qhnd) * Eval (lrcj);\n        when dtzl => return Eval (rnbs) + Eval (gppj);\n        when gnzq => return 5;\n        when zlpv => return Eval (pmng) * Eval (wgvj);\n        when nqgr => return 4;\n        when tftg => return 1;\n        when fhjc => return Eval (sbpb) / Eval (nhcr);\n        when fwbm => return Eval (jcch) * Eval (qhlj);\n        when wtlq => return 3;\n        when nzhf => return Eval (fjzn) * Eval (bnws);\n        when nqpq => return 2;\n        when jqzv => return 2;\n        when crrj => return Eval (vnbv) / Eval (grww);\n        when glpw => return 8;\n        when cnbg => return Eval (jmbp) * Eval (jnqv);\n        when bdcm => return 2;\n        when bcww => return 11;\n        when wrbf => return 2;\n        when hpvb => return Eval (zswl) * Eval (qpbz);\n        when qffb => return Eval (jvqz) + Eval (qgtf);\n        when mfmc => return Eval (hnbn) * Eval (twwv);\n        when cnzj => return Eval (qqdn) * Eval (pvtb);\n        when wbnh => return Eval (cshj) * Eval (snvw);\n        when swds => return Eval (bmlj) + Eval (scdn);\n        when twtb => return 3;\n        when dlgc => return Eval (gfbw) + Eval (djgh);\n        when bvzn => return 2;\n        when gwpm => return Eval (rrll) + Eval (zshp);\n        when rtnf => return Eval (qbwf) + Eval (bqnn);\n        when sdmb => return 15;\n        when mtjq => return 2;\n        when dpmg => return 3;\n        when drct => return Eval (bvfr) + Eval (rtmh);\n        when zrpj => return Eval (gfml) * Eval (tsms);\n        when gwlm => return 2;\n        when msdr => return 3;\n        when fqbl => return Eval (wbbf) + Eval (pbgr);\n        when zwqw => return Eval (lnqm) - Eval (nzdj);\n        when lbvn => return Eval (zwbh) + Eval (btbn);\n        when dggg => return Eval (bnmf) / Eval (trpv);\n        when bjwg => return Eval (trdj) + Eval (lpqs);\n        when bnzl => return Eval (vfhg) * Eval (pjds);\n        when qtmp => return 2;\n        when llpf => return 2;\n        when zwqn => return Eval (lfhb) + Eval (spcf);\n        when trpt => return Eval (mdrm) * Eval (qdrc);\n        when lzgm => return Eval (jzvg) + Eval (qlzg);\n        when swhh => return 2;\n        when tpnf => return 15;\n        when rgrp => return 7;\n        when zswl => return 3;\n        when gzbv => return Eval (djgb) + Eval (dvwj);\n        when ppfs => return 5;\n        when nfhf => return 5;\n        when pgrc => return Eval (pdmb) * Eval (qgwg);\n        when jjwr => return 6;\n        when fvsf => return 2;\n        when qmvq => return Eval (hlzp) * Eval (zvvd);\n        when twjq => return 2;\n        when twsj => return 5;\n        when mwrc => return 2;\n        when sbpb => return Eval (djpm) * Eval (pfpt);\n        when cbjq => return Eval (ztqg) - Eval (tzls);\n        when mgsl => return 2;\n        when vzgd => return Eval (qmcb) + Eval (wfbz);\n        when qrll => return 2;\n        when slpm => return Eval (fbpz) * Eval (jjwr);\n        when rffd => return Eval (mfmc) / Eval (csdf);\n        when jjbm => return Eval (slpc) * Eval (bncr);\n        when pjds => return Eval (cpqv) + Eval (ldtj);\n        when btfl => return Eval (qvfg) + Eval (lqdf);\n        when sfcv => return 7;\n        when vtnq => return 5;\n        when fzdp => return Eval (fzrd) * Eval (slww);\n        when cwjp => return 9;\n        when mpnj => return 2;\n        when wnbb => return Eval (zssf) + Eval (qnld);\n        when nfgv => return Eval (lzhf) + Eval (mqzw);\n        when pszs => return 4;\n        when chpt => return 2;\n        when bhpw => return Eval (cnbg) + Eval (zrnz);\n        when dfps => return 5;\n        when pzqv => return 3;\n        when fjzz => return 8;\n        when ffqr => return 16;\n        when bqvg => return Eval (lrqh) + Eval (wpdn);\n        when qlmg => return Eval (mpvz) + Eval (wpvg);\n        when lfhb => return Eval (jscq) + Eval (bpnt);\n        when pqqj => return 2;\n        when qhtv => return 5;\n        when wchl => return Eval (ffqr) + Eval (mdnp);\n        when vcwt => return Eval (llfg) + Eval (wjtc);\n        when nfbp => return 2;\n        when bbcn => return 8;\n        when smld => return 2;\n        when mvmj => return Eval (lqdc) * Eval (bhmz);\n        when mqph => return Eval (jjgt) + Eval (vtjg);\n        when brmz => return Eval (mpfm) + Eval (zcgs);\n        when ttdb => return Eval (zncl) + Eval (nqpv);\n        when bcsc => return 6;\n        when frjj => return 9;\n        when jcjf => return Eval (lgpg) + Eval (qmvq);\n        when pmfh => return 3;\n        when drrf => return 9;\n        when lmht => return 7;\n        when sstg => return Eval (vrct) + Eval (wfjn);\n        when swhz => return Eval (zvvp) * Eval (dbvt);\n        when rtpz => return Eval (nnsc) + Eval (zmlh);\n        when qrzq => return 2;\n        when rtmt => return 12;\n        when pmds => return 3;\n        when vfzw => return Eval (jhlw) * Eval (vmzc);\n        when smhv => return Eval (ffnt) * Eval (gtwp);\n        when vdzv => return 5;\n        when btqb => return 3;\n        when wclq => return Eval (rwth) + Eval (drln);\n        when vzrz => return Eval (bsvc) + Eval (vmjn);\n        when ztct => return Eval (zscd) / Eval (lhml);\n        when zvvd => return Eval (tcqz) - Eval (cmnv);\n        when mfrc => return Eval (jmcp) + Eval (lpvs);\n        when sdrn => return 9;\n        when jfvq => return Eval (pgdw) + Eval (vbvt);\n        when qjrs => return Eval (qvpw) + Eval (cpdf);\n        when tnnt => return Eval (psfr) + Eval (hjlz);\n        when fqlp => return Eval (bblh) + Eval (dbfm);\n        when nwhm => return 3;\n        when rlcw => return 2;\n        when rwjc => return Eval (ljzj) + Eval (zdrh);\n        when tfqh => return 5;\n        when crqg => return 3;\n        when nrps => return Eval (lrdn) + Eval (hmfb);\n        when pmng => return Eval (gzrs) + Eval (vtns);\n        when gmzt => return Eval (tlmq) * Eval (bfzd);\n        when fhdz => return 6;\n        when fwzf => return 4;\n        when tzls => return Eval (fnqf) + Eval (fpcs);\n        when pvtb => return 2;\n        when gpdf => return Eval (zslv) * Eval (qwqc);\n        when zcgs => return Eval (jlmb) * Eval (crnb);\n        when clbn => return 2;\n        when wghf => return Eval (fwbm) - Eval (jcjf);\n        when vffj => return Eval (frjp) + Eval (mrtq);\n        when gfbw => return Eval (csfh) + Eval (rlvd);\n        when tzth => return Eval (tvtj) * Eval (bnvg);\n        when vwhb => return 2;\n        when scwp => return 3;\n        when rpbm => return 3;\n        when zdhf => return 2;\n        when fdmf => return 3;\n        when lqdf => return 2;\n        when rndt => return Eval (wtbs) + Eval (lrsc);\n        when jnzr => return 5;\n        when qpqs => return Eval (bcng) / Eval (nwdv);\n        when tmhg => return Eval (vtvn) - Eval (nzbp);\n        when dtfz => return Eval (bdgd) * Eval (dfdl);\n        when pnvc => return Eval (brqb) * Eval (drrq);\n        when mfnh => return Eval (rdhg) * Eval (rmvq);\n        when vjgb => return 3;\n        when czvm => return 18;\n        when qhnd => return 3;\n        when dhfw => return Eval (jmcf) + Eval (vjjw);\n        when nqpv => return Eval (bhvg) + Eval (zmvz);\n        when rhcv => return Eval (ddtd) / Eval (jqzv);\n        when lqqh => return 5;\n        when mspl => return 5;\n        when ngps => return 11;\n        when bcmp => return 2;\n        when nlsw => return Eval (gnjq) * Eval (vzrz);\n        when mhlj => return 4;\n        when bqnn => return Eval (pgrc) - Eval (bwff);\n        when fbqs => return 11;\n        when cnln => return Eval (sqml) * Eval (wlqd);\n        when vjbz => return 5;\n        when vhhz => return Eval (pwpn) * Eval (dsng);\n        when crmb => return 5;\n        when wbgs => return 3;\n        when qhvn => return 3;\n        when lsnd => return 1;\n        when hhcv => return 2;\n        when vmjn => return 12;\n        when fbtc => return 2;\n        when jgnj => return 4;\n        when jmcp => return 2;\n        when mfhg => return 2;\n        when ztdn => return 2;\n        when zttf => return 3;\n        when tjwt => return 16;\n        when lzzh => return 11;\n        when rnns => return Eval (frrn) * Eval (pnmc);\n        when ffnn => return 3;\n        when wpvg => return Eval (qvpv) * Eval (frqq);\n        when wjds => return 3;\n        when nnmh => return 5;\n        when jswz => return Eval (vthd) - Eval (jjrh);\n        when qjqw => return 2;\n        when bndd => return 7;\n        when mdpg => return 2;\n        when wtwb => return 2;\n        when nbfg => return Eval (vwvc) * Eval (rbtb);\n        when nmts => return Eval (pfml) * Eval (jqqs);\n        when nvjf => return Eval (mddc) * Eval (lrbp);\n        when gqgh => return Eval (wzsh) * Eval (tqzv);\n        when btqt => return Eval (qbzv) + Eval (wtrh);\n        when cblz => return 5;\n        when nvpd => return 3;\n        when vldc => return 2;\n        when drhw => return Eval (dngq) * Eval (nmlt);\n        when bpjf => return Eval (ndlf) + Eval (tjwt);\n        when dpgl => return 2;\n        when ggnd => return 3;\n        when qzpn => return 2;\n        when ttvz => return 2;\n        when qwqc => return 3;\n        when zhmb => return 15;\n        when nzdj => return Eval (svvh) + Eval (qplw);\n        when rrnp => return Eval (qrnj) + Eval (hmvq);\n        when mbvg => return Eval (sgzh) / Eval (mdpg);\n        when mlbw => return Eval (jwwv) * Eval (jhzw);\n        when wvfb => return Eval (mvmj) + Eval (phjj);\n        when tzhp => return 15;\n        when zjcn => return Eval (pgfr) * Eval (dgvh);\n        when wbbf => return Eval (ghvn) * Eval (dfrb);\n        when mfsz => return Eval (fpvs) * Eval (lzgm);\n        when bfpq => return Eval (tmhg) * Eval (nvlv);\n        when vpvl => return Eval (blnq) * Eval (jfsr);\n        when pnrv => return Eval (lfrb) - Eval (qwnt);\n        when lbgc => return Eval (bzdh) * Eval (wszm);\n        when pbdd => return Eval (dcpm) * Eval (nrsd);\n        when jsrb => return 13;\n        when bbzt => return 8;\n        when mhdn => return Eval (bsmm) * Eval (rzzg);\n        when jpcd => return 2;\n        when ldzb => return Eval (nqpr) * Eval (qnds);\n        when nmlg => return 2;\n        when pnpc => return 5;\n        when rbqt => return 5;\n        when dsqb => return Eval (mrjc) / Eval (ftqd);\n        when zhqg => return Eval (lpjr) * Eval (zttf);\n        when dphz => return 3;\n        when gbzd => return Eval (ttvz) * Eval (tsjq);\n        when cldm => return 4;\n        when ftbq => return 5;\n        when rzff => return Eval (gdpg) + Eval (cgvs);\n        when tzcd => return 1;\n        when gzwh => return Eval (bjfh) * Eval (qtfp);\n        when qgnb => return Eval (vdgt) + Eval (zwwb);\n        when jzvg => return 5;\n        when qqwz => return Eval (pnwh) * Eval (wlmv);\n        when jbtg => return 9;\n        when rrgh => return 2;\n        when bvfr => return Eval (jzcd) + Eval (gjbv);\n        when mwdl => return Eval (rlcw) * Eval (jffq);\n        when chfs => return Eval (mrlq) - Eval (cgvv);\n        when gwmr => return Eval (hbwh) * Eval (wzdj);\n        when qcml => return 3;\n        when zbhj => return Eval (ctqb) * Eval (hfbg);\n        when zshp => return Eval (wphq) * Eval (hzpr);\n        when pvcs => return 4;\n        when sszh => return 2;\n        when jdsc => return 15;\n        when ndnm => return 8;\n        when lrlz => return 1;\n        when wpbs => return 2;\n        when bcpn => return 7;\n        when glts => return Eval (gpdf) - Eval (vznc);\n        when qnld => return Eval (jrvp) * Eval (smnv);\n        when hrtv => return Eval (bdcm) * Eval (cgnr);\n        when zbbf => return Eval (shtz) + Eval (fvsb);\n        when vvbz => return Eval (bqht) * Eval (zwqn);\n        when vvjg => return Eval (zgzs) * Eval (sbpp);\n        when lrlg => return 10;\n        when zpht => return 10;\n        when ndtz => return Eval (cnzj) + Eval (qsml);\n        when stcv => return 3;\n        when jjrh => return Eval (mlwr) * Eval (dqjz);\n        when hsbr => return Eval (dbcs) / Eval (zngg);\n        when wtrh => return Eval (sclr) + Eval (chsm);\n        when jfqs => return 15;\n        when hjgd => return 12;\n        when hgnr => return 9;\n        when brqb => return 4;\n        when ndsm => return Eval (tmhl) + Eval (ddln);\n        when fjgh => return Eval (cbjl) + Eval (pchr);\n        when tptf => return 3;\n        when njcj => return Eval (ppll) * Eval (psfp);\n        when jjvz => return Eval (vhqz) + Eval (fmvw);\n        when grww => return 2;\n        when jvqf => return 2;\n        when sgvm => return Eval (vhwz) * Eval (gzgm);\n        when zscd => return Eval (dshq) * Eval (tbwl);\n        when mgjl => return 3;\n        when bfgp => return Eval (jbvq) * Eval (ppcl);\n        when mpst => return Eval (zzpd) * Eval (qcnn);\n        when wjzd => return Eval (vwht) * Eval (pzcc);\n        when wqdj => return Eval (zvmv) + Eval (sntb);\n        when csdf => return 2;\n        when cgwj => return 3;\n        when rccr => return 2;\n        when vsgw => return 3;\n        when pvwn => return Eval (fpwz) * Eval (wnjc);\n        when mfql => return 3;\n        when dspn => return Eval (qlvz) + Eval (bcsc);\n        when llcn => return 4;\n        when dcph => return 4;\n        when npcs => return Eval (lrvc) + Eval (mcfr);\n        when wgvj => return 4;\n        when bblh => return 1;\n        when dmrn => return 9;\n        when qbzv => return 1;\n        when lrdn => return 3;\n        when wzfr => return Eval (nltq) + Eval (lrlz);\n        when bwnc => return 2;\n        when dswn => return 11;\n        when bnws => return 2;\n        when cdnp => return Eval (zvst) * Eval (cwjp);\n        when fddw => return Eval (zhgt) * Eval (mfst);\n        when nbbd => return Eval (flvw) * Eval (thlz);\n        when lbzc => return Eval (jfrn) * Eval (gdgd);\n        when sntb => return Eval (bhrb) * Eval (lhgv);\n        when vzts => return 6;\n        when jvfw => return Eval (hlms) + Eval (lwlc);\n        when mqcv => return 2;\n        when jhzw => return 5;\n        when lhpf => return Eval (dqzt) * Eval (fjld);\n        when znjr => return 2;\n        when wrvl => return Eval (pdbt) * Eval (qlvg);\n        when cdwt => return 6;\n        when vtjg => return Eval (stcr) * Eval (bvzn);\n        when dvnh => return Eval (brqv) * Eval (jdmt);\n        when pcgq => return Eval (jtcf) * Eval (qssh);\n        when nhjt => return 2;\n        when pmqh => return Eval (dflc) * Eval (rzsn);\n        when zrwb => return Eval (gtqh) * Eval (fwjg);\n        when zphs => return Eval (bcww) + Eval (sbtd);\n        when nmvn => return Eval (vrpp) * Eval (mdht);\n        when sbvl => return 3;\n        when bcdf => return Eval (rhwm) * Eval (zbhj);\n        when jhwn => return Eval (mgjl) * Eval (tprm);\n        when ftjv => return 3;\n        when ncnm => return Eval (vzcr) * Eval (wqfg);\n        when bgwj => return Eval (qlqt) / Eval (dnwd);\n        when hrbr => return Eval (gvmj) + Eval (vspf);\n        when qljb => return 3;\n        when vdsz => return 3;\n        when nhpf => return Eval (rdpg) + Eval (qrll);\n        when gvfn => return Eval (drnb) / Eval (fhmz);\n        when ppts => return Eval (zhrs) * Eval (lccp);\n        when fvhm => return 7;\n        when rrqr => return 2;\n        when lnqm => return Eval (rwjc) + Eval (vnvr);\n        when qwnz => return Eval (hfbh) + Eval (vdbp);\n        when cgvr => return 3;\n        when lvrc => return 4;\n        when vcfm => return 5;\n        when zhgt => return 3;\n        when nvdh => return 3;\n        when llfg => return Eval (cgcc) * Eval (nqhg);\n        when wjgf => return 2;\n        when nztj => return Eval (wqfz) + Eval (tdlw);\n        when shpt => return 2;\n        when gzmv => return 3;\n        when tqzv => return Eval (rtpz) + Eval (glqr);\n        when pdmb => return 2;\n        when fpcs => return 5;\n        when mwmp => return 6;\n        when hcfs => return 2;\n        when bshp => return Eval (chvq) + Eval (pdbc);\n        when gppj => return 1;\n        when pzpp => return 5;\n        when ltnz => return Eval (dswn) * Eval (tsqc);\n        when wzdj => return 3;\n        when frst => return 5;\n        when scdn => return 6;\n        when fpsh => return 2;\n        when gzwm => return 2;\n        when jmbs => return Eval (lwlb) * Eval (sqcb);\n        when rqsw => return 5;\n        when bnvg => return 3;\n        when tfwb => return 2;\n        when snwm => return 6;\n        when zvrq => return 5;\n        when vnpq => return Eval (djjs) + Eval (rmrj);\n        when cfbh => return 4;\n        when ntnh => return Eval (jvfw) * Eval (jzdn);\n        when jnwv => return Eval (tlnz) * Eval (zqpw);\n        when npvl => return Eval (sbqm) * Eval (zmmd);\n        when tpwq => return Eval (jnll) / Eval (flhf);\n        when flhs => return Eval (qcml) + Eval (zmdq);\n        when pnvd => return Eval (cwvl) + Eval (dgpr);\n        when zvvp => return 3;\n        when fcql => return 20;\n        when jrvp => return 17;\n        when wbvt => return Eval (bftg) + Eval (tlzh);\n        when vwht => return 3;\n        when pzvr => return 3;\n        when qncp => return 3;\n        when bcgz => return Eval (tpjp) / Eval (bngr);\n        when dcbt => return Eval (rctr) + Eval (wltv);\n        when csgr => return Eval (wrvl) / Eval (znjr);\n        when rsdv => return Eval (vcwt) * Eval (mqcv);\n        when fnqf => return 2;\n        when hzrc => return Eval (jdbp) + Eval (jnwv);\n        when cdvw => return Eval (sjfs) + Eval (fzvh);\n        when bsvc => return Eval (pwln) / Eval (nrjc);\n        when tlwr => return 3;\n        when hjmr => return 3;\n        when spjg => return 5;\n        when mqgl => return Eval (mqlt) * Eval (jlnf);\n        when mzzd => return 3;\n        when dqnv => return Eval (mhnm) * Eval (zhqg);\n        when lqcm => return Eval (ffqs) / Eval (zvrq);\n        when sqzp => return 5;\n        when drvt => return Eval (hhws) * Eval (llpf);\n        when ghvn => return Eval (vrjj) + Eval (vfrh);\n        when hfbh => return 16;\n        when wtlg => return 19;\n        when dsgt => return Eval (hhcv) * Eval (npcs);\n        when vvzh => return 6;\n        when sclr => return Eval (dddm) * Eval (nttr);\n        when jqqs => return Eval (znlh) + Eval (ffnn);\n        when zprq => return Eval (jmnj) * Eval (mwqc);\n        when dczh => return Eval (vvvb) * Eval (wcpr);\n        when lpzb => return Eval (bqvg) + Eval (mlgj);\n        when dqsv => return Eval (pmfh) * Eval (zrbc);\n        when hgzs => return 3;\n        when vrpp => return 10;\n        when snbm => return 4;\n        when tdrq => return Eval (hqdv) * Eval (csln);\n        when tbwl => return Eval (sdmb) * Eval (zrfw);\n        when jdmt => return Eval (btwt) - Eval (gwpm);\n        when fzgj => return 4;\n        when vnvr => return Eval (pmqh) * Eval (pwlt);\n        when mcht => return 2;\n        when ztrt => return Eval (vlhc) * Eval (swds);\n        when bncr => return Eval (wpcs) - Eval (pcgq);\n        when nqsl => return Eval (qcfn) + Eval (fsgb);\n        when cclc => return Eval (hjfj) + Eval (cfdl);\n        when ztpd => return Eval (dzlc) + Eval (zcgn);\n        when lfrb => return Eval (rbsf) * Eval (hzjj);\n        when pvfv => return 2;\n        when swpl => return 2;\n        when csnf => return 1;\n        when ptdz => return 2;\n        when nvhn => return 2;\n        when rdhg => return Eval (nnhm) * Eval (wpbs);\n        when jclb => return 2;\n        when cscm => return Eval (lclg) * Eval (mrwz);\n        when fcgj => return Eval (hmrz) * Eval (nwbt);\n        when hgwm => return Eval (mspl) * Eval (rmfv);\n        when rqbq => return 2;\n        when wjtc => return Eval (fszd) + Eval (tpmp);\n        when dpvl => return 8;\n        when nwdv => return 3;\n        when zcgn => return Eval (lzzh) * Eval (brfc);\n        when jvrt => return Eval (bhzq) / Eval (rqsw);\n        when zmdq => return Eval (sdwj) + Eval (mwdl);\n        when rtsd => return Eval (rcmc) + Eval (jtjd);\n        when nqzz => return 11;\n        when dshq => return Eval (rtnf) * Eval (chvn);\n        when mddc => return 2;\n        when rpwz => return 3;\n        when pmlg => return 8;\n        when blmp => return Eval (vwmr) * Eval (ndpf);\n        when hqbb => return 2;\n        when chtt => return 2;\n        when cchg => return 2;\n        when bntz => return Eval (tvrd) * Eval (ncsp);\n        when gvgp => return 3;\n        when vvhm => return Eval (mspb) * Eval (dpgl);\n        when nlcv => return 5;\n        when rwcd => return Eval (qffb) + Eval (nzcv);\n        when rfcq => return 6;\n        when zgdb => return 2;\n        when mggl => return Eval (cchg) * Eval (crcm);\n        when mwjg => return Eval (vjwz) * Eval (vsmt);\n        when rbbh => return 13;\n        when mqlt => return Eval (gwlm) * Eval (mqvg);\n        when ddtd => return Eval (qcnv) + Eval (wjzv);\n        when hpmm => return 3;\n        when cjlm => return 6;\n        when cpdf => return Eval (jjbm) * Eval (mtnb);\n        when gqrp => return Eval (tdrq) + Eval (djrh);\n        when zmtg => return 8;\n        when vwdl => return Eval (hzmn) * Eval (nqms);\n        when ggpn => return 11;\n        when mtfr => return Eval (jlqg) * Eval (dlgc);\n        when nsfm => return 4;\n        when cftm => return 18;\n        when wcdm => return Eval (tsbf) * Eval (wgvv);\n        when jcch => return 2;\n        when zqjp => return Eval (tzhp) - Eval (nldv);\n        when wjmq => return 6;\n        when cbgj => return Eval (mdjm) * Eval (tqfr);\n        when jmnj => return Eval (ppts) + Eval (fqbl);\n        when tlnz => return Eval (vfgt) * Eval (vdjz);\n        when fqjd => return 2;\n        when ngzp => return 11;\n        when trdj => return 10;\n        when qrch => return Eval (nfhf) + Eval (vhtl);\n        when hmrz => return Eval (qjrs) * Eval (rtsd);\n        when rvnh => return 3;\n        when humn =>\n          case part is\n            when part_1 => return 4481;\n            when part_2 => return human;\n          end case;\n        when jstb => return 5;\n        when vqlt => return 2;\n        when vlqd => return Eval (ndgh) * Eval (zptr);\n        when vjjw => return Eval (mrlc) / Eval (pvfv);\n        when mnlp => return Eval (svdw) + Eval (mtjq);\n        when jtcf => return 4;\n        when lwlc => return Eval (qqtm) * Eval (cnvb);\n        when jdgq => return 2;\n        when vznc => return 2;\n        when dcfw => return Eval (qvvc) * Eval (wqdj);\n        when fqwz => return Eval (twtb) + Eval (vtnq);\n        when hhbn => return 4;\n        when wrpp => return 14;\n        when mmnw => return 3;\n        when rdpb => return 10;\n        when hcsc => return 5;\n        when nfvj => return 4;\n        when qznt => return Eval (zfjw) * Eval (wfld);\n        when flvw => return 5;\n        when wphq => return 5;\n        when bpwd => return 2;\n        when cbfh => return 2;\n        when bcbw => return Eval (jtvm) * Eval (cdnm);\n        when dvwj => return Eval (zwgg) * Eval (dspn);\n        when tnbt => return Eval (qdfp) * Eval (bpwd);\n        when qlzt => return 12;\n        when rjfh => return 5;\n        when cprt => return 3;\n        when qgwg => return Eval (jrgs) + Eval (sphc);\n        when zpbt => return Eval (swfp) / Eval (mldc);\n        when drln => return 6;\n        when jdcd => return 3;\n        when jzcd => return Eval (nvjl) - Eval (swpl);\n        when sbpp => return 17;\n        when ttwm => return 5;\n        when rdbs => return Eval (wsml) * Eval (drrf);\n        when pfpt => return Eval (pmrt) * Eval (fvsf);\n        when rfbw => return Eval (ntpj) + Eval (vwpq);\n        when bqld => return Eval (zqjp) + Eval (rbzl);\n        when rrmg => return 19;\n        when rbsf => return 3;\n        when mlgj => return Eval (vvgt) + Eval (dmsz);\n        when jfcd => return Eval (bsqn) / Eval (blgf);\n        when sjrh => return 7;\n        when djjd => return Eval (fddw) + Eval (svvq);\n        when jhgd => return Eval (fjnh) * Eval (bbzt);\n        when nlts => return Eval (fjgh) - Eval (cnln);\n        when ppwc => return Eval (lhpf) - Eval (zprq);\n        when gptt => return 2;\n        when bvvl => return 20;\n        when ssnq => return Eval (cfmw) + Eval (wfnm);\n        when gmhz => return 4;\n        when nnsc => return Eval (cvqf) + Eval (vpvl);\n        when zbzf => return Eval (nlth) * Eval (dhfw);\n        when jhvm => return 16;\n        when mrrt => return 7;\n        when pmrt => return Eval (mwrc) * Eval (mnhc);\n        when rddj => return Eval (fbcd) / Eval (tfwb);\n        when wszm => return Eval (hsbr) + Eval (rscq);\n        when pbgr => return Eval (glqw) * Eval (qqnm);\n        when hzlh => return 2;\n        when qnbn => return Eval (jpvr) - Eval (bgzz);\n        when hrcp => return Eval (fjvg) * Eval (vjbz);\n        when dnwd => return Eval (lqrf) * Eval (flhd);\n        when rvlz => return 3;\n        when stcr => return Eval (cblz) + Eval (nfnw);\n        when ptvh => return 3;\n        when vmnc => return 5;\n        when bmwf => return Eval (rpbm) * Eval (cvgt);\n        when jzdn => return 2;\n        when djrh => return Eval (ccjf) * Eval (fqgl);\n        when lwlb => return 5;\n        when bqht => return Eval (cldm) * Eval (btqb);\n        when brfj => return Eval (prbr) + Eval (qqwz);\n        when rlqm => return 2;\n        when mdht => return Eval (jflm) - Eval (trpt);\n        when lbbj => return 2;\n        when blnq => return 6;\n        when chfz => return 3;\n        when sqsc => return 5;\n        when mwrt => return Eval (slnh) + Eval (thcc);\n        when nvrb => return 3;\n        when lgrj => return Eval (qnvn) * Eval (tnbt);\n        when pvcn => return Eval (qhwm) * Eval (smld);\n        when fbgc => return 2;\n        when mqnl => return Eval (drlt) * Eval (bbhp);\n        when bdtp => return Eval (gzpf) * Eval (qdnl);\n        when wdwf => return Eval (fhjc) - Eval (zpbt);\n        when hhjc => return Eval (qbvr) + Eval (fmwn);\n        when jzlv => return Eval (cftm) * Eval (rhtv);\n        when smwb => return Eval (dgbr) + Eval (rbbh);\n        when bhvg => return Eval (lpfz) + Eval (bjnj);\n        when zmmd => return Eval (smsm) + Eval (jfcd);\n        when mdld => return Eval (zzqd) + Eval (bdmw);\n        when qlqt => return Eval (zfbq) + Eval (ntqb);\n        when dgbr => return Eval (sbwd) * Eval (cgvr);\n        when rwsm => return 10;\n        when jnll => return Eval (nztj) * Eval (vzgb);\n        when dbht => return Eval (jdcd) * Eval (rccr);\n        when bhmz => return 3;\n        when mrlq => return Eval (bbjs) + Eval (drdl);\n        when fzdg => return 2;\n        when jbsh => return 2;\n        when svzv => return 2;\n        when zjmw => return 3;\n        when tcgm => return 2;\n        when nzcv => return 6;\n        when rmrj => return Eval (mtsv) + Eval (snlb);\n        when bjnj => return 2;\n        when qsml => return 18;\n        when mfts => return Eval (mwjg) * Eval (pjsp);\n        when ffqs => return Eval (rhcv) - Eval (rrnt);\n        when dbcw => return Eval (gtbs) * Eval (mbvg);\n        when wpcs => return Eval (phbh) * Eval (mnhf);\n        when rvhs => return 2;\n        when qmcb => return 17;\n        when hlms => return 11;\n        when vwpq => return 2;\n        when wslz => return Eval (szhq) / Eval (hstj);\n        when jpvr => return Eval (sflt) + Eval (drvt);\n        when hcdz => return Eval (nfhw) * Eval (qgjf);\n        when svvq => return Eval (twdf) * Eval (rhqj);\n        when lgpg => return Eval (wglc) + Eval (gwmr);\n        when mlwr => return Eval (zfmv) + Eval (hbqm);\n        when hbqm => return 1;\n        when fgbm => return Eval (lltp) + Eval (fwmw);\n        when cjlh => return Eval (btfl) * Eval (mpnj);\n        when tlmq => return Eval (fqwz) * Eval (lwhp);\n        when zzqd => return Eval (vnpq) / Eval (rlqm);\n        when drdl => return Eval (hzlh) * Eval (btqt);\n        when sdjb => return Eval (ssnq) * Eval (gzwm);\n        when ntmt => return 3;\n        when rwth => return Eval (tdjh) + Eval (cstb);\n        when jjgt => return Eval (crqg) * Eval (dmrn);\n        when mpvz => return Eval (ppwc) * Eval (chpt);\n        when qbmm => return Eval (rqpj) + Eval (rfcm);\n        when zdrh => return Eval (csml) + Eval (cvvv);\n        when trft => return Eval (lbbv) * Eval (nlgg);\n        when dqjz => return 7;\n        when gfrq => return 4;\n        when vvgt => return Eval (zrwb) / Eval (rfcq);\n        when tsft => return Eval (sstg) + Eval (ngfs);\n        when gzpf => return 2;\n        when tfpw => return Eval (gmln) * Eval (hqbd);\n        when cddt => return 6;\n        when rlbp => return 1;\n        when ndph => return Eval (ztzq) * Eval (jgzl);\n        when blbc => return Eval (jfvq) * Eval (cprt);\n        when cvhn => return Eval (jdgq) * Eval (llcn);\n        when zncl => return Eval (mwrt) + Eval (dbgp);\n        when rthb => return 2;\n        when jfld => return 4;\n        when gdgd => return 7;\n        when lrsc => return Eval (vdzv) * Eval (czst);\n        when gzgm => return 4;\n        when bhrb => return Eval (pnvc) / Eval (smdh);\n        when bsmm => return 2;\n        when qnds => return Eval (sbvl) * Eval (szmm);\n        when bhzq => return Eval (zhmb) * Eval (qfss);\n        when vwvc => return 17;\n        when qmgt => return 3;\n        when gfml => return 4;\n        when tjqj => return Eval (glpw) * Eval (zsns);\n        when vlmc => return 4;\n        when qlnr => return Eval (ndph) + Eval (twtq);\n        when fvph => return 3;\n        when jgzl => return Eval (drct) + Eval (vwdt);\n        when wnjc => return 2;\n        when ffbb => return 2;\n        when hzmn => return Eval (pgbv) + Eval (rwbg);\n        when rpbj => return Eval (shrh) * Eval (jvqf);\n        when sqmd => return 2;\n        when ndcd => return Eval (sdgs) * Eval (spjg);\n        when mmbs => return 3;\n        when mhbr => return Eval (wggq) + Eval (grcv);\n        when nsqq => return Eval (cvfw) * Eval (ffmp);\n        when wgvv => return 2;\n        when rvmp => return Eval (nnzp) * Eval (dbcw);\n        when dwnz => return 2;\n        when jvtz => return Eval (fctt) + Eval (bfpq);\n        when nzzv => return Eval (jbcl) * Eval (llnl);\n        when cqcg => return 3;\n        when nrvw => return 2;\n        when qqtm => return 3;\n        when fvng => return 19;\n        when phrv => return 3;\n        when tlzh => return 11;\n        when twjs => return Eval (ltnz) - Eval (ltsv);\n        when lhgv => return Eval (nwqz) + Eval (qflq);\n        when rctr => return Eval (mhdn) * Eval (mvnc);\n        when snlb => return 4;\n        when dfgh => return 7;\n        when tvtj => return 13;\n        when flcb => return 2;\n        when nqpr => return 3;\n        when jmbp => return 4;\n        when rcmc => return Eval (bpjf) / Eval (qrzq);\n        when mnpl => return Eval (pbdd) - Eval (qpct);\n        when twcj => return 3;\n        when nlth => return 2;\n        when drrq => return 13;\n        when fszd => return Eval (bmwf) + Eval (qspw);\n        when mlrz => return 2;\n        when jvgd => return Eval (dvnh) - Eval (mpjj);\n        when jtvw => return Eval (nzhf) - Eval (wfnl);\n        when ftvm => return 3;\n        when cgcz => return Eval (njcj) - Eval (bjbr);\n        when dfzw => return 2;\n        when tdhw => return Eval (rzjm) * Eval (qrgn);\n        when qwnt => return 2;\n        when mspb => return Eval (dggg) + Eval (ghtd);\n        when fhmz => return 2;\n        when dqzt => return 5;\n        when brfc => return Eval (dczh) - Eval (tfpw);\n        when hstj => return 2;\n        when rzjm => return 5;\n        when jbcl => return 3;\n        when zhpq => return Eval (gpzn) * Eval (cnmq);\n        when hmrs => return Eval (ltqr) * Eval (hslj);\n        when mtdh => return 8;\n        when lwhp => return 5;\n        when wnvf => return 8;\n        when qqdn => return 3;\n        when wrmw => return Eval (fwrh) * Eval (rbmm);\n        when gzrs => return Eval (jclb) * Eval (zjpc);\n        when nzwc => return 3;\n        when wflc => return Eval (cbgj) / Eval (qllm);\n        when gtwp => return 3;\n        when trbs => return 2;\n        when zsns => return 2;\n        when vvvb => return Eval (wrpp) - Eval (qrsg);\n        when cstb => return Eval (dfps) * Eval (svwg);\n        when gcmv => return Eval (whbb) * Eval (mfnh);\n        when vrjj => return Eval (lbbj) * Eval (jgnj);\n        when rrll => return Eval (scdt) * Eval (zjmw);\n        when wgsb => return Eval (jqrl) * Eval (jlwb);\n        when scdt => return Eval (vlmc) * Eval (qfln);\n        when wqqv => return Eval (nrps) * Eval (pnwz);\n        when szhq => return Eval (nchp) * Eval (ndtz);\n        when tqzf => return 3;\n        when wpqd => return Eval (jqsn) * Eval (przh);\n        when vmzc => return Eval (nhpf) * Eval (gcqh);\n        when pjlz => return 2;\n        when mdjm => return 3;\n        when qgjf => return Eval (pgvq) + Eval (spgw);\n        when qnhq => return Eval (rncj) * Eval (rllb);\n        when hfbg => return 2;\n        when jfsr => return 8;\n        when nfhw => return 2;\n        when cstm => return Eval (rgzs) * Eval (nbcb);\n        when ghvl => return Eval (dbfd) + Eval (qbmm);\n        when tzcl => return 2;\n        when pzzg => return Eval (ltmj) - Eval (mfts);\n        when cdqv => return Eval (dfgh) + Eval (mnlp);\n        when wcpr => return 5;\n        when jdrg => return Eval (qmpm) + Eval (hlmn);\n        when gtqh => return 8;\n        when hlmn => return Eval (rdnj) + Eval (sjcd);\n        when hnqc => return Eval (mfsz) / Eval (hbzt);\n        when sphc => return Eval (vrcl) * Eval (nhfw);\n        when bnlr => return Eval (qhvn) * Eval (vvzh);\n        when dbfd => return Eval (bcnp) / Eval (ffvs);\n        when hpzh => return Eval (snwm) + Eval (rrnp);\n        when ghqp => return 5;\n        when dfql => return Eval (dzwg) * Eval (snbl);\n        when hbzt => return Eval (shwr) + Eval (rthb);\n        when chsm => return Eval (crmb) * Eval (scwp);\n        when lpjq => return Eval (wlpd) * Eval (fcgs);\n        when plfd => return Eval (sqsc) * Eval (hvsd);\n        when vbvt => return Eval (ghqp) * Eval (qmjq);\n        when rdpg => return 7;\n        when vhds => return 12;\n        when rmfv => return 5;\n        when smft => return Eval (crmw) * Eval (msdr);\n        when wlpd => return 2;\n        when cvvw => return 2;\n        when bsqn => return Eval (wlfp) + Eval (sdjb);\n        when svcp => return Eval (jfmb) + Eval (rwsm);\n        when qflq => return Eval (scrz) * Eval (dtfz);\n        when bwwc => return 3;\n        when wqfg => return Eval (qmzt) * Eval (chfz);\n        when lbqn => return 5;\n        when zbhw => return Eval (wcdm) + Eval (hhjc);\n        when jlnf => return 3;\n        when nlst => return Eval (wmzt) + Eval (twjs);\n        when zfjw => return Eval (tbdh) + Eval (rmmz);\n        when wfms => return 2;\n        when fjps => return 5;\n        when djpm => return Eval (pznf) * Eval (qlnr);\n        when snsc => return 2;\n        when hnlj => return 5;\n        when pvfm => return 2;\n        when cwhc => return 3;\n        when blgg => return 15;\n        when jmwl => return Eval (rdpb) * Eval (zpht);\n        when wbsb => return Eval (jcdb) * Eval (ngbz);\n        when jwwv => return 2;\n        when jdsd => return 5;\n        when rsnp => return 3;\n        when rrnt => return Eval (jnnp) * Eval (dmtd);\n        when nfnw => return 2;\n        when mpfm => return Eval (mfrc) * Eval (qrch);\n        when mnzz => return Eval (lwld) + Eval (jbwd);\n        when lfjp => return 3;\n        when qvfg => return Eval (fdmf) * Eval (svst);\n        when mjmv => return Eval (cdwt) + Eval (pzvr);\n        when lclg => return 8;\n        when pcvv => return Eval (rvmp) + Eval (hmrs);\n        when wsml => return 3;\n        when gvbp => return 3;\n        when mpjj => return 10;\n        when vcqw => return Eval (jjjj) * Eval (brmz);\n        when lhvt => return Eval (pmds) * Eval (tqzf);\n        when qpdv => return 15;\n        when mrlc => return Eval (zbhw) * Eval (svzv);\n        when bdmw => return Eval (fpsh) * Eval (hwvf);\n        when vntv => return Eval (npvl) * Eval (mbqs);\n        when cfdl => return Eval (mfhg) * Eval (gzbv);\n        when gvww => return 2;\n        when dqhh => return Eval (gzwh) * Eval (thpg);\n        when mtnb => return Eval (mqph) * Eval (bnfp);\n        when wlfp => return Eval (ntsl) + Eval (lfhp);\n        when zslv => return 3;\n        when lqrr => return Eval (hhbn) * Eval (gmzh);\n        when qfzb => return Eval (nhjt) + Eval (mjmt);\n        when ltzm => return 12;\n        when qcnn => return Eval (mnpl) - Eval (wsnf);\n        when bhvr => return Eval (lflj) + Eval (rfjw);\n        when wnzr => return Eval (jbrp) * Eval (nnmh);\n        when zglw => return Eval (flcb) * Eval (cqmq);\n        when svdw => return 4;\n        when pfml => return Eval (bnlr) + Eval (ndcd);\n        when zpqd => return 2;\n        when fjnh => return 5;\n        when rhqj => return Eval (qrpv) + Eval (ngzp);\n        when szmm => return 3;\n        when ztwb => return 9;\n        when npnf => return 1;\n        when wltv => return Eval (rqfq) - Eval (hncq);\n        when bwff => return Eval (dwdd) + Eval (qhzd);\n        when slnh => return Eval (ljnf) * Eval (tnfz);\n        when ppwz => return Eval (hqbb) * Eval (nlts);\n        when hgls => return Eval (wnzr) / Eval (wwtj);\n        when dbvt => return 3;\n        when wrst => return Eval (qdrg) + Eval (bnfz);\n        when rzzg => return Eval (rpbj) + Eval (fsrm);\n        when prbr => return Eval (hpzh) - Eval (zmtg);\n        when bvdb => return 2;\n        when jlmb => return Eval (cmtm) - Eval (qbjm);\n        when rbpq => return Eval (wnbb) * Eval (glts);\n        when jwjj => return 15;\n        when dhts => return 8;\n        when dcpm => return 3;\n        when qvpv => return Eval (grcn) * Eval (cgwj);\n        when bbhp => return 2;\n        when sjfs => return Eval (ztpd) - Eval (bnzl);\n        when wqpv => return Eval (fzgj) * Eval (rvvn);\n        when sdhj => return 2;\n        when wfbz => return 2;\n        when mdnp => return Eval (gvfn) * Eval (tfqh);\n        when ctjq => return Eval (tgvp) * Eval (wjzd);\n        when mbqs => return Eval (rrmg) * Eval (rnnq);\n        when wcfp => return 3;\n        when ftzm => return 3;\n        when nwbt => return Eval (bhpw) * Eval (bhgh);\n        when bmsf => return Eval (fnws) / Eval (bcmp);\n        when cmnt => return Eval (bvjd) + Eval (lccn);\n        when wqfz => return 4;\n        when jrgs => return Eval (hjgd) + Eval (mpst);\n        when gmzh => return Eval (drhw) / Eval (sdsl);\n        when pnvs => return Eval (bmsf) * Eval (qljb);\n        when gcvn => return Eval (wqqv) + Eval (dqnv);\n        when qbvr => return Eval (ltds) - Eval (vsgw);\n        when phbh => return Eval (snsc) * Eval (flhs);\n        when shtz => return Eval (pnrv) + Eval (pvcs);\n        when smsm => return 4;\n        when gznh => return 7;\n        when tjch => return Eval (ncrt) * Eval (rrgh);\n        when bpnt => return Eval (ccfw) + Eval (dfql);\n        when lljf => return 3;\n        when qfsz => return 2;\n        when dgvh => return 3;\n        when lvbp => return Eval (hdrj) + Eval (trbs);\n        when cdvv => return 4;\n        when qlzg => return 2;\n        when rwbg => return 2;\n        when snff => return 4;\n        when flrw => return 3;\n        when tdnf => return 4;\n        when nzlr => return 2;\n        when ftzc => return 2;\n        when pznf => return Eval (cllb) * Eval (zzcv);\n        when zjvz => return Eval (znfq) * Eval (chlt);\n        when nvjl => return Eval (ngzt) * Eval (wbgs);\n        when qtvv => return 2;\n        when hdff => return 4;\n        when swmh => return Eval (vrbh) + Eval (jdjq);\n        when ghfr => return 2;\n        when ghtd => return Eval (cfzf) * Eval (gnsc);\n        when mfmt => return Eval (cdqv) * Eval (chfs);\n        when pgtq => return Eval (phwc) * Eval (gbgs);\n        when frjp => return 17;\n        when bnfz => return 2;\n        when qfqz => return Eval (mswh) * Eval (slds);\n        when djmr => return 2;\n        when crcm => return Eval (lsnd) + Eval (zbqq);\n        when ngbg => return Eval (jgld) * Eval (lhfr);\n        when sbqm => return 3;\n        when wlqd => return 2;\n        when jfrn => return 3;\n        when jbqf => return Eval (cdvw) * Eval (dnvm);\n        when zhrs => return Eval (pjjj) + Eval (fngd);\n        when lvtv => return Eval (nvjf) / Eval (nmlg);\n        when vclb => return Eval (bbcn) + Eval (jqhr);\n        when qtgd => return 2;\n        when hqbd => return 4;\n        when qqnm => return Eval (nsqq) - Eval (rfbw);\n        when nvjh => return 6;\n        when jcgh => return Eval (pmwl) * Eval (hcqw);\n        when bgzz => return Eval (swsv) * Eval (qldj);\n        when slds => return 2;\n        when lwsn => return Eval (hcfs) + Eval (rswn);\n        when bhgh => return Eval (hcsc) * Eval (mzzd);\n        when bjbr => return 3;\n        when tgvp => return Eval (smft) / Eval (cnhr);\n        when dbfm => return 9;\n        when msmm => return Eval (djmr) * Eval (bshp);\n        when llqs => return Eval (mmps) + Eval (pwqg);\n        when qqpl => return 5;\n        when pfdc => return Eval (mwmp) + Eval (zvqs);\n        when qlvg => return 2;\n        when wzdv => return 3;\n        when glqr => return Eval (qqpl) * Eval (blgg);\n        when vdgt => return 5;\n        when qrnj => return Eval (fjrq) * Eval (nwhm);\n        when fbrf => return 3;\n        when gvmj => return Eval (ngbg) / Eval (vsqt);\n        when nrjc => return 2;\n        when sdsl => return 2;\n        when mqvg => return Eval (tbqq) - Eval (bzqw);\n        when chvq => return Eval (jdsd) + Eval (cgcz);\n        when lrzn => return Eval (gfrq) + Eval (drgv);\n        when crrm => return 2;\n        when pgbv => return Eval (swhz) + Eval (dqld);\n        when brqv => return 2;\n        when gmln => return 2;\n        when wcmz => return 3;\n        when hbhz => return 18;\n        when vrcl => return 5;\n        when hqdv => return 5;\n        when nchp => return Eval (dtzl) + Eval (qpdv);\n        when bfvd => return 7;\n        when nnhm => return Eval (pzpp) * Eval (dwnz);\n        when thpg => return 4;\n        when jpzw => return 3;\n        when vrmt => return Eval (lqrr) - Eval (smrq);\n        when hnbn => return 2;\n        when tsbf => return Eval (lljf) + Eval (mqnl);\n        when nbpq => return 2;\n        when csml => return Eval (lbtn) * Eval (zspm);\n        when cnmq => return 8;\n        when qbwf => return Eval (vvhm) - Eval (dsqb);\n        when jbrp => return 11;\n        when bbzc => return Eval (ffbb) * Eval (lqft);\n        when pgfr => return 3;\n        when fmwn => return 2;\n        when lrvc => return 10;\n        when stqc => return 5;\n        when ngzt => return Eval (rlbp) + Eval (fbjn);\n        when mdrm => return Eval (jhwn) + Eval (lmht);\n        when mrtq => return Eval (rzcm) * Eval (nqgr);\n        when lpvs => return 9;\n        when lqfq => return 3;\n        when rnnq => return 3;\n        when jdfj => return 15;\n        when tqst => return Eval (cjbz) + Eval (rvhn);\n        when dnzc => return Eval (mmbs) * Eval (qlmw);\n        when lwld => return 1;\n        when sgjm => return 8;\n        when bfzd => return 17;\n        when dchw => return 4;\n        when rlrb => return Eval (tftg) + Eval (qbqm);\n        when pchr => return Eval (trft) + Eval (bcbw);\n        when lvhm => return Eval (dhqh) * Eval (dchw);\n        when mswh => return 5;\n        when sdgs => return 5;\n        when snfj => return 1;\n        when sdwj => return 2;\n        when qmqt => return Eval (wttp) / Eval (cgnv);\n        when przh => return Eval (wqlh) + Eval (nqzz);\n        when qrpv => return Eval (sqmd) * Eval (tpdj);\n        when pjsp => return 5;\n        when hpmw => return Eval (zdsr) * Eval (rlrb);\n        when jhlw => return 9;\n        when ntqb => return Eval (gzmv) * Eval (pzzg);\n        when qpct => return 3;\n        when rvvn => return Eval (rrqr) * Eval (wflc);\n        when lmcj => return Eval (szcv) + Eval (lqcm);\n        when bvjd => return 2;\n        when fngd => return Eval (wjds) * Eval (nrvw);\n        when fnws => return Eval (jmwl) + Eval (rtgr);\n        when frqq => return 4;\n        when ltsv => return 3;\n        when cmnv => return 7;\n        when wdqj => return Eval (vhrn) * Eval (hpmw);\n        when cjbz => return Eval (qlzt) * Eval (fqjd);\n        when rqpj => return Eval (tqst) * Eval (ptdz);\n        when lbtn => return 8;\n        when dbgp => return Eval (lbzn) * Eval (jqtj);\n        when qbjm => return 12;\n        when ljzj => return 15;\n        when mrvr => return 3;\n        when nght => return 2;\n        when djff => return 12;\n        when jmqh => return 14;\n        when vcpt => return Eval (ppwz) * Eval (zvqw);\n        when vsqt => return 5;\n        when tfjw => return Eval (bhvr) * Eval (vjgb);\n        when hwvf => return Eval (vszg) + Eval (lvrc);\n        when qgtf => return 6;\n        when mmtj => return 6;\n        when blgf => return 3;\n        when mvmz => return Eval (qpqb) * Eval (cvhn);\n        when svhz => return Eval (jqcf) * Eval (nzzv);\n        when wfds => return 3;\n        when pnmc => return 13;\n        when szvb => return Eval (mdld) + Eval (bfgp);\n        when bnwj => return 2;\n        when dnvm => return Eval (msmm) - Eval (tqfz);\n        when fwrh => return Eval (wdqj) - Eval (dqnp);\n        when cspp => return Eval (mggl) + Eval (rndt);\n        when lltp => return Eval (rwcd) * Eval (wfds);\n        when smrq => return Eval (lrlg) + Eval (bwqm);\n        when rgzs => return 3;\n        when crmw => return Eval (ntmt) + Eval (cjlh);\n        when dncw => return 5;\n        when rvjf => return Eval (mttr) * Eval (frlv);\n        when wlmv => return 4;\n        when fqbj => return Eval (pfdc) * Eval (rqbd);\n        when fwjg => return Eval (vdsz) * Eval (brfj);\n        when gnsc => return 2;\n        when gtwd => return 2;\n        when qdnl => return Eval (nmvn) - Eval (wpqd);\n        when pjjj => return Eval (bnjt) + Eval (fhdz);\n        when ntsl => return 1;\n        when glqw => return 3;\n        when wmzt => return 3;\n        when vjzr => return Eval (swmh) + Eval (svhz);\n        when ncgd => return 3;\n        when bngr => return 5;\n        when qtfp => return 2;\n        when bdqg => return 2;\n        when hzpr => return 5;\n        when tctd => return 13;\n        when jlqg => return 4;\n        when qhlj => return Eval (gcvn) + Eval (bntz);\n        when jtvm => return 9;\n        when szcv => return Eval (jswz) + Eval (lbvn);\n        when sfmn => return Eval (wchl) + Eval (cscm);\n        when lfhp => return Eval (nght) * Eval (wcfp);\n        when root =>\n          case part is\n            when part_1 => return Eval (bsbd) + Eval (fcgj);\n            when part_2 => return Eval (bsbd) - Eval (fcgj);\n          end case;\n        when jbwd => return 6;\n        when zrnr => return 2;\n        when hrmz => return Eval (mthn) * Eval (dncw);\n        when rfjw => return 13;\n        when hpdh => return 2;\n        when jqrl => return Eval (pvwn) + Eval (hjmr);\n        when vgsm => return 5;\n        when mvgg => return Eval (nbfg) + Eval (mtfr);\n        when hcqw => return 14;\n        when cdtq => return Eval (rjrt) / Eval (mffc);\n        when spgw => return Eval (wbvt) * Eval (clbn);\n        when wfjn => return 5;\n        when hrtz => return Eval (llqs) * Eval (rvlz);\n        when rzsn => return 5;\n        when fbcd => return Eval (mfmt) + Eval (humn);\n        when vhwz => return Eval (mtwg) + Eval (fbgc);\n        when lvcn => return 4;\n        when grdf => return Eval (dbht) + Eval (sgvm);\n        when pdbc => return Eval (rsnp) * Eval (djqq);\n        when qssh => return 5;\n        when wnjl => return 9;\n        when btwt => return Eval (tzth) * Eval (hrtv);\n        when hplt => return 11;\n        when mwwr => return Eval (bsnq) * Eval (crrm);\n        when smqg => return 14;\n        when dqcj => return Eval (blbc) + Eval (bghp);\n        when ptwr => return 7;\n        when mttr => return Eval (hnqc) * Eval (wfms);\n        when pzcc => return 5;\n        when jscq => return 1;\n        when hzcm => return 4;\n        when tsjq => return Eval (nsfm) * Eval (hpdh);\n        when fsgb => return Eval (vhhz) + Eval (jhgd);\n        when plvw => return Eval (zpqd) * Eval (rffd);\n        when tcqz => return Eval (dqhh) + Eval (mlrz);\n        when mqzp => return 2;\n        when tldn => return Eval (rjfh) * Eval (zwqw);\n        when rwmq => return Eval (tdnf) * Eval (jdrg);\n        when vnft => return Eval (mqrm) + Eval (tjch);\n        when ztqg => return Eval (wtwb) * Eval (bqld);\n        when fjvg => return Eval (snfj) + Eval (gbzd);\n        when nzdz => return Eval (sfcv) + Eval (qtgd);\n        when qrgn => return 5;\n        when tbqq => return Eval (jplv) * Eval (rmzw);\n        when tdjh => return Eval (wrst) * Eval (wnjl);\n        when qwqw => return 5;\n        when pdbt => return 11;\n        when bnmb => return Eval (cvnr) * Eval (nvrb);\n        when lslq => return 1;\n        when twwv => return 19;\n        when rzcm => return 6;\n        when jtjd => return 6;\n        when htgm => return 3;\n        when pjss => return 2;\n        when mrwz => return 12;\n        when djqq => return 4;\n        when jmcf => return 12;\n        when hmqr => return Eval (zrpj) - Eval (nttd);\n        when lqdc => return 5;\n        when gpzn => return Eval (hpvb) + Eval (tpwq);\n        when pgdw => return 4;\n        when mwgb => return Eval (nvdh) * Eval (mrrt);\n        when wggq => return Eval (bgwj) + Eval (tldn);\n        when mwqc => return 2;\n        when bnfp => return 13;\n        when pwlt => return 5;\n        when hlzp => return Eval (phrv) + Eval (hrmz);\n        when qplw => return Eval (ncgd) * Eval (cmnt);\n        when vhqz => return Eval (pgtq) - Eval (ncnm);\n        when zptr => return 3;\n        when gtbs => return 13;\n        when zwwb => return Eval (pqqj) * Eval (dpqz);\n        when hmfb => return 4;\n        when mffc => return 3;\n        when lqgr => return 9;\n        when bcqm => return Eval (vjzr) + Eval (jzlv);\n        when cbdr => return Eval (wbsb) + Eval (cspp);\n        when bssd => return 2;\n        when dmsz => return Eval (vwdl) + Eval (rmqt);\n        when fpwz => return Eval (ltsl) * Eval (fbqs);\n        when rbmm => return 2;\n        when rvhn => return Eval (ttwm) * Eval (tctd);\n        when hqjt => return 7;\n        when bftg => return Eval (ftjv) * Eval (lghm);\n        when ppjl => return Eval (lfpz) / Eval (nlcv);\n        when nzbp => return Eval (chtt) * Eval (hnst);\n        when rwzt => return Eval (ltgf) * Eval (qwqq);\n        when zwgg => return 5;\n        when frlv => return 3;\n        when vmgn => return 1;\n        when tvrd => return Eval (qnhq) + Eval (ldzb);\n        when wfld => return 8;\n        when pnwz => return Eval (stlr) / Eval (fbrf);\n        when ndmd => return 2;\n        when fmbj => return Eval (slmm) * Eval (twsj);\n        when jqcf => return 3;\n        when jqsn => return 15;\n        when wzsh => return 3;\n        when hjqq => return 11;\n        when cvqf => return Eval (mpws) * Eval (sdrn);\n        when wrll => return 2;\n        when vtns => return Eval (jvrt) / Eval (cjvp);\n        when wsnf => return 4;\n        when qfjg => return 1;\n        when rsqz => return Eval (bbzc) - Eval (vfwd);\n        when dddm => return 2;\n        when ftmn => return Eval (wcmz) * Eval (hrtz);\n        when bcnd => return 13;\n        when qgtc => return 3;\n        when vthd => return Eval (zbzf) * Eval (mmnw);\n        when mvnc => return 2;\n        when ndpf => return 10;\n        when pwlh => return Eval (hbhz) + Eval (rtmt);\n        when cfzf => return Eval (rlqh) + Eval (qfrg);\n        when qldj => return 2;\n        when ftqd => return Eval (nssr) * Eval (mqzp);\n        when lhml => return 7;\n        when mrmm => return Eval (pszs) * Eval (cjlm);\n        when crnb => return Eval (ndnm) + Eval (lslq);\n        when qpbz => return 3;\n        when qspw => return 4;\n        when jtrg => return 7;\n        when nwwb => return Eval (hfvj) * Eval (snmq);\n        when rgpt => return 4;\n        when spcf => return Eval (cdvv) * Eval (wpgm);\n        when brqh => return Eval (bndd) + Eval (nbbd);\n        when qfrg => return Eval (hdff) * Eval (qmgt);\n        when ddmr => return Eval (fhzm) + Eval (qvbn);\n        when lpqs => return 1;\n        when zvqs => return 11;\n        when dfdl => return 3;\n        when vnbv => return Eval (ldbp) * Eval (frjl);\n        when bwqm => return 19;\n        when zjpc => return 4;\n        when btbn => return Eval (cvvw) * Eval (hnlf);\n        when bpgp => return Eval (nqlh) - Eval (gqgh);\n        when jbsn => return 3;\n        when tdlw => return 3;\n        when fsrm => return Eval (pzqv) * Eval (zjcn);\n        when rjrt => return Eval (nzwc) * Eval (gcmz);\n        when wpdn => return Eval (rsdv) * Eval (wcfj);\n        when dzvg => return 2;\n        when rdfn => return Eval (rbqt) * Eval (btzg);\n        when zrnz => return Eval (cbjq) * Eval (jmbs);\n        when djgb => return Eval (mrnr) + Eval (ttdb);\n        when pwln => return Eval (vqlt) * Eval (mnrr);\n        when vfgt => return 7;\n        when tbdh => return Eval (dzvg) * Eval (stcv);\n        when jlwb => return 3;\n        when cshj => return Eval (pwgj) + Eval (rpbg);\n        when lzhf => return 5;\n        when hncq => return 11;\n        when nqms => return 5;\n        when lhfr => return Eval (fgbm) / Eval (mstm);\n        when ltdq => return 4;\n        when zssf => return 5;\n        when dqld => return Eval (sjrh) * Eval (zdhf);\n        when grcv => return Eval (pnvs) * Eval (gvgp);\n        when zfbq => return Eval (ggbp) * Eval (plfd);\n        when lmjg => return 4;\n        when lncn => return 1;\n        when qmjq => return 5;\n        when rnbs => return Eval (vtgj) + Eval (dpmg);\n        when mstm => return 2;\n        when pnwh => return 2;\n        when ccfw => return 8;\n        when tsqc => return 2;\n        when gqpj => return Eval (hqjt) + Eval (fwzf);\n        when tnfz => return Eval (qrln) * Eval (nvpd);\n        when rhwm => return 4;\n        when bcnp => return Eval (dcfw) / Eval (nzlr);\n        when fvrg => return 3;\n        when vtgj => return 5;\n        when wwtj => return 5;\n        when slmm => return Eval (crrj) + Eval (bcgz);\n        when mjmt => return 4;\n        when zzpd => return 2;\n        when wttp => return Eval (lbgc) - Eval (gnrj);\n        when qdfp => return Eval (qlvw) * Eval (hmfd);\n        when psfr => return Eval (wfbp) * Eval (wzdv);\n        when rlqh => return Eval (ptwr) * Eval (lvbp);\n        when mgsz => return Eval (qqpt) * Eval (hgls);\n        when cjvp => return 2;\n        when hrjj => return 2;\n        when fjrq => return 6;\n        when qmpm => return Eval (bwwc) * Eval (hcdz);\n        when lddq => return Eval (rjbz) + Eval (ppsl);\n        when snbl => return Eval (vwhb) * Eval (szwj);\n        when bghp => return Eval (wgcm) * Eval (tfdv);\n        when zdnh => return 11;\n        when cbqn => return Eval (ppfs) * Eval (fjps);\n        when pbzb => return 2;\n        when rmzw => return Eval (ftvm) + Eval (mhlj);\n        when qpqb => return Eval (ptnv) + Eval (vhds);\n        when jffq => return 3;\n        when rscq => return Eval (bcdf) + Eval (tfjw);\n        when wjzv => return Eval (vcqw) / Eval (nqpq);\n        when ngbz => return 2;\n        when hdrj => return 5;\n        when slpc => return Eval (jstb) + Eval (lncn);\n        when bmzw => return 5;\n        when cmtm => return Eval (twcj) * Eval (tjqj);\n        when pwqg => return 17;\n        when dgpr => return Eval (bpgp) / Eval (lmjg);\n        when trpv => return 7;\n        when qnvn => return 2;\n        when gcqh => return 3;\n        when bdgd => return 2;\n        when dbcs => return Eval (nrqv) - Eval (zlpv);\n        when nrqv => return Eval (fvph) * Eval (hzrc);\n        when cnvb => return Eval (hrjj) * Eval (lbqn);\n        when cvgt => return Eval (qhtv) * Eval (vgsm);\n        when tqlp => return 2;\n        when sgpj => return 11;\n        when swsv => return 7;\n        when hndh => return 2;\n        when smwv => return Eval (gssz) + Eval (rgrp);\n        when dwdd => return Eval (fzdp) / Eval (gtwd);\n        when jszj => return Eval (gqrp) + Eval (tpnf);\n        when ncrt => return Eval (ntnh) + Eval (mwgb);\n        when rpbg => return 1;\n        when jvsz => return Eval (ndmd) * Eval (hrbr);\n        when ffvs => return 2;\n        when mnhf => return 3;\n        when hbwh => return Eval (ggpn) + Eval (pbzb);\n        when tpmp => return Eval (qjqw) * Eval (hzvm);\n        when nttr => return 3;\n        when ldbg => return Eval (cprm) * Eval (wrbf);\n        when ntpj => return 4;\n        when lbbv => return 3;\n        when vrct => return 2;\n        when lccn => return 5;\n        when nrsd => return 10;\n        when fvzw => return Eval (mwwr) + Eval (vmgn);\n        when vgjq => return 2;\n        when dptm => return 6;\n        when ggbp => return Eval (wbnh) + Eval (jhvm);\n        when qdrg => return 5;\n        when hcpf => return 4;\n        when zrbc => return 3;\n        when tpjw => return Eval (shcg) / Eval (hjmp);\n        when jnqv => return Eval (wwqp) + Eval (jcgh);\n        when fzrd => return 2;\n        when cbjl => return Eval (jdfj) * Eval (bnwj);\n        when bnjt => return 1;\n        when czpd => return 4;\n        when fjld => return Eval (tpjw) + Eval (ghvl);\n        when sbwd => return 4;\n        when rqfq => return Eval (lhmd) * Eval (nfvj);\n        when pwpn => return 3;\n        when ztzq => return Eval (nqsl) - Eval (vzts);\n        when ltqr => return Eval (dqcj) + Eval (qbgj);\n        when nlgg => return Eval (rvhs) * Eval (rqss);\n        when ltsl => return 2;\n        when zgzs => return 3;\n        when mqrm => return Eval (cqcg) * Eval (cbdr);\n        when fhtw => return Eval (fcql) + Eval (brqh);\n        when zdfg => return Eval (blmp) + Eval (qwcl);\n        when dzwg => return 4;\n        when czst => return Eval (smwb) - Eval (pvcn);\n        when ncsp => return Eval (rddj) - Eval (zhpq);\n        when bsnq => return 3;\n        when sflt => return Eval (qtvv) + Eval (ftmn);\n        when vsmt => return Eval (pwlh) + Eval (gztl);\n        when vszg => return Eval (smqg) / Eval (dfzw);\n        when tqfz => return Eval (wmdp) / Eval (mwms);\n        when fhzm => return Eval (lfjp) + Eval (rjtc);\n        when wgcm => return Eval (dsgt) / Eval (tqlp);\n        when zsvh => return Eval (grdf) + Eval (svcp);\n        when hjfj => return Eval (lmcj) * Eval (hndh);\n        when pqsr => return 2;\n        when lrbp => return Eval (wgsb) / Eval (htgm);\n        when twdf => return 2;\n        when jdbp => return Eval (pnvd) * Eval (ghfr);\n        when smdh => return 4;\n        when cjhz => return Eval (pvfm) * Eval (gbtc);\n        when psfp => return 3;\n        when cqmq => return 13;\n        when nvlv => return 17;\n        when lrqh => return Eval (gmzt) + Eval (gmpl);\n        when wqlh => return 16;\n        when qrsg => return 3;\n        when zzcv => return 14;\n        when sgzh => return Eval (mvgg) * Eval (zgdb);\n        when vrbh => return Eval (wqpv) / Eval (gwhs);\n        when drlt => return 5;\n        when shrh => return 13;\n        when qrln => return 2;\n        when hslj => return Eval (mgsz) * Eval (jddd);\n        when mtsv => return 3;\n        when hmfd => return 2;\n        when grcn => return 13;\n        when fctt => return Eval (smhv) * Eval (qzpn);\n        when lhmd => return Eval (vszd) + Eval (nfgv);\n        when rtgr => return Eval (nvhn) * Eval (szvb);\n        when zmvz => return Eval (fqbj) * Eval (swhh);\n        when jdjq => return 4;\n        when vhzf => return 2;\n        when fmvc => return Eval (fjcg) * Eval (dhts);\n        when dzlc => return Eval (rbpq) + Eval (vntv);\n        when fbjn => return Eval (tvrz) / Eval (nvjh);\n        when ppcl => return 3;\n        when jjjj => return 2;\n        when wfnm => return Eval (fvrg) * Eval (tzcl);\n        when dflc => return 2;\n        when ffnt => return Eval (mzfn) + Eval (vcpt);\n        when zbnt => return 3;\n        when dqnh => return 2;\n        when slww => return Eval (stzl) + Eval (pcwz);\n        when djjs => return Eval (ltzm) + Eval (qfjg);\n        when sqml => return 7;\n        when lghm => return 2;\n        when bsbd => return Eval (rzff) * Eval (wdwf);\n        when gwhs => return Eval (czpd) * Eval (jbsh);\n        when zqpw => return Eval (jsrb) + Eval (jwjj);\n        when drgv => return 3;\n        when rswn => return 5;\n        when gnjq => return 2;\n        when sjcd => return Eval (bcpn) * Eval (fvzw);\n        when fzml => return 11;\n        when mthn => return 2;\n        when cgnr => return 4;\n        when ldbp => return Eval (vrmt) + Eval (gptt);\n        when lqrf => return 2;\n        when gjbv => return Eval (djff) * Eval (stqc);\n        when ljnf => return Eval (rtjb) * Eval (wtnp);\n        when hjmp => return 6;\n        when mrnr => return 2;\n        when zspm => return 5;\n        when qlvz => return Eval (gjzv) + Eval (hpmm);\n        when tfdv => return 2;\n        when vtvn => return Eval (hrcp) * Eval (wtlq);\n        when qlmw => return Eval (vcfm) + Eval (pqsr);\n        when hsmp => return Eval (rpwz) * Eval (wclq);\n        when wcfj => return 2;\n        when brst => return 5;\n        when fnrh => return 2;\n        when qhzd => return Eval (fqlp) + Eval (jpzw);\n        when mmps => return Eval (jfld) * Eval (lqgr);\n        when lpfz => return Eval (lqfq) * Eval (wgbc);\n        when bjcs => return Eval (mhbr) / Eval (vgjq);\n        when tbqc => return 2;\n        when qhwm => return 3;\n        when hzvm => return Eval (npnf) + Eval (nhnp);\n        when nqhg => return Eval (tcjb) + Eval (hgzs);\n        when bzdh => return 2;\n        when gbtc => return 3;\n        when wfnl => return 5;\n        when ndlf => return Eval (cdnp) + Eval (ddmr);\n        when nmlt => return Eval (pnpc) * Eval (hnlj);\n        when nhfw => return Eval (tbqc) + Eval (dnzc);\n        when rtbm => return 3;\n        when fbpz => return Eval (sqzp) + Eval (pjrt);\n        when rjtc => return Eval (tjtl) + Eval (wtlg);\n        when vspf => return Eval (bnmb) + Eval (ndsm);\n        when dhqh => return Eval (dhpp) * Eval (zsvh);\n        when ddln => return 1;\n        when lbzn => return 2;\n        when vhrn => return Eval (bjcs) - Eval (vnft);\n        when cgcc => return 6;\n        when cgvs => return 7;\n        when jqtj => return 5;\n        when wqnp => return 12;\n        when dmtd => return Eval (fjzz) + Eval (sgpj);\n        when rlvd => return Eval (vlqd) / Eval (mgsl);\n        when cvvv => return Eval (bqtp) * Eval (pnwv);\n        when rjdp => return Eval (qfzb) + Eval (csnf);\n        when hmvq => return 17;\n        when vjtf => return Eval (lbzc) * Eval (djjd);\n        when gbgs => return Eval (mqfd) - Eval (fmbj);\n        when wgbc => return 3;\n        when vdbp => return 1;\n        when vtdp => return 10;\n        when cgvv => return Eval (bfvd) * Eval (pbhg);\n        when vfhg => return Eval (nlsw) - Eval (qgnb);\n        when pcwz => return Eval (dptm) * Eval (frjj);\n        when zngg => return 4;\n        when scrz => return 2;\n        when tvrz => return Eval (wslz) / Eval (dpvl);\n        when mqzw => return 2;\n        when zfmv => return 10;\n        when gdmv => return 5;\n        when cgnv => return 2;\n        when qlvw => return Eval (rfcv) + Eval (nlst);\n        when fjzn => return Eval (hgnr) + Eval (lqml);\n        when vzgb => return 12;\n        when dsng => return 5;\n        when pbvh => return 3;\n        when qbqm => return 10;\n        when vwdt => return Eval (lgrj) / Eval (pmlg);\n        when lhsw => return Eval (lpjq) + Eval (rdbs);\n        when hzjj => return 3;\n        when jplv => return 3;\n        when zmlh => return Eval (nfbp) * Eval (fhtw);\n        when zwbh => return Eval (sshm) * Eval (rjdp);\n        when mhnm => return Eval (bwnc) + Eval (fzwr);\n        when wmdp => return Eval (tdhw) - Eval (gjmt);\n        when pbhg => return 2;\n        when qmzt => return 9;\n        when dlws => return Eval (bssd) * Eval (rtbm);\n        when rbzl => return Eval (pjlz) * Eval (qfqz);\n        when tpjp => return Eval (jdsc) * Eval (wqnp);\n        when vlgn => return 2;\n        when phwc => return 10;\n        when bcng => return Eval (ctjq) + Eval (bdtp);\n        when cvnr => return Eval (qtmp) + Eval (bmzw);\n        when bmlj => return Eval (fvng) + Eval (czvm);\n        when llhb => return 3;\n        when nbcb => return Eval (rnns) + Eval (ldbg);\n        when ffmp => return Eval (plzd) + Eval (tzcd);\n        when nnzp => return Eval (lhsw) * Eval (tlwr);\n        when szlh => return 2;\n        when gztl => return 11;\n        when mtwg => return Eval (hcpf) * Eval (pjss);\n        when mpws => return Eval (pnfb) * Eval (pbvh);\n        when fqgl => return 3;\n        when qqpt => return 5;\n        when bqtp => return 2;\n        when nttd => return 9;\n        when svvh => return Eval (shpt) * Eval (fmvc);\n        when drnb => return Eval (lqqh) * Eval (mlbw);\n        when ptnv => return Eval (csgr) + Eval (plvw);\n        when wtnp => return 3;\n        when ndgh => return 4;\n        when lrgv => return 2;\n        when nrqr => return Eval (vvbz) + Eval (vfzw);\n        when hfvj => return 2;\n        when ctqb => return Eval (tsft) * Eval (lrgv);\n        when nqlh => return Eval (zdfg) * Eval (sdhj);\n        when nhnp => return 13;\n        when tcjb => return 12;\n        when mnhc => return Eval (szlh) * Eval (pcvv);\n        when jnnp => return 3;\n        when zbqq => return Eval (mtdh) * Eval (frst);\n        when gjzv => return Eval (brst) * Eval (twjq);\n        when shwr => return 5;\n        when gmpl => return Eval (qlmg) / Eval (cddt);\n        when lfpz => return Eval (mvmz) + Eval (hsmp);\n        when tmhl => return Eval (jbsn) * Eval (fhjz);\n        when wglc => return 14;\n        when ppll => return 5;\n        when ccbp => return 4;\n        when jflm => return Eval (cclc) / Eval (rgpt);\n        when mwms => return 2;\n        when svwg => return 4;\n        when qfss => return 10;\n        when tjtl => return 7;\n        when vwmr => return Eval (lvtv) + Eval (tvgm);\n        when cllb => return 3;\n        when nssr => return 3;\n        when qcfn => return Eval (lvcn) * Eval (wjmq);\n        when rmvq => return 2;\n        when rbtb => return Eval (mgmw) / Eval (gvww);\n        when jcdb => return Eval (mjmv) * Eval (zbnt);\n        when cdpw => return Eval (ngps) * Eval (hmqr);\n        when zdsr => return 2;\n        when plzd => return Eval (rvnh) * Eval (sszh);\n        when phjj => return Eval (hzcm) * Eval (bvdb);\n        when bnmf => return Eval (jtvw) * Eval (rdfn);\n        when twtq => return Eval (jbqf) - Eval (ztct);\n        when qwcl => return Eval (jjvz) / Eval (tptf);\n        when ccjf => return 13;\n        when mrjc => return Eval (fnrh) * Eval (cstm);\n        when thlz => return 2;\n        when thcc => return Eval (ljtp) + Eval (ztwb);\n        when fjcg => return 2;\n        when flhd => return 3;\n        when gnrj => return Eval (ppjl) * Eval (mmtj);\n        when hnlf => return 5;\n        when tprm => return 2;\n        when vlhc => return 13;\n        when tvgm => return Eval (gdmv) * Eval (dqsv);\n        when qvpw => return Eval (gqpj) * Eval (jvtz);\n        when vfwd => return 5;\n        when pmwl => return Eval (lwsn) * Eval (lddq);\n        when rzbj => return 17;\n        when rncj => return 5;\n        when znfq => return 2;\n        when rjbz => return Eval (gznh) * Eval (mcht);\n        when hhws => return Eval (vclb) + Eval (ftbq);\n        when qfln => return 3;\n        when ltmj => return Eval (wghf) / Eval (zjvz);\n        when csln => return 17;\n        when snvw => return 3;\n        when ltgf => return 3;\n        when wfbp => return 2;\n        when hjlz => return Eval (qmqt) + Eval (jvgd);\n        when zvst => return 3;\n        when qvvc => return 8;\n        when bjfh => return 3;\n        when mzfn => return Eval (cdpw) * Eval (ftzm);\n        when dqnp => return Eval (bcqm) / Eval (wjgf);\n        when stlr => return Eval (vzgd) * Eval (gvbp);\n        when cvfw => return 3;\n        when rtmh => return 15;\n        when rqss => return 3;\n        when jddd => return Eval (dcph) + Eval (mrvr);\n        when gggh => return 3;\n        when gssz => return Eval (nwwb) * Eval (vmnc);\n        when tsms => return Eval (gnzq) * Eval (rqbq);\n        when lrcj => return 19;\n        when pnfb => return 3;\n        when rtjb => return 2;\n        when zvmv => return Eval (fvhm) * Eval (gmhz);\n        when dfrb => return Eval (fbtc) + Eval (bppp);\n        when mcfr => return 1;\n        when pjrt => return 1;\n        when ltds => return Eval (wrll) * Eval (wnvf);\n        when fvsb => return Eval (qncp) * Eval (cfbh);\n        when nldv => return 4;\n        when cdnm => return 3;\n        when jwqg => return 2;\n        when jvqz => return 1;\n        when sqdd => return Eval (rzbj) + Eval (mqgl);\n        when cwvl => return Eval (jszj) + Eval (rvjf);\n        when qcnv => return Eval (nrqr) + Eval (wrmw);\n        when fhjz => return 2;\n        when svst => return Eval (qgtc) + Eval (snbm);\n        when qdrc => return 17;\n        when cfmw => return 1;\n        when jgld => return 5;\n        when bppp => return Eval (llhb) * Eval (qwqw);\n        when wwqp => return Eval (vjtf) + Eval (rwmq);\n        when cprm => return 4;\n        when fcgs => return 7;\n        when swfp => return Eval (tnnt) + Eval (lvhm);\n        when frjl => return 2;\n        when nwqz => return 1;\n        when mldc => return 3;\n        when mgmw => return Eval (pfvz) * Eval (hjqq);\n        when mnrr => return Eval (vvjg) / Eval (gggh);\n        when hvtv => return Eval (qznt) * Eval (wzfr);\n        when tpdj => return 9;\n        when znlh => return 4;\n        when qbgj => return Eval (mhzn) + Eval (nmts);\n        when cnhr => return 3;\n        when djgh => return Eval (bdqg) + Eval (nzdz);\n        when lccp => return 3;\n        when frrn => return 3;\n        when bbjs => return 7;\n        when gdpg => return 8;\n        when pnwv => return Eval (lhvt) * Eval (ggnd);\n        when vhtl => return Eval (snff) * Eval (vldc);\n        when vjwz => return 2;\n        when qwqq => return 2;\n        when rdnj => return Eval (smwv) + Eval (dcbt);\n        when nltq => return Eval (cbqn) - Eval (lrzn);\n        when fpvs => return Eval (jvsz) / Eval (fzdg);\n        when shcg => return Eval (qpqs) - Eval (snhd);\n        when stzl => return Eval (rwzt) + Eval (mnzz);\n        when rfcv => return Eval (qwnz) * Eval (mfql);\n        when snhd => return Eval (jtrg) * Eval (sqdd);\n        when gjmt => return 3;\n        when btzg => return 5;\n        when vfrh => return 9;\n        when lpjr => return Eval (bvvl) + Eval (rmvt);\n        when nzbz => return Eval (dqnh) * Eval (hplt);\n        when dhpp => return 2;\n        when hvsd => return 3;\n        when ldtj => return 2;\n        when chlt => return 4;\n        when rhtv => return Eval (fzml) * Eval (jnzr);\n        when wpgm => return 5;\n        when csfh => return 2;\n        when mhzn => return Eval (zglw) * Eval (slpm);\n        when wtbs => return Eval (ltdq) * Eval (vhzf);\n        when cpqv => return 15;\n        when dngq => return 2;\n        when vszd => return 12;\n        when pgvq => return Eval (ptvh) * Eval (hgwm);\n        when smnv => return 3;\n        when zrfw => return 7;\n        when jbvq => return 7;\n        when rmqt => return Eval (gcmv) / Eval (vlgn);\n        when pfvz => return 2;\n        when fmvw => return Eval (qnbn) * Eval (jpcd);\n        when jqhr => return 4;\n        when szwj => return 3;\n        when tqfr => return Eval (mrmm) + Eval (bcnd);\n        when rmvt => return 3;\n        when qllm => return 3;\n        when gcmz => return Eval (zrnr) * Eval (vffj);\n        when sqcb => return Eval (sfmn) + Eval (hvtv);\n        when chvn => return 3;\n        when fzvh => return Eval (ztrt) * Eval (nbpq);\n        when sbtd => return 3;\n        when hnst => return Eval (wvfb) + Eval (zphs);\n        when ljtp => return 16;\n        when lqml => return 4;\n        when dpqz => return 3;\n        when pwgj => return Eval (flrw) * Eval (cbfh);\n        when qvbn => return 2;\n        when ppsl => return Eval (dlws) + Eval (bjwg);\n        when jfmb => return Eval (jbtg) * Eval (cwhc);\n        when bzqw => return 2;\n        when nhcr => return 3;\n        when llnl => return 3;\n        when fzwr => return 5;\n        when mfst => return Eval (cdtq) / Eval (qfsz);\n        when flhf => return 3;\n        when whbb => return 8;\n        when rllb => return 3;\n        when rfcm => return Eval (rsqz) * Eval (ztdn);\n        when lqft => return Eval (tcgm) * Eval (nzbz);\n        when snmq => return Eval (jwqg) + Eval (zdnh);\n        when fwmw => return Eval (jfqs) + Eval (sgjm);\n        when ngfs => return Eval (ccbp) * Eval (dphz);\n        when mqfd => return Eval (lpzb) / Eval (ftzc);\n        when lflj => return Eval (vtdp) * Eval (cjhz);\n        when vzcr => return Eval (jmqh) + Eval (zbbf);\n      end case;\n    end Eval;\n  begin\n    return Eval (root);\n  end Compute;\n\nend AoC_2022_21_Pkg;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_21_pkg.ads",
    "content": "with AoC_Toolbox;\nwith Interfaces;\n\npackage AoC_2022_21_Pkg is\n\n  use AoC_Toolbox, Interfaces;\n\n  type Monkey_Mini is\n    (root_m,\n     dbpl,\n     cczh,\n     zczc,\n     ptdq,\n     dvpt,\n     lfqf,\n     humn_m,\n     ljgn,\n     sjmn,\n     sllz,\n     pppw,\n     lgvd,\n     drzm,\n     hmdt);\n\n  function Compute_Mini (part : Part_Type; human : Integer_64) return Integer_64;\n\n  type Monkey is\n    (rmmz,\n     vdjz,\n     rqbd,\n     zvqw,\n     sshm,\n     dtzl,\n     gnzq,\n     zlpv,\n     nqgr,\n     tftg,\n     fhjc,\n     fwbm,\n     wtlq,\n     nzhf,\n     nqpq,\n     jqzv,\n     crrj,\n     glpw,\n     cnbg,\n     bdcm,\n     bcww,\n     wrbf,\n     hpvb,\n     qffb,\n     mfmc,\n     cnzj,\n     wbnh,\n     swds,\n     twtb,\n     dlgc,\n     bvzn,\n     gwpm,\n     rtnf,\n     sdmb,\n     mtjq,\n     dpmg,\n     drct,\n     zrpj,\n     gwlm,\n     msdr,\n     fqbl,\n     zwqw,\n     lbvn,\n     dggg,\n     bjwg,\n     bnzl,\n     qtmp,\n     llpf,\n     zwqn,\n     trpt,\n     lzgm,\n     swhh,\n     tpnf,\n     rgrp,\n     zswl,\n     gzbv,\n     ppfs,\n     nfhf,\n     pgrc,\n     jjwr,\n     fvsf,\n     qmvq,\n     twjq,\n     twsj,\n     mwrc,\n     sbpb,\n     cbjq,\n     mgsl,\n     vzgd,\n     qrll,\n     slpm,\n     rffd,\n     jjbm,\n     pjds,\n     btfl,\n     sfcv,\n     vtnq,\n     fzdp,\n     cwjp,\n     mpnj,\n     wnbb,\n     nfgv,\n     pszs,\n     chpt,\n     bhpw,\n     dfps,\n     pzqv,\n     fjzz,\n     ffqr,\n     bqvg,\n     qlmg,\n     lfhb,\n     pqqj,\n     qhtv,\n     wchl,\n     vcwt,\n     nfbp,\n     bbcn,\n     smld,\n     mvmj,\n     mqph,\n     brmz,\n     ttdb,\n     bcsc,\n     frjj,\n     jcjf,\n     pmfh,\n     drrf,\n     lmht,\n     sstg,\n     swhz,\n     rtpz,\n     qrzq,\n     rtmt,\n     pmds,\n     vfzw,\n     smhv,\n     vdzv,\n     btqb,\n     wclq,\n     vzrz,\n     ztct,\n     zvvd,\n     mfrc,\n     sdrn,\n     jfvq,\n     qjrs,\n     tnnt,\n     fqlp,\n     nwhm,\n     rlcw,\n     rwjc,\n     tfqh,\n     crqg,\n     nrps,\n     pmng,\n     gmzt,\n     fhdz,\n     fwzf,\n     tzls,\n     pvtb,\n     gpdf,\n     zcgs,\n     clbn,\n     wghf,\n     vffj,\n     gfbw,\n     tzth,\n     vwhb,\n     scwp,\n     rpbm,\n     zdhf,\n     fdmf,\n     lqdf,\n     rndt,\n     jnzr,\n     qpqs,\n     tmhg,\n     dtfz,\n     pnvc,\n     mfnh,\n     vjgb,\n     czvm,\n     qhnd,\n     dhfw,\n     nqpv,\n     rhcv,\n     lqqh,\n     mspl,\n     ngps,\n     bcmp,\n     nlsw,\n     mhlj,\n     bqnn,\n     fbqs,\n     cnln,\n     vjbz,\n     vhhz,\n     crmb,\n     wbgs,\n     qhvn,\n     lsnd,\n     hhcv,\n     vmjn,\n     fbtc,\n     jgnj,\n     jmcp,\n     mfhg,\n     ztdn,\n     zttf,\n     tjwt,\n     lzzh,\n     rnns,\n     ffnn,\n     wpvg,\n     wjds,\n     nnmh,\n     jswz,\n     qjqw,\n     bndd,\n     mdpg,\n     wtwb,\n     nbfg,\n     nmts,\n     nvjf,\n     gqgh,\n     btqt,\n     cblz,\n     nvpd,\n     vldc,\n     drhw,\n     bpjf,\n     dpgl,\n     ggnd,\n     qzpn,\n     ttvz,\n     qwqc,\n     zhmb,\n     nzdj,\n     rrnp,\n     mbvg,\n     mlbw,\n     wvfb,\n     tzhp,\n     zjcn,\n     wbbf,\n     mfsz,\n     bfpq,\n     vpvl,\n     pnrv,\n     lbgc,\n     pbdd,\n     jsrb,\n     bbzt,\n     mhdn,\n     jpcd,\n     ldzb,\n     nmlg,\n     pnpc,\n     rbqt,\n     dsqb,\n     zhqg,\n     dphz,\n     gbzd,\n     cldm,\n     ftbq,\n     rzff,\n     tzcd,\n     gzwh,\n     qgnb,\n     jzvg,\n     qqwz,\n     jbtg,\n     rrgh,\n     bvfr,\n     mwdl,\n     chfs,\n     gwmr,\n     qcml,\n     zbhj,\n     zshp,\n     pvcs,\n     sszh,\n     jdsc,\n     ndnm,\n     lrlz,\n     wpbs,\n     bcpn,\n     glts,\n     qnld,\n     hrtv,\n     zbbf,\n     vvbz,\n     vvjg,\n     lrlg,\n     zpht,\n     ndtz,\n     stcv,\n     jjrh,\n     hsbr,\n     wtrh,\n     jfqs,\n     hjgd,\n     hgnr,\n     brqb,\n     ndsm,\n     fjgh,\n     tptf,\n     njcj,\n     jjvz,\n     grww,\n     jvqf,\n     sgvm,\n     zscd,\n     mgjl,\n     bfgp,\n     mpst,\n     wjzd,\n     wqdj,\n     csdf,\n     cgwj,\n     rccr,\n     vsgw,\n     pvwn,\n     mfql,\n     dspn,\n     llcn,\n     dcph,\n     npcs,\n     wgvj,\n     bblh,\n     dmrn,\n     qbzv,\n     lrdn,\n     wzfr,\n     bwnc,\n     dswn,\n     bnws,\n     cdnp,\n     fddw,\n     nbbd,\n     lbzc,\n     sntb,\n     vzts,\n     jvfw,\n     mqcv,\n     jhzw,\n     lhpf,\n     znjr,\n     wrvl,\n     cdwt,\n     vtjg,\n     dvnh,\n     pcgq,\n     nhjt,\n     pmqh,\n     zrwb,\n     zphs,\n     nmvn,\n     sbvl,\n     bcdf,\n     jhwn,\n     ftjv,\n     ncnm,\n     bgwj,\n     hrbr,\n     qljb,\n     vdsz,\n     nhpf,\n     gvfn,\n     ppts,\n     fvhm,\n     rrqr,\n     lnqm,\n     qwnz,\n     cgvr,\n     lvrc,\n     vcfm,\n     zhgt,\n     nvdh,\n     llfg,\n     wjgf,\n     nztj,\n     shpt,\n     gzmv,\n     tqzv,\n     pdmb,\n     fpcs,\n     mwmp,\n     hcfs,\n     bshp,\n     gppj,\n     pzpp,\n     ltnz,\n     wzdj,\n     frst,\n     scdn,\n     fpsh,\n     gzwm,\n     jmbs,\n     rqsw,\n     bnvg,\n     tfwb,\n     snwm,\n     zvrq,\n     vnpq,\n     cfbh,\n     ntnh,\n     jnwv,\n     npvl,\n     tpwq,\n     flhs,\n     pnvd,\n     zvvp,\n     fcql,\n     jrvp,\n     wbvt,\n     vwht,\n     pzvr,\n     qncp,\n     bcgz,\n     dcbt,\n     csgr,\n     rsdv,\n     fnqf,\n     hzrc,\n     cdvw,\n     bsvc,\n     tlwr,\n     hjmr,\n     spjg,\n     mqgl,\n     mzzd,\n     dqnv,\n     lqcm,\n     sqzp,\n     drvt,\n     ghvn,\n     hfbh,\n     wtlg,\n     dsgt,\n     vvzh,\n     sclr,\n     jqqs,\n     zprq,\n     dczh,\n     lpzb,\n     dqsv,\n     hgzs,\n     vrpp,\n     snbm,\n     tdrq,\n     tbwl,\n     jdmt,\n     fzgj,\n     vnvr,\n     mcht,\n     ztrt,\n     bncr,\n     nqsl,\n     cclc,\n     ztpd,\n     lfrb,\n     pvfv,\n     swpl,\n     csnf,\n     ptdz,\n     nvhn,\n     rdhg,\n     jclb,\n     cscm,\n     fcgj,\n     hgwm,\n     rqbq,\n     wjtc,\n     dpvl,\n     nwdv,\n     zcgn,\n     jvrt,\n     zmdq,\n     rtsd,\n     nqzz,\n     dshq,\n     mddc,\n     rpwz,\n     pmlg,\n     blmp,\n     hqbb,\n     chtt,\n     cchg,\n     bntz,\n     gvgp,\n     vvhm,\n     nlcv,\n     rwcd,\n     rfcq,\n     zgdb,\n     mggl,\n     mwjg,\n     rbbh,\n     mqlt,\n     ddtd,\n     hpmm,\n     cjlm,\n     cpdf,\n     gqrp,\n     zmtg,\n     vwdl,\n     ggpn,\n     mtfr,\n     nsfm,\n     cftm,\n     wcdm,\n     jcch,\n     zqjp,\n     wjmq,\n     cbgj,\n     jmnj,\n     tlnz,\n     fqjd,\n     ngzp,\n     trdj,\n     qrch,\n     hmrz,\n     rvnh,\n     humn,\n     jstb,\n     vqlt,\n     vlqd,\n     vjjw,\n     mnlp,\n     jtcf,\n     lwlc,\n     jdgq,\n     vznc,\n     dcfw,\n     fqwz,\n     hhbn,\n     wrpp,\n     mmnw,\n     rdpb,\n     hcsc,\n     nfvj,\n     qznt,\n     flvw,\n     wphq,\n     bpwd,\n     cbfh,\n     bcbw,\n     dvwj,\n     tnbt,\n     qlzt,\n     rjfh,\n     cprt,\n     qgwg,\n     zpbt,\n     drln,\n     jdcd,\n     jzcd,\n     sbpp,\n     ttwm,\n     rdbs,\n     pfpt,\n     rfbw,\n     bqld,\n     rrmg,\n     rbsf,\n     mlgj,\n     jfcd,\n     sjrh,\n     djjd,\n     jhgd,\n     nlts,\n     ppwc,\n     gptt,\n     bvvl,\n     ssnq,\n     gmhz,\n     nnsc,\n     zbzf,\n     jhvm,\n     mrrt,\n     pmrt,\n     rddj,\n     wszm,\n     pbgr,\n     hzlh,\n     qnbn,\n     hrcp,\n     dnwd,\n     rvlz,\n     stcr,\n     ptvh,\n     vmnc,\n     bmwf,\n     jzdn,\n     djrh,\n     lwlb,\n     bqht,\n     brfj,\n     rlqm,\n     mdht,\n     lbbj,\n     blnq,\n     chfz,\n     sqsc,\n     mwrt,\n     nvrb,\n     lgrj,\n     pvcn,\n     fbgc,\n     mqnl,\n     bdtp,\n     wdwf,\n     hhjc,\n     jzlv,\n     smwb,\n     bhvg,\n     zmmd,\n     mdld,\n     qlqt,\n     dgbr,\n     rwsm,\n     jnll,\n     dbht,\n     bhmz,\n     mrlq,\n     fzdg,\n     jbsh,\n     svzv,\n     zjmw,\n     tcgm,\n     nzcv,\n     rmrj,\n     bjnj,\n     qsml,\n     mfts,\n     ffqs,\n     dbcw,\n     wpcs,\n     rvhs,\n     qmcb,\n     hlms,\n     vwpq,\n     wslz,\n     jpvr,\n     hcdz,\n     svvq,\n     lgpg,\n     mlwr,\n     hbqm,\n     fgbm,\n     cjlh,\n     tlmq,\n     zzqd,\n     drdl,\n     sdjb,\n     ntmt,\n     rwth,\n     jjgt,\n     mpvz,\n     qbmm,\n     zdrh,\n     trft,\n     dqjz,\n     gfrq,\n     vvgt,\n     tsft,\n     gzpf,\n     tfpw,\n     cddt,\n     rlbp,\n     ndph,\n     blbc,\n     cvhn,\n     zncl,\n     rthb,\n     jfld,\n     gdgd,\n     lrsc,\n     gzgm,\n     bhrb,\n     bsmm,\n     qnds,\n     bhzq,\n     vwvc,\n     qmgt,\n     gfml,\n     tjqj,\n     vlmc,\n     qlnr,\n     fvph,\n     jgzl,\n     wnjc,\n     ffbb,\n     hzmn,\n     rpbj,\n     sqmd,\n     ndcd,\n     mmbs,\n     mhbr,\n     nsqq,\n     wgvv,\n     rvmp,\n     dwnz,\n     jvtz,\n     nzzv,\n     cqcg,\n     nrvw,\n     qqtm,\n     fvng,\n     phrv,\n     tlzh,\n     twjs,\n     lhgv,\n     rctr,\n     snlb,\n     dfgh,\n     tvtj,\n     flcb,\n     nqpr,\n     jmbp,\n     rcmc,\n     mnpl,\n     twcj,\n     nlth,\n     drrq,\n     fszd,\n     mlrz,\n     jvgd,\n     jtvw,\n     ftvm,\n     cgcz,\n     dfzw,\n     tdhw,\n     qwnt,\n     mspb,\n     fhmz,\n     dqzt,\n     brfc,\n     hstj,\n     rzjm,\n     jbcl,\n     zhpq,\n     hmrs,\n     mtdh,\n     lwhp,\n     wnvf,\n     qqdn,\n     wrmw,\n     gzrs,\n     nzwc,\n     wflc,\n     gtwp,\n     trbs,\n     zsns,\n     vvvb,\n     cstb,\n     gcmv,\n     vrjj,\n     rrll,\n     wgsb,\n     scdt,\n     wqqv,\n     szhq,\n     tqzf,\n     wpqd,\n     vmzc,\n     pjlz,\n     mdjm,\n     qgjf,\n     qnhq,\n     hfbg,\n     jfsr,\n     nfhw,\n     cstm,\n     ghvl,\n     tzcl,\n     pzzg,\n     cdqv,\n     wcpr,\n     jdrg,\n     gtqh,\n     hlmn,\n     hnqc,\n     sphc,\n     bnlr,\n     dbfd,\n     hpzh,\n     ghqp,\n     dfql,\n     hbzt,\n     chsm,\n     lpjq,\n     plfd,\n     vbvt,\n     rdpg,\n     vhds,\n     rmfv,\n     smft,\n     wlpd,\n     cvvw,\n     bsqn,\n     svcp,\n     qflq,\n     bwwc,\n     wqfg,\n     lbqn,\n     zbhw,\n     jlnf,\n     nlst,\n     zfjw,\n     wfms,\n     fjps,\n     djpm,\n     snsc,\n     hnlj,\n     pvfm,\n     cwhc,\n     blgg,\n     jmwl,\n     wbsb,\n     jwwv,\n     jdsd,\n     rsnp,\n     rrnt,\n     nfnw,\n     mpfm,\n     mnzz,\n     lfjp,\n     qvfg,\n     mjmv,\n     lclg,\n     pcvv,\n     wsml,\n     gvbp,\n     mpjj,\n     vcqw,\n     lhvt,\n     qpdv,\n     mrlc,\n     bdmw,\n     vntv,\n     cfdl,\n     gvww,\n     dqhh,\n     mtnb,\n     wlfp,\n     zslv,\n     lqrr,\n     qfzb,\n     ltzm,\n     qcnn,\n     bhvr,\n     wnzr,\n     zglw,\n     svdw,\n     pfml,\n     zpqd,\n     fjnh,\n     rhqj,\n     szmm,\n     ztwb,\n     npnf,\n     wltv,\n     bwff,\n     slnh,\n     ppwz,\n     hgls,\n     dbvt,\n     wrst,\n     rzzg,\n     prbr,\n     bvdb,\n     jlmb,\n     rbpq,\n     jwjj,\n     dhts,\n     dcpm,\n     qvpv,\n     bbhp,\n     sjfs,\n     wqpv,\n     sdhj,\n     wfbz,\n     mdnp,\n     ctjq,\n     mbqs,\n     wcfp,\n     ftzm,\n     nwbt,\n     bmsf,\n     cmnt,\n     wqfz,\n     jrgs,\n     gmzh,\n     pnvs,\n     gcvn,\n     qbvr,\n     phbh,\n     shtz,\n     smsm,\n     gznh,\n     tjch,\n     bpnt,\n     lljf,\n     qfsz,\n     dgvh,\n     lvbp,\n     cdvv,\n     qlzg,\n     rwbg,\n     snff,\n     flrw,\n     tdnf,\n     nzlr,\n     ftzc,\n     pznf,\n     zjvz,\n     nvjl,\n     qtvv,\n     hdff,\n     swmh,\n     ghfr,\n     ghtd,\n     mfmt,\n     pgtq,\n     frjp,\n     bnfz,\n     qfqz,\n     djmr,\n     crcm,\n     ngbg,\n     sbqm,\n     wlqd,\n     jfrn,\n     jbqf,\n     zhrs,\n     lvtv,\n     vclb,\n     qtgd,\n     hqbd,\n     qqnm,\n     nvjh,\n     jcgh,\n     bgzz,\n     slds,\n     lwsn,\n     bhgh,\n     bjbr,\n     tgvp,\n     dbfm,\n     msmm,\n     llqs,\n     qqpl,\n     pfdc,\n     qlvg,\n     wzdv,\n     glqr,\n     vdgt,\n     qrnj,\n     fbrf,\n     gvmj,\n     nrjc,\n     sdsl,\n     mqvg,\n     chvq,\n     lrzn,\n     crrm,\n     pgbv,\n     brqv,\n     gmln,\n     wcmz,\n     hbhz,\n     vrcl,\n     hqdv,\n     nchp,\n     bfvd,\n     nnhm,\n     thpg,\n     jpzw,\n     vrmt,\n     hnbn,\n     tsbf,\n     nbpq,\n     csml,\n     cnmq,\n     qbwf,\n     jbrp,\n     bbzc,\n     pgfr,\n     fmwn,\n     lrvc,\n     stqc,\n     ngzt,\n     mdrm,\n     mrtq,\n     lpvs,\n     lqfq,\n     rnnq,\n     jdfj,\n     tqst,\n     dnzc,\n     lwld,\n     sgjm,\n     bfzd,\n     dchw,\n     rlrb,\n     pchr,\n     lvhm,\n     mswh,\n     sdgs,\n     snfj,\n     sdwj,\n     qmqt,\n     przh,\n     qrpv,\n     pjsp,\n     hpmw,\n     jhlw,\n     ntqb,\n     qpct,\n     rvvn,\n     lmcj,\n     bvjd,\n     fngd,\n     fnws,\n     frqq,\n     ltsv,\n     cmnv,\n     wdqj,\n     cjbz,\n     rqpj,\n     lbtn,\n     dbgp,\n     qbjm,\n     ljzj,\n     mrvr,\n     nght,\n     djff,\n     jmqh,\n     vcpt,\n     vsqt,\n     tfjw,\n     hwvf,\n     qgtf,\n     mmtj,\n     blgf,\n     mvmz,\n     svhz,\n     wfds,\n     pnmc,\n     szvb,\n     bnwj,\n     dnvm,\n     fwrh,\n     cspp,\n     lltp,\n     smrq,\n     rgzs,\n     crmw,\n     dncw,\n     rvjf,\n     wlmv,\n     fqbj,\n     fwjg,\n     gnsc,\n     gtwd,\n     qdnl,\n     pjjj,\n     ntsl,\n     glqw,\n     wmzt,\n     vjzr,\n     ncgd,\n     bngr,\n     qtfp,\n     bdqg,\n     hzpr,\n     tctd,\n     jlqg,\n     qhlj,\n     jtvm,\n     szcv,\n     sfmn,\n     lfhp,\n     root,\n     jbwd,\n     zrnr,\n     hrmz,\n     rfjw,\n     hpdh,\n     jqrl,\n     vgsm,\n     mvgg,\n     hcqw,\n     cdtq,\n     spgw,\n     wfjn,\n     hrtz,\n     rzsn,\n     fbcd,\n     vhwz,\n     lvcn,\n     grdf,\n     pdbc,\n     qssh,\n     wnjl,\n     btwt,\n     hplt,\n     mwwr,\n     smqg,\n     dqcj,\n     ptwr,\n     mttr,\n     pzcc,\n     jscq,\n     hzcm,\n     tsjq,\n     fsgb,\n     plvw,\n     tcqz,\n     mqzp,\n     tldn,\n     rwmq,\n     vnft,\n     ztqg,\n     fjvg,\n     nzdz,\n     qrgn,\n     tbqq,\n     tdjh,\n     qwqw,\n     pdbt,\n     bnmb,\n     lslq,\n     twwv,\n     rzcm,\n     jtjd,\n     htgm,\n     pjss,\n     mrwz,\n     djqq,\n     jmcf,\n     hmqr,\n     lqdc,\n     gpzn,\n     pgdw,\n     mwgb,\n     wggq,\n     mwqc,\n     bnfp,\n     pwlt,\n     hlzp,\n     qplw,\n     vhqz,\n     zptr,\n     gtbs,\n     zwwb,\n     hmfb,\n     mffc,\n     lqgr,\n     bcqm,\n     cbdr,\n     bssd,\n     dmsz,\n     fpwz,\n     rbmm,\n     rvhn,\n     hqjt,\n     bftg,\n     ppjl,\n     nzbp,\n     rwzt,\n     zwgg,\n     frlv,\n     vmgn,\n     tvrd,\n     wfld,\n     pnwz,\n     ndmd,\n     fmbj,\n     jqcf,\n     jqsn,\n     wzsh,\n     hjqq,\n     cvqf,\n     wrll,\n     vtns,\n     wsnf,\n     qfjg,\n     rsqz,\n     dddm,\n     ftmn,\n     bcnd,\n     qgtc,\n     vthd,\n     mvnc,\n     ndpf,\n     pwlh,\n     cfzf,\n     qldj,\n     ftqd,\n     lhml,\n     mrmm,\n     crnb,\n     qpbz,\n     qspw,\n     jtrg,\n     nwwb,\n     rgpt,\n     spcf,\n     brqh,\n     qfrg,\n     ddmr,\n     lpqs,\n     zvqs,\n     dfdl,\n     vnbv,\n     bwqm,\n     zjpc,\n     btbn,\n     bpgp,\n     jbsn,\n     tdlw,\n     fsrm,\n     rjrt,\n     wpdn,\n     dzvg,\n     rdfn,\n     zrnz,\n     djgb,\n     pwln,\n     vfgt,\n     tbdh,\n     jlwb,\n     cshj,\n     lzhf,\n     hncq,\n     nqms,\n     lhfr,\n     ltdq,\n     zssf,\n     dqld,\n     grcv,\n     zfbq,\n     lmjg,\n     lncn,\n     qmjq,\n     rnbs,\n     mstm,\n     pnwh,\n     ccfw,\n     tsqc,\n     gqpj,\n     tnfz,\n     rhwm,\n     bcnp,\n     fvrg,\n     vtgj,\n     wwtj,\n     slmm,\n     mjmt,\n     zzpd,\n     wttp,\n     qdfp,\n     psfr,\n     rlqh,\n     mgsz,\n     cjvp,\n     hrjj,\n     fjrq,\n     qmpm,\n     lddq,\n     snbl,\n     bghp,\n     zdnh,\n     cbqn,\n     pbzb,\n     rmzw,\n     qpqb,\n     jffq,\n     rscq,\n     wjzv,\n     ngbz,\n     hdrj,\n     slpc,\n     bmzw,\n     cmtm,\n     pwqg,\n     dgpr,\n     trpv,\n     qnvn,\n     gcqh,\n     bdgd,\n     dbcs,\n     nrqv,\n     cnvb,\n     cvgt,\n     tqlp,\n     sgpj,\n     swsv,\n     hndh,\n     smwv,\n     dwdd,\n     jszj,\n     ncrt,\n     rpbg,\n     jvsz,\n     ffvs,\n     mnhf,\n     hbwh,\n     tpmp,\n     nttr,\n     ldbg,\n     ntpj,\n     lbbv,\n     vrct,\n     lccn,\n     nrsd,\n     fvzw,\n     vgjq,\n     dptm,\n     ggbp,\n     qdrg,\n     hcpf,\n     zrbc,\n     tpjw,\n     jnqv,\n     fzrd,\n     cbjl,\n     bnjt,\n     czpd,\n     fjld,\n     sbwd,\n     rqfq,\n     pwpn,\n     ztzq,\n     ltqr,\n     nlgg,\n     ltsl,\n     zgzs,\n     mqrm,\n     fhtw,\n     zdfg,\n     dzwg,\n     czst,\n     ncsp,\n     bsnq,\n     sflt,\n     vsmt,\n     vszg,\n     tqfz,\n     fhzm,\n     wgcm,\n     zsvh,\n     hjfj,\n     pqsr,\n     lrbp,\n     twdf,\n     jdbp,\n     smdh,\n     cjhz,\n     psfp,\n     cqmq,\n     nvlv,\n     lrqh,\n     wqlh,\n     qrsg,\n     zzcv,\n     sgzh,\n     vrbh,\n     drlt,\n     shrh,\n     qrln,\n     hslj,\n     mtsv,\n     hmfd,\n     grcn,\n     fctt,\n     lhmd,\n     rtgr,\n     zmvz,\n     jdjq,\n     vhzf,\n     fmvc,\n     dzlc,\n     fbjn,\n     ppcl,\n     jjjj,\n     wfnm,\n     dflc,\n     ffnt,\n     zbnt,\n     dqnh,\n     slww,\n     djjs,\n     sqml,\n     lghm,\n     bsbd,\n     gwhs,\n     zqpw,\n     drgv,\n     rswn,\n     gnjq,\n     sjcd,\n     fzml,\n     mthn,\n     cgnr,\n     ldbp,\n     lqrf,\n     gjbv,\n     ljnf,\n     hjmp,\n     mrnr,\n     zspm,\n     qlvz,\n     tfdv,\n     vtvn,\n     qlmw,\n     hsmp,\n     wcfj,\n     brst,\n     fnrh,\n     qhzd,\n     mmps,\n     lpfz,\n     bjcs,\n     tbqc,\n     qhwm,\n     hzvm,\n     nqhg,\n     bzdh,\n     gbtc,\n     wfnl,\n     ndlf,\n     nmlt,\n     nhfw,\n     rtbm,\n     fbpz,\n     rjtc,\n     vspf,\n     dhqh,\n     ddln,\n     lbzn,\n     vhrn,\n     cgcc,\n     cgvs,\n     jqtj,\n     wqnp,\n     dmtd,\n     rlvd,\n     cvvv,\n     rjdp,\n     hmvq,\n     vjtf,\n     gbgs,\n     wgbc,\n     vdbp,\n     vtdp,\n     cgvv,\n     vfhg,\n     pcwz,\n     zngg,\n     scrz,\n     tvrz,\n     mqzw,\n     zfmv,\n     gdmv,\n     cgnv,\n     qlvw,\n     fjzn,\n     vzgb,\n     dsng,\n     pbvh,\n     qbqm,\n     vwdt,\n     lhsw,\n     hzjj,\n     jplv,\n     zmlh,\n     zwbh,\n     mhnm,\n     wmdp,\n     pbhg,\n     qmzt,\n     dlws,\n     rbzl,\n     tpjp,\n     vlgn,\n     phwc,\n     bcng,\n     cvnr,\n     bmlj,\n     llhb,\n     nbcb,\n     ffmp,\n     nnzp,\n     szlh,\n     gztl,\n     mtwg,\n     mpws,\n     fqgl,\n     qqpt,\n     bqtp,\n     nttd,\n     svvh,\n     drnb,\n     ptnv,\n     wtnp,\n     ndgh,\n     lrgv,\n     nrqr,\n     hfvj,\n     ctqb,\n     nqlh,\n     nhnp,\n     tcjb,\n     mnhc,\n     jnnp,\n     zbqq,\n     gjzv,\n     shwr,\n     gmpl,\n     lfpz,\n     tmhl,\n     wglc,\n     ppll,\n     ccbp,\n     jflm,\n     mwms,\n     svwg,\n     qfss,\n     tjtl,\n     vwmr,\n     cllb,\n     nssr,\n     qcfn,\n     rmvq,\n     rbtb,\n     jcdb,\n     cdpw,\n     zdsr,\n     plzd,\n     phjj,\n     bnmf,\n     twtq,\n     qwcl,\n     ccjf,\n     mrjc,\n     thlz,\n     thcc,\n     fjcg,\n     flhd,\n     gnrj,\n     hnlf,\n     tprm,\n     vlhc,\n     tvgm,\n     qvpw,\n     vfwd,\n     pmwl,\n     rzbj,\n     rncj,\n     znfq,\n     rjbz,\n     hhws,\n     qfln,\n     ltmj,\n     csln,\n     snvw,\n     ltgf,\n     wfbp,\n     hjlz,\n     zvst,\n     qvvc,\n     bjfh,\n     mzfn,\n     dqnp,\n     stlr,\n     cvfw,\n     rtmh,\n     rqss,\n     jddd,\n     gggh,\n     gssz,\n     tsms,\n     lrcj,\n     pnfb,\n     rtjb,\n     zvmv,\n     dfrb,\n     mcfr,\n     pjrt,\n     ltds,\n     fvsb,\n     nldv,\n     cdnm,\n     jwqg,\n     jvqz,\n     sqdd,\n     cwvl,\n     qcnv,\n     fhjz,\n     svst,\n     qdrc,\n     cfmw,\n     jgld,\n     bppp,\n     wwqp,\n     cprm,\n     fcgs,\n     swfp,\n     frjl,\n     nwqz,\n     mldc,\n     mgmw,\n     mnrr,\n     hvtv,\n     tpdj,\n     znlh,\n     qbgj,\n     cnhr,\n     djgh,\n     lccp,\n     frrn,\n     bbjs,\n     gdpg,\n     pnwv,\n     vhtl,\n     vjwz,\n     qwqq,\n     rdnj,\n     nltq,\n     fpvs,\n     shcg,\n     stzl,\n     rfcv,\n     snhd,\n     gjmt,\n     btzg,\n     vfrh,\n     lpjr,\n     nzbz,\n     dhpp,\n     hvsd,\n     ldtj,\n     chlt,\n     rhtv,\n     wpgm,\n     csfh,\n     mhzn,\n     wtbs,\n     cpqv,\n     dngq,\n     vszd,\n     pgvq,\n     smnv,\n     zrfw,\n     jbvq,\n     rmqt,\n     pfvz,\n     fmvw,\n     jqhr,\n     szwj,\n     tqfr,\n     rmvt,\n     qllm,\n     gcmz,\n     sqcb,\n     chvn,\n     fzvh,\n     sbtd,\n     hnst,\n     ljtp,\n     lqml,\n     dpqz,\n     pwgj,\n     qvbn,\n     ppsl,\n     jfmb,\n     bzqw,\n     nhcr,\n     llnl,\n     fzwr,\n     mfst,\n     flhf,\n     whbb,\n     rllb,\n     rfcm,\n     lqft,\n     snmq,\n     fwmw,\n     ngfs,\n     mqfd,\n     lflj,\n     vzcr);\n\n  function Compute (part : Part_Type; human : Integer_64) return Integer_64;\n\nend AoC_2022_21_Pkg;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_21_questions.txt",
    "content": "--- Day 21: Monkey Math ---\n\nThe monkeys are back!\nYou're worried they're going to try to steal your stuff again,\nbut it seems like they're just holding their ground and making\nvarious monkey noises at you.\n\nEventually, one of the elephants realizes you don't speak monkey\nand comes over to interpret. As it turns out, they overheard you\ntalking about trying to find the grove; they can show you a\nshortcut if you answer their riddle.\n\nEach monkey is given a job: either to yell a specific number or\nto yell the result of a math operation.\nAll of the number-yelling monkeys know their number from the start;\nhowever, the math operation monkeys need to wait for two other monkeys\nto yell a number, and those two other monkeys might also\nbe waiting on other monkeys.\n\nYour job is to work out the number the monkey named root\nwill yell before the monkeys figure it out themselves.\n\nFor example:\n\nroot: pppw + sjmn\ndbpl: 5\ncczh: sllz + lgvd\nzczc: 2\nptdq: humn - dvpt\ndvpt: 3\nlfqf: 4\nhumn: 5\nljgn: 2\nsjmn: drzm * dbpl\nsllz: 4\npppw: cczh / lfqf\nlgvd: ljgn * ptdq\ndrzm: hmdt - zczc\nhmdt: 32\n\nEach line contains the name of a monkey, a colon,\nand then the job of that monkey:\n\n    A lone number means the monkey's job is simply to yell that number.\n    \n    A job like aaaa + bbbb means the monkey waits for monkeys\n      aaaa and bbbb to yell each of their numbers;\n      the monkey then yells the sum of those two numbers.\n      \n    aaaa - bbbb means the monkey yells aaaa's number minus bbbb's number.\n    \n    Job aaaa * bbbb will yell aaaa's number multiplied by bbbb's number.\n    \n    Job aaaa / bbbb will yell aaaa's number divided by bbbb's number.\n\nSo, in the above example, monkey drzm has to wait for monkeys hmdt\nand zczc to yell their numbers. Fortunately, both hmdt and zczc have\njobs that involve simply yelling a single number, so they do this\nimmediately: 32 and 2. Monkey drzm can then yell its number by\nfinding 32 minus 2: 30.\n\nThen, monkey sjmn has one of its numbers (30, from monkey drzm),\nand already has its other number, 5, from dbpl.\nThis allows it to yell its own number by finding 30 multiplied by 5: 150.\n\nThis process continues until root yells a number: 152.\n\nHowever, your actual situation involves considerably more monkeys.\nWhat number will the monkey named root yell?\n\n--- Part Two ---\n\nDue to some kind of monkey-elephant-human mistranslation, you seem\nto have misunderstood a few key details about the riddle.\n\nFirst, you got the wrong job for the monkey named root; specifically,\nyou got the wrong math operation.\nThe correct operation for monkey root should be =, which means that\nit still listens for two numbers (from the same two monkeys as before),\nbut now checks that the two numbers match.\n\nSecond, you got the wrong monkey for the job starting with humn:. \nIt isn't a monkey - it's you. Actually, you got the job wrong,\ntoo: you need to figure out what number you need to yell so that\nroot's equality check passes. (The number that appears after humn:\nin your input is now irrelevant.)\n\nIn the above example, the number you need to yell to pass root's\nequality test is 301. (This causes root to get the same number,\n150, from both of its monkeys.)\n\nWhat number do you yell to pass root's equality test?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_22.adb",
    "content": "--  Solution to Advent of Code 2022, Day 22\n-------------------------------------------\n--  Monkey Map\n--\n--  https://adventofcode.com/2022/day/22\n--  Copy of questions in: aoc_2022_22_questions.txt\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\nprocedure AoC_2022_22 is\n\n  use AoC_Toolbox, HAT;\n\n  subtype Range_x is Integer range 1 .. 150;\n  subtype Range_y is Integer range 1 .. 200;\n\n  map   : array (Range_x, Range_y) of Character;\n\n  lowest, highest : Point;\n\n  procedure Adapt_Highest_Value_Point (using : Point) is\n  begin\n    highest.x := Max (highest.x, using.x);\n    highest.y := Max (highest.y, using.y);\n  end Adapt_Highest_Value_Point;\n\n  procedure Show is\n  begin\n    for y in lowest.y .. highest.y loop\n      for x in lowest.x .. highest.x loop\n        Put (map (x, y));\n      end loop;\n      Put_Line ('|');\n    end loop;\n  end Show;\n\n  procedure Clear is\n  begin\n    for y in Range_y loop\n      for x in Range_x loop\n        map (x, y) := ' ';\n      end loop;\n    end loop;\n  end Clear;\n\n  cube_side : array (Data_Type) of Positive;\n\n  function Locate_Cube_Face (p : Point; data : Data_Type) return Natural is\n    q : Point;\n    side : constant Positive := cube_side (data);\n  begin\n    q.x := (p.x - 1) / side;\n    q.y := (p.y - 1) / side;\n\n    case data is\n\n      when mini =>\n        case q.x is\n          when 0 => return 2;\n          when 1 => return 3;\n          when 2 =>\n            case q.y is\n              when 0 => return 1;\n              when 1 => return 4;\n              when 2 => return 5;\n              when others => null;\n            end case;\n          when 3 => return 6;\n          when others => null;\n        end case;\n\n      when input =>\n        case q.x is\n          when 0 =>\n            case q.y is\n              when 2 => return 4;\n              when 3 => return 6;\n              when others => null;\n            end case;\n          when 1 =>\n            case q.y is\n              when 0 => return 1;\n              when 1 => return 3;\n              when 2 => return 5;\n              when others => null;\n            end case;\n          when 2 =>\n            return 2;\n          when others => null;\n        end case;\n    end case;\n\n    Put (\"Locate_Cube_Face issue\");\n\n    return 0;\n  end Locate_Cube_Face;\n\n  subtype Cube_Face_ID is Integer range 1 .. 6;\n\n  procedure Blocks_to_Origin (bo : out Point; face_id : Cube_Face_ID; data : Data_Type) is\n  begin\n    case data is\n\n      when mini =>\n        case face_id is\n          when 1 => bo.x := 2; bo.y := 0;\n          when 2 => bo.x := 0; bo.y := 1;\n          when 3 => bo.x := 1; bo.y := 1;\n          when 4 => bo.x := 2; bo.y := 1;\n          when 5 => bo.x := 2; bo.y := 2;\n          when 6 => bo.x := 3; bo.y := 2;\n        end case;\n\n      when input =>\n        case face_id is\n          when 1 => bo.x := 1; bo.y := 0;\n          when 2 => bo.x := 2; bo.y := 0;\n          when 3 => bo.x := 1; bo.y := 1;\n          when 4 => bo.x := 0; bo.y := 2;\n          when 5 => bo.x := 1; bo.y := 2;\n          when 6 => bo.x := 0; bo.y := 3;\n        end case;\n\n    end case;\n  end Blocks_to_Origin;\n\n  procedure Relative_to_Face (p : in out Point; face_id : Cube_Face_ID; data : Data_Type; way : Integer) is\n    side_length : constant Positive := cube_side (data);\n    bo : Point;\n  begin\n    Blocks_to_Origin (bo, face_id, data);\n    p.x := p.x - way * bo.x * side_length;\n    p.y := p.y - way * bo.y * side_length;\n  end Relative_to_Face;\n\n  procedure Relative_to_current_Face (p : in out Point; data : Data_Type) is\n  begin\n    Relative_to_Face (p, Locate_Cube_Face (p, data), data, 1);\n  end Relative_to_current_Face;\n\n  verbosity_level : constant Natural := 0;\n\n  procedure Run\n    (part     :     Part_Type;\n     data     :     Data_Type;\n     path     :     VString;\n     start    :     Point;\n     d, final : out Point)\n  is\n    dxr, dyr : Real;\n    walking_steps : Integer;\n    c, co : Character;\n    p, left, right, up, down : Point;\n    side_length : constant Positive := cube_side (data);\n\n    function Inv (coord : Positive) return Positive is\n    begin\n      return 1 + side_length - coord;\n    end Inv;\n\n    procedure Go is\n      new_face : Natural := 0;\n      rp, np, nd : Point;\n\n      procedure From_Left (set_new_face : Positive) is\n      begin\n        new_face := set_new_face;\n        np.x := 1;\n        nd := right;\n      end From_Left;\n\n      procedure From_Right (set_new_face : Positive) is\n      begin\n        new_face := set_new_face;\n        np.x := side_length;\n        nd := left;\n      end From_Right;\n\n      procedure From_Top (set_new_face : Positive) is\n      begin\n        new_face := set_new_face;\n        np.y := 1;\n        nd := down;\n      end From_Top;\n\n      procedure From_Bottom (set_new_face : Positive) is\n      begin\n        new_face := set_new_face;\n        np.y := side_length;\n        nd := up;\n      end From_Bottom;\n\n      procedure Wrap_around_through_Left_Side is\n      begin\n        for x in reverse Range_x loop\n          if map (x, np.y) /= ' ' then\n            np.x := x;\n            exit;\n          end if;\n        end loop;\n      end Wrap_around_through_Left_Side;\n\n      procedure Wrap_around_through_Right_Side is\n      begin\n        for x in Range_x loop\n          if map (x, np.y) /= ' ' then\n            np.x := x;\n            exit;\n          end if;\n        end loop;\n      end Wrap_around_through_Right_Side;\n\n      procedure Wrap_around_through_Top_Side is\n      begin\n        for y in reverse Range_y loop\n          if map (np.x, y) /= ' ' then\n            np.y := y;\n            exit;\n          end if;\n        end loop;\n      end Wrap_around_through_Top_Side;\n\n      procedure Wrap_around_through_Bottom_Side is\n      begin\n        for y in Range_y loop\n          if map (np.x, y) /= ' ' then\n            np.y := y;\n            exit;\n          end if;\n        end loop;\n      end Wrap_around_through_Bottom_Side;\n\n      procedure Cube_Crawl_through_Left_Side is\n      begin\n        rp := p;  --  Point relative to current face.\n        Relative_to_current_Face (rp, data);\n        case data is\n\n          when mini =>\n            case Locate_Cube_Face (p, data) is\n              when 1 => From_Top    (3); np.x := rp.y;\n              when 2 => From_Bottom (6); np.x := Inv (rp.y);\n              when 5 => From_Bottom (3); np.x := Inv (rp.y);\n              when others =>\n                null;\n            end case;\n\n          when input =>\n            case Locate_Cube_Face (p, data) is\n              when 1 => From_Left (4); np.y := Inv (rp.y);\n              when 3 => From_Top  (4); np.x := rp.y;\n              when 4 => From_Left (1); np.y := Inv (rp.y);\n              when 6 => From_Top  (1); np.x := rp.y;\n              when others =>\n                null;\n            end case;\n        end case;\n        Relative_to_Face (np, new_face, data, -1);\n      end Cube_Crawl_through_Left_Side;\n\n      procedure Cube_Crawl_through_Right_Side is\n      begin\n        rp := p;  --  Point relative to current face.\n        Relative_to_current_Face (rp, data);\n        case data is\n\n          when mini =>\n            case Locate_Cube_Face (p, data) is\n              when 1 => From_Right (6);   np.y := Inv (rp.y);\n              when 4 => From_Top   (6);   np.x := Inv (rp.y);\n              when 6 => From_Right (1);   np.y := Inv (rp.y);\n              when others =>\n                null;\n            end case;\n\n          when input =>\n            case Locate_Cube_Face (p, data) is\n              when 2 => From_Right  (5); np.y := Inv (rp.y);\n              when 3 => From_Bottom (2); np.x := rp.y;\n              when 5 => From_Right  (2); np.y := Inv (rp.y);\n              when 6 => From_Bottom (5); np.x := rp.y;\n              when others =>\n                null;\n            end case;\n        end case;\n        Relative_to_Face (np, new_face, data, -1);\n      end Cube_Crawl_through_Right_Side;\n\n      procedure Cube_Crawl_through_Top_Side is\n      begin\n        rp := p;  --  Point relative to current face.\n        Relative_to_current_Face (rp, data);\n        case data is\n\n          when mini =>\n            case Locate_Cube_Face (p, data) is\n              when 2 => From_Top   (1); np.x := Inv (rp.x);\n              when 3 => From_Left  (1); np.y := rp.x;\n              when 1 => From_Top   (2); np.x := Inv (rp.x);\n              when 6 => From_Right (4); np.y := Inv (rp.x);\n              when others =>\n                null;\n            end case;\n\n          when input =>\n            case Locate_Cube_Face (p, data) is\n              when 1 => From_Left   (6); np.y := rp.x;\n              when 2 => From_Bottom (6); np.x := rp.x;\n              when 4 => From_Left   (3); np.y := rp.x;\n              when others =>\n                null;\n            end case;\n        end case;\n        Relative_to_Face (np, new_face, data, -1);\n      end Cube_Crawl_through_Top_Side;\n\n      procedure Cube_Crawl_through_Bottom_Side is\n      begin\n        rp := p;  --  Point relative to current face.\n        Relative_to_current_Face (rp, data);\n        case data is\n\n          when mini =>\n            case Locate_Cube_Face (p, data) is\n              when 2 => From_Bottom (5); np.x := Inv (rp.x);\n              when 3 => From_Left   (5); np.y := Inv (rp.x);\n              when 5 => From_Bottom (2); np.x := Inv (rp.x);\n              when 6 => From_Left   (2); np.y := Inv (rp.x);\n              when others =>\n                null;\n            end case;\n\n          when input =>\n            case Locate_Cube_Face (p, data) is\n              when 6 => From_Top   (2); np.x := rp.x;\n              when 5 => From_Right (6); np.y := rp.x;\n              when 2 => From_Right (3); np.y := rp.x;\n              when others =>\n                null;\n            end case;\n        end case;\n        Relative_to_Face (np, new_face, data, -1);\n      end Cube_Crawl_through_Bottom_Side;\n\n    begin\n      if walking_steps = 0 then\n        return;\n      end if;\n      if verbosity_level > 0 then\n        Put (p.x, 3); Put (\",\"); Put (p.y, 3); Put (\"  -> (\");\n        Put (walking_steps, 0); Put (\") -> \");\n      end if;\n      d.x := +Integer (dxr);\n      d.y := -Integer (dyr);  --  top down geometry...\n      loop\n        if verbosity_level > 0 then\n          Put ('.');\n        end if;\n        nd := d;\n        np.x := p.x + d.x;\n        np.y := p.y + d.y;\n\n        if d.x < 0 then\n          if np.x < 1 or else map (np.x, np.y) = ' ' then\n            case part is\n              when part_1 => Wrap_around_through_Left_Side;\n              when part_2 => Cube_Crawl_through_Left_Side;\n            end case;\n          end if;\n        end if;\n        if d.x > 0 then\n          if np.x > highest.x or else map (np.x, np.y) = ' ' then\n            case part is\n              when part_1 => Wrap_around_through_Right_Side;\n              when part_2 => Cube_Crawl_through_Right_Side;\n            end case;\n          end if;\n        end if;\n        if d.y < 0 then\n          if np.y < 1 or else map (np.x, np.y) = ' ' then\n            case part is\n              when part_1 => Wrap_around_through_Top_Side;\n              when part_2 => Cube_Crawl_through_Top_Side;\n            end case;\n          end if;\n        end if;\n        if d.y > 0 then\n          if np.y > highest.y or else map (np.x, np.y) = ' ' then\n            case part is\n              when part_1 => Wrap_around_through_Bottom_Side;\n              when part_2 => Cube_Crawl_through_Bottom_Side;\n            end case;\n          end if;\n        end if;\n\n        --  Check new point\n        if map (np.x, np.y) = '.' then\n          p := np;\n          d := nd;\n        else\n          exit;\n        end if;\n        walking_steps := walking_steps - 1;\n        exit when walking_steps = 0;\n      end loop;\n      dxr := Real (+d.x);\n      dyr := Real (-d.y);\n      if verbosity_level > 0 then\n        Put (p.x, 3); Put (\",\"); Put (p.y, 3); New_Line;\n      end if;\n    end Go;\n  begin\n    p := start;\n    dxr := 1.0;\n    dyr := 0.0;\n    left.x := -1;\n    left.y :=  0;\n    right.x := +1;\n    right.y :=  0;\n    up.x :=  0;\n    up.y := -1;\n    down.x :=  0;\n    down.y := +1;\n    if verbosity_level > 1 then\n      Put_Line (+\"highest.x: \" & highest.x'Image);\n      Put_Line (+\"highest.y: \" & highest.y'Image);\n      Put_Line (+\"side: \" & side_length'Image);\n    end if;\n    walking_steps := 0;\n    c := ' ';\n    for pos in 1 .. Length (path) loop\n      co := c;\n      c := Element (path, pos);\n      case c is\n        when '0' .. '9' =>\n          if co in '0' .. '9' then\n            walking_steps := walking_steps * 10 + Ord (c) - Ord ('0');\n          else\n            walking_steps :=                      Ord (c) - Ord ('0');\n          end if;\n        when 'L' =>\n          Go;\n          Rotate (dxr, dyr, Pi * 0.5);\n        when 'R' =>\n          Go;\n          Rotate (dxr, dyr, -Pi * 0.5);\n        when others =>\n          null;\n      end case;\n    end loop;\n    Go;\n    final := p;\n  end Run;\n\n  data_line : VString;\n\n  procedure Data_Acquisition (data : Data_Type; start : out Point) is\n    c : Character;\n    f : File_Type;\n    p : Point;\n  begin\n    lowest.x := 1;\n    lowest.y := 1;\n    highest.x := 1;\n    highest.y := 0;\n    start.x := 0;\n    start.y := 1;\n    Clear;\n    case data is\n      when mini =>\n        Open (f, \"mini.txt\");\n      when input =>\n        Open (f, \"aoc_2022_22.txt\");\n    end case;\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get_Line (f, data_line);\n      exit Read_Data when data_line = \"\";\n      p.y := highest.y + 1;\n      for x in 1 .. Length (data_line) loop\n        c :=  Element (data_line, x);\n        if start.x = 0 and then c /= ' ' then\n          start.x := x;\n        end if;\n        p.x := x;\n        map (p.x, p.y) := c;\n      end loop;\n      Adapt_Highest_Value_Point (p);\n    end loop Read_Data;\n    Get_Line (f, data_line);\n    if verbosity_level > 0 then\n      Show;\n    end if;\n    Close (f);\n  end Data_Acquisition;\n\n  T0 : constant Time := Clock;\n  r : array (Part_Type) of Integer;\n\n  data : constant Data_Type := input;\n  start, dir, final : Point;\n  facing : Natural;\n\nbegin\n  cube_side (mini)  := 4;\n  cube_side (input) := 50;\n  Data_Acquisition (data, start);\n\nParts :\n  for part in Part_Type loop\n    if verbosity_level > 0 then\n      Put_Line (part'Image);\n    end if;\n    Run (part, data, data_line, start, dir, final);\n    if dir.x > 0 then facing := 0; end if;\n    if dir.y > 0 then facing := 1; end if;\n    if dir.x < 0 then facing := 2; end if;\n    if dir.y < 0 then facing := 3; end if;\n    r (part) := 1000 * final.y + 4 * final.x + facing;\n    if verbosity_level > 0 then\n      Put_Line (r (part)'Image);\n    end if;\n  end loop Parts;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (part_1) /= Integer'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Final password after a walk; edges are...\");\n    Put_Line (+\"  (part 1) wrapped around . . . . :\" & r (part_1)'Image);\n    Put_Line (+\"  (part 2) on a cube's surface  . :\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 26558\n    --  Part 2: validated by AoC: 110400\n  end if;\nend AoC_2022_22;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_22.txt",
    "content": "                                                  ...###..#...##................#......#....#........#.....#..#.......#...#.......#.......#..#........\n                                                  ..........##.........#.#.........#...#....#....#...........#...............#...................#....\n                                                  ..........................#.#..............##......#.........#.#......##......#.#...................\n                                                  ...................#...........#........#.#....#....................................................\n                                                  ....#................#..................#.....#....#...........#......#..#..#.........#......#......\n                                                  ......................##..#.....................#..##...#..........#.......#.#...#.......#..#......#\n                                                  ........#.....#..............#........................#........#......#...#...............#.........\n                                                  #............#..#............#....#....#...#...#.......#........................#...................\n                                                  .............#.##....#...#..#..#...........#.....#...#..............#.#.#..#........................\n                                                  ..........#........................#.................#..#.....#.......##..#.........................\n                                                  .#.##....#..#............##.................................##.............................##.......\n                                                  ...###....#...#....#.........#.#.....#.........#..#........#..........#........#....#....#......#...\n                                                  .##...................#....................#.............##....#............##.......#..#...........\n                                                  ...............#.......................#........#.................#..##...........#.......#........#\n                                                  .....#..............................#..................##.#.............#..................#...#....\n                                                  ....#....................................#.......................#...#.....#........#...............\n                                                  ..............#.......................#...........#..............#...............#..#..#....#.......\n                                                  ......#.................##...........#...........#........#............#...#.#..............#..#...#\n                                                  ..............#...#...............#......#.......#...............#..............#...............#...\n                                                  ..........##................#...#..#.......#......#...................#..#...........#............#.\n                                                  ............................#.........#.....#....#.....#.....#......#..#...#.....#...#.......#......\n                                                  ...##.................#...#....#.#.......#.....................#......#...##..................#.....\n                                                  .#......#...#..............................................#.........#..................#...........\n                                                  ...........................#.#.#.................#.....#.............#.......#..##..................\n                                                  .............#.......#.............#......#..............#.#...............#........................\n                                                  ...................#...#...#....#.....#....................#.......#.............#........#.........\n                                                  ......#....#....#........#...........#..................#....#..........................##....#....#\n                                                  .........##..##.#.#......#.#.....#.....................#.#.#..........#....##................#..#...\n                                                  ...#...#.........#..........##.#.............##.#.....#...............#........#....................\n                                                  .................................#..#...............#.......................#...................#...\n                                                  ..#.......#...#.......#.....#.........................#.#....#..#...........##..#...................\n                                                  ...#...#..............#.......#...#..................#........#...................#...............#.\n                                                  ....#..#....##..#....#....#...........................#.............................................\n                                                  ...#...#.......................#..#...#..#..#................#........#.............................\n                                                  ..........#.......................##...................#.................#......................##..\n                                                  ....#.#........#....#..#....#........#......#.....#...........................#...............#....#\n                                                  ...................#..................................#........................#....................\n                                                  ..........#.#...#.............##.........................#........#...................#.............\n                                                  .................#.......................................................#.............#............\n                                                  ...#..#...#....#..................#..................#.........................#................#.#.\n                                                  ..#..#.........................................................................................#...#\n                                                  .....##.............................#....#.....#.......#.......#.#..............#............#......\n                                                  .#..........#.....#.......#........#....#..............#................##..........................\n                                                  ..........#...##...........#.........................#...........#............#.....#.#.#........#..\n                                                  ........##.#.................#..#...................#...........##..#.......................#.......\n                                                  ..#.............#...#...#...........#.....#..................#..........#......................#....\n                                                  ..#................###..................#..............#.....................#......#............#..\n                                                  ...........#.........#.....#.#.#.#................#.............#.#.................#.....#....#....\n                                                  .......#............#.......#......##.....#.......#.....#.###...............#......#.#..............\n                                                  .........#.....#.......#....#........#.......##....#................................#...............\n                                                  ..............##..#...#.#.....................#...\n                                                  ............##.........#..........................\n                                                  ..#.........#......###..#........#...#............\n                                                  ...##.#......#....................................\n                                                  .................#....#.#....#............#.#....#\n                                                  .##........#...#........#..........#.............#\n                                                  ................#..#.......#.......#.....#........\n                                                  ...##........#...#.#............#....#...........#\n                                                  ............#...#...............#.#.......#.......\n                                                  .##...............................................\n                                                  ..........###..................#..#.#....#...#....\n                                                  ......#...........#....#..#..#........#...........\n                                                  ....#.....#...#..#.#..#................#..........\n                                                  ........#...#......#...................#.#......#.\n                                                  .#....#......................#..#...#.........#...\n                                                  ..............#............#..............#....#..\n                                                  ...................#...........#.#........#.#.#...\n                                                  ............#.................##..................\n                                                  ..#..........................#.#...#.......#..#...\n                                                  ..#.....#.........#.........#..#...#......#.......\n                                                  .........#..........#.#.....#......#...........#..\n                                                  .....#...........#.#........#......#.......#....#.\n                                                  .#.........##...#...#......#.......#.............#\n                                                  .........................##......#.....#........#.\n                                                  ...#......#.#......#..............................\n                                                  .........#...........#...........#...#............\n                                                  ##.............#..................#.#.............\n                                                  #.......................#.#.....#........#........\n                                                  .....#...........#....................#..........#\n                                                  ........#.#..........#...................#........\n                                                  ......#.......#..........#...................#..#.\n                                                  #....#................#............#...........#..\n                                                  ..#...##.#..............................#.........\n                                                  ......##.....#.............#................#.....\n                                                  ....#.....#..............#......#..#..#.#........#\n                                                  #.........#...............##....#.#........#......\n                                                  ....................#.......................#.....\n                                                  .....................................##...........\n                                                  ........................#.........................\n                                                  ..##....#.......#................#.#..........#...\n                                                  .......#.............#.............#....#...#.#...\n                                                  ....#.#......#.......##.#....#........#...........\n                                                  ..#.....#..#.#....................................\n                                                  ...........................#.....#......#......#..\n                                                  .........#.....#........#........................#\n                                                  .......#....#........#...#............#.#.........\n                                                  ...#...#..............#...#...............##......\n                                                  ..#.......................................#.......\n                                                  ..................................................\n                                                  .........................#..#.............#.......\n....#.....#....#......##........#......#..............#.........#........#..............#....#......\n...............##...##..............#......................#................................#.......\n......................................#..........#..#.#...#......#..................#...............\n....#......................#........................#.............#.......#...............#..#......\n..............................#....###.............#............................##...............#..\n...........................#...#...................#......#......#...........#...............#....#.\n..........##............#................#....#................#.......#..........#....#............\n#.........#.......#..............#.............#....#.#...#................#.#.....................#\n...#...............#...............#.............................#......#...#.......#......##.....#.\n..............#...............#...#..........................#..........#......#.....#..............\n................#........................#.........#..........#..........#.............#....#.......\n......#................#....#.....................#..#............#...#..#.....................##.#.\n...........#....#.....#.....#..#..............#.........#...#...#......#.....................#......\n.....#...........#...........#...#.....#.##....#..#.......#........###.#...#..#..........#.##.......\n##......#.................#.#........#.............#.........#......................................\n................#....#.#...........................#...................#.#.............#.........#..\n#......#......#...................#.#.#.#............#......#.................#.....#...............\n##.......#..............#....................................#.....#.........#........#.............\n.#.....#...........#..#................#.....#..#........#........#............#.....##..#..........\n.##........#......................#......#...........##............#...........................#....\n...#..................#........#..#....##.........##........#...#......##..##.......#..........#....\n.......................#..............#.......#..#......#.#......#...#........#.................#...\n.#....#...........................#..#..............##......#.#......#................#.............\n...........#.........................#.#................#..................#........................\n.......#..............#..............#.....#...........#......##........#.........#...........#.....\n#..#.......................#.......###......#...##..................................#........#......\n...#...........#..........#..........#.....#...........................#.....#.....#........#.....#.\n..................#.#........................#...#...........#...#...................#........#.....\n.#..........#.#....................#..#...............#.......#...#.......#...#........#..........#.\n............................#.................#.#..#...........#..............#.....................\n.............#........#.#.#............#...............#...........#......................#.........\n#..........#.......#......#................#.......#.........#.#......#......................#......\n.......#.#.............#...................#....#...............##......#...............#........##.\n#.........#........................................#...#................#..#........................\n.............#.#........#.........#....#..................#.........#..#..............#.#.....##....\n...#..........#.............#...#....#.....#....................#....................#..............\n.......#................#...........#.............#.#....................#........................#.\n..................................#.#......#....#................................#....#.............\n....#..#...#..#.#.......#...........#.................................................#....#........\n#.....#..#..............#..#.....#.........#...#.....#....#......#..................#........#......\n.......#.#............................................#.#......#.#..................##...#..#.....#.\n........................#.........................#...............................#.................\n..............#..#............................#.....#...#...............#...#...#...................\n.....#.#................................#..##...............#.....#.#.#..#.............#.#..........\n#...........................#....#......#.....#.......#..#..#..................#.............#....#.\n...#.....................................#..........................................................\n......#....................................................#....#.......#..#......................#.\n#............................#..........#...........................................#.##..........#.\n.....#...#.............#..#...............................#..............#....##.#..#.#.............\n..................................#................#...#......#...................#..........#...#..\n...........#..........................#.......#...\n.......#...#..#........#..........................\n........#..##.##..#.............##..#...........#.\n..#.#.......##..#..#.............#.............#..\n......#.....#.........#...##.#...#..#.............\n............#..#.............#......#.............\n.........................##.............#......#..\n.#..............................##................\n.#.......................#................#.......\n....#.#...........#...............................\n.............................#.........#..........\n...............#..#.#.....##...................#..\n...#..........................#.............#....#\n................#.............#............##.....\n#.......##..#..#....................#.............\n.........#............#..#.....................#..\n........#...........#...#...#.............#.......\n........#........#..#...#..#..#...#...............\n....#....#...#.......#...........................#\n......#........##....#.#.#........................\n............#....................................#\n......##...................#............#.....#...\n.........#..#.#.#..........#..........#..........#\n#...........#...#..........#.##............#......\n.....#..#.....#......#.....#............#.........\n..........................................#.......\n...........#..#............#....................#.\n......#.....#.....#...#.#.........................\n....#.....#....#........##...........#............\n................#.......#....#.............#...#..\n..............#..#.#.#..................#........#\n.............#........#.......................#...\n........#......#.......#.#....#..#................\n.......................#..........#.......#.#.....\n......#..........#...###.......#.......#.#........\n...............#..#..#..#...#....................#\n..#.........#........#.....#........#.............\n...#.............#....#...........#...............\n.......#......#...##............................#.\n....................#..##..#..#..#..............#.\n......#...........................................\n......#........#.......#.........#....#....#...#..\n..............#..#.#........................#..#..\n.................#.........................#.#....\n............#................#....................\n..#.....................#.........................\n............#..............#......................\n..................#...................#...#.......\n......#.##.......#.........................#......\n.........#........#...............#.....#.........\n\n9L44R12L3L7L37L27L37R32R15R42R15L41R50R41L47R26L44R26L3L20L2L9L13L45R19L9L26L5R27L44L3R38L38L29R50R28L6R26L40L36R46L22L43L47R16L44R17L44L46L2R25R17R7L35R24L26L24L35R42R28L14R34L4L16R15L23R17R43L34R13R1R35R25R35L21L22L45R50R47R42R12L30R46R31R5R41L27L2L13L38R46L48R11L48L44R17L42L8R48L44R10L38L43L15L26L27L32R24R21R34L47L30R38L36R4L32R44L45R37R42L46R16L30R23L29L25L4L37L29R18R39L44L8R10R29R19R5L5L34L44R1L4R41L26L36R25L48R25L50R32L47L39R39R8L48R43L41L12L43L32L36L14L7R27R28R43R33L5L9R24L30R27R47R30R36R36L6L6R8R2L18R10R42R25L36L33L35R6R26L48R13L14L41L6R19R8L37R19R14L23L47L34R46L11R33L29R5R18L2R14R31R4R15L27L42R50L34L4L47R17L28R6L4R11L25R39L24R2R31R6R12L50R29R1L29R32L2L22L28L35R27R3R22L7R47R47L43R29R29L41L5R44L20L6R41L33L14L39R13R16R8R3R46R39L9R20L43L32L39R43L5R43L34L47R9L8L36L50R30L48R17L4R12L36L36L29R48R11R39R24R27L40L47R31L34R35R4R14R47L38R15R18R16L22L38L11R6R31R8R27R50L26R9L37R24R6L19R6L25R42R6L21L40L10L10L47L22R44R8R26L15R49R30L5R12L36R41R22L4R44L47L5L43L2R18L24L37L28R18R9R32R45R24L6R44R33L48L17R21R21L32R35R38L38R28L45R2L41L24L16L10L37R14R25R44R25L43L10R33L39R16R12R43L35L9L50L2R18L21L3L15R21R4R33L21R12R24L22L15L18R48R36R9R14L18R31L39R8R28L27R48R13R5R9R8R6L30L25L14L26L38L8R24L10L25R6R8R45L36R48R16R11R14R2R36R45L12L27L39R50L26L44L39R41L30R48L27R25R40L28R43R32R46R43R34L40R45L42R5L7R37L44L39L26L42R37R3R38R42R47R16L15R30R18R24R26L46R25R40R44R1R17R4L41R44R44L38L33R48R37L28L23L19R47R28R3L10R6R4R10R17L28R47R21R15R17L29R42L37L44L27R20R31R7L16R33R6R12L40L33R2L25L7L32R16L21R1R36R4L24L15R34R31L10L28R3R41L49L4L49L45R37R19L47R12R27L20L1L7R13R18L17L13L11R1R13L41R34L11R18L34R18L18R44L5L33R42L25R22L6R40R29L17R45R26R3R12R44R49L20R30L32R8R20R8R26L31L24R35L50L33L40L6L4L35L44L45R12R48R13R3L21R9R31R6L15R23L9R12R48R23R11L16R4R40R20L13R35R21L3L30L26L5L10L15L31L23L47R49R10L25L46R2R35L14R23R41L6L3R3L7L49R2L34R42L46L45L37L2L15L4R33R27R30R40R25L43L34L32R8R40L36R32R16L18R32L48R19L12R14L36L16R9R34L44L30L1R7L18L48L12L40R40R14R25R16R36L16L26R47L27L33L7L43L35R40L41L30L19L5R8L49R48R27R19R41L39L36L50L27L49L10R11L34R46L5L28L12L17L47L26L33R18R43R3L2R34R46L39L35L38R35R26R34R8R15R11L44R44L3R19L14R15R42R36L32L35R20L6L25L22L32L24L24R9L4L15R28L17R13L44L17L13L40R36R10R27L35R22L48L38L33R34L26R29L34R43L5L28R49R17L2R13L9R20L26R8L18R40R23L17L25L11L33R15L48L18R11R22L46R15L47L33R31R47R22R10R47R12L48L15R27L44L6R44R36L43R30R39R28R25R32L34R44R29R26R1R11R50R43L42L14R46R3R5L6L38L24R12R49L26L29L40R24L49R9R43L36L33R48R38R33L19L7L21R37R7L32L50R6R15R30R5L14L47L22L30L4R18L36L11L42L3L3R41L48L30L40L6R20R26L45R37L18L41R39R31L18R10R44R9R37R22L22R50R7R20R7R38L34L7R34R14R16L46R35L6R7L50L2L4L5R5R48R29L44R4R2R25R7L18R46L11R8R33L17L47R19R48R11R29L22L11R14L19L13L3L42R38R33R20L44L1R12L18L9L37R3R10L5R49L45R40L10R41L4R9R41R25L40L9L18L45L21R25R2L49L45R39R37L42R24R3L6R38R16R48R36L47L37R49R8R12R27R44R47L28L34L17L46R8L31R16L19L14R28L39R28R40R36R22L45R10L41R22L16L24R7L7R29L5L11R14R6R41R44L49R27R43R42R44R16L20L47R4L12L1R26R9R10R46L19L23R30L29R25R39R7L46R24L34L38R23R10L33L19R32R35R29L13R9L21L32L39L40R18R44L15R22L27R42R7R4R47R26L26R50R20L36L42R36R39L10L26R2R40L5L44R32R12R32R2L24R50L22L37L34L47R10L32R19L36L42L26L12R21L47R44R17L13R23R3R4L12L34L47R13L45R3L28R16R35R6L33R49R36R3R17R43L19R10L39L5L18R19R45R23R23L26L32R11L33R43R45L30R9L11R38L44L38R43L44L39R7L41R6L10R22R41R20R27L22L35L34R10L42R13R5L45R15L20R48R50L16R48L6L24L22R7R23L11R37L9L32L42R30L28L11R1R7R50R2R36L26R13R45R49R19R25R49L10L5R18L50L13R31L41L38R43R14L5R25R22R28L42L8R28L22L21L24L17L27R43L7L30R39R31R48L47L19R13R42L50R17L9L47R19L18R18L42L22R23L41R46L17R20L45R28R45L47R16R12R34R49L31R20L18L6R16R9L32L42L3L40R41R29R22R7R14R37R39R23L20L22L32R12L11L35L50R19L34R11L48L2R11L30L48L19R11R34L32R23R31L1L13R26L3R23R22R36L34R33R43L2R27R48L38R18L50L42L41L19L37R12R41L15R50R36L27R50R31R28R34L29R43R23L30R8R19L46L19R16L18R14L43L45L30R46R18R1R37R15L46L36L22R14R25L5L21L24R48L7R41L32R41R30L6R6L13R34R13R37L47L3L37R33R23R47L49L13R10L12R9L45R44L11L15R26L16L19L48R35R37L29L26L43L19L26R44R45R49R11R38R7R43R37R41L47L47R42L28L24R16R14R40R25R24L1R2L40L11R14L5R4R43L4R4L27R24R13L17L14L25L42L37L47L47L26R11L24R40R8L42R48L9R27L41R37L17R20L31L44R37R39R35R26L12L47L27L7R7L43R35L17R12R25R49L33R16L21R27L20R18R49L20L45L41L50L39R8L35L41L43R36L20R28R15L43L32L25L15R7R42L44L33R45R14R17L45R2L43L29R50L21L46R33L19R18L23R37R3L24L21R18L50R3R16R9L47L33L43R7R42R10L50R4R16R50R22R2L19L42R43L15R11R39R42L45L26L25L12R35L45R12R22R14R37R17R1R19L7R20R50R21R33R31R48L20R4L31L38L28L35L37R5R33L20L28R5R48L12L8R12R43L26R30L7R41L18L41R27L38L5R45L7R22L32L49R6R7R3L31L13R12R2R31L46R12L31L10R4R12L48L33L41R22R25L22R15R17R12L45R36R30L10L46R10R29R23L5L19R18L27L48R36L41R44L1R41R5L23R11R25R50R41R42R50L26L28R31R3L33L25L34L42R3R35R1R50R16R22L10L33R31L41L5L49R4L47R45L4L3L44R16L35L26R27R17L21L43L18R33R15R33R49L49R21R26R37R39L37L23L23R12L49R44L12R39R16L22R12R32L38R11R14R28R6L13L26R12R9L46L34L25R6R5L19L13L18R10R28L8R27L26L15L38L23R35L21R47R7R1R18L10R44L31L43L45R49R20L14R35R15R13L45R30R36L35R42L8R11L1L49L5R14L17R5L33R40L35R43L43R46R40L2R36L47L19R11R1L21L36R2R7L3R48R31R12R19R29L22R47L40R38L7R24L42L5R7R22L43L11L37R38L18R6R1L6L29R39L12L13L29R27R31R24R46L29L28L10L42L37L16L25R4L22L22R10R16L18L42R28L33L14R46R19R42L18R5L11R27L47R10R47L11R1L31L36R24L8R39R21L40L48L39R17L8L45L40L30L39R25L1L11L23L37R10R48L6L48R23L44L46R23R2R44R19R35L35L34L37R24L1R12L38R44L38L3R35L37R7R7R50R21R20R9L7R37R48L23R9L32R11R27R30R20R3R4L21L16R16R6R32R37R22L33L3L19R27L42L24L19L3L11R36R22R20L1R47R22R42L3L26R41R15L44L47L33L35R44R13R39L30R50R45R15L24R45L8R6L33L22R12L23R46R16R45L20R5R21R12L46L45R37R26L19L22R47L41R16L36L5L40L25L20L50L46L36R3L13R14L22R8L8R37R26R47L26L19L6L24R3L41R17R39L20L5L29L27R10R37L26R24L30L41R42L37R20R7L7R49L9L4L19L48R16R7R38L37R48R40R1R1L15R8L22L16R44L38L20R13R9R19L20R28R5R40L2R22R1\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_22_questions.txt",
    "content": "--- Day 22: Monkey Map ---\n\nThe monkeys take you on a surprisingly easy trail through the jungle.\nThey're even going in roughly the right direction according to your\nhandheld device's Grove Positioning System.\n\nAs you walk, the monkeys explain that the grove is protected by\na force field. To pass through the force field, you have to enter\na password; doing so involves tracing a specific path on a\nstrangely-shaped board.\n\nAt least, you're pretty sure that's what you have to do;\nthe elephants aren't exactly fluent in monkey.\n\nThe monkeys give you notes that they took when they last saw\nthe password entered (your puzzle input).\n\nFor example:\n\n        ...#\n        .#..\n        #...\n        ....\n...#.......#\n........#...\n..#....#....\n..........#.\n        ...#....\n        .....#..\n        .#......\n        ......#.\n\n10R5L5R10L4R5L5\n\nThe first half of the monkeys' notes is a map of the board.\nIt is comprised of a set of open tiles (on which you can move,\ndrawn .) and solid walls (tiles which you cannot enter,\ndrawn #).\n\nThe second half is a description of the path you must follow.\nIt consists of alternating numbers and letters:\n\n    A number indicates the number of tiles to move in the direction\n      you are facing. If you run into a wall, you stop moving forward\n      and continue with the next instruction.\n      \n    A letter indicates whether to turn 90 degrees clockwise (R) or\n      counterclockwise (L). Turning happens in-place;\n      it does not change your current tile.\n\nSo, a path like 10R5 means \"go forward 10 tiles, then turn clockwise\n90 degrees, then go forward 5 tiles\".\n\nYou begin the path in the leftmost open tile of the top row of tiles.\nInitially, you are facing to the right (from the perspective of how\nthe map is drawn).\n\nIf a movement instruction would take you off of the map, you wrap\naround to the other side of the board. In other words, if your next\ntile is off of the board, you should instead look in the direction\nopposite of your current facing as far as you can until you find the\nopposite edge of the board, then reappear there.\n\nFor example, if you are at A and facing to the right, the tile in\nfront of you is marked B; if you are at C and facing down, the tile\nin front of you is marked D:\n\n        ...#\n        .#..\n        #...\n        ....\n...#.D.....#\n........#...\nB.#....#...A\n.....C....#.\n        ...#....\n        .....#..\n        .#......\n        ......#.\n\nIt is possible for the next tile (after wrapping around) to be a wall;\nthis still counts as there being a wall in front of you, and so movement\nstops before you actually wrap to the other side of the board.\n\nBy drawing the last facing you had with an arrow on each tile you visit,\nthe full path taken by the above example looks like this:\n\n        >>v#    \n        .#v.    \n        #.v.    \n        ..v.    \n...#...v..v#    \n>>>v...>#.>>    \n..#v...#....    \n...>>>>v..#.    \n        ...#....\n        .....#..\n        .#......\n        ......#.\n\nTo finish providing the password to this strange input device, you need\nto determine numbers for your final row, column, and facing as your\nfinal position appears from the perspective of the original map.\nRows start from 1 at the top and count downward; columns start from 1\nat the left and count rightward. (In the above example, row 1,\ncolumn 1 refers to the empty space with no tile on it in the\ntop-left corner.) Facing is 0 for right (>), 1 for down (v),\n2 for left (<), and 3 for up (^).\nThe final password is the sum of 1000 times the row, 4 times\nthe column, and the facing.\n\nIn the above example, the final row is 6, the final column is 8,\nand the final facing is 0.\nSo, the final password is 1000 * 6 + 4 * 8 + 0: 6032.\n\nFollow the path given in the monkeys' notes. What is the final password?\n\n--- Part Two ---\n\nAs you reach the force field, you think you hear some Elves\nin the distance. Perhaps they've already arrived?\n\nYou approach the strange input device, but it isn't quite what\nthe monkeys drew in their notes. Instead, you are met with a large\ncube; each of its six faces is a square of 50x50 tiles.\n\nTo be fair, the monkeys' map does have six 50x50 regions on it.\nIf you were to carefully fold the map, you should be able to shape\nit into a cube!\n\nIn the example above, the six (smaller, 4x4) faces of the cube are:\n\n        1111\n        1111\n        1111\n        1111\n222233334444\n222233334444\n222233334444\n222233334444\n        55556666\n        55556666\n        55556666\n        55556666\n\nYou still start in the same position and with the same facing as before,\nbut the wrapping rules are different. Now, if you would walk off\nthe board, you instead proceed around the cube. From the perspective\nof the map, this can look a little strange. In the above example,\nif you are at A and move to the right, you would arrive at B facing\ndown; if you are at C and move down, you would arrive at D facing up:\n\n        ...#\n        .#..\n        #...\n        ....\n...#.......#\n........#..A\n..#....#....\n.D........#.\n        ...#..B.\n        .....#..\n        .#......\n        ..C...#.\n\nWalls still block your path, even if they are on a different face\nof the cube. If you are at E facing up, your movement is blocked\nby the wall marked by the arrow:\n\n        ...#\n        .#..\n     -->#...\n        ....\n...#..E....#\n........#...\n..#....#....\n..........#.\n        ...#....\n        .....#..\n        .#......\n        ......#.\n\nUsing the same method of drawing the last facing you had with an\narrow on each tile you visit, the full path taken by the above\nexample now looks like this:\n\n        >>v#    \n        .#v.    \n        #.v.    \n        ..v.    \n...#..^...v#    \n.>>>>>^.#.>>    \n.^#....#....    \n.^........#.    \n        ...#..v.\n        .....#v.\n        .#v<<<<.\n        ..v...#.\n\nThe final password is still calculated from your final position and\nfacing from the perspective of the map.\nIn this example, the final row is 5, the final column is 7,\nand the final facing is 3, so the final password is\n1000 * 5 + 4 * 7 + 3 = 5031.\n\nFold the map into a cube, then follow the path given\nin the monkeys' notes. What is the final password?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_23.adb",
    "content": "--  Solution to Advent of Code 2022, Day 23\n-------------------------------------------\n--  Unstable Diffusion\n--\n--  https://adventofcode.com/2022/day/23\n--  Copy of questions in: aoc_2022_23_questions.txt\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\nprocedure AoC_2022_23 is\n  use AoC_Toolbox, HAT;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  verbosity_level : constant Natural := 0;\n\n  radius : constant := 200;\n\n  subtype Range_x is Integer range -radius .. radius;\n  subtype Range_y is Integer range -radius .. radius;\n\n  lowest, highest : Point;\n\n  procedure Adapt_Lowest_Value_Point (using : Point) is\n  begin\n    lowest.x := Min (lowest.x, using.x);\n    lowest.y := Min (lowest.y, using.y);\n  end Adapt_Lowest_Value_Point;\n\n  procedure Adapt_Highest_Value_Point (using : Point) is\n  begin\n    highest.x := Max (highest.x, using.x);\n    highest.y := Max (highest.y, using.y);\n  end Adapt_Highest_Value_Point;\n\n  map : array (Range_x, Range_y) of Character;\n\n  procedure Extend_Boundaries (p : Point) is\n  begin\n    Adapt_Lowest_Value_Point (p);\n    Adapt_Highest_Value_Point (p);\n  end Extend_Boundaries;\n\n  elf             : constant Character := '#';\n  elf_before_move : constant Character := 'x';\n  elf_after_move  : constant Character := '@';\n\n  procedure Clear_Map is\n  begin\n    for y in Range_y loop\n      for x in Range_x loop\n        map (x, y) := '.';\n      end loop;\n    end loop;\n  end Clear_Map;\n\n  procedure Clean_Map is\n    c : Character;\n  begin\n    for y in lowest.y .. highest.y loop\n      for x in lowest.x .. highest.x loop\n        c := map (x, y);\n        if c in '1' .. '4'\n          or else c = elf_before_move\n        then\n          map (x, y) := '.';\n        elsif c = elf_after_move then\n          map (x, y) := elf;\n        end if;\n      end loop;\n    end loop;\n  end Clean_Map;\n\n  elves : Natural;\n\n  function Count_Empty_Ground return Natural is\n    elf_low, elf_high : Point;\n  begin\n    elf_low.x := radius;\n    elf_low.y := radius;\n    elf_high.x := -radius;\n    elf_high.y := -radius;\n    for y in lowest.y .. highest.y loop\n      for x in lowest.x .. highest.x loop\n        if map (x, y) = elf then\n          elf_low.x  := Min (elf_low.x, x);\n          elf_low.y  := Min (elf_low.y, y);\n          elf_high.x := Max (elf_high.x, x);\n          elf_high.y := Max (elf_high.y, y);\n        end if;\n      end loop;\n    end loop;\n    return\n      (elf_high.y - elf_low.y + 1) *\n      (elf_high.x - elf_low.x + 1) - elves;\n  end Count_Empty_Ground;\n\n  type Direction_Set is array (Direction) of Boolean;\n\n  procedure Show is\n  begin\n    for y in reverse lowest.y .. highest.y loop  --  y axis appears bottom -> up.\n      for x in lowest.x .. highest.x loop\n        Put (map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  function Is_Elf (c : Character) return Boolean is\n  begin\n    return c = elf or else c = elf_before_move;\n  end Is_Elf;\n\n  start : Direction;\n  any_move : Boolean;\n\n  function Next (d : Direction) return Direction is\n  begin\n    case d is\n      when north => return south;\n      when south => return west;\n      when west  => return east;\n      when east  => return north;\n    end case;\n  end Next;\n\n  procedure Do_Round (verbosity_enabled : Boolean) is\n\n    procedure Do_Half_Round (half : Positive) is\n      elf_look : Direction;\n      is_possible, all_possible : Direction_Set;\n      dest : Point;\n    begin\n      for d in Direction loop\n        all_possible (d) := True;\n      end loop;\n      for y in lowest.y .. highest.y loop\n        for x in lowest.x .. highest.x loop\n          if Is_Elf (map (x, y)) then\n            is_possible := all_possible;\n            if Is_Elf (map (x - 1, y + 1)) then\n              is_possible (north) := False;\n              is_possible (west)  := False;\n            end if;\n            if Is_Elf (map (x + 1, y + 1)) then\n              is_possible (north) := False;\n              is_possible (east)  := False;\n            end if;\n            if Is_Elf (map (x - 1, y - 1)) then\n              is_possible (south) := False;\n              is_possible (west)  := False;\n            end if;\n            if Is_Elf (map (x + 1, y - 1)) then\n              is_possible (south) := False;\n              is_possible (east)  := False;\n            end if;\n            if Is_Elf (map (x, y + 1)) then\n              is_possible (north) := False;\n            end if;\n            if Is_Elf (map (x, y - 1)) then\n              is_possible (south) := False;\n            end if;\n            if Is_Elf (map (x - 1, y)) then\n              is_possible (west) := False;\n            end if;\n            if Is_Elf (map (x + 1, y)) then\n              is_possible (east) := False;\n            end if;\n            if is_possible (north)\n              and then is_possible (south)\n              and then is_possible (west)\n              and then is_possible (east)\n            then\n              --  This Elf has enough room around him,\n              --  thus no incentive to move.\n              null;\n            else\n              elf_look := start;\n            Look_Directions :\n              for dir_count in 1 .. 4 loop\n                if is_possible (elf_look) then\n                  --  Mark the destination cell.\n                  case elf_look is\n                    when north => dest.x := x; dest.y := y + 1;\n                    when south => dest.x := x; dest.y := y - 1;\n                    when west  => dest.x := x - 1; dest.y := y;\n                    when east  => dest.x := x + 1; dest.y := y;\n                  end case;\n                  Extend_Boundaries (dest);\n                  if half = 1 then\n                    --  Consider a move in chosen direction:\n                    case map (dest.x, dest.y) is\n                      when '.' => map (dest.x, dest.y) := '1';\n                      when '1' => map (dest.x, dest.y) := '2';\n                      when '2' => map (dest.x, dest.y) := '3';\n                      when '3' => map (dest.x, dest.y) := '4';\n                      when others =>\n                        Put (\"Bug : \" & map (dest.x, dest.y));\n                    end case;\n                  else\n                    --  Move... but only if there is no other\n                    --          Elf planning to move there.\n                    if map (dest.x, dest.y) = '1' then\n                      any_move := True;\n                      map (x, y)           := elf_before_move;\n                      map (dest.x, dest.y) := elf_after_move;\n                      --  We don't put immediately `elf` on\n                      --  destination cell.\n                      --  The reason is to avoid double-moves\n                      --  on adjacent cells (the Elves move all\n                      --  at the same time)...\n                    end if;\n                  end if;\n                  exit Look_Directions;\n                end if;\n                elf_look := Next (elf_look);\n              end loop Look_Directions;\n            end if;\n          end if;\n        end loop;\n      end loop;\n    end Do_Half_Round;\n\n  begin\n    Clean_Map;\n    any_move := False;\n\n    if verbosity_enabled and then verbosity_level > 1 then\n      Put_Line (\"--- after cleanup\");\n      Show;\n    end if;\n\n    for half in 1 .. 2 loop\n      Do_Half_Round (half);\n      if verbosity_enabled and then verbosity_level > 1 then\n        Put_Line (\"--- after half round\" & half'Image);\n        Show;\n      end if;\n    end loop;\n\n    start := Next (start);\n  end Do_Round;\n\n  procedure Data_Acquisition is\n    p : Point;\n    f : File_Type;\n    s : VString;\n    c : Character;\n  begin\n    Clear_Map;\n    lowest.x := radius;\n    lowest.y := radius;\n    highest.x := -radius;\n    highest.y := -radius;\n    Open (f, \"aoc_2022_23.txt\");\n    p.y := 0;\n    elves := 0;\n    start := north;\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      p.y := p.y - 1;\n      for i in 1 .. Length (s) loop\n        p.x := i;\n        c := Element (s, i);\n        map (p.x, p.y) := c;\n        if c = elf then\n          elves := elves + 1;\n          Adapt_Lowest_Value_Point (p);\n          Adapt_Highest_Value_Point (p);\n        end if;\n      end loop;\n    end loop Read_Data;\n    Close (f);\n  end Data_Acquisition;\n\n  T0 : constant Time := Clock;\n  r : array (Part_Type) of Integer;\n  last_round : Integer := 10;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\nParts :\n  for part in part_1 .. part_1 loop\n    Data_Acquisition;\n    if verbosity_level > 0 then\n      Show;\n    end if;\n    for round in 1 .. 10 loop\n      if verbosity_level > 0 then\n        Put_Line (\"===== Round\" & round'Image & \" =====\");\n      end if;\n      Do_Round (True);\n      if verbosity_level = 1 then\n        Show;\n      end if;\n    end loop;\n    Clean_Map;\n    if verbosity_level > 0 then\n      Put_Line (\"===== 10th Round Evaluation =====\");\n      Show;\n    end if;\n    r (part_1) := Count_Empty_Ground;\n    if not compiler_test_mode then\n      for round in 11 .. Integer'Last loop\n        exit when not any_move;\n        last_round := round;\n        Do_Round (False);\n      end loop;\n      if verbosity_level > 0 then\n        Put_Line\n          (\"===== Stable state after\" & last_round'Image &\n           \" rounds =====\");\n        Show;\n      end if;\n      r (part_2) := last_round;\n    end if;\n  end loop Parts;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"===== Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 3689\n    --  Part 2: validated by AoC: 965\n  end if;\nend AoC_2022_23;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_23.txt",
    "content": "###..#####..#....##.#..#...#.#.#..#.##..##...#.#.###.#.###...###.#....\n#..#..#.#....#.#.####.#.#.....#..####...####.##.#.#....####...#..#.#..\n...##...#.#####..###......#.#.#..##.#..#..#####.#..###.#.####.#.####..\n#.#...#...#.#..##.#.#..#.####...#.#####.###.##....##.###.#.##..####.#.\n...##.##..#.##.###..##.####.##.#...##...#.#...#.##.#..##...###.###....\n.......#.#..#.#....#....#.....##...#.#...###..#..#.##...#....##...#..#\n#.##..#.#..#.#####.#.#....##..#..##..###...#.###.####.#.....#..#.#.##.\n.#####.......###.##.#....#...##.#.#...#.######...##.#.#.###...###..#..\n.#.###..#####.##.##...#..##..#.#..#.####.##..###.##..##..##..##..##.#.\n..##..###.###.....#...###.#.#...#####.##..######.#.#.#...#..####....#.\n.#.....#..#........#####.###.##..#.####..#.#.#.###.###.#.....###.....#\n.#.##....#..#..#..#..#.#.#.....###.##.####.###.#..#..###..##.......###\n##.##..###...##....#....#........#.#######....#..#.##..#.##...#.#####.\n.#####.#.#.######.##....#..###.##......####..#...#.##.######...####.##\n#..###..#...##.##..#.#.....##...#.##.#.####.###.##....#.###.###...#.##\n..##.#...###...#...###.#.#.###.#.####..##..#...#..##...#..####...#.###\n###.....#..#....#.#......###..##.#...####...#..########..#.##.....####\n###..##....#.......#..###.#.#..##..#...###.......###....###.##..#..##.\n#..#.#..#.###....#.##.#.....#.##.##..#.##.###..##..###.##.###..#.##...\n#..#....#..##......###.######..#..#####.##...#.#..#..##..#.#....####.#\n.....#...#..####..##..#.#.##..##.###..#.###..#....##.##.##.####.......\n...#..#.####....###.#......#..###.##.#.#..##.#..#####.###..###..##.###\n#.###...#.#####..##.##..#.#....###.####.##.....####..#...#.###.#####..\n..#####.#...#.#..#..#.#.#.#.#......#.##.#.....##....#.##..###..####..#\n...#####.#.#..#..###..##.#.##.##...#.##.#.##.#.#.....#.###..####.#.#..\n####....##.##....#.#.###.##..#.#......#....#.###..#.#######.#..##...#.\n#.#..#..####..#.#...##.#...###.....##.###...#.#.#####.#....###.###.##.\n#.####.....#........##.#..##..##.###.#.##.#.#.#...##..#########.###..#\n#.#.#..#########.###.##..###.#...#.##.#..#....###...###.#..##.##.##...\n.#.#..##.......###.##.#.##......###..#....###.#...###.#.....#.#####...\n##.##..#.#..#....####.##..######.#.#..##...#...##.#.##..#.#....#.#.#.#\n.#..#...#.###....#..#.#.#...#####...#.#####.#.....#.#.##.#...##..##.##\n.##.#.######.#.####.#..##.#.####.##.##..##.######..#.#######..#.#..##.\n.#....#.#.###.##.....#..##.#.#####..##..###.##.#...#.#.#....#....###.#\n.#.#.#..#.....##.#....##.#....###.###......#.#..#.#...##...#..#.###..#\n..#..#....##.##...#.#...#......#.#####....###.#..#.#..#..#.####..#####\n.#.#..#....####..#....##..####.#.#.#...#.##.#..........###.....#..#..#\n.#.##.#.#.....##.#...###.....#####.##.##......###.#.##..####.##....#..\n...#..##.#..#....#.....##..#.#.##.###.##.#.#..##.#.#...##.#...####...#\n##.#.########....#.#..##..#.##...###..#...#.##.###..####.###.......#.#\n#.##...##..#####..##..###.#..######..###..######..#.#.#..########.#...\n##..##..##.##.##...###..#.#.#..#.#.###.#..#...#..#.#....#..##....#..#.\n..#####..#.#.##.##.####.#..#.####.#.#.....#....#.##...##.....###....##\n##..####..#.###.##..######.#..#.##.##..####..#.##.#.##.#.#.###.#.##...\n#.#...#..##.##...##....#..#..#.#.#####....#.#.#.###..#..#.#..#....#...\n#.###....##.........###...###..##.#..#.##.#.....#..#.######..#.###....\n#######..###.#..###...#..#####.....#..#...#..##..#....#.#####..###....\n.#...###..###....##.##.....#.##.#.###.#.####...#...#.#.##........#.#.#\n##..#..#......#.#.###.#.#.#.#....#.#...####.###.##.#.#..###........##.\n.#..#..#.#.###..#...#..###.##....#........#.#.#.####.#..#.#.####..#.##\n..########..#..#..#.####.####.###.#####..#..######..#.#.#....#......#.\n###.##..##.####.#.......###.....####.#.#..#.#.#..#.#..##.###...#.##.##\n.....##..#..#.#.#.####...##..######.#.####..#..##.###......###.#....#.\n#..###...#..##........#.#.###.##.##..#..#..##.##.#.#..##.#..##.##...#.\n..#....#.#.#####.##...#.##.#..##....##.##.#....##..#.######..#.####.#.\n#...##.#.##.#.#...#.###.#.#.##.....##.###.#...#.#.#####.######.##.#.##\n#.#.###..#.#..####..###..#####.#.........#..####.##.###.###.#....#....\n.#.#...#.#.###..##....#..#.###.#...#.#..###..###..#.##.#.##.#.#...##..\n...##..#.#.#.###..##...#####..##.#.#.####.#...####.#.#..#..##...##.###\n...####..###.###.#.#...#.##...#.###...#.#.#.#.#.....#..#...##..##.#...\n##..###...##.#.###.##.##..#.#####.###.......##.####..##.....#.#.##..#.\n......##.....#...#.###.##.#..#####.#.###....#.#..###.#....##...##.#.##\n...#.#.###.##...##.####..##.##..#...#.#.......##..#..#....##...#.#.#..\n..##.....###.....#...#.#.##..###..####.###..###...#..#...#..###...##..\n.#.#.#.#..####..#...###.#.#..##.##.#.#..#..##.......#.#..#.####.###.##\n#..###..###.#.......#.#...##.###.#....#..#.##.#.##.##.####.####.#####.\n###.#...#....#.#..##.#.##.##.#.#..##..##..#####.#.#.#.##.....##.##..##\n##.##..#....##...###.##..#...#.....#.#..##......#...#.###....#.#..#..#\n##..#..###..####.#.#.#.##.#.###.###.##.#.##....##.#.#..#.#..#.#...###.\n#.##..##.#.###..#.#.####.#...#...##..#..##.###.#.#.......#....##.##...\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_23_questions.txt",
    "content": "--- Day 23: Unstable Diffusion ---\n\nYou enter a large crater of gray dirt where the grove is supposed to be.\nAll around you, plants you imagine were expected to be full of fruit are\ninstead withered and broken.\nA large group of Elves has formed in the middle of the grove.\n\n\"...but this volcano has been dormant for months.\n Without ash, the fruit can't grow!\"\n\nYou look up to see a massive, snow-capped mountain towering above you.\n\n\"It's not like there are other active volcanoes here;\n we've looked everywhere.\"\n\n\"But our scanners show active magma flows; clearly it's going somewhere.\"\n\nThey finally notice you at the edge of the grove, your pack almost\noverflowing from the random star fruit you've been collecting.\nBehind you, elephants and monkeys explore the grove, looking concerned.\nThen, the Elves recognize the ash cloud slowly spreading\nabove your recent detour.\n\n\"Why do you--\" \"How is--\" \"Did you just--\"\n\nBefore any of them can form a complete question, another Elf\nspeaks up: \"Okay, new plan. We have almost enough fruit already, and\nash from the plume should spread here eventually. If we quickly plant new\nseedlings now, we can still make it to the extraction point. Spread out!\"\n\nThe Elves each reach into their pack and pull out a tiny plant.\nThe plants rely on important nutrients from the ash, so they can't\nbe planted too close together.\n\nThere isn't enough time to let the Elves figure out where to plant the\nseedlings themselves; you quickly scan the grove (your puzzle input)\nand note their positions.\n\nFor example:\n\n....#..\n..###.#\n#...#.#\n.#...##\n#.###..\n##.#.##\n.#..#..\n\nThe scan shows Elves # and empty ground .; outside your scan, more empty\nground extends a long way in every direction. The scan is oriented so that\nnorth is up; orthogonal directions are written N (north), S (south),\nW (west), and E (east), while diagonal directions are written NE, NW, SE, SW.\n\nThe Elves follow a time-consuming process to figure out where they should\neach go; you can speed up this process considerably. The process consists\nof some number of rounds during which Elves alternate between considering\nwhere to move and actually moving.\n\nDuring the first half of each round, each Elf considers the eight positions\nadjacent to themself. If no other Elves are in one of those eight positions,\nthe Elf does not do anything during this round. Otherwise, the Elf looks in\neach of four directions in the following order and proposes moving one step\nin the first valid direction:\n\n    If there is no Elf in the N, NE, or NW adjacent positions,\n      the Elf proposes moving north one step.\n     \n    If there is no Elf in the S, SE, or SW adjacent positions,\n      the Elf proposes moving south one step.\n      \n    If there is no Elf in the W, NW, or SW adjacent positions,\n      the Elf proposes moving west one step.\n      \n    If there is no Elf in the E, NE, or SE adjacent positions,\n      the Elf proposes moving east one step.\n\nAfter each Elf has had a chance to propose a move, the second half of\nthe round can begin. Simultaneously, each Elf moves to their proposed\ndestination tile if they were the only Elf to propose moving to that\nposition. If two or more Elves propose moving to the same position,\nnone of those Elves move.\n\nFinally, at the end of the round, the first direction the Elves\nconsidered is moved to the end of the list of directions.\nFor example, during the second round, the Elves would try proposing\na move to the south first, then west, then east, then north.\nOn the third round, the Elves would first consider west, then east,\nthen north, then south.\n\nAs a smaller example, consider just these five Elves:\n\n.....\n..##.\n..#..\n.....\n..##.\n.....\n\nThe northernmost two Elves and southernmost two Elves all propose\nmoving north, while the middle Elf cannot move north and proposes\nmoving south. The middle Elf proposes the same destination as the\nsouthwest Elf, so neither of them move, but the other three do:\n\n..##.\n.....\n..#..\n...#.\n..#..\n.....\n\nNext, the northernmost two Elves and the southernmost Elf all propose\nmoving south. Of the remaining middle two Elves, the west one cannot\nmove south and proposes moving west, while the east one cannot move\nsouth or west and proposes moving east. All five Elves succeed in\nmoving to their proposed positions:\n\n.....\n..##.\n.#...\n....#\n.....\n..#..\n\nFinally, the southernmost two Elves choose not to move at all.\nOf the remaining three Elves, the west one proposes moving west,\nthe east one proposes moving east, and the middle one proposes\nmoving north; all three succeed in moving:\n\n..#..\n....#\n#....\n....#\n.....\n..#..\n\nAt this point, no Elves need to move, and so the process ends.\n\nThe larger example above proceeds as follows:\n\n== Initial State ==\n..............\n..............\n.......#......\n.....###.#....\n...#...#.#....\n....#...##....\n...#.###......\n...##.#.##....\n....#..#......\n..............\n..............\n..............\n\n== End of Round 1 ==\n..............\n.......#......\n.....#...#....\n...#..#.#.....\n.......#..#...\n....#.#.##....\n..#..#.#......\n..#.#.#.##....\n..............\n....#..#......\n..............\n..............\n\n== End of Round 2 ==\n..............\n.......#......\n....#.....#...\n...#..#.#.....\n.......#...#..\n...#..#.#.....\n.#...#.#.#....\n..............\n..#.#.#.##....\n....#..#......\n..............\n..............\n\n== End of Round 3 ==\n..............\n.......#......\n.....#....#...\n..#..#...#....\n.......#...#..\n...#..#.#.....\n.#..#.....#...\n.......##.....\n..##.#....#...\n...#..........\n.......#......\n..............\n\n== End of Round 4 ==\n..............\n.......#......\n......#....#..\n..#...##......\n...#.....#.#..\n.........#....\n.#...###..#...\n..#......#....\n....##....#...\n....#.........\n.......#......\n..............\n\n== End of Round 5 ==\n.......#......\n..............\n..#..#.....#..\n.........#....\n......##...#..\n.#.#.####.....\n...........#..\n....##..#.....\n..#...........\n..........#...\n....#..#......\n..............\n\nAfter a few more rounds...\n\n== End of Round 10 ==\n.......#......\n...........#..\n..#.#..#......\n......#.......\n...#.....#..#.\n.#......##....\n.....##.......\n..#........#..\n....#.#..#....\n..............\n....#..#..#...\n..............\n\nTo make sure they're on the right track, the Elves like to check after\nround 10 that they're making good progress toward covering enough ground.\nTo do this, count the number of empty ground tiles contained by the\nsmallest rectangle that contains every Elf. (The edges of the rectangle\nshould be aligned to the N/S/E/W directions; the Elves do not have the\npatience to calculate arbitrary rectangles.)\nIn the above example, that rectangle is:\n\n......#.....\n..........#.\n.#.#..#.....\n.....#......\n..#.....#..#\n#......##...\n....##......\n.#........#.\n...#.#..#...\n............\n...#..#..#..\n\nIn this region, the number of empty ground tiles is 110.\n\nSimulate the Elves' process and find the smallest rectangle that\ncontains the Elves after 10 rounds.\n\nHow many empty ground tiles does that rectangle contain?\n\n--- Part Two ---\n\nIt seems you're on the right track. Finish simulating the process\nand figure out where the Elves need to go.\nHow many rounds did you save them?\n\nIn the example above, the first round where no Elf moved was round 20:\n\n.......#......\n....#......#..\n..#.....#.....\n......#.......\n...#....#.#..#\n#.............\n....#.....#...\n..#.....#.....\n....#.#....#..\n.........#....\n....#......#..\n.......#......\n\nFigure out where the Elves need to go.\nWhat is the number of the first round where no Elf moves?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_24.adb",
    "content": "--  Solution to Advent of Code 2022, Day 24\n-------------------------------------------\n--  Blizzard Basin\n--\n--  https://adventofcode.com/2022/day/24\n--  Copy of questions in: aoc_2022_24_questions.txt\n\n--  Runs in 0.12 second with GNAT.\n--  Runs in 134 seconds with HAC.\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\nprocedure AoC_2022_24 is\n  use AoC_Toolbox, HAT;\n\n  verbosity_level : constant Natural := 0;\n\n  f : File_Type;\n  s : VString;\n\n  subtype Range_x is Integer range  0 .. 101;\n  subtype Range_y is Integer range -1 ..  36;\n  subtype Range_t is Integer range  0 .. 700;\n\n  lowest, highest : Point;\n\n  inf : constant Natural := Integer'Last / 4;\n\n  --  Convention: 0-based, y axis appears top -> down.\n\n  type Blizzard is array (Range_x, Range_y) of Boolean;\n\n  leftward_blizzard, upward_blizzard,\n  rightward_blizzard, downward_blizzard : Blizzard;\n\n  best : array (Range_x, Range_y, Range_t) of Natural;\n\n  procedure Show (time_step : Natural) is\n  begin\n    for y in lowest.y .. highest.y loop  --  y axis appears top -> down.\n      for x in lowest.x .. highest.x loop\n        if    leftward_blizzard  ((x + time_step) mod (highest.x + 1), y) then Put ('<');\n        elsif upward_blizzard    (x, (y + time_step) mod (highest.y + 1)) then Put ('^');\n        elsif rightward_blizzard ((x - time_step) mod (highest.x + 1), y) then Put ('>');\n        elsif downward_blizzard  (x, (y - time_step) mod (highest.y + 1)) then Put ('v');\n        else Put ('.');\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  procedure Clear (b : in out Blizzard) is\n  begin\n    for y in Range_y loop\n      for x in Range_x loop\n        b (x, y) := False;\n      end loop;\n    end loop;\n  end Clear;\n\n  --  Dijkstra shortest path algorithm.\n  --  Code adapted from AoC_2022_12.\n  --\n\n  list_length_max : constant := 200_000;  --  Adjusted by doubling until no Constraint_Error.\n\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  type Node is record\n    len  : Natural;   --  Length in space-time\n    pt   : Point_3D;  --  dimensions: x, y, t\n    pred : Natural;   --  This is just for displaying the path.\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  stats : constant Boolean := True;\n  stats_first_visit      : Natural := 0;\n  stats_added_revisit    : Natural := 0;\n  stats_rejected_revisit : Natural := 0;\n\n  function Dijkstra_Algorithm (start : Point_3D; part : Part_Type) return Natural is\n\n    blizzard_cycle : Positive;\n    cur_pt  : Point_3D;\n    cur_len : Natural;\n\n    procedure Visit (x, y : Integer) is\n      len_to, ins, t : Integer;\n    begin\n      t := cur_pt.z + 1;\n      if         (x in 0 .. highest.x    --  The valley.\n         and then y in 0 .. highest.y\n         and then not\n                  (leftward_blizzard  ((x + t) mod (highest.x + 1), y)\n           or else rightward_blizzard ((x - t) mod (highest.x + 1), y)\n           or else upward_blizzard    (x, (y + t) mod (highest.y + 1))\n           or else downward_blizzard  (x, (y - t) mod (highest.y + 1))))\n\n        or else (x = 0 and then y = -1)  --  The \"starting block\".\n        or else\n                  (x = highest.x         --  The end (and new start...).\n          and then y = highest.y + 1)\n      then\n        len_to := cur_len + 1;\n        if verbosity_level > 1 then\n          Put (+\"x: \" & x & \", y: \" & y &\n               \", t: \" & t & \"  cur_len = \" & cur_len);\n          if best (x, y, t mod blizzard_cycle) < inf then\n            Put\n              (+\"  old best (x, y, time_step) = \" &\n               best (x, y, t mod blizzard_cycle) & \", \");\n          else\n            Put (\"  not visited, \");\n          end if;\n        end if;\n        if len_to < best (x, y, t mod blizzard_cycle) then\n          --  Improvement on cell (x, y).\n          best (x, y, t mod blizzard_cycle) := len_to;\n          --\n          --  Insert in a sorted way.\n          --\n          ins := explored + 1;\n          for i in current + 1 .. explored loop\n            if current < list (i).len then\n              ins := i;  --  Insert here.\n              --  Optional: remove another node\n              --  with the same (x, y) and a larger length.\n              exit;\n            end if;\n          end loop;\n          for i in reverse ins .. explored loop\n            list (i + 1) := list (i);\n          end loop;\n          list (ins).len := len_to;\n          list (ins).pt.x := x;\n          list (ins).pt.y := y;\n          list (ins).pt.z := t;\n          list (ins).pred := current;\n          explored := explored + 1;\n          if verbosity_level > 1 then\n            Put_Line (\" ->   added\");\n          end if;\n          if stats then\n            if best (x, y, t mod blizzard_cycle) < inf then\n              stats_first_visit := stats_first_visit + 1;\n            else\n              stats_added_revisit := stats_added_revisit + 1;\n            end if;\n          end if;\n        else\n          if stats then\n            if best (x, y, t mod blizzard_cycle) < inf then\n              stats_rejected_revisit := stats_rejected_revisit + 1;\n            else\n              Put (\"Uh (rejected but = inf) ?\");\n            end if;\n          end if;\n          if verbosity_level > 1 then\n            Put_Line (\" ->   NOT added\");\n          end if;\n        end if;\n      end if;\n    end Visit;\n\n  begin\n    current  := 0;\n    explored := 0;\n    blizzard_cycle :=\n      (highest.x + 1) * (highest.y + 1) / GCD (highest.x + 1, highest.y + 1);\n    if verbosity_level > 0 then\n      Put_Line (\"blizzard_cycle\" & blizzard_cycle'Image);\n    end if;\n\n    for t in 0 .. Min (blizzard_cycle - 1, best'Last (3)) loop\n      for x in 0 .. highest.x loop\n        for y in -1 .. highest.y + 1 loop\n          best (x, y, t) := inf;\n        end loop;\n      end loop;\n    end loop;\n\n    cur_pt := start;\n    best (cur_pt.x, cur_pt.y, cur_pt.z mod blizzard_cycle) := 0;\n    loop\n      cur_len := best (cur_pt.x, cur_pt.y, cur_pt.z mod blizzard_cycle);\n      Visit (cur_pt.x,     cur_pt.y);  --  Wait in place.\n      Visit (cur_pt.x - 1, cur_pt.y);\n      Visit (cur_pt.x + 1, cur_pt.y);\n      Visit (cur_pt.x, cur_pt.y - 1);\n      Visit (cur_pt.x, cur_pt.y + 1);\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_pt := list (current).pt;\n      case part is\n        when part_1 =>\n          exit when cur_pt.x = highest.x\n           and then cur_pt.y = highest.y;\n        when part_2 =>\n          exit when cur_pt.x = 0\n           and then cur_pt.y = 0;\n      end case;\n    end loop;\n    return cur_pt.z + 1;\n  end Dijkstra_Algorithm;\n\n  T0 : constant Time := Clock;\n  r : array (Part_Type) of Integer;\n\n  start : Point_3D;\n\nbegin\n    Clear (leftward_blizzard);\n    Clear (upward_blizzard);\n    Clear (rightward_blizzard);\n    Clear (downward_blizzard);\n    lowest.x := 0;\n    lowest.y := 0;\n    Open (f, \"aoc_2022_24.txt\");\n    Get_Line (f, s);\n    highest.x := Length (s) - 3;\n    highest.y := -1;\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      exit Read_Data when End_Of_File (f);  --  Discard last line\n      highest.y := highest.y + 1;\n      for i in 2 .. Length (s) - 1 loop\n        case Element (s, i) is\n          when '.' => null;\n          when '<' => leftward_blizzard (i - 2, highest.y) := True;\n          when '^' => upward_blizzard (i - 2, highest.y) := True;\n          when '>' => rightward_blizzard (i - 2, highest.y) := True;\n          when 'v' => downward_blizzard (i - 2, highest.y) := True;\n          when others => Put (\"Whut?\");\n        end case;\n      end loop;\n    end loop Read_Data;\n    Close (f);\n\n    if verbosity_level > 0 then\n      for i in 0 .. 18 loop\n        Put_Line (i, 0);\n        Show (i);\n        New_Line;\n      end loop;\n    end if;\n\n    start.x := 0;\n    start.y := -1;\n    start.z := 0;\n    r (part_1) := Dijkstra_Algorithm (start, part_1);\n    start.x := highest.x;\n    start.y := highest.y + 1;\n    start.z := r (part_1);\n    r (part_2) := Dijkstra_Algorithm (start, part_2);\n    start.x := 0;\n    start.y := -1;\n    start.z := r (part_2);\n    r (part_2) := Dijkstra_Algorithm (start, part_1);\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (part_1) /= Integer'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    if stats then\n      Put_Line (+\"Firstly visited cells    : \" & stats_first_visit);\n      Put_Line (+\"Added revisited cells    : \" & stats_added_revisit);\n      Put_Line (+\"Rejected revisited cells : \" & stats_rejected_revisit);\n    end if;\n    Put_Line (+\"Shortest time for...\");\n    Put_Line (+\"  (part 1) one trip . . . . :\" & r (part_1)'Image);\n    Put_Line (+\"  (part 2) three trips  . . :\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 238\n    --  Part 2: validated by AoC: 751\n  end if;\nend AoC_2022_24;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_24.txt",
    "content": "#.####################################################################################################\n#>^<.v^^v>>^>vv..<><v.<^<^<v.^>>^<>>><><<>^v^>.^<>><<^vv><^<>>vv^v.<.^v><<<>.<v><<^v<v^<>.<vv<>vv<<v>#\n#<v<vv><^>v<><.<<^^<>^>v<^vvvv^<<v<<^.^.^>.<><^><<^v<^><<v>vv<<>>>^.^<>>>^vvv^><^v^^>>><<vvv>><<><><.#\n#>.vv^^^<^>v>vvv>^.<v<>...v^<>v<><<..vvv<^<<v>^>^<^v^>><^^v.v>>><^.^>vv^^v>v<^^.vv<v<v<>>^^>v>vvv^v><#\n#.<v>^^<^v^^<^>>^>><v>^vv>^<v<v^^<>^v><v<^<>>.v^>^.v^><vvv^.^.>vvv^.v.>.>^<^.<^>><^><v<<v>^^>><><^^^<#\n#<^<<v^vvv>>><>^^>>v.v.v^^>^<>><^>>^^><v>v<^.^.v<..>>>.>>.<^<^^^>.<>^^.v^>>>v>v>^^v>^><>><<.^.^>vv^^.#\n#<^^>^v><..v^v<^.<vv^v<.<>.<>.^v^>^^>>v^^v.<.^><>^v.^^v>v<^^vv<<^^v<>><>^<v>>^<><v^.>>>>^v.>v.><.>v>>#\n#<>.<<v.><^><<>>v><><>^..^v^<v>v<v.<>^<>>^v.^^>>.v^.<v>v>.v.v<>v.<.vv<<^<>^^^^>>.<vv<><<>vv>^>.v^<^>>#\n#<.^<vv<><v^^<^v^.<><>v>>>.<<v<<v>>v^..v<<>^>^v>>.<>>v<^>^>^<vvv<><<<..v><<<v>><v<^v^<<^vvv>^>^<v<vv<#\n#>^>^v>><<>>.^<>>^.^<v>^>>.<v^>v<<>vv><.v<.^^^>v<v>.v^v^.>>^^^vvvv<^<^<v>^.^<>v<^.^<>v>>vv<>>^^^>v>><#\n#>><^<<v<>>^<^>v>v^v><v<v><^v>v>^>^<>>^v>vv^>^v<vv^v>.<^><.vv^^^<^><..<<<>^>^.^>>>^<>.^<^>^<>^^v>v<v>#\n#><<><v><v^v>.v>^.<^><^^v><<<<<.^>>.^^<v>v>>^<^<>.^.>>>.>>.^v>v.<^^v^<^<>v<>^^<v^><<^^^<><v^>v>v<^.v<#\n#<v>.v<<><vvv^<>^^^<<v<v^v^><v.><<.^^>vvv^>^v>v><><<.v>v<<<><..>>v>>v><^^>^^.^>v.v..>^><^.<>^<<^<<v<<#\n#<vv<<vvv<vv>v><<.v<v<><.>^vv.^<<<<<<<v<^<^v^v>.v><vv<v^>^^^.^vv<<v>.<<><>>><^<^.^<>^>^<>v.v.v^><v<<.#\n#.>^.>vv<v<><vv^v.^v<.^.v<><>^^>^.>v^<><v<<><vv<<^v>^>v<>^v>v>>v<>^<v.<v^^<<v><<.^<^>.vv.>>^.vv<><v><#\n#>>v>>>.v<v<^^>><^^v^>>v>v^>>^<v^^^^.vv.^vv<vv><v^v<>^v<>>>>^^v>^<v<v^<>><>.v>>v..^>..<v<<>.v<<.<^>v<#\n#<><^>>v^<^^vv>v<v.>.v.<^v.^>vvv<^>v><^>v><><.v>>.^^>><<>.v^<<^.<.^^.<v><v.^.v<^^^^<^<^>vv<v<.v<<v<^>#\n#<<^^<<^vvv<<<<.^vv^.><<vv>v^><>..^.^^v>v>^^<<v>^v.v>^v><>>^v><<.v>v<>^v<v<>v<^v^.^<vv>>^>v>^><<v><.<#\n#<<>v.v>...^^.<<^>>.<>^^^v>^<^><v<<<><<vv^.v^>.v^.>>^<v>>^<v^^<v>>vv<<>.>>.v^v><.^v.>^>^><^^v^^v<v>^<#\n#<^vv^<><<<v^^<^>>v><^<<v^^v^>>^>v<>.<>>v>v<><v.>v<><<<<.<<.<<>>>><><vv><^v<<<^>v<^<^^<v^><^<..v>.vv>#\n#><^>>>.^.>v<^^>>vv<v><^<<v.<.>^<^<^v>vv>v^^><.^.^>>.v.>v^.>>^<>^^^>vvv>..v^vv<^v>>v<><><<<^^<<v>^^<>#\n#>^<vv>^v<<.<<v>^><><>>v.>.^<>^^vv<<>>>v^<>>><<v.v>>^<<vv<^vvv><><.v><.vv^v^.v.>vv^<><.v^>vv.<<<v<><<#\n#>v<^>>.>>v>v>><^>^>^.^>^>vv>^<<><^v.<vvv<^.><>>v>v>^<>><^>^^<>v>v>.<^v^>>>v^>vvv.>.>^<><>.v^vv><>^>>#\n#>><>v^>^>>^>^^>^>^<^>>vv>>>>>>vvv.v>.^v<v<vvv<<>.<^v.vv.v>^>>vv<<v^>^^^^>>^v.^v>>v<vvv<.<>^^<^v<<<.<#\n#<>vv<^v>v^<v>>^<<>v^>vvvv>v^><^>^v<v^^^>><^><<.^>v^vv.v<<<>..v<^<.vv>.v>^>>>^^v^v^<^v^<^^<<vv>.>.>><#\n#<<<v><>v.><v>><v^<^>><>^<vv><<.<<<<.v^v>v>v>.><>.<v><^.<^>^^><v>vv.<v>.v.>>.^>^>v<^vvvv>><>^^v<^>v>.#\n#>.^>^>.<v.v<.<>vv<v<>^v<.>^>v<^v^>.>^<^..v<>>v.v>^.v<^>>^^^<v.<>v><v.^v^.>vv<<^<v^<.^^^.^>>.v>.vv.^.#\n#<^v><>.<^v<v<^v<vv^^>.>v^^<v>^<.<^^<<.^>vv^^<^>v<v<^<v^^>vv^v>v^^>>..v^>.<v>v>v<v^<>^<^><.>^>>><<v.<#\n#>>^<vv.<<>v.<>v.^>>^^vv^<^>vv<^>v.v>>.^.v^.v<v>^<>^.>><^>v>.>>v^<^>.>>^v<<v<<^^<vvvvv><^>^>v^^^^>^v>#\n#<^.>^v>^<>>^.^<>.>..><>.<v^v^vv^>v^..v<<><>>^.^><^^<^^<^v<<^<^>.<><^.>^<^vv^>>>>^^>>><v<<<<^><.>^>.<#\n#.v<>><^^vv^<<v^v><<<v<<<v><>><>>v^>v>^^^v<<<<<<>.^v<>.^<><<^vv<^>>v.^><v>v<^v>^v><v>>v<^^>vv.^<^>.>.#\n#>^<.>v^^^><<v><>^.>vvv>v^<^>v><<<><><.^>>.>vv.^<<<<<^<^>^>v<^^<^<><v<.<>v<<><<v<^>>v>>>^<>>>.<<^<^<<#\n#>^^>.vv^><.>v<vv>^><>v><^<v.<v^>.^><v<v>v^>^<v^v>v<<v^^<^>.^<v<vv<.>>v>v^v.<vv^^^^><v>^<>^v^>vv>>vv>#\n#><>^<^^>^>v<^^<vv^<<^>v<>>v^>^v.v.v>^^><^<<<<>v>vv<v>^^<v>>.v<><<^><^^<<>>>>^>v>^>><><^>v><^^><v^^>>#\n#><<<v<v><>^vv.^<>^>><v>vv^v^v<<v.v<v^>>vvvv^v<^<v^.><^^v><><v<^^<>><<>v^vv<^>v><>><<<^>>^^<^>><>v<v<#\n#>^v><>v<>>^v>^<v^<vv><>^^>>>>v><v^v^>>>v<^<<<<<v<^<>>v><^<<^^^<^<>v<>^<v><^.>>><<^v.<>v^^.>>^^.^>^v<#\n####################################################################################################.#\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_24_questions.txt",
    "content": "--- Day 24: Blizzard Basin ---\n\nWith everything replanted for next year (and with elephants and monkeys\nto tend the grove), you and the Elves leave for the extraction point.\n\nPartway up the mountain that shields the grove is a flat, open area\nthat serves as the extraction point.\nIt's a bit of a climb, but nothing the expedition can't handle.\n\nAt least, that would normally be true; now that the mountain is covered\nin snow, things have become more difficult than the Elves are used to.\n\nAs the expedition reaches a valley that must be traversed to reach the\nextraction site, you find that strong, turbulent winds are pushing small\nblizzards of snow and sharp ice around the valley.\nIt's a good thing everyone packed warm clothes!\nTo make it across safely, you'll need to find a way to avoid them.\n\nFortunately, it's easy to see all of this from the entrance to the\nvalley, so you make a map of the valley and the blizzards\n(your puzzle input). For example:\n\n#.#####\n#.....#\n#>....#\n#.....#\n#...v.#\n#.....#\n#####.#\n\nThe walls of the valley are drawn as #; everything else is ground.\nClear ground - where there is currently no blizzard - is drawn as ..\nOtherwise, blizzards are drawn with an arrow indicating their\ndirection of motion: up (^), down (v), left (<), or right (>).\n\nThe above map includes two blizzards, one moving right (>) and\none moving down (v). In one minute, each blizzard moves one\nposition in the direction it is pointing:\n\n#.#####\n#.....#\n#.>...#\n#.....#\n#.....#\n#...v.#\n#####.#\n\nDue to conservation of blizzard energy, as a blizzard reaches\nthe wall of the valley, a new blizzard forms on the opposite\nside of the valley moving in the same direction. After another\nminute, the bottom downward-moving blizzard has been replaced with\na new downward-moving blizzard at the top of the valley instead:\n\n#.#####\n#...v.#\n#..>..#\n#.....#\n#.....#\n#.....#\n#####.#\n\nBecause blizzards are made of tiny snowflakes, they pass right\nthrough each other. After another minute, both blizzards\ntemporarily occupy the same position, marked 2:\n\n#.#####\n#.....#\n#...2.#\n#.....#\n#.....#\n#.....#\n#####.#\n\nAfter another minute, the situation resolves itself, giving\neach blizzard back its personal space:\n\n#.#####\n#.....#\n#....>#\n#...v.#\n#.....#\n#.....#\n#####.#\n\nFinally, after yet another minute, the rightward-facing blizzard\non the right is replaced with a new one on the left facing\nthe same direction:\n\n#.#####\n#.....#\n#>....#\n#.....#\n#...v.#\n#.....#\n#####.#\n\nThis process repeats at least as long as you are observing\nit, but probably forever.\n\nHere is a more complex example:\n\n#.######\n#>>.<^<#\n#.<..<<#\n#>v.><>#\n#<^v^^>#\n######.#\n\nYour expedition begins in the only non-wall position in the\ntop row and needs to reach the only non-wall position in\nthe bottom row. On each minute, you can move up, down, left,\nor right, or you can wait in place. You and the blizzards\nact simultaneously, and you cannot share a position\nwith a blizzard.\n\nIn the above example, the fastest way to reach your goal\nrequires 18 steps. Drawing the position of the expedition\nas E, one way to achieve this is:\n\nInitial state:\n#E######\n#>>.<^<#\n#.<..<<#\n#>v.><>#\n#<^v^^>#\n######.#\n\nMinute 1, move down:\n#.######\n#E>3.<.#\n#<..<<.#\n#>2.22.#\n#>v..^<#\n######.#\n\nMinute 2, move down:\n#.######\n#.2>2..#\n#E^22^<#\n#.>2.^>#\n#.>..<.#\n######.#\n\nMinute 3, wait:\n#.######\n#<^<22.#\n#E2<.2.#\n#><2>..#\n#..><..#\n######.#\n\nMinute 4, move up:\n#.######\n#E<..22#\n#<<.<..#\n#<2.>>.#\n#.^22^.#\n######.#\n\nMinute 5, move right:\n#.######\n#2Ev.<>#\n#<.<..<#\n#.^>^22#\n#.2..2.#\n######.#\n\nMinute 6, move right:\n#.######\n#>2E<.<#\n#.2v^2<#\n#>..>2>#\n#<....>#\n######.#\n\nMinute 7, move down:\n#.######\n#.22^2.#\n#<vE<2.#\n#>>v<>.#\n#>....<#\n######.#\n\nMinute 8, move left:\n#.######\n#.<>2^.#\n#.E<<.<#\n#.22..>#\n#.2v^2.#\n######.#\n\nMinute 9, move up:\n#.######\n#<E2>>.#\n#.<<.<.#\n#>2>2^.#\n#.v><^.#\n######.#\n\nMinute 10, move right:\n#.######\n#.2E.>2#\n#<2v2^.#\n#<>.>2.#\n#..<>..#\n######.#\n\nMinute 11, wait:\n#.######\n#2^E^2>#\n#<v<.^<#\n#..2.>2#\n#.<..>.#\n######.#\n\nMinute 12, move down:\n#.######\n#>>.<^<#\n#.<E.<<#\n#>v.><>#\n#<^v^^>#\n######.#\n\nMinute 13, move down:\n#.######\n#.>3.<.#\n#<..<<.#\n#>2E22.#\n#>v..^<#\n######.#\n\nMinute 14, move right:\n#.######\n#.2>2..#\n#.^22^<#\n#.>2E^>#\n#.>..<.#\n######.#\n\nMinute 15, move right:\n#.######\n#<^<22.#\n#.2<.2.#\n#><2>E.#\n#..><..#\n######.#\n\nMinute 16, move right:\n#.######\n#.<..22#\n#<<.<..#\n#<2.>>E#\n#.^22^.#\n######.#\n\nMinute 17, move down:\n#.######\n#2.v.<>#\n#<.<..<#\n#.^>^22#\n#.2..2E#\n######.#\n\nMinute 18, move down:\n#.######\n#>2.<.<#\n#.2v^2<#\n#>..>2>#\n#<....>#\n######E#\n\nWhat is the fewest number of minutes required to avoid\nthe blizzards and reach the goal?\n\n--- Part Two ---\n\nAs the expedition reaches the far side of the valley,\none of the Elves looks especially dismayed:\n\nHe forgot his snacks at the entrance to the valley!\n\nSince you're so good at dodging blizzards, the Elves\nhumbly request that you go back for his snacks.\nFrom the same initial conditions, how quickly can you\nmake it from the start to the goal, then back to the\nstart, then back to the goal?\n\nIn the above example, the first trip to the goal takes\n18 minutes, the trip back to the start takes 23 minutes,\nand the trip back to the goal again takes 13 minutes,\nfor a total time of 54 minutes.\n\nWhat is the fewest number of minutes required to reach\nthe goal, go back to the start, then reach the goal again?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_25.adb",
    "content": "--  Solution to Advent of Code 2022, Day 25\n-------------------------------------------\n--  Full of Hot Air\n--\n--  https://adventofcode.com/2022/day/25\n--  Copy of questions in: aoc_2022_25_questions.txt\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\n--  Interfaces is needed for compiling on both\n--  HAC and GNAT (64-bit integer: Integer_64):\nwith Interfaces;\n\nprocedure AoC_2022_25 is\n  use HAT, Interfaces;\n\n  f : File_Type;\n  s : VString;\n  i, k, sum : Integer_64;\n\nbegin\n  sum := 0;\n  Open (f, \"aoc_2022_25.txt\");\nRead_Data :\n  while not End_Of_File (f) loop\n    Get_Line (f, s);\n    i := 0;\n    for j in 1 .. Length (s) loop\n      case Element (s, j) is\n        when '0' => k := 0;\n        when '1' => k := 1;\n        when '2' => k := 2;\n        when '-' => k := -1;\n        when '=' => k := -2;\n        when others => Put (\"Whut?\");\n      end case;\n      i := i * 5 + k;\n    end loop;\n    sum := sum + i;\n  end loop Read_Data;\n  Close (f);\n\n  s := +\"\";\n  while sum /= 0 loop\n    case sum mod 5 is\n      when 0 => s := '0' & s;\n      when 1 => s := '1' & s;\n      when 2 => s := '2' & s;\n      when 3 => s := '=' & s;  sum := sum + 5;  --  -2\n      when 4 => s := '-' & s;  sum := sum + 5;  --  -1\n      when others => null;\n    end case;\n    sum := sum / 5;\n  end loop;\n  Put_Line (s);\n\n  --  Part 1: validated by AoC: 2=-0=01----22-0-1-10\nend AoC_2022_25;\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_25.txt",
    "content": "1=0=01=0=2111-1211\n1==21=\n20--\n1-=1200=-=0\n211==12=2=0111==\n2=-10\n1221=221=0-1=-\n12=02=-12020=12=01-\n12112101\n20\n120120=21=1002-1\n10==1-02=1\n1=11200001-=--\n1=222-1=012=2\n20===1-1102-=\n1020\n102=-==-=2-\n112-2112-00012-\n1010=--121\n202022=-=2-22=\n122==1=1020011=-00\n10212==-0\n2=--12020=1-0=-2=-\n1110-1-2\n20==210221=-21--12\n1=-02--=22=-122\n2=-=0=00=1--1-2=--\n2==2==2-\n2=12=1\n2=01=\n202=20202-000\n1=0-=020021022012\n2=0-011-=2=-0-=21\n1=211\n1-=1=11=--010=---\n1000020-12==\n2-=122-1211-0=\n10=2220122012\n2=21-01=212\n10111==2=2-12\n111\n1=2---2211=2011=--\n1--=0000=1-020\n2=02-=-\n1-011=\n12020-0=-1-220100\n2-==000=21=1\n2-0100000-12-2-=\n1-=1\n1221=2-1==02-=202\n200\n122-2-0\n10=2101-22\n1==-120-1\n2=2=2=-11--==-==\n2111-=2=-=-2\n1--\n1-0=10-0112-12=\n10=\n2=01=1=-=20=\n1=\n1211-2=-1=\n222=\n122=2-1-0\n1-2=20-=02122-1\n1==-=2===0-=1100--11\n12-0=201=10=-=\n1=01=2=22-2-1-1\n120==222100=0\n11=-=--12=2-1101\n102=1221=---0==021\n2-=-2=202-=-==\n100=1=02020-221=\n1=0=-220=\n1001-\n20==2==1-1\n1=2-2=2=-12=\n10=0--2\n10-202-2002=22=\n2=2=\n1-011=0=-12---\n1002220\n2=\n1--=2---111\n222==2\n11100\n1=0=201\n1--02-\n1=11-==0=021\n1-=00=\n1==12-20-=002001=\n1=0=-=21-\n1000-1=0-0=1=01-2-\n2==\n1-0\n1=101-0-1\n1=0=\n11=2==-0-2202-0=\n10-0=0=1-002\n1-=0210=01120-\n1112=2-0-2=-01\n1-1=022=21\n2=1-2--120\n10002--0=220-0-2=12\n11002102100\n11000-2-12\n120=-==1-2-=\n21\n11\n2=121-\n1==\n1=-\n1-=--2=-\n2=-10-=0\n2200-1-\n2=21-1200==\n1-102210=002=--112\n1-10\n122=202=201-=-10-1\n2212121=02102\n21=2-211=-1-20-\n101-=01-1\n200012112=\n22=21201=22\n1-1212=1-=1\n1212-==1=01\n22==--=\n1=-2-1-==020-10-=\n1=1210=--00\n1=--=1=\n2010111-00111-2=2\n11=21-0=2-01\n21=\n1=-0-220\n102-=0\n1=---0-\n1-1122-=121222--0\n10110=1-20--1-1\n20=--21220-=\n1=---22-\n2-000===1101=\n20-\n10==\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_25_question.txt",
    "content": "--- Day 25: Full of Hot Air ---\n\nAs the expedition finally reaches the extraction point, several large\nhot air balloons drift down to meet you. Crews quickly start unloading\nthe equipment the balloons brought: many hot air balloon kits, some\nfuel tanks, and a fuel heating machine.\n\nThe fuel heating machine is a new addition to the process.\nWhen this mountain was a volcano, the ambient temperature was more\nreasonable; now, it's so cold that the fuel won't work at all\nwithout being warmed up first.\n\nThe Elves, seemingly in an attempt to make the new machine feel welcome,\nhave already attached a pair of googly eyes and started calling it \"Bob\".\n\nTo heat the fuel, Bob needs to know the total amount of fuel that will\nbe processed ahead of time so it can correctly calibrate heat output\nand flow rate. This amount is simply the sum of the fuel requirements\nof all of the hot air balloons, and those fuel requirements are even\nlisted clearly on the side of each hot air balloon's burner.\n\nYou assume the Elves will have no trouble adding up some numbers and\nare about to go back to figuring out which balloon is yours when\nyou get a tap on the shoulder. Apparently, the fuel requirements\nuse numbers written in a format the Elves don't recognize; predictably,\nthey'd like your help deciphering them.\n\nYou make a list of all of the fuel requirements (your puzzle input),\nbut you don't recognize the number format either. For example:\n\n1=-0-2\n12111\n2=0=\n21\n2=01\n111\n20012\n112\n1=-1=\n1-12\n12\n1=\n122\n\nFortunately, Bob is labeled with a support phone number.\nNot to be deterred, you call and ask for help.\n\n\"That's right, just supply the fuel amount to the-- oh, for more\nthan one burner? No problem, you just need to add together our\nSpecial Numeral-Analogue Fuel Units. Patent pending!\nThey're way better than normal numbers for--\"\n\nYou mention that it's quite cold up here and ask if they can skip ahead.\n\n\"Okay, our Special Numeral-Analogue Fuel Units - SNAFU for short -\nare sort of like normal numbers. You know how starting on the right,\nnormal numbers have a ones place, a tens place, a hundreds place,\nand so on, where the digit in each place tells you how many of\nthat value you have?\"\n\n\"SNAFU works the same way, except it uses powers of five\ninstead of ten. Starting from the right, you have a ones\nplace, a fives place, a twenty-fives place, a\none-hundred-and-twenty-fives place, and so on.\nIt's that easy!\"\n\nYou ask why some of the digits look like - or = instead of \"digits\".\n\n\"You know, I never did ask the engineers why they did that.\nInstead of using digits four through zero, the digits are\n2, 1, 0, minus (written -), and double-minus (written =).\nMinus is worth -1, and double-minus is worth -2.\"\n\n\"So, because ten (in normal numbers) is two fives and no\nones, in SNAFU it is written 20. Since eight (in normal numbers)\nis two fives minus two ones, it is written 2=.\"\n\n\"You can do it the other direction, too.\nSay you have the SNAFU number 2=-01.\nThat's 2 in the 625s place, = (double-minus) in the 125s place,\n- (minus) in the 25s place, 0 in the 5s place, and 1 in the 1s place.\n(2 times 625) plus (-2 times 125) plus (-1 times 25) plus (0 times 5)\nplus (1 times 1). That's 1250 plus -250 plus -25 plus 0 plus 1. 976!\"\n\n\"I see here that you're connected via our premium uplink service,\nso I'll transmit our handy SNAFU brochure to you now.\nDid you need anything else?\"\n\nYou ask if the fuel will even work in these temperatures.\n\n\"Wait, it's how cold? There's no way the fuel - or any fuel -\nwould work in those conditions! There are only a few places\nin the-- where did you say you are again?\"\n\nJust then, you notice one of the Elves pour a few drops from\na snowflake-shaped container into one of the fuel tanks,\nthank the support representative for their time, and disconnect the call.\n\nThe SNAFU brochure contains a few more examples of decimal\n(\"normal\") numbers and their SNAFU counterparts:\n\n  Decimal          SNAFU\n        1              1\n        2              2\n        3             1=\n        4             1-\n        5             10\n        6             11\n        7             12\n        8             2=\n        9             2-\n       10             20\n       15            1=0\n       20            1-0\n     2022         1=11-2\n    12345        1-0---0\n314159265  1121-1110-1=0\n\nBased on this process, the SNAFU numbers in the example\nabove can be converted to decimal numbers as follows:\n\n SNAFU  Decimal\n1=-0-2     1747\n 12111      906\n  2=0=      198\n    21       11\n  2=01      201\n   111       31\n 20012     1257\n   112       32\n 1=-1=      353\n  1-12      107\n    12        7\n    1=        3\n   122       37\n\nIn decimal, the sum of these numbers is 4890.\n\nAs you go to input this number on Bob's console, you discover\nthat some buttons you expected are missing.\nInstead, you are met with buttons labeled =, -, 0, 1, and 2.\nBob needs the input value expressed as a SNAFU number, not in decimal.\n\nReversing the process, you can determine that for the decimal\nnumber 4890, the SNAFU number you need to supply to Bob's console is 2=-1=0.\n\nThe Elves are starting to get cold.\nWhat SNAFU number do you supply to Bob's console?\n"
  },
  {
    "path": "exm/aoc/2022/aoc_2022_xx.adb",
    "content": "--  Solution to Advent of Code 2022, Day $$\n-------------------------------------------\n--  $ puzzle title here!\n--\n--  https://adventofcode.com/2022/day/$\n--  Copy of questions in: aoc_2022_$$_questions.txt\n\nwith AoC_Toolbox;\n\n--  For building this program with \"full Ada\",\n--  files hat*.ad* are in ../../../src\n--  See also the GNAT project file aoc_2022.gpr .\nwith HAT;\n\n--  --  Interfaces is needed for compiling on both\n--  --  HAC and GNAT (64-bit integer: Integer_64):\n--  with Interfaces;\n\nprocedure AoC_2022_XX is\n  --  use HAT, Interfaces;\n  use AoC_Toolbox, HAT;\n\n  verbosity_level : constant Natural := 0;\n\n  c, sep : Character;\n  asm : String (1 .. 3);\n  i : Integer;\n  f : File_Type;\n  s : VString;\n  bits : constant := 5;\n  subtype Bit_Range is Integer range 1 .. bits;\n  stat_ones : array (Bit_Range) of Natural;\n  \n  type Set is array (Character) of Boolean;\n  group : array (0 .. 2) of Set;\n\n  procedure Reset is\n  begin\n    for i in group'Range loop\n      for c in Character loop\n        group (i)(c) := False;\n      end loop;\n    end loop;\n  end Reset;\n\n  type Storage is array (1 .. 100) of Character;\n  \n  type Stack is record\n    top : Natural;\n    s   : Storage;\n  end record;\n  \n  sT : array (1 .. 9) of Stack;\n\n  --\n\n  subtype Range_x is Integer range 0 .. 500;\n  subtype Range_y is Integer range 0 .. 500;\n\n  lowest, highest : Point;\n\n  procedure Adapt_Lowest_Value_Point (using : Point) is\n  begin\n    lowest.x := Min (lowest.x, using.x);\n    lowest.y := Min (lowest.y, using.y);\n  end Adapt_Lowest_Value_Point;\n\n  procedure Adapt_Highest_Value_Point (using : Point) is\n  begin\n    highest.x := Max (highest.x, using.x);\n    highest.y := Max (highest.y, using.y);\n  end Adapt_Highest_Value_Point;\n\n  map   : array (Range_x, Range_y) of Character;\n\n  procedure Show is\n  begin\n    for y in lowest.y .. highest.y loop  --  y axis appears top -> down.\n      for x in lowest.x .. highest.x loop\n        Put (map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  procedure Clear is\n  begin\n    for y in Range_y loop\n      for x in Range_x loop\n        map (x, y) := ' ';\n      end loop;\n    end loop;\n  end Clear;\n\n  T0 : constant Time := Clock;\n  r : array (Part_Type) of Integer;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\nParts :\n  for part in part_1 .. part_1 loop\n    Clear;\n    lowest.x := 1;\n    lowest.y := 0;\n    highest.x := 1;\n    highest.y := 0;\n    Open (f, \"mini.txt\");  --  \"input.txt\");  --  aoc_2022_$$.txt\n  Read_Data :\n    while not End_Of_File (f) loop\n      Get (f, asm);\n      Get (f, i);\n      Get (f, sep);\n      Get (f, c);\n      Get (f, sep);\n      Get_Line (f, s);\n    end loop Read_Data;\n    Close (f);\n    if verbosity_level > 0 then\n      Put_Line (+\"bzz bzz \");\n    end if;\n    r (part) := 0;\n  end loop Parts;\n\n  if Argument_Count >= 2 then\n    --  Compiler test mode.\n    if r (part_1) /= Integer'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: bla bla:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2: bli bli:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: \n    --  Part 2: validated by AoC: \n  end if;\nend AoC_2022_XX;\n"
  },
  {
    "path": "exm/aoc/2022/gen_jumbo_day_1.adb",
    "content": "--  Translation of gen_jumbo_day1.py:\n--\n--  import random\n--  random.seed(42)\n--\n--  with open('day1_jumbo', 'w') as fd:\n--      for i in range(10_000_000):\n--          for j in range(random.randint(3, 10)):\n--              fd.write(str(random.randint(1, 8) * 1000) + '\\n')\n--          fd.write('\\n')\n\nwith HAT;\n\nprocedure Gen_Jumbo_Day_1 is\n  use HAT;\n  fd : File_Type;\nbegin\n  Random_Seed (42);\n  Create (fd, \"day1_jumbo.txt\");\n  for i in 1 .. 10_000_000 loop\n    for j in 1 .. 3 + Rand (7) loop\n      Put_Line (fd, (1 +  Rand (7)) * 1000, 0);\n    end loop;\n    New_Line (fd);\n  end loop;\n  Close (fd);\nend Gen_Jumbo_Day_1;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Advent of Code 2023 examples.\n--\n--  Some programs work with both HAC and \"full Ada\" compilers like,\n--  GNAT some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject AoC_2023 is\n\n   for Source_Dirs use\n     (\".\",\n      \"..\",              --  For the AoC_Toolbox package\n      \"../../../src\");   --  GNAT's access to the HAT package.\n\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\",\n       \"Fast_Unchecked\");\n\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   type AoC_Styles_Checks_Type is\n      (\"Level_0\",\n       \"Level_1\",\n       \"Level_2\");\n\n   AoC_Styles_Checks : AoC_Styles_Checks_Type := external (\"AoC_Styles_Checks\", \"Level_1\");\n\n   for Main use\n     (\"aoc_2023_25.adb\",\n      \"aoc_2023_24.adb\",\n      \"aoc_2023_23.adb\",\n      \"aoc_2023_22.adb\",\n      \"aoc_2023_21.adb\",\n      \"aoc_2023_20.adb\",\n      \"aoc_2023_19.adb\",\n      \"aoc_2023_18.adb\",\n      \"aoc_2023_17.adb\",\n      \"aoc_2023_16.adb\",\n      \"aoc_2023_15.adb\",\n      \"aoc_2023_14.adb\",\n      \"aoc_2023_13.adb\",\n      \"aoc_2023_12.adb\",\n      \"aoc_2023_11.adb\",\n      \"aoc_2023_10.adb\",\n      \"aoc_2023_09.adb\",\n      \"aoc_2023_08.adb\",\n      \"aoc_2023_07.adb\",\n      \"aoc_2023_06.adb\",\n      \"aoc_2023_05.adb\",\n      \"aoc_2023_04.adb\",\n      \"aoc_2023_03.adb\",\n      \"aoc_2023_02.adb\",\n      \"aoc_2023_01.adb\");\n   \n   case AoC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n      when \"Fast_Unchecked\" =>\n         for Object_Dir use \"obj_fast_unchecked\";\n   end case;\n\n   Common_Compiler_Options :=\n     (\"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n      \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n      \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n      \"-gnatf\",   --  Full errors. Verbose details, all undefined references\n      \"-gnatq\",   --  Don't quit, try semantics, even if parse errors\n      \"-gnatQ\");  --  Don't quit, write ali/tree file even if compile errors\n    \n   Style_Checks_1 := \n     (\"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",       --  Style: check x:no extra parens\n      --  \"-gnatye\",   --  Style: check e:end/exit labels present\n      \"-gnatytc\");     --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   Style_Checks_2 := \n     (\"-gnatye\",       --  Style: check e:end/exit labels present\n      \"-gnaty2\");      --  Style: check indentation\n\n   case AoC_Styles_Checks is\n      when \"Level_0\" => null;\n      when \"Level_1\" => Common_Compiler_Options := Common_Compiler_Options & Style_Checks_1;\n      when \"Level_2\" => Common_Compiler_Options := Common_Compiler_Options & Style_Checks_1 & Style_Checks_2;\n   end case;\n\n   Fast_Options :=\n     (\"-Ofast\", \"-gnatn\", \"-ffunction-sections\");\n     \n   Fast_Unchecked_Options :=\n     (\"-Ofast\", \"-gnatpn\", \"-ffunction-sections\");\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Debug_Options ;\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Options;\n         when \"Fast_Unchecked\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Unchecked_Options;\n      end case;\n   end Compiler;\n\n   Common_Linker_Options :=\n     (\"-g\", \"-Xlinker\",\n      \"--stack=0x20000000,0x200000\");\n     --  ^ Absent that, GNAT-compiled programs using lots of recursion\n     --    die with error code 16#C0000005# (Windows, Access Violation)\n     --    - no Ada exception, no trace-back...\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Linker_Options;\n         when \"Fast\" | \"Fast_Unchecked\" =>\n            for Default_Switches (\"ada\") use Common_Linker_Options & (\"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend AoC_2023;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_01.adb",
    "content": "--  Solution to Advent of Code 2023, Day 1\n------------------------------------------\n--  Trebuchet?!\n--\n--  https://adventofcode.com/2023/day/1\n--  Copy of questions in: aoc_2023_01_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_01 is\n  use AoC_Toolbox, HAT;\n  --\n  total : array (Part_Type) of Natural;\n  --\n  procedure Read_Data is\n  --  input : constant VString := +\"mini.txt\";\n    input : constant VString := +\"aoc_2023_01.txt\";\n    --\n    c : Character;\n    f : File_Type;\n    s : VString;\n    first_digit : array (Part_Type) of Boolean;\n    n1p, n2p : array (Part_Type) of Digit_Type;\n\n    procedure Test_Word (pos : Positive; n : Digit_Type) is\n      res : Integer := -1;\n    begin\n      case n is\n        when 0 => if Index (s, \"zero\",  pos) = pos then res := n; end if;\n        when 1 => if Index (s, \"one\",   pos) = pos then res := n; end if;\n        when 2 => if Index (s, \"two\",   pos) = pos then res := n; end if;\n        when 3 => if Index (s, \"three\", pos) = pos then res := n; end if;\n        when 4 => if Index (s, \"four\",  pos) = pos then res := n; end if;\n        when 5 => if Index (s, \"five\",  pos) = pos then res := n; end if;\n        when 6 => if Index (s, \"six\",   pos) = pos then res := n; end if;\n        when 7 => if Index (s, \"seven\", pos) = pos then res := n; end if;\n        when 8 => if Index (s, \"eight\", pos) = pos then res := n; end if;\n        when 9 => if Index (s, \"nine\",  pos) = pos then res := n; end if;\n      end case;\n      if res >= 0 then\n        n2p (part_2) := res;\n        if first_digit (part_2) then\n          n1p (part_2) := n2p (part_2);\n          first_digit (part_2) := False;\n        end if;\n      end if;\n    end Test_Word;\n\n    procedure Process_Digit (n : Digit_Type) is\n    begin\n      for part in Part_Type loop\n        if first_digit (part) then\n          n1p (part) := n;\n          first_digit (part) := False;\n        end if;\n        n2p (part) := n;\n      end loop;\n    end Process_Digit;\n\n  begin\n    for part in Part_Type loop\n      total (part) := 0;\n    end loop;\n    Open (f, input);\n    while not End_Of_File (f) loop\n      for part in Part_Type loop\n        first_digit (part) := True;\n      end loop;\n      Get_Line (f, s);\n      for i in 1 .. Length (s) loop\n        c := Element (s, i);\n        case c is\n          when '0' .. '9' =>\n            Process_Digit (Ord (c) - Ord ('0'));\n          when 'z' =>\n            Test_Word (i, 0);\n          when 'o' =>\n            Test_Word (i, 1);\n          when 't' =>\n            Test_Word (i, 2);\n            Test_Word (i, 3);\n          when 'f' =>\n            Test_Word (i, 4);\n            Test_Word (i, 5);\n          when 's' =>\n            Test_Word (i, 6);\n            Test_Word (i, 7);\n          when 'e' =>\n            Test_Word (i, 8);\n          when 'n' =>\n            Test_Word (i, 9);\n          when others =>\n            null;\n        end case;\n      end loop;\n      for part in Part_Type loop\n        total (part) := total (part) + 10 * n1p (part) + n2p (part);\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  if compiler_test_mode then\n    if total (part_1) /= Integer_Value (Argument (1)) or\n       total (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & total (part_1));\n    Put_Line (+\"Part 2: \" & total (part_2));\n    --  Part 1: validated by AoC: 52974\n    --  Part 2: validated by AoC: 53340\n  end if;\nend AoC_2023_01;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_01.txt",
    "content": "two934seven1\n8825eightknfv\nsevenoneqbfzntsix55\nfoursqpqvv192rdrbtcccfourone\n9jpzhpxqthreelmrnlhfqmn4\nonedpsckg3xdhmgtsixthreefivejlncszkxeight\n4twofour\n7eighttwo17fournsmrznntgjrdpkdjvx\n573\nninethree3\n3gngzkpkgrf\nqeightwo2xjvfkfiveone\ntwoonej26\nsgoneightfoureight5sevenjzsqghg\nbnrb36xtjd7four9\nthreepprhsff3prbpfivesevenseven4\n38sevennineninemnfzklttkxnine3\n8mllzkfqklhonefivemv4\nonedcqlqcrzn66three\n1fourjthreefc2gbtbdzsix\neight7two4258\n4hmfzdzf\n26dsmdzznm7\nplckvxznnineh34eight2\ndhrvd4eightgxznhqmh\n5fxhhkghvm3nineshpcxhtwo6fourhrktpbq\nqklhmhmdlgeighttwoonetwo52five\n86threemmpchhzdvsvxfzrj\n9clvchpgrslnkhdmfkjmlrvgnf\n8ncpdtspfivethree\ngtbtkqcgvh8945\nsevencrkbt3btljpdpgstlf\n8nine37bpkmtghhnc2hnreightwohvs\n5qxmsrthreempcmpdcnnv41\n8threezrxhxgx4g\njhsb3onep1\neight71rnz\n7p16lrxktlr6\n8one5fivelvdbjzz\n1nine2twodhnineonesixkqfcbgdlfg\nfour8sixfourfive\npjdmt4one8sdsdhhqxlqgzpk6qrtdvxm\nsixzfourkdpmnn92qbjkjqfqpn\n42threefiveh\n5fhgzt8threemzhblb6\nbbc3kxhvbfrn8four6five\n91fknhthreefour\nsix9fttmqpninethreevhgtrxklbvxbljsp1\nfour5five1471mtfv\n3bjkggcntwo3ptmjhmthree7\nfour2eightone\nthreedrzktlgbz4five\ndmpgttqfivekcdjbf49six\n9bplkkgrxgjqjqb3seven\n4861sx4six\nhjzmxtxvxkkpbvgpvmgb4two8bqxlvponesq\nlkxxtkctlphjfivepjlrg1\nxszdbbvxjrfxs2vrmmbfourpzcfmgppk33eightwors\n966fourflbfsk3\n1bskshtjseven5qlbjhqgzhbzxvlxsvtcmmzseven\n56two28cbhfsdcjsix2four\n6s5qcmvjltqeightslhnzmvbfvcmxj\ntwosevenjxk6lhrkknnkq\nkjkj2lkkldqbgzhglmthree9\nftxhnpms1onetwoxg2\nthree9sixsevenmrgggztckzgzv7\nstvgmjgnine2vvsnjhlzkstwo5szsbvzjdzb\nv6\nthreetwolscvhrlmm3r\ntwo17kblkphfninefour6six1\none6fiveeight9sixjzljjfknrhkzxr\ndgpqm43xthreekxgspjzrzcsix\n2two8fourpppb2\nfiveseven5four\n5rttwofivefnmbkn8nine2eight\n43threeninelgnpzrdtbc1lbkjkvqrdcd\n1seventx\nnctwonefourjzgskmxjmq2\nrpzpht2tdxczzfthreeseven\ntwo1seven\n6bjztkxhsixkgnkroneightht\n9mqzkgmv4vxqrpf4\n49hlj\n46gv\n75sixfddn75\neight87xzjkdpnnjjfqeight\n9pfcdhxbcrnpsnmvkqnsqsninedgtlmmc5\nxmfbn34\n99lvrrndpqcnhznn\nqsmxhxfph24three\nlql25\n8five1dhrkm\ntwoninefourcxksqfmn1\n7eightdclrvn\none2seveneight3ninemcpnmonetwo\n33fivefivenftbczsdstlxzbp\n9r97five\n5fivessskxvnt6qqbkkqrggxg9gsdtbptpn\nthreesjdpjdkczjgthree6\ntwojqm86\nbttrx15qfznmdncnz5\nppckphrtzhstd3xvthzrxxlrrjtk\nqkm6ckeight7gnmqkltz6jsrgjhbck\nzdjjjlpmjtphbjpm9threeskqrphxbfqqeightone\nkonesix1three\nfour24391rzxtffour\nhsevenfive36fqrbjpfj7\ndxdcssixbcnp8two639\nhnvg2\nsixeighthmqkjjsix6tbvdhzone2vsn\ndfzlxq7pjmq5\n5n3\ntwovjcgxdsdngt2smfxfqxeight\nftpjlnvg5qshclfzqtc2eightninefivecsrgk\nzzgsjsjffpvcgfmjtnpkrsqlmpzlt9four\n4btrhpznzr8oneightg\npph2one\n5seveneighteight\n31sfrfrcgmseven\nfour7bdqgrhfive3\nnbrzbggpseven9prthjvknq\n3sixonefourh\nfourgkrpkzdmhtwoseven6txplz\nfour84ldbhnkxjph\n6eightonesrb\ngnmckftk62jgsjxzpk\nbzctx9onetmcnzhxkrtchjgqxv66\n1three5\n27two\n34eightwox\n6ndgrbmfkfive2ksxfbnjbl7fkrm\nkxpz4gjmgcgzzq63five\nnfvmfrbc151one8nggsdqvm\n4clnctseven5nsn5\nhcrpbvqmmdbstlxccthkththreebm6\ngdnmh6cslzhjhdl8nine\nsevenninethreefive4bgknpbnine\n2sevent6three1\n2jbrmdxgpnine7\nnshlgtbkmcmgkmqone3\ndklhc9sevenrxxzzxltsnlltqcjrbgprnx\ngmrjhlvzppmklnl39\nkv86eight3dcdpp6pmdzcvsix\nfiveseven2sevensix6952\n3xrtthnsevenjxsxpzvc\n256nmzrlzbczv\n4dp7onesixvpcf\n25onesevenonexvnst4smvlfszcrv\nlcxncproneseven37five\nninezjsrptfivenhsqxrdz7one\ncscdmnfrcxfqdtkmhkldgjlxdjqsxslhdzvvt4\nsixfnjnfkqm67blkmnqtwo\nfivethree7\n2five5ninegcmqbkpp61npkpml9\n3qktrxninefour\nqdhmxstwo44two\n21nine\nrbnineone3xppvtbmv3sevenvxkkgmgklg\nmcvzplmpvptwo38\nsv176threeone\n5vksixqsccgdkrrfourcgnpsfxbvj\nxxtwone6eight\nthreeonespkbnsj9onesevenpz5\nfivenncrfvhfdsevengxzkxbkrklgsfvllrkbx4\n69kp1seven8dqkrx\ndmb9ccghdjjpjxfivehtwo4\n6nhgdkpdone\ntfvqdqdqcszxbrdmmrninesct2\n8sevenfour2eight8rskc\ncpmgffcvln9sjdsgfivesix5rppfsfmmqtffive\n5two7\n7threecrkljthreetwo\n6qgqzsdhprd\n959zgjscgtm\nfourtwoppfrdqgtseven9\n8bbchvoneeightr\ngtddrb1rznsdjtonethree5four\n8rrskfzlmlbrsninezdzpt3\n6njhmkpp4onefive8two\n4cqpnkcxjtwoqzqmjnqccfs256hcnqpfm\nnineeightseven62sixhlxlps\ndtqplzzf87threecthree\nmqptgzjxddxgxpjr5\n9194jbjjktwofive\nfive514foursevendzxlh2\n6nineeight85zvx\nfour8gsgrstfmdv99hpkfgptzqkhsmgsnlggrseven\n9three298\n3fpttzk35\nrbtckzonexkqmfxrnsbsrkqbq66sixkcqfzjfour\nsixkdcrrrppcsix399fccnsbhfxvfiveft\nxfjxbfvmbxbf3twokkcfrbcfbmkmhghsbzf\n9sixonesix3lqqf9\neight3fourgcmp\nxjccxkhkvgltzqslmseven5twoqhcmpsixeightnine\n62eight8\nhzhccdkxb336\ngcsbmkdfmqvxtfj81\ntwo445nine\nxhrkgql8six41nine1\n5dnlcsjb\njdqdg8gtgrctwo4fourthree\nfive4five\n3threecggvthjv6\nsevenzrjzqhgtvtqvkp3three5sixhxdmfour\n2249eight6\ndrt5trhdjqf3fourfourkfour4\n5oneone1\nthreeseven5six\n45bclsgsqx\n6ggfjqls\nrhpmhfournrzg418onevlkcxxdrd\nfcvgszpsixthreegqqctvdqnfrbnlbmknlvgfour1\ntwoxvrhmxjbbn2eight\n27eighteightsevensix6six\nveightwosix54bcvvtcgbqfzprp7four2\n9kthreeqntgvbb34693\nzxcdmfg48ftlhk\n1mhcctbmbzmfivefourtwo3\ntwo6vxsdfhgstslsix\nthreesixmzhvfqsix5xhrhrvsfh7kpcrsp\noneggkztrmsgrthree536three\n7seveneight81ronesix\nsixllrjlqtffqvtdjqhctt66four3twoone\n2zxqpgmgz\n7rfngpqkqgfivetwojf\nvvbfnnine3ngv\n59sixninelmhmqchlthkbpthree33\n1three6seven1seven5qntpbnsfour\n7nfzfsdxzfive8fjvllc4\n56seven5seven\n1fivegqbrdgths\nfour32vmhvnk\nhvdjnmpqvqbnrcrclkgkrfseven6lgrvthv\n28xngctrvmnc4ntvxhmxfsj13\nonep1onecjjmxxtd\n9eightwof\nhzgmtfdj8nine7seven\neightseven3\nfivepnhlninefive1lcftks\n122ninelrgmdgmqzd\nzjsix3\n7rffvg9hbjpx\n3h76\nfouronessbhxlcclkzmnnbksixlcdqtf3\n4fivesix228five\nsixrlthree1bzhddfbkrgxpgxfivef\ndxgqnkqfgq8\nonemcfourbmkhh5px\nfmtqjcbxznine3three\nqzkcxvnffg1gmhplhlffgtwo3onevg7five\ntwokj7xv63six\nfour58\nfvjeightwosixrbrgnmrrmdtwomseven69seven\n5fivefour\n6pg8twomrqfzkxrthree9\n7xqtqfrpprlvhnthree\nl35sevencreight4\nthreechpctdgtq8fxspqtnvggkxtmeighteighthdgngnmc\none16twosix\nthreetwofour3eight1pvgcthree\n229\nngcnthreeone7hqbbntqxeightkgtc\nqtgkz1ntone68\nnine2seven\ntwo1jjccnlrqlsdfvtgjmmhh5prfpcc\nonesixvtbjgdqmtg1eight\n77qkvdszsp9ctqndxzrjc\nrnldvcmks74355\nfourkljgznpqntwofoureightlc3zmljfnqnr\n8threetbv6cdjjbtmmxcfour4qlqjql\njfkvbvjxjzk7\n7eight8vhsdrd\nonezdgffrmz2\neightseven8\n7gjdsevenjsdkljn2fv\nkmst4\n3five8smctrhdhfninelzbrszmbdm\nfiveseven4ninevdfive3\n8jg6nine4jmmsbpbnskoneqxgjrphhf\nmgfourfour3hgmrzkntjm2hxrrfsghnone\nninecqmg72\nldthtljblpl3fiveonervtxnxczfx2\n9sevencsevennscmbjgthree\n7lnj9four\nfgtwonexmkvkcgpq36sixsmfnxjs\nqgmfmnh6twoeight\n56sqrseven\n183877\nntt1seveneight513\n7three6dzdrs\n8sixsevenfour\nmzfhdnhseven4eightvjsdnxlonenfzlcxr\nsixzdczsbtq29one4eight6\njmxcbmktjzeight5fivenhtzfsdqbx\nfour2rvlppone258\nfivezvlqr236nine\n262\n58six2nineone5\ntwoeighttwo3ktzhmdvlx\n64nsjgqsqkhfqmfk\nfoursx18\ngklzjvvv93zzmzgpn\nonenmcvr6\nqsnmlbmlr6\nsbtwonesevenfourhgltwofzhzmbsrfm6two\n8fdhxeighttpcjkkmgsgnpnvsix2eighttwo\n5pvxnxxdfourfour75\n85vtsgkn1kfzkszmbld4cpgrqsfive\nsdbzkzp1dq5lk\n28161twodfznxckr\nxfpgnrlfour61\nkzkkp65qtqfppc7f9\ntwospplzdrdfvsixsnldtwotwo29six\n9fpbm\n3one83dlvdr\n9rvbtwo25sixkzlxfkg9\n8jbmfbfsxrnxk7oneninesix\n3798\njhcqmfive9\nnine35\n596\nnvzztnine2vhhchqkzfjzmkgjbzlxhvtdhddnr\n5bltnjlmt12threenh2\neight5sevenninepgxvhflb4eightmxv\nxtrct7fournfivefourfive\ndhbpsnpxsglnt5vsnclxhnntt61two\ntwoonekntsmsd81fourfourfive\ngpnceightdx5pklsp79x\nfour5fszlnphhxvhgbmfcdkdbgbc7\nxbxtjllpr9threeninesixbbtkn6\np7\nnine644two5\n5zzzlmspbcx9vfdllvqtl8five\nfour2bxmrthree\n7rhgfnzqbpgmpnfz\nthreejhfmbmxzp469\n74ninebmtpfkzbcg5nine\nfflpg34two25lvnmxvqlv\njtqtnthxqflp2onesix39\n9sevenninefd8qpfiveseven\n28mb5\nlflcphkxqqnzhd2five\n3seven4fftnss\nninezxhxqxxpblm9\n4ninevgpmxxmqlf8\nsevenfiveonesevenfjccpmnnninesix3nine\nqmkvt6pxbdcbrcsrgppzptzchkmone\n2sixone\n6dzskdbknpsix\ntwonpqfsvbmqgeight23ct\n4sevensxdzsfbmmmdrdjtpbh\nsxkpmmhsix9five7\nfnxtgfrltwo67threepvbsixzvj\n54jmvmdbkltqsixtmccscsixeight\n6fivefourrbshbc82jrfm2\ndhlpvhzhms6\n419bhbcdsvftxfvvkxcxprksjs4\nsqrq17nine\n84rjcbktz8hrplcqsvhqqnnqnsevencjhone\ngkmljdk2dgrlptkxdsix3four599\ncnjpf818sevennine\n8cvg\n3jqbbpfpxmpkrhfoursix\n9zkrhbmzkbzlcnxlgdsixthree8\nnine9kvxeight2zqvzhgjzjz\nfourbglmlqzgvzhjrmz2nzqxlqseven\nseven4five8nine44eight\nonegnine6\nqeightwosixfivesevenzmjfrqvnsbnqlt7four\neightvrshp9xnxlgqcnninegvbj\nninelpbvs9three8ltzvxnd4\nnmnlzone3grqbzcdnpxsbcbzxn4fjptnsrqsqgsdcv\n18fourcqfive1gccxg\ngfglone6bqsqjmlftcqpqmmqmglskzfourvkhd9\n5cxgkn1g\n29seven9ppr\nfiverkmhxvnbp3lvpeight1one\n77four5dsdqzvt\ngvvpbone23\ntwolrjs56one\nsix2745six\nkbxplzpsixsevenseven5one3\nthreexzrcfgffkjsix9zgdseven56\nonetrqcfl6\nthree23nine\nfour2mv\nxzfnzkmeightthn6twotwoeightqmf\nhxxxldcvj99three5qgmllbtrsq\n6zcszjbrzjpgrvfivemnzkpbq2six\n6zvtsixone73three\nthreeflxtwo5fivefhbjptgfjmgbhpmbjmsv\n5nineeightfourd\nfive26five7sixthree1three\nfzvsixsix3mxxhseven\ntwoccxdqqkdvc2two9ps6threefour\n447lkkoneonefour6rx\n8seveneightwox\nsgjv21\nsoneightkmtps8onesixvpsdcfbbz\n8pzrtoneffhg\nmmzeight631\n5fonefive\nfoursgx8fiveltczmccpzx\nsevensdbhnpmjninetwovlv1three\n64qrjdtpxbxdbcqmmlqtnine6sevenfxhcrjnine\n1seventhree\nktmfour3\nfournine8skzxtftwo9h9\nbjq8\nmrshhhzsixcxsxxmbh1bone9fivelsplqv\n7threezvgxdvrthree7227\nznnvfive5mctxdfive3j4\nfive2three8\ngdtdqc9nine1\nthree3eightgnsxrmbmxld9six\nzsgmcpxxvseven7onetwoseven6\n8n3919hfiveoneightf\n3rfrzmlfsjxthreefour\ndnnshdvxdl6onendg27\n66lpbz\nsevenlkjpxthree5\n8clqlplvljone5hfh81\nfourldvjsixfourfour5xrmcnf\n9nine2\n4one1\n4vzjgncrztvstcf9one4\nfour37\n4sixlqpnqxqtrhpc3\n8threejzg\nznxccm8\none8eighteightkcvnqjpsp6nine\nfivesixgc74oneseventhreesix\n5twohshtsdtqk2\nhzmchfourvzjgnt2threetwo5cgfld\none9three836one8nk\nssslsdftjfgkpzkln5\nxhsxxkzk1x2tzbjthsnsix\n8nineeight3njq\nninethree5eightbfour2\nfive56sixclxjqsjseven8eight\nthree3cninenz\nlt3onevpkgsixsix\n4pkbmgtwo6zmvn71eight7\n2eight6cdd83\n5kvp3zhzq\nvtcmdkkcmnmf1two\nnine2nponeoneseven\nxm1twofoursevenfoureight\nggkvsljtddcmznlxlqb4one32oneightppn\nonehdq785\nvzthreezjbdrlvhglbbcvlfk5\neight9smt1sixsevenckqxlbvdzone\none7fdcbzjtfhbps9oneonetfftbneight\n3sixfgqbsngnd1zmqbxfllbp\nroneight28one8fpzmkhvdhbqlrfive\n4five2four453ttlvfqxb\nfive2four413hhnts8six\nxlfpxbzrbphb3one\neightone8nineeight\n1zprfttxqmtbhzckcfoursix2threenine\n7sixzqrjxn92pnbfxzbrnmvrnpjpdone\npvlfeight1xkgrvczlcfvvl8kzcktkjbj\nfour7phjzlzn3two3two9seven\n1tkcdvdtj7nqfsrnmfzghmkrqeight\n36fourxfdgrprrdgmjczxb\nfive5fivefdkgnkfgd5\n5seven5sxlkbldznz53three8tmkzlrt\n8dkxkfvjkprxtjlh5tjvjm2glkpbmhjd\nseventwo3\nbgssljzld2one5seventhree4\nsixfourrqzdbdhhhc7lkxqbtsseven55\n6threegtwo7fivesrbvfk\n2mpxkrtjphdseven\n14seven9dkk\n85dmtjqkchp7two4\nhvqfbchqhpbggrqhf4ps\ndzdknbdceight72fourcmfvsrzt\nxmvgjjfourfourmjmkh5onefive8\nqdfreighteightninecdxrtdbd7\nmxlhxlbvbndqfzmseven34four\n432three5vqhmjzgvghnhhg\nghczftpkttwo4sixoneone4brf\nkbbzcpsqsl7qdlgff5fourfive6jk\nv8nxzpjxntcbtwonrcgztsthree1eightpfdsp\n7zjdzbnrpltfivemgcsjzrdjskhfmbgvlr5dl\n9kpbzzr\n8386six3mzh3\n41nineeightfive\ntwotwo5threebvgmmhqrlqltqmndhveightsix2\n58drxrgkklm\n8two48six3sixthtwo\neight88msfnone87nine\nfour5lvxfhktrconexqzqvl\nsix8mrlccbeightonejnzbdkm4one\noneseveneight366xzqmnmfvvrph\njoneight7nine7five\n5fourtwo26onefivegsnbcjj\ncpjnvhnzxsevendbnblfkpx44lzn88\nzfmdcsfkktwogxmrsbtwo2six78\nninetwo59foursevenoneightsx\nvjbbphb5dddvksevenpmnmtjvzdvxkkbcqxbb\n9ccgtrznm4\nzplpfivesixkjfdvrv6rfmqk\nhfxhpsxgxjfdbfmjb6one\nthreethree9\nsix3seven\nseven286\nbnkrghgbkzdz29two31\ngvlzrhntvseven3\ntwosevengdkzgv6\nrddtz12five9znvtsljztbztprthreeszkfhh\nnfivesevenhfpklnxqb4nineonermtfsk\nzzz2onegpthree4fdnqxrtcnh8\n4xchnsevenxnkbrdpzsnine6\nhveightwofourfive8\n8one3\n7chfpsbh1two\ntwo2eight5gchbxqvrmdfqvghtnjssix1\nzfbeightwo3\nqhjnfxpfoursix9five\n8fourrbrrjqqph\nfive5threethreezfvskmsv76\nsixvtjnktt4\n5cndcht2fivebdnxcnzzmfninenineqzktj\nqfzclldsvzvcdqfxhtqqtknine527\nonefjrmmfqvgnxnjdtkdmk25zghnp\nhvddcjnoneeightnine9eight\n9lxpszk\n17fourfiverfnbmkrxlvone\nqxvdlrxq89vf\nqeightwotwo2\nrzmxzgnzljzssnxscvv9seven2kbnineseven\nsevenseven8\nrkhkone8four\nzn68\n5pvfjmjxthreeninevtj88\n51dtwo5ngvxnmjeightgbhzxbd\ntwo6kxkvscbxcg34six3\nqbn1\nhgxgtwoqtmsqbv3\nthreethreejmtjk18two\nsixone4fourseven6zcgpdqps\nfiveqptd8gtjfour1twothree\n89fivefive4\nsixvnvmdmfeightcbbvbrkffqstwo7\nthree4fivefive5klxvsbhslzsix29\ntwo9sixhncrcvxmf\nrsp146\neight2jtvps\n7four6\n77p1znpskm\nbbdvfhqmxddlsvdpmtvctnine135\ndlclxtkxk85bn\nbxbjslnrfk6\n51zfrtvmcbkkrnd7\n27fivetwobbssnklg\ntwojxdksqkm9ninejninekcbdgnsq3\nnineninebsbd8\nsevensevenggddbfxqrmonethree744\nsrtbzcbsmfivetwothreejvzjzxqm1tjnjldcxnine\nnbsix32\n25144spnmfvvj1dxpqmhsldk\n5two4mrqnpxzs7foursevensevenr\nfourk9zszmnbvmkdrz\nlpqseven2seven\nhcjgtjcxh1dskx\nssrnf2ninenine6ngbhfhdqsnine\ncz82jhmgn14cktblcl\nkxjzflkkbx53nine62one\nhbcnpbmfour1two\nckjksxthree346pjtr\nccslpmqnine27twodr\ncptwo5twoggmrjvl15eight\n4vlktln5kqfsnvrbjbszqzclmnkxseventhreefive\none2eightwopp\n2sixsixone5\nklvsngvv38tcxvhpdhh5\nfivefllgljkdg9ndlkpbmgbrndqbpxqdk\n7ppkvstbtnvseventhreessd1three9\nthreepnrcmb3\nthrqrcmzpzt7nine1three\njvgrqgbcshhlnqrl2vrlppxbnjfrdtwofbsdvt\nrnhninezxbrlmnlczqnneightsix9one\nghvqdxkqqfthree17\ndthreeseven2\nrkxfthree7nmfive6\n6vhnh\n13brdgbrdsvthreethreerttfkr\nninelgfdc7\n88z9vzscqthkgnhmztjnhthreeseven\n1nine3mtgrfive8nine1\nthh5fivezfmtlsnvtdkfour34\n26six6cbjdssevenq2tl\ngxxnhsxqvjcvssrbrhbst6sixvcchxstbpb1ppqdbx\nvninexhkjkmzvhfpvcd7ninezzldthree\n2twozknrxvcsj\n3193spfourxcbdnf\n84six4vc1eightsix\nzljb46four6six\nsixfive2seven1\n1fbmq9fourmhbzzkhctp6ninenine\nonefourtworckjqzhqseven5seven\nfive973knlxmtmdone8prtqlsltwo\n2ncgbgpq\n3eightthreepknbcs58three6\n6fivesrgqxhnzfouroneqpmgpmzgfoureight\nmphrj33five\n8sixfives26sdscdjtpchmh\nfour64mtlxmnsjbtdkpmf4\nonefivenine9nine81two\nvfc9nqttbmbdkonegclxcgbxkx87t\nsqnzdrcs8sevensix6sixdjcmk6\n7npppqmrmblzjqckk8fourbpxlbtwonine\nnbkklkvpl2smlqbh\n37eighttwo17fh77\neight7ninekkbvtwo\neight18cmzzdpgl5\nsixdc17nine9ghzpdpnxcbxvztcrd\nfourfivelrmch54\njbqbpzxbbdfiveeight9jnzfdh5xfmhhrkrkds\n146two6fourclmcllhl\n222dqgtptqqn\ngvhninesevenfiveonefcvnlmfcvjvf5\n9xgljlphcxeightfivehpdlfrmd1fmqhrnvbzboneightjd\n8sf3five6eight\nzrprbc8\ngqb6sixninerpsrpnlldteightgn\n2jdlxzk\nhfrbqn4zbpxqb81tlfxgxdvzz91\nqtdnxgmjjstlc1nndsnbbcdm6nine\nz7twonezp\ntwo17sevenljskthntjzxpkjrkc\nfivelvfive948\nsninehxqlkmv7oneonedbdvztzgh8\n2fourxcrkrcvn\nclh4four5htj\nhdkx4eighteightsix1kgtbb\nnlbsqhkltvmzs2njschfbmsl3fivensztjtwobxkfn\nfnrg3837five\nvxcldjmjxxcqntqcqnninefivestbbjvptfvkbr9onetwo\n4six7two\n8five5sevenslfqtblfiveone\n26ninemhvqkjgcvflplncfsixtwo\n7eight523\n9fiveplfdp1qhqhj15t\nthree3eightrzvccr4h\n9vhmkkjfhtfjtwotwotkfvlhvs\nvxoneightczdfl4\n3one2\nthreeeightfive2four\ngksfxtb4\n1jjgdldklznbktwo59\n761sxvprrzj2kxsmlmtpbqseven\n681q\n84ctsbf1six\nfivetwomfgplcfgfive7one1vgbz\nrfnqnnmsdcj6foureightfjfkphqpktwo\n9vntpmfsevensevenfour\n7zvchbn6two9five\nfourseven7\n2lvtkkbhtjeightfour89\n5nine5threemgsd\n933nxone5threeone\n2dtbbmghgxvkmtvnlgsxjlgbc\n1mcrlzhvzrc2\nftwonegsndgxmbzn6one\n916vfvzvh8twolvhvlc34\ndtk7eight6c6\nkbhjg6qkdgh8rqlmstq4\neightseven8\nbhlhcphznb92two\nq8d\n375sevenvhrhkbtbvncmqqmpxdhqzzggvr\n9onefour1nhmjb\nhqckpzrvgmgqjmvsrjhqx8twodgxkbh\n5grdsbtp6onezrkdvpdqt2\ntdgkr4\nfoureight24\nktds45zvjd\neighttwo58lldklbmxn91fvlqllnxl\nthreefive3bdmfbrhfklhxjvdgjxbp1\nhqpfgvk56oneone8\ntwo32fivetwo1nklfhjfffthree\n77jggmjkbqone\n6fckfqeight\nfivetwo8\n7five7threethreeb\ntwosvbzfmv1fourtwoeightsixfive\nninehninebgjnknth5bhzqlvthree6\nonefrdv3one1\nfive35\nfour3three3six9four55\nxbssqpvjnine9six9threefivetwomjdvmpxrh\nctroneighttwofive3npxgbhfsix1rjnl\n8ckbzlmsbfxdn\n51gckxqqbnkntmvx1ltfmdvnlcjnine\neight7gkql5\nsixjghxscppnfive23284\neight7pgqxvsix\n46eightrjhgdmvf5\nfour4bmjzzjqp1rv523twonevm\n3sixseven81oneeightwocr\nsixmmnqkrfplg7ztrpsixone4six\n1sixfive5nhrq9\nsix8threeoneckbvqc9mzhb6nine\n33sixdfzmds12jcvfour6\n1cdlflvqhrkqpktdnnsx7six8eight7\n8four18\ntpfourvblonez8six\nfourone2smjpvclnine\n99zdtdpbbvhnninefourvzfmzbscdldhxtcjfh\nfzjeightwoeightnineseven6\ntwonine2\nfourseven1eight\n2x3one\nqbjc1jtnbpdbr2six3\nsglmt84five5nine\nsixnljjqh4foursix\n4nxjgs79six\nlhkpzgzjr3z7\nonefourflllxbtkpvgfive2\nsixrdr1twoeight165\n1dxvjdhzb76915\n44pxzzttvdc185txvrpxq\n4fourfgllhzfz\nnxssptkdldkpchnseven9522nine\nnine7fivefivefffvqpvsqzsvnvlzfvfs2seven\nbzphzhgf2xrlqjgonefour3bclmhtlzbmddrq\nvsxf7eightzzndgfourfour\nrqbhb14eightthreethreevkjzhjlkcmfive\nsbkrlm3nine\nzkzlqfbzscndtlmn14four9bsscd\nsix33\n1gbcgnpfnseven7plppdqone3smljtjlkhj\n9jsmdjshtzm92stx9onesd\n51four4two3one1\nbxkpcpcntkflxccsixseven1threengtrrp\n4dsdllkqnpxglbseight\n7threetd3onefour\n3vcnzndxfhfzvncfivefllrqvndtx964x\nnineeight1eightgqnzfhqkzgvfvctwo1\n6fourthreeseveneight\neighteighttrhtplssvjnnkkreight4sixoneseven\n43hqrtctwotwo\nkcxfvhjksix3six2jbkrlmtwoseven\n43sevenpvqh9eight7xcbvnckrkshdx\nsixfive3745three\nhmxfmzqdpfzjjzdxsix8472qcpbrsgx3\nthreelnzgs96five1\n1dftdbtgjrpfive3cztvmxkcxh\npmrfive4jxfxq1\neightclrzz981492\nmscl2eight3\ntwovb8four7sevenfourkmzpdmpgxj\n59onefourxnmptgtcone\n6gsvxlbqspvzpsq\neightthreesixtworcmpjkfvnsevenseven1six\nghmflkhprkthsix9\n441fourfcvxonefourhg5\nfour795seven\ntone11\n22seven9two\n5seventwo2\nfiveone6h\n936sevensixnine1lkp\n62kvhcg\nsix19\ntd25\n9two2four4fourmeight\none6twosevencrthreeseven97\n1kttqbqkzvvr7265six\n65rzmfpfqjtzb11m1eight\nseven1rrhpxjqtp\nplktlvxkpkndhx66fivefivexkh\ntttwonefournine9oneonesplmp5d\ngkbl1fbn3two97onetwo\n1seventqngll\ndqfiverscjjrk7\n4sixfour4onethreecvbj\n24x6qhgtsxtrfh\nh6\nfourfour3three\n8hrdbnvxgndthhpmrgm\nggzjfour8pxdlpx\nrnsixnine9fivensxfzzgzlseven\nsqzseven7\nrcpkzht5\njxhtrkzl7eight3eightn68eight\neightfive24\nkgxv7kclnsscsmqtnmv\nfoursix2chgckldprp3zqntzscxfc\nsixsixfourone3tnbpxbmgqccncgxxnine\noneeightkgsbdthreefivepvrsktvhrnine5s\n4vtpzghfsj\n7four1lttzxpzcbtqqdthreek\nfive76\nvlqvvdhhnfzfssvthree3ccsdjhgc3seven\n2nine8six\nlddxjsczqkd26g5jpvdlfour\n1twotwofcl\nsltfz55knrfvhhbbeightsevenninesevenfour\n27155bvv\ndxjzmftwo2vnljlsthree3three\ntwoqdpzhjhbzksix49dhdfq\nthree2fivenineqbxkgfivefour\nqnpsfq8twoonevsjffive9\ngqvvmhxgx6gdsqmgccrmzrzltwo81szbnbkxt\n2one1czgjvtcgxfivenqsfourthreethree\nppcspzrnnssvnht9hdfoursix\nmmqrzdkmt7sjqgsrq9rhxpgpsixgkjflnht\n57foursixfive4fourfive\ntjrfj3qldspjklvdtcb6ninefivejmbntcthree\ncgjnhsixsixsixfive7\neightqdqgjppcfive7fivexznfsmtk\nfivefive864scrf\nsix95five17threeslktfgd\n77mrrjzc1cbnkxfkxcdmxsmtwonet\nsxmsjccjrseven45\nkjpsn1eightccctxthreevvffseveneighttwo\n5twoneqr\n3threemvlqpvhdqgtqseight\njqrxrqlz93ninesmppvdhtxk5five8\nthreesixsntqreight593nine9\nfouroneznpfive6qmn8\neightfive3sixxrrjgzlb\ngds345twotwotnjrnhjxdz\n27nprk7\neight1three2onefourcfctvmhnqlfour\n1fourvjgkpdrsj4kd2ncd\nnine85ncsqbrmdtxbtrjxgztq\ntwonineeightonerdnkjkrbpsbzcpone5\nnine8lkkvxfvlsixseven\n49three9\njqmzthzjjseven5\nseventwo9z7four5twohstlzjx\nbzvbvsix7\n2five4\nfourthreesevenfour2nine1fivezspphbmjv\n7skjhonejhklktvzjflnineonemmgvnnine\npmgxshqpjhn9qptllp\n2nine5\nfourqpzjrtttssthsxsq1jkrlnkk\neight53njhcfhbjfthree3ksgrrj\ncgmvkqlcgzgfqxmgkfdzxxnxjgsd6eighttvggmfbdvztwo\nonefour8txkkpvfourzbhpsnrzleightseveng\n49z2six591one\n768five\nxgkfonethreexnlcptbgxhnine4fivetwosix\n6ghccxxjponelmxeight4\n3ninedlkvcbfmd2ktmjxsgdgr\n3threefourxcgnxhkqkjbdzb\n49eight44rlhg83gktmtm\nfnbnnpvcthrsjxnqdn9\nldrfhknine3394lgvseightwoj\nzmpsc3lzlkmqjc5eightthree\nllpmmfsmt8llknhrn\nonedvc3sixxx9four\n148eightq6\n95one9sevenfourfour79\none9eight78gnrthxbn\n95xzzlpjzqdtonezfntwo6sixf\neight1sevenn8bgnmnxbmdk\n1sixseventhree2\ntwogjprzznd9sixsevencpfbh1\ngnbtwomtltppkxxtwonlfxsbzjtt4bjlfxlqhlx\nthree5oneoneqd3bcjgl\npzngtc2four4811\nnnlqscgg8nine7vst4three\nfourcdqc7vvqhpgqlkjsevenfivefiveseven\n5sixtwo9sixqmxxgjvjqjtworlzpv\n6dkknsmfmnq\n2two74five7\nfour3vvfskp\nqqvpdttrfiveseven6\ntbgeight8eightsix976\nsevenninetwo3jdone\nthree6seven7nine82\nfxffmkjn2sevensix\n5xzbf4bjqfrfourpjhscxz\n5eighttwoeight7fivex1bnfpr\n1j3262\ntwo1fvxchkcdtqctph\nvgnrqn4three\nplzrk3tmqpxnhpkq6four\nfour5eightone6threedbnjkvjvzxl\nbxcqcdnjjsz66gnxbhcct2nfhqlbs\ntwovvqb9pxrxkmflzqeight\n86\neight9eightsevenone2\ndclk16seven\nlzs15four\n265ninetzpnbxzllkq\nttldqsnineffpplcxmbvknkmtdbzlsix7sbkvqhn77\neightgxzcjvgmtgzc9gndqxbxnsktvp\nmpqxldjnfive1pzvxbqqtwonine\ngzbczdrqkmtm3lzrhnf\nmlbsfqvrrtcrvhjjbs5\nfiveljrcn27\nbvnxlsfmv6eightnine3rhsb\nfive5five\neight31zztkhrznmkbx2kvzl4eight\nfvccqgfzsqfour453125frz\nxxf5threefourtq58\nstvfjpj1ggnzgcfzldd2hbxmbgtftpskbtqmgv\n11cbcps6\ndltxch6onenzsmqbfn4onezkdntjzpc4\n4eightthreej7lpqbvzz\nsevenlgonexmrmtfhqpfourp7\nhjjdgtldrfivednsfdnmn24vtqgxk\n41tnjbxk2gghb\n2eightwotg\neightkvhkzfivesixtcnpsxssvveight2\n59dnmmpone6mzqlnf8dvnone\nkfvqrgv87trlninedf\n85bnxlhdrmjt\nzvzxt4pzlnbb\njfour6lpvvvbdn76tbblfqtwo\nlnqpscgkone1\nmcnfzmvzkxp1\nthreeseven9onepvqhgdxcxmhtkxxvlhqrnine\nsixrzrjcmbpppcvf1bvbhblrmz\n6tzthree7sevenlm9\nfour3gkqrmpgnjltwo\nthreetctttrh3\nctcfljkgm7bcphzxzjj7sb43zdkvkddktwo\nsixzjkxlfourhqtwonbslgpt9vljz1\nsgz5\nvrrfjbjpsevenzbqcnthreelhxjqmdd2\nsfmjnbnnpvthreedbsh7six5\ntwovdjqdtrxg5\nnineeight7five\n4xlpdvlvonekqmqvcqjsevennsd\nfiveblbxxjcbhxvnkfd9one7twoninebj\nxdxp54sixseventwo\nonefive7\nppgsqgjfourfourfivegtbrlkdvs1jl\ntwotwoeight6sqlmffdm2three\ncvszcvq8eight\n79three\n44fivembtdfivetwones\nzqkthreefoureightthreethree2five\n74twotwo\nsix6fnjz1plxb19\nmkfj72nine\nseven1nine5fourqsgrj\n5fntdgbzkjfhxlqrzcq7\nsix9lgddrhjc9\n1zfzp7\n2lmncxvxbbsix7jbjrjsnvx1nine\n6eightseven3\n5vsqhnone\nxoneight3j\n1gxvbbhfdmsthxgrvnm\nsixthreeone13\n2three8bzbbd\n3dsix1\n24kmxnlpqxgpsevenfoursixfour\nfqpzqphmczcvlf2mxqvxnfqxthreeone\neight789eightnhsh67\nzznxlmhgr3eight\nbeightwolgnb4997fgx35dt\nfour1dsgpfzltwo57threefivetwo\nxnjjvmlkkgsht99\n1sixhhqkx9\neightdhmgqjflthone44eight\n9ftzbdsdkd9plrrtwo\nvhbvd8h\ntxxonemsfshdrpc15onefive1four\nqgbd4eightrqxlznbjqxmxgmbrnvh7jkd\neighteighttwofive5jsqkgm\n89hn\n3lzfjpcthreeonenine\nhkpc2sixdfldx1\n3two72jbxttzfcv\nmmkjmmlvcxxvtwo25nine2\n8751gphkmsvsjhvkzfc\none8kmcktvzgdninegkl\ntwokpxphkbjctqdcvf63one3prfive\ntwotsxhbppfjcpkdfourfiveseven8sixn\n3fouronebnclssixfour6eight\ncmdgcsix1\n2eighttdqsjdrtwolmvpxqgxhd5five\none7ninefivesevenqvpf5xmccsseven\n2n7xbptnkxzcninedhhpdcsqkc\n5n\n1kfv4821\npslpmthreethreeone29tlmgj\nsixsevenlhn1\nnine9twoqrdgdxxfsevenmjseven\nrkrdlnjknine62\nf3\n6zzrfxdxseventhree\n265one\nseven3lbcvjxqhhdpzkttqsixjzzjjbclfq1fiveeightwojx\nseightwoone8qxcfgszninesvfcnxc68\nstrqnb5eightbpnkcjdz6\nfiveninebtpbpjqbgx2bmjrgmprnd\nsixgtxr2fourrdkjg\nfivebxsevensixone872dlx\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_01_questions.txt",
    "content": "--- Day 1: Trebuchet?! ---\n\nSomething is wrong with global snow production, and you've been selected to take a look. The Elves have even given you a map; on it, they've used stars to mark the top fifty locations that are likely to be having problems.\n\nYou've been doing this long enough to know that to restore snow operations, you need to check all fifty stars by December 25th.\n\nCollect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!\n\nYou try to ask why they can't just use a weather machine (\"not powerful enough\") and where they're even sending you (\"the sky\") and why your map looks mostly blank (\"you sure ask a lot of questions\") and hang on did you just say the sky (\"of course, where do you think snow comes from\") when you realize that the Elves are already loading you into a trebuchet (\"please hold still, we need to strap you in\").\n\nAs they're making the final adjustments, they discover that their calibration document (your puzzle input) has been amended by a very young Elf who was apparently just excited to show off her art skills. Consequently, the Elves are having trouble reading the values on the document.\n\nThe newly-improved calibration document consists of lines of text; each line originally contained a specific calibration value that the Elves now need to recover. On each line, the calibration value can be found by combining the first digit and the last digit (in that order) to form a single two-digit number.\n\nFor example:\n\n1abc2\npqr3stu8vwx\na1b2c3d4e5f\ntreb7uchet\n\nIn this example, the calibration values of these four lines are 12, 38, 15, and 77. Adding these together produces 142.\n\nConsider your entire calibration document. What is the sum of all of the calibration values?\n\n--- Part Two ---\n\nYour calculation isn't quite right. It looks like some of the digits are actually spelled out with letters: one, two, three, four, five, six, seven, eight, and nine also count as valid \"digits\".\n\nEquipped with this new information, you now need to find the real first and last digit on each line. For example:\n\ntwo1nine\neightwothree\nabcone2threexyz\nxtwone3four\n4nineeightseven2\nzoneight234\n7pqrstsixteen\n\nIn this example, the calibration values are 29, 83, 13, 24, 42, 14, and 76. Adding these together produces 281.\n\nWhat is the sum of all of the calibration values?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_02.adb",
    "content": "--  Solution to Advent of Code 2023, Day 2\n------------------------------------------\n--  Cube Conundrum\n--\n--  https://adventofcode.com/2023/day/2\n--  Copy of questions in: aoc_2023_02_questions.txt\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_02 is\n  use HAT;\n\n  r : array (1 .. 2) of Integer;\n\n  procedure Read_Data is\n    input : constant VString := +\"aoc_2023_02.txt\";\n    --\n    c, sep : Character;\n    game : String (1 .. 4);  --  The string \"Game\".\n    id, n : Integer;\n    f : File_Type;\n    s : VString;\n    valid : Boolean;\n    max_r, max_g, max_b : Integer;\n  begin\n    Open (f, input);\n    while not End_Of_File (f) loop\n      valid := True;\n      max_r := 0;\n      max_g := 0;\n      max_b := 0;\n      Get (f, game);\n      Get (f, id);\n      Get (f, sep);\n      while not (End_Of_File (f) or else End_Of_Line (f)) loop\n        Get (f, n);\n        Get (f, sep);\n        s := +\"\";\n        while not End_Of_Line (f) loop\n          Get (f, c);\n          exit when c = ',' or c = ';';\n          s := s & c;\n        end loop;\n        if s = \"red\" then\n          valid := valid and n <= 12;\n          max_r := Max (max_r, n);\n        elsif s = \"green\" then\n          valid := valid and n <= 13;\n          max_g := Max (max_g, n);\n        elsif s = \"blue\" then\n          valid := valid and n <= 14;\n          max_b := Max (max_b, n);\n        end if;\n      end loop;\n      if valid then\n        r (1) := r (1) + id;\n      end if;\n      r (2) := r (2) + max_r * max_g * max_b;\n    end loop;\n    Close (f);\n  end Read_Data;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  r (1) := 0;\n  r (2) := 0;\n  Read_Data;\n  if compiler_test_mode then\n    if r (1) /= Integer_Value (Argument (1)) or\n       r (2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (1));\n    Put_Line (+\"Part 2: \" & r (2));\n    --  Part 1: validated by AoC: 2176\n    --  Part 2: validated by AoC: 63700\n  end if;\nend AoC_2023_02;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_02.txt",
    "content": "Game 1; 4 green, 2 blue; 1 red, 1 blue, 4 green; 3 green, 4 blue, 1 red; 7 green, 2 blue, 4 red; 3 red, 7 green; 3 red, 3 green\nGame 2; 1 blue, 11 red, 1 green; 3 blue, 2 red, 4 green; 11 red, 2 green, 2 blue; 13 green, 5 red, 1 blue; 4 green, 8 red, 3 blue\nGame 3; 9 red, 2 blue; 4 blue, 2 green, 1 red; 7 red, 4 blue, 3 green; 3 blue, 6 red; 9 blue, 4 red; 3 red\nGame 4; 5 blue, 11 green, 3 red; 6 green, 3 blue, 7 red; 17 blue, 9 green; 1 red, 5 blue, 3 green; 6 red, 7 blue, 4 green\nGame 5; 3 green, 7 blue, 7 red; 6 green, 3 red, 4 blue; 7 blue, 4 red\nGame 6; 1 green, 3 blue; 2 blue, 9 red; 2 green, 13 blue, 11 red; 7 red, 12 blue, 1 green\nGame 7; 2 blue, 6 red, 12 green; 7 red, 8 blue, 6 green; 7 blue, 3 green, 7 red; 5 blue, 9 green, 13 red\nGame 8; 13 blue, 1 green; 3 red, 9 blue; 3 red, 4 blue; 2 red, 3 blue, 1 green; 1 green, 15 blue, 4 red\nGame 9; 1 green, 5 blue, 11 red; 2 red, 1 blue; 2 red, 5 blue\nGame 10; 8 red, 20 green; 12 green, 1 red, 2 blue; 5 red, 3 blue, 7 green; 4 red, 19 green, 6 blue; 3 blue, 4 red, 14 green; 9 red, 15 green\nGame 11; 7 green, 4 blue, 14 red; 7 red, 8 green; 6 blue, 6 red; 5 blue, 10 red, 11 green; 12 red, 2 green\nGame 12; 4 blue, 5 green, 8 red; 2 green, 4 blue, 7 red; 4 blue, 3 green, 2 red; 2 red, 4 green\nGame 13; 7 blue, 8 red; 5 green, 15 blue, 2 red; 7 green, 3 blue, 12 red\nGame 14; 4 green, 16 red; 6 red, 2 green; 5 red, 1 blue, 3 green; 1 blue, 1 red, 2 green\nGame 15; 3 green; 2 blue, 1 red, 2 green; 6 blue; 3 blue, 1 red, 2 green; 2 red, 1 green\nGame 16; 13 green, 3 red; 9 green, 1 blue; 4 blue, 1 red, 18 green; 2 red, 3 blue, 7 green; 17 green, 2 red, 3 blue; 12 green, 2 red\nGame 17; 2 blue, 4 green, 3 red; 2 red, 5 green, 11 blue; 5 green, 15 blue, 2 red; 3 green, 13 blue; 6 blue, 2 green, 2 red; 8 blue, 1 red\nGame 18; 6 red, 4 green, 7 blue; 2 red, 3 green, 12 blue; 3 red, 6 blue, 6 green; 9 red, 10 blue; 6 green, 4 blue, 2 red; 12 red, 12 blue, 9 green\nGame 19; 3 blue, 2 red, 3 green; 16 red, 3 blue, 5 green; 2 red, 6 green; 3 green, 2 blue, 15 red; 2 blue, 13 red, 1 green\nGame 20; 2 blue; 1 green, 5 blue, 2 red; 3 blue, 2 red, 1 green; 1 red, 2 blue\nGame 21; 15 green, 13 blue, 4 red; 9 green, 6 red, 19 blue; 6 blue, 1 green, 1 red; 1 red, 11 green, 9 blue; 3 red, 14 green, 8 blue\nGame 22; 3 blue, 10 red, 1 green; 2 red, 6 green; 9 green, 3 blue, 4 red; 2 blue, 4 green\nGame 23; 5 red, 2 green, 5 blue; 4 green, 12 red, 2 blue; 3 green, 8 red, 4 blue\nGame 24; 1 green, 16 red, 3 blue; 10 red, 1 blue; 2 blue, 1 green, 7 red; 12 red, 1 green; 14 red, 1 green; 1 blue, 8 red, 1 green\nGame 25; 8 blue, 9 red, 6 green; 2 blue, 4 green, 8 red; 1 green, 9 blue, 2 red; 14 red, 4 blue\nGame 26; 4 blue, 3 green; 1 red, 3 blue; 6 red, 2 green, 6 blue; 5 green, 2 red; 5 blue, 5 green; 6 red, 1 blue\nGame 27; 6 green, 9 blue; 1 red, 6 green, 8 blue; 3 green, 1 blue, 1 red; 3 red, 4 blue; 2 red, 2 blue; 4 red, 3 green, 7 blue\nGame 28; 5 green, 2 blue; 5 blue; 1 red, 4 blue, 3 green; 1 green, 2 red\nGame 29; 1 green, 2 red, 4 blue; 1 green, 2 red, 1 blue; 9 red, 6 blue\nGame 30; 1 green, 1 red, 5 blue; 13 blue, 4 green, 2 red; 10 green, 11 blue; 9 green, 2 red, 12 blue\nGame 31; 4 red, 5 blue; 8 blue, 1 red, 1 green; 4 red, 5 green; 3 green; 9 blue, 2 red, 7 green\nGame 32; 5 blue, 4 red, 5 green; 10 red, 10 green, 5 blue; 10 red, 12 green, 6 blue; 8 red, 1 blue, 13 green; 6 green, 14 red, 2 blue\nGame 33; 9 green, 6 red, 4 blue; 1 red, 2 blue, 13 green; 4 red, 4 green, 5 blue\nGame 34; 1 blue, 1 red; 9 green, 14 red, 1 blue; 3 blue, 7 green\nGame 35; 1 red, 11 green, 5 blue; 1 red, 5 blue, 17 green; 19 green, 6 blue; 4 green, 7 blue; 10 blue, 7 green\nGame 36; 9 green, 6 blue, 4 red; 8 blue, 13 green, 1 red; 5 blue, 5 green; 15 green, 1 red\nGame 37; 1 green, 9 red, 1 blue; 14 green; 11 green, 6 red\nGame 38; 2 blue; 9 green, 1 blue, 8 red; 4 green, 1 blue, 3 red\nGame 39; 7 red, 7 blue; 3 green, 6 blue, 2 red; 3 green, 4 red\nGame 40; 5 blue, 2 red, 6 green; 6 blue, 10 green, 4 red; 8 green, 6 blue; 3 green, 2 blue; 2 red, 14 green\nGame 41; 5 red, 14 blue, 3 green; 3 red, 3 blue, 7 green; 19 blue, 15 green, 6 red; 5 green, 18 blue; 1 green, 7 red, 9 blue; 14 green, 10 blue, 1 red\nGame 42; 2 red, 3 green; 2 blue, 3 red; 15 green, 1 blue; 2 blue, 15 green, 1 red; 7 red, 15 green\nGame 43; 4 green, 6 red, 9 blue; 4 green, 3 red, 18 blue; 6 green, 7 blue; 4 red, 7 blue; 8 blue, 7 green, 1 red; 5 red, 14 blue\nGame 44; 2 green, 11 blue; 1 green, 5 red, 8 blue; 4 green, 17 blue, 4 red\nGame 45; 6 blue, 3 green, 2 red; 8 green, 12 blue, 3 red; 13 blue, 11 green; 13 blue, 9 green; 2 blue, 3 green, 3 red; 2 blue, 10 green\nGame 46; 14 blue, 12 green, 3 red; 2 green, 1 red, 10 blue; 5 red, 7 green\nGame 47; 15 blue, 1 red; 1 red, 14 blue; 1 red, 16 blue; 3 green, 8 blue\nGame 48; 1 green, 3 blue, 1 red; 8 blue, 2 red, 8 green; 14 red, 4 green, 11 blue\nGame 49; 6 red, 5 blue, 2 green; 3 red, 11 blue; 1 blue, 14 green, 6 red\nGame 50; 7 red, 7 blue; 7 blue, 7 red; 13 blue, 1 green, 2 red; 7 green, 5 red, 9 blue\nGame 51; 4 blue, 9 red, 1 green; 16 red; 2 blue, 6 red; 11 red, 6 blue\nGame 52; 4 green, 4 blue, 9 red; 5 blue, 4 red, 16 green; 16 green, 3 red\nGame 53; 2 green, 12 red; 2 red, 5 green, 15 blue; 9 blue, 17 red, 9 green; 2 blue, 6 red, 4 green\nGame 54; 2 red, 3 blue, 5 green; 8 green, 3 blue; 9 green, 3 blue, 3 red; 1 blue, 4 green\nGame 55; 6 green, 11 blue, 12 red; 10 blue, 6 red, 13 green; 7 green, 9 blue; 10 green, 20 red, 7 blue; 9 green, 14 red, 8 blue; 14 green, 15 red\nGame 56; 1 green, 8 red, 1 blue; 1 green, 3 blue, 13 red; 5 red, 3 blue; 5 blue, 16 red; 12 red, 4 blue\nGame 57; 7 green, 5 blue; 13 blue; 1 red, 11 green, 4 blue; 1 red, 7 green, 5 blue\nGame 58; 14 blue, 6 green, 9 red; 7 blue, 1 green, 11 red; 3 red, 9 blue, 6 green; 4 green, 2 red; 2 blue, 6 green; 11 blue, 1 red\nGame 59; 6 red, 1 blue, 5 green; 4 green; 15 green; 7 red, 1 blue, 12 green; 7 red, 1 blue, 3 green\nGame 60; 3 blue, 6 red, 2 green; 7 green, 6 red, 4 blue; 3 green, 1 red, 4 blue; 3 red, 1 green; 9 red, 5 green, 4 blue\nGame 61; 1 green, 3 blue; 1 red, 2 green; 1 green, 2 blue, 2 red\nGame 62; 10 green, 15 blue, 14 red; 11 blue, 11 red, 16 green; 5 red, 5 green, 12 blue\nGame 63; 2 blue, 5 red; 7 blue, 2 green, 2 red; 2 red, 1 blue\nGame 64; 9 blue, 12 red, 4 green; 5 blue, 13 red; 1 red, 2 green, 7 blue\nGame 65; 4 blue, 8 red; 13 green, 8 blue, 5 red; 1 green, 5 blue, 7 red; 11 red, 7 blue, 10 green\nGame 66; 8 red, 17 blue; 1 green, 9 red, 7 blue; 12 red\nGame 67; 14 blue, 12 green, 3 red; 12 green; 9 green, 13 red, 15 blue; 2 red, 10 green, 1 blue\nGame 68; 11 blue, 14 green; 14 green; 9 blue, 7 green, 1 red; 9 blue, 7 green; 17 green, 2 blue; 4 green, 4 blue\nGame 69; 4 blue, 14 green, 6 red; 11 red, 7 green, 10 blue; 4 red, 8 blue, 8 green; 7 green, 6 red, 7 blue\nGame 70; 12 red, 16 green, 11 blue; 16 green, 15 blue, 5 red; 10 blue, 1 red, 12 green; 9 red, 8 blue, 4 green; 2 green, 8 red, 3 blue\nGame 71; 8 red, 1 blue, 5 green; 12 green, 7 red; 11 green, 1 blue, 7 red\nGame 72; 5 green, 15 red; 7 green, 3 red, 4 blue; 10 red, 1 green; 6 blue, 15 red, 3 green\nGame 73; 1 green, 5 red, 1 blue; 6 red, 3 blue, 6 green; 11 red, 1 blue\nGame 74; 5 red; 1 blue, 3 green, 3 red; 2 green, 7 red; 1 blue, 2 red; 3 red, 1 green\nGame 75; 13 blue, 20 red, 10 green; 3 green, 5 blue, 14 red; 9 red, 13 green, 7 blue; 1 blue, 15 red, 2 green; 11 blue, 2 green, 17 red; 11 red, 13 blue, 13 green\nGame 76; 9 red, 7 green, 2 blue; 7 red, 2 blue, 8 green; 4 blue, 3 red, 9 green; 4 red, 1 green; 1 red, 2 green, 3 blue\nGame 77; 5 red, 2 green, 15 blue; 12 green, 4 red, 2 blue; 10 blue, 6 red, 9 green; 7 blue, 3 green; 16 blue, 4 red, 5 green\nGame 78; 11 blue, 3 green, 19 red; 3 blue, 1 red; 8 red, 14 blue, 3 green; 8 blue, 8 green, 16 red; 8 blue, 14 red; 12 blue, 11 red, 2 green\nGame 79; 10 blue, 5 red, 1 green; 3 blue, 13 red; 15 red, 1 green; 4 red, 6 blue, 1 green; 1 green, 6 blue\nGame 80; 7 red, 1 green, 1 blue; 1 blue, 4 red, 3 green; 2 red, 2 green; 7 red, 1 blue, 1 green; 2 red, 1 green, 3 blue\nGame 81; 12 green, 2 red, 8 blue; 1 green, 1 blue, 1 red; 7 blue, 1 red, 11 green; 1 red, 12 blue, 4 green\nGame 82; 18 red, 5 blue, 4 green; 6 green, 11 red; 11 green, 18 red, 5 blue; 4 green, 17 red, 4 blue; 5 blue, 14 red, 15 green\nGame 83; 4 red, 6 blue, 6 green; 9 red, 4 green; 8 green, 7 blue; 2 blue, 9 red, 13 green; 2 blue, 9 green, 11 red\nGame 84; 15 blue; 4 green, 1 red, 15 blue; 2 green, 16 blue; 3 green, 14 blue; 16 blue\nGame 85; 3 red, 7 green, 8 blue; 3 blue, 17 green, 7 red; 13 green, 4 blue; 6 blue, 8 green\nGame 86; 16 green, 6 blue; 12 blue, 9 red, 11 green; 17 green, 4 blue, 8 red\nGame 87; 6 blue, 3 green, 13 red; 13 blue; 12 red, 2 green, 1 blue\nGame 88; 6 red, 2 blue; 16 red, 13 blue, 1 green; 2 green, 11 blue, 2 red; 12 blue, 9 red, 1 green; 5 blue, 2 red, 2 green; 18 red, 3 blue\nGame 89; 6 green, 5 blue; 4 green, 4 blue; 3 red, 5 blue\nGame 90; 3 green, 8 blue; 2 green, 7 blue, 9 red; 8 red, 2 blue, 4 green; 1 green, 3 red, 7 blue; 4 blue, 4 green, 2 red; 9 red, 3 blue, 3 green\nGame 91; 9 red, 12 green, 1 blue; 11 green, 9 red, 2 blue; 1 blue, 8 red, 4 green; 6 red, 9 green; 2 blue, 10 red, 1 green; 2 blue, 15 green, 13 red\nGame 92; 3 green, 11 red, 16 blue; 8 blue, 1 red, 6 green; 4 green, 1 red, 5 blue\nGame 93; 9 blue, 3 red, 13 green; 2 red, 9 blue; 3 blue, 17 green, 5 red; 4 green, 8 blue\nGame 94; 2 blue, 3 red, 9 green; 4 blue, 1 red, 6 green; 8 green, 2 blue; 4 green, 2 blue, 7 red\nGame 95; 5 green, 3 blue; 4 blue, 3 green, 8 red; 3 green, 4 red, 3 blue; 2 blue, 4 red; 9 blue, 5 red, 3 green\nGame 96; 11 green; 10 green, 5 blue, 11 red; 5 blue, 13 red, 15 green; 10 green, 1 blue, 11 red\nGame 97; 5 green, 6 blue, 1 red; 7 green, 1 red; 5 blue; 3 blue, 1 red\nGame 98; 1 blue, 5 green, 7 red; 3 red, 5 green, 1 blue; 4 blue, 8 green, 2 red; 4 green, 1 blue, 6 red\nGame 99; 12 blue, 8 green; 2 green; 3 red, 7 green, 5 blue; 1 green, 1 blue, 2 red\nGame 100; 4 blue, 14 red; 12 red, 1 blue; 2 red, 2 blue; 8 red; 14 red, 2 blue, 1 green; 3 blue\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_02_questions.txt",
    "content": "--- Day 2: Cube Conundrum ---\n\nYou're launched high into the atmosphere! The apex of your trajectory just barely reaches the surface of a large island floating in the sky. You gently land in a fluffy pile of leaves. It's quite cold, but you don't see much snow. An Elf runs over to greet you.\n\nThe Elf explains that you've arrived at Snow Island and apologizes for the lack of snow. He'll be happy to explain the situation, but it's a bit of a walk, so you have some time. They don't get many visitors up here; would you like to play a game in the meantime?\n\nAs you walk, the Elf shows you a small bag and some cubes which are either red, green, or blue. Each time you play this game, he will hide a secret number of cubes of each color in the bag, and your goal is to figure out information about the number of cubes.\n\nTo get information, once a bag has been loaded with cubes, the Elf will reach into the bag, grab a handful of random cubes, show them to you, and then put them back in the bag. He'll do this a few times per game.\n\nYou play several games and record the information from each game (your puzzle input). Each game is listed with its ID number (like the 11 in Game 11: ...) followed by a semicolon-separated list of subsets of cubes that were revealed from the bag (like 3 red, 5 green, 4 blue).\n\nFor example, the record of a few games might look like this:\n\nGame 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green\nGame 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue\nGame 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red\nGame 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red\nGame 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green\n\nIn game 1, three sets of cubes are revealed from the bag (and then put back again). The first set is 3 blue cubes and 4 red cubes; the second set is 1 red cube, 2 green cubes, and 6 blue cubes; the third set is only 2 green cubes.\n\nThe Elf would first like to know which games would have been possible if the bag contained only 12 red cubes, 13 green cubes, and 14 blue cubes?\n\nIn the example above, games 1, 2, and 5 would have been possible if the bag had been loaded with that configuration. However, game 3 would have been impossible because at one point the Elf showed you 20 red cubes at once; similarly, game 4 would also have been impossible because the Elf showed you 15 blue cubes at once. If you add up the IDs of the games that would have been possible, you get 8.\n\nDetermine which games would have been possible if the bag had been loaded with only 12 red cubes, 13 green cubes, and 14 blue cubes. What is the sum of the IDs of those games?\n\n--- Part Two ---\n\nThe Elf says they've stopped producing snow because they aren't getting any water! He isn't sure why the water stopped; however, he can show you how to get to the water source to check it out for yourself. It's just up ahead!\n\nAs you continue your walk, the Elf poses a second question: in each game you played, what is the fewest number of cubes of each color that could have been in the bag to make the game possible?\n\nAgain consider the example games from earlier:\n\nGame 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green\nGame 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue\nGame 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red\nGame 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red\nGame 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green\n\n    In game 1, the game could have been played with as few as 4 red, 2 green, and 6 blue cubes. If any color had even one fewer cube, the game would have been impossible.\n    Game 2 could have been played with a minimum of 1 red, 3 green, and 4 blue cubes.\n    Game 3 must have been played with at least 20 red, 13 green, and 6 blue cubes.\n    Game 4 required at least 14 red, 3 green, and 15 blue cubes.\n    Game 5 needed no fewer than 6 red, 3 green, and 2 blue cubes in the bag.\n\nThe power of a set of cubes is equal to the numbers of red, green, and blue cubes multiplied together. The power of the minimum set of cubes in game 1 is 48. In games 2-5 it was 12, 1560, 630, and 36, respectively. Adding up these five powers produces the sum 2286.\n\nFor each game, find the minimum set of cubes that must have been present. What is the sum of the power of these sets?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_03.adb",
    "content": "--  Solution to Advent of Code 2023, Day 3\n------------------------------------------\n--  Gear Ratios\n--\n--  https://adventofcode.com/2023/day/3\n--  Copy of questions in: aoc_2023_03_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_03 is\n  use AoC_Toolbox, HAT;\n  --\n  --\n  r : array (Part_Type) of Integer;\n  --\n  procedure Read_Data is\n  --  input : constant VString := +\"mini.txt\"; size : constant := 12;\n    input : constant VString := +\"aoc_2023_03.txt\"; size : constant := 142;\n    --\n    f : File_Type;\n    c : Character;\n    --\n    subtype Row is String (1 .. size);\n    t : array (0 .. 2) of Row;  --  Window of 3 rows.\n    --\n    type Gear_Info is record\n      adjacent_numbers : Natural;\n      ratio            : Natural;\n    end record;\n    type Gear_Row is array (1 .. size) of Gear_Info;\n    g : array (0 .. 2) of Gear_Row;\n    --\n    procedure Clear (gr : in out Gear_Row) is\n    begin\n      for j in gr'Range loop\n        gr (j).adjacent_numbers := 0;\n        gr (j).ratio := 1;\n      end loop;\n    end Clear;\n    --\n    n : Integer;\n    procedure Mark_Gear (i, j : Natural) is\n    begin\n      if t (i)(j) = '*' then\n        g (i)(j).adjacent_numbers := g (i)(j).adjacent_numbers + 1;\n        g (i)(j).ratio := g (i)(j).ratio * n;\n      end if;\n    end Mark_Gear;\n    --\n    cur : Integer := 1;\n    j1, j2 : Integer;\n    sym : Boolean;\n    --\n    procedure Analyse is\n      prev_1 : constant Integer := (cur - 1) mod 3;\n      prev_2 : constant Integer := (cur - 2) mod 3;\n    begin\n      j1 := 2;\n      loop\n        if t (prev_1)(j1) in '0' .. '9' then\n          j2 := j1;\n          loop\n            exit when t (prev_1)(j2 + 1) not in '0' .. '9';\n            j2 := j2 + 1;\n          end loop;\n          --  Now t (cur-1)(j1 .. j2) contains a number\n          --  n := Integer'Value (t (cur-1)(j1 .. j2));  Nice to have in HAC...\n          n := 0;\n          for j in j1 .. j2 loop\n            n := n * 10 + Ord (t (prev_1)(j)) - Ord ('0');\n          end loop;\n          --  Now, we look at symbols around the number.\n          sym := False;\n          for j in j1 - 1 .. j2 + 1 loop\n            c := t (prev_2)(j);  --  2 rows before\n            if not (c = '.' or c in '0' .. '9') then\n              sym := True;\n              Mark_Gear (prev_2, j);\n            end if;\n            c := t (cur)(j);  --  Current row\n            if not (c = '.' or c in '0' .. '9') then\n              sym := True;\n              Mark_Gear (cur, j);\n            end if;\n          end loop;\n          --  Previous row (being analysed): left and right character.\n          sym := sym or (t (prev_1)(j1 - 1) /= '.') or (t (prev_1)(j2 + 1) /= '.');\n          Mark_Gear (prev_1, j1 - 1);  --  Left\n          Mark_Gear (prev_1, j2 + 1);  --  Right\n          if sym then\n            --  Add numbers with an adjacent symbol:\n            r (part_1) := r (part_1) + n;\n          end if;\n          j1 := j2 + 1;\n        else\n          j1 := j1 + 1;\n        end if;\n        exit when j1 >= size - 1;\n      end loop;\n      --  Collect the complete gear info\n      for j in 2 .. size - 1 loop\n        if g (prev_2)(j).adjacent_numbers = 2 then\n          --  Sum the gear ratios\n          r (part_2) := r (part_2) + g (prev_2)(j).ratio;\n        end if;\n      end loop;\n    end Analyse;\n  begin\n    --  Clear the window\n    for i in 0 .. 2 loop\n      for j in 1 .. size loop\n        t (i)(j) := '.';\n      end loop;\n      Clear (g (i));\n    end loop;\n    Open (f, input);\n    while not End_Of_File (f) loop\n      for j in 2 .. size - 1 loop\n        Get (f, t (cur)(j));\n      end loop;\n      --  Analyse the *previous* row.\n      Analyse;\n      cur := (cur + 1) mod 3;\n      Clear (g (cur));\n    end loop;\n    Close (f);\n    for j in 1 .. size loop\n      t (cur)(j) := '.';\n    end loop;\n    Analyse;\n  end Read_Data;\n  --\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 539590\n    --  Part 2: validated by AoC: 80703636\n  end if;\nend AoC_2023_03;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_03.txt",
    "content": "..224.....487...................718.....................378............................................284........310......313..........311.\n....*..............................*744....486*485......*......741......@...359.#666...439................*925....*......$..+........@......\n.235................758..440...........................251....*......262.....*..........*......................752......774.......515.......\n.........705%..@746........+..942*591.347.470...#..257.........637...........793.......299..../.....813....509......464......&.........688..\n.....82................................*.../..901.....*..................836.....&............814...*........*..............80...17*....*...\n.../...*...679.661.....299...........222.............875.....213...161............964...894.........998.....310....258.85...........735.586.\n.650..23..#......*.......................................760*........@./........................202...................*.....339.............\n..............598......#.....536....702*.........705..........793......957............./........*...935...........965.......................\n..................*.357...+.....@.......242.......*......283..*...=956.......118.......959...184...*..............*....401*527.....348...161\n.63=...955.523..77......978.846....849..........699..........790........=911.*.....87...............486.........914..............=..........\n.........*.........842......*.......*..................*127....................844...*....946.......................235...209@...710.735....\n...........@.........*.....144....226....298........560.....253.........431......*...586.......723..../...482.......&...................*...\n...........871../918........................+....................329*......%.....906.............*...350.....@...............365.......361..\n......................536............................+..793..........664.....739................507......289.....256%...73..*...............\n.356..834..............*.........96.939..............28.+....=..............*...........................*................$.553..........526.\n...*...*.............501..746....*..-.......=.................890.....+...701..............807........447......97$..%...........58......$...\n.891....346...699...........*.421......+....666......198*791......340.433............#...%...*.......................316........*.....%.....\n..............%........81.984...........462....................../..........116...711....963...$................380.......745...85....224...\n.........370......923..@.....................563...........188+.........326*...................67.815..............*582.....................\n.........*........-........#530.........489........59...................................................#.....57.........100.*.......441*161\n.637*....961...........118...........21*...........@..216+.........................+....432*.*309..64....992.......81......=.781.644........\n.....324.........126......*166...............&...................385*..............233............*................*..436...........*517....\n.88*.........390*................355..335...372....+254..............294...$589........&..803/.....38..-...........56..$....................\n....235.-.........+196...948....*........-................359.........................398.............608..../.................145..346.....\n........915.................-.485.945.................936*................114.............118...............490.536..............*.%........\n.663........61.......856..........+....343....859...............*345.......*...=862............711.............................313.....606..\n........23...$.....@..................*......................316.....529.362.............49......................307*791....................\n225...............281...#..222.....@..283..............675............*.........911*90..-.....914..%39....509...............................\n.......797*....$........23..../...895.............67.......164.896.....554.....................*............=..............460........181...\n...........211.474...............................@...........*....*201..........911.717.#....192.75..679...........$.........*.........=....\n....355.........................&.....................678.650......................*.....128.....*.....*.........925..230...105.............\n....*.......409#.......*897.....698....427.........+....*.......*...............................313...670..521.......*....&.............*308\n...838..335.................367........-..........325....233...224...950......688.....199.774.........................793.108........501....\n...........*..102..924.349...+..595....................................*................&..............395+.....................753.........\n.........318...*......*........*....676...759.154...................524...........908.........694.211................173...........*214..424\n....458........403...........958.98....*........*..............688......957...488..+...........*.../....................................*...\n.......*.............591...............218.....203.....196$.......+....*........*......................765......971......./....927*741..227.\n......592..%60.$.....*.....885/....287...............................474.........409......226.174.......@........*.....230..................\n...............162.169.................510..962..............17......................32@..*...*.................225....................-....\n.....880...................201.....823*........*...914.724.........89...&.......267=.....717.54.436..........60...............&.........69..\n710........601....306.287.....+.........65...308....&...=.../......*.....926..................................*........278.415......-.......\n..............*..*......&..........241.%...................827../.265.............662.678......@...#......@.....$......-............734.144.\n.............424..434.....701.....*........380*731.............24.................*...&........973..741....728..357.........................\n........304.................*...881................238.....740.........947........587...22...........................271*........603....@...\n...................266.....918....................*..........+.519.617..*...826..........*............./268..974.........486.376....*.295...\n...939.........363.*...............378..........302....586........*....740...=..........380........931...........................12.........\n...*..........-.....387...............*..588..............*..../...............315...................-...712..491.........956.....#.........\n.180.454...................104..661...91...*.............811....370......471...-....419....804..........*...................*...............\n.....*.......@../464........%..*............243.....578...................&..........*...........604..250.....784....750....998.............\n.....245....165.................771...................&.......#.691...768....654....261.........................*.......*............566....\n441..................91.....194.......643...932*............379.#....$.......*.................86.............940..263.638...........*......\n...+.............%.../.......#.........*........344...795..................991..........544....*..................*..........767...266......\n.......-..708..727.....191$......*.....698....=...................990................+.....*....308.......@......325.........*.........44...\n...18.397....=.....93.........649.900.........62....-........322.....*.......@......339....619..........404..........540........./....*.....\n..../...............%............................742............*...........196................874.205........96#..............203.224......\n.........704...727.................496.......*........135....769........./.................%....&....*.../..=.........757...................\n........*........*..424..........&........714.5........*...........@....884...............114.......674.144..83..........*302...........%...\n........29....179..*............104..................531....629.455..................473......300....................254..............640...\n..................296.......................................................1........*.......%..............548........*.....103............\n....381...........................365#..713.282.......%744....................../....709...#...=...431...$.*......*.....837.....*9.....*....\n......*.90.....347.179#...................%.......359..........92............304...*.....923.446.......385.699.....749..............193.206.\n....922.+.......*.......-197.....................*.......128........273....@.....758..............439...................650*54.736#.........\n................817..-..........152..594..949..807.......$...224...*.....124............889.......=...................................625...\n....139....667......239........*...........*.......387........%..806........../...........*..788....632...........=8......584-......*.%.....\n...........*.................280...........11.........*726............181......761..-....66.....%....-................64...........14.......\n............742.736.725..........708.667..........332.......828*750......-.........425.......................944.....*...................926\n.719...110...........*.....348...=..........121......*........................................*.......961.....*.......971...........+.......\n..../.....*629........830..*............91....&..241..491...930............561................889....*....710.333..............163...311....\n......%...................252.../..................*...........*270.......................165.....208.......*..................../.......694\n...914...126...267.183........952..$645......414.822................................69.......-..........=..112.464..267....359..........*...\n.............7*..........................806.../.....931.....*.....355..............*....928...........854.........-..............*993...101\n439.897...........%...........8......381...*........*....748..987....*............437.......*....954.......................*................\n.......*595....783........49.....110.$...675...8...60.....=........981........&..........730....*.............336.......120.790..........386\n............90..............*212...*..........*.......985.....153........*..12...912*383......665.....754.....-.....................950.....\n......790#.*........896@.........773....777..581..514*....910.....5.....579.............................=.......#.....................*.....\n...&.......496...........347..............*...............*...................../............................790..............334......912..\n692............609....&.......694..........693...213....620......695......871..385.......82..........785.......................*..163.......\n.........#....*......984.........*.................=............*.......................................*.545...-............978.....*......\n......971...477.............465......196*313..........447.......766......49.......126*480.............798......792..359*193...........837...\n................157...........+..................773.=..............752$....................447*565..........................*53............\n.384%..........@.........449............470..749...@.........@792..............138..527.......................339.....299.505...........287.\n......691........700........@......96..........*........721*.....................@....*...942......845........*......-.........713..........\n.....*......260/...*...........................491..452.....336.......................73....+..960..........238...........163$..&...=.@.....\n....689.............831...282....709.960.............=.............204............................#..............59...97..........199..111..\n........................$........../........-....498......................557....&...........972............450.............................\n.............653........476...398.........619...*.....*280..923..............*31..691.........*........=...*.....67......782................\n..............*....%..........*.........+......268...........&........428....................408....740....576....*.......*.........$.......\n....-../...734......317.114.332...795...743.........................-..=..908...........381.......................914...420.*647....528.....\n..284.825...............*......................721/.=929.........324.....*....167.561...*.....815*466.......................................\n..............389..304.480.......851..@....585..............942%......#.496....*....-.53................170....938*..........518............\n........368..*.....@..............*....941..+.......*...............930.........364.......522......................59.........+....$....652.\n...........+.963...................949...........828.784......860............*......420.....*..................*......548...........310.*...\n.....476...............*...............=...94.+..................&........589.833....*..426.940.....&.....959.993.&88....................398\n.......*................624....917...838..*...664.......721........................833...$.......672......$............19...................\n....350.......................&....=..............333.................707....................................240..336....=...746.263..$463..\n.........................-.........220.....663...../.............*849..#..631.....712....=.../...308.580.............*..........*...........\n.78@......../..........422....444.............*...............281............*...*....447..37.......*................814....................\n........./...788...810.........&..............369..985....-................92................................684...............74...........\n......279.........*......128/....464........#...../......944........978...............163..984*5.@............+.......165......*....285.....\n..................889.............*.......969........................%.......5......&....$........272....................*......374.........\n.........&..............@948..*..13.358........796.............632............*....789........91*..............*66........152...............\n........508...+..............3...........544.....$.517.....703....*774.......434............/....794........932.............................\n...$...........241.....74...........974..*...954............*.......................375..772...........218.........414...........*366....252\n.501..566...............*..........*....599.....#........256.....468@..942.101.........*..........156...*.............*.......998...........\n...../.............263.312....+..767..............#.........................*...&95..838.162=.....+....130.........583..544.......176.......\n............................936......826.......421.......-139.......982...893.......................*..................*........./..........\n.284.....=724...................661.$....694........85..........438.............51...............616.698.*36.....262......357+........224...\n....@..........491........+........................@......193......*596...........%../844...387.................$.....132.........%.........\n.......84..............362.................................*..98..........&................*....14....394..........$..............56........\n.........*432.....512................704......424.............*............74........196%..875...*.....*............132.......229...........\n..............723*.........568........*..108........672......55.172...217.........................289.427........................*..........\n.........#795.........214....*.336...94....*....988................%..&.............*86......*...............838&.......540.......902.......\n.922...........288........719.....*........845...&..558......#...................524......195.704.....................................77....\n...*....842....../...166........883...-................*503..451..305../....600............................900..280.....*169...586..........\n751....*.........../.*......944......116....416.........................877....*....418...194........644..*....=.....244..........#.....354.\n.......118......208...................................788...................826........$....$...207.....@..152...........893*608.......&....\n..948.......................203../....206.............*....341./977.916.........49...#........@....-............+385........................\n...*......266.................*...607...@.990......964..............-..........*.....340...697........62..............526.....-.............\n..675.....*..........612....604.............*..............492.884...........212...............*157....*...679.........*....706...716%.518..\n......103.749..989...*...................739..............$......=..=..................212..684.....35.......*.........785..............+...\n..343*......../.......680.....................*423.................476....&....420..............241..*......532.....+.......864$.....&......\n..................826........403..311...60.451.............+...........562....../.......306.......*..............420..................321...\n...241..............*...........+..=....@......*240.......845....@.........740.................968..389.177*...................640..........\n......*82...........963...211%...............38...............901.....404.........&..253..............-.....37.........218.501...*....320...\n....*...........................#215...264......298........................*970..801....*....569...............3.......*......%..859.*......\n.136.818...212...........91*72........*.........-...750.....775*728.29.270...............984.&...371..........*.........639..........670....\n...........*.../959................438.....524......*...943.........*................755...................162.................446#.........\n..........290.............751................*.....557..*...483.............421.........*............189.%................/.................\n....................9.786..-......835.......978........445.%..........350........860..662.......#...*....354........*.....682...............\n.117..57+....441...*....+............................................../............*.........88....142..........%.927......................\n...*...........*..402....................874.....734.926$../...............*633......219.84/............662...205...................334.....\n...981........367........338...332/.........=......*......119....375#.334.......146..............%.....$................384.............-511\n........165................=....................666.....................#..614.....-..%744..617.887.......848*..............................\n...........*.203.593...158....*..........152..............+817.....866.......&...............*......../.......904........701.165.80.........\n404..977.93..*....*....*...396.281......*....953....*................*.........116..97.70=..179....107..338................$...*....622.....\n......=.....445........................382.....*...672................859......*...%....................&..........-.571......717....*......\n..................240............175..........808..............225..........988............/604..............232.448..*..651......769.......\n.........569*....*........975*.....*....968..............585.....*................26.................................394....@.142...........\n......*......498..969.........360.666...%.........................919.......360........-.*.........%...................................484..\n...407................886...................................84......................933...101....58........839..425.........................\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_03_questions.txt",
    "content": "--- Day 3: Gear Ratios ---\n\nYou and the Elf eventually reach a gondola lift station; he says the gondola lift will take you up to the water source, but this is as far as he can bring you. You go inside.\n\nIt doesn't take long to find the gondolas, but there seems to be a problem: they're not moving.\n\n\"Aaah!\"\n\nYou turn around to see a slightly-greasy Elf with a wrench and a look of surprise. \"Sorry, I wasn't expecting anyone! The gondola lift isn't working right now; it'll still be a while before I can fix it.\" You offer to help.\n\nThe engineer explains that an engine part seems to be missing from the engine, but nobody can figure out which one. If you can add up all the part numbers in the engine schematic, it should be easy to work out which part is missing.\n\nThe engine schematic (your puzzle input) consists of a visual representation of the engine. There are lots of numbers and symbols you don't really understand, but apparently any number adjacent to a symbol, even diagonally, is a \"part number\" and should be included in your sum. (Periods (.) do not count as a symbol.)\n\nHere is an example engine schematic:\n\n467..114..\n...*......\n..35..633.\n......#...\n617*......\n.....+.58.\n..592.....\n......755.\n...$.*....\n.664.598..\n\nIn this schematic, two numbers are not part numbers because they are not adjacent to a symbol: 114 (top right) and 58 (middle right). Every other number is adjacent to a symbol and so is a part number; their sum is 4361.\n\nOf course, the actual engine schematic is much larger. What is the sum of all of the part numbers in the engine schematic?\n\n--- Part Two ---\n\nThe engineer finds the missing part and installs it in the engine! As the engine springs to life, you jump in the closest gondola, finally ready to ascend to the water source.\n\nYou don't seem to be going very fast, though. Maybe something is still wrong? Fortunately, the gondola has a phone labeled \"help\", so you pick it up and the engineer answers.\n\nBefore you can explain the situation, she suggests that you look out the window. There stands the engineer, holding a phone in one hand and waving with the other.\nYou're going so slowly that you haven't even left the station. You exit the gondola.\n\nThe missing part wasn't the only issue - one of the gears in the engine is wrong. A gear is any * symbol that is adjacent to exactly two part numbers.\nIts gear ratio is the result of multiplying those two numbers together.\n\nThis time, you need to find the gear ratio of every gear and add them all up so that the engineer can figure out which gear needs to be replaced.\n\nConsider the same engine schematic again:\n\n467..114..\n...*......\n..35..633.\n......#...\n617*......\n.....+.58.\n..592.....\n......755.\n...$.*....\n.664.598..\n\nIn this schematic, there are two gears. The first is in the top left; it has part numbers 467 and 35, so its gear ratio is 16345. The second gear is in the lower right; its gear ratio is 451490. (The * adjacent to 617 is not a gear because it is only adjacent to one part number.) Adding up all of the gear ratios produces 467835.\n\nWhat is the sum of all of the gear ratios in your engine schematic?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_04.adb",
    "content": "--  Solution to Advent of Code 2023, Day 4\n------------------------------------------\n--  Scratchcards\n--\n--  https://adventofcode.com/2023/day/4\n--  Copy of questions in: aoc_2023_04_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_04 is\n  use AoC_Toolbox, HAT;\n  --\n  r : array (Part_Type) of Integer;\n  --\n  procedure Read_Data is\n    --  input : constant VString := +\"mini.txt\"; margin : constant := 8; winners : constant := 5; candidates : constant := 8;\n    input : constant VString := +\"aoc_2023_04.txt\"; margin : constant := 10; winners : constant := 10; candidates : constant := 25;\n    --\n    sep : String (1 .. 3);\n    card_id : String (1 .. margin);  --  A string like \"Card 214: \"\n    winning : array (1 .. winners) of Positive;\n    copies : array (0 .. winners) of Positive;\n    n, won_1, won_2, cur, next : Natural;\n    f : File_Type;\n  begin\n    Open (f, input);\n    for j in 0 .. winners loop\n      copies (j) := 1;\n    end loop;\n    cur := 0;\n    while not End_Of_File (f) loop\n      Get (f, card_id);\n      for j in 1 .. winners loop\n        Get (f, winning (j));\n      end loop;\n      Get (f, sep);\n      won_1 := 0;\n      won_2 := 0;\n      for i in 1 .. candidates loop\n        Get (f, n);\n        for j in 1 .. winners loop\n          if n = winning (j) then\n            if won_1 = 0 then\n              won_1 := 1;\n            else\n              won_1 := won_1 * 2;\n            end if;\n            won_2 := won_2 + 1;\n          end if;\n        end loop;\n      end loop;\n      r (part_1) := r (part_1) + won_1;\n      r (part_2) := r (part_2) + copies (cur);\n      --  Spread the copies of the cards:\n      for i in 1 .. won_2 loop\n        next := (cur + i) mod (winners + 1);\n        copies (next) := copies (next) + copies (cur);\n      end loop;\n      copies (cur) := 1;\n      cur := (cur + 1) mod (winners + 1);\n    end loop;\n    Close (f);\n  end Read_Data;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 23750\n    --  Part 2: validated by AoC: 13261850\n  end if;\nend AoC_2023_04;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_04.txt",
    "content": "Card   1: 29 21 67 44  6 13 68 15 60 79 | 75 44 60 30 10 68 40 70 36 79  3 13 64 15  4 46 21 22 67 47 73 86 29 53  6\nCard   2: 15 61  5 39 42 79  4 81 72 89 | 74 79 20 81 72 85 25 76 36 49 51 18 34 90 57 17 11 24 89 73 19 37 61 54  2\nCard   3: 75 31 33 22 49 70 37 98 92 94 |  1 87 73 92 57 94 84 10  5 79 69 74 96 37 40 55 18 21 85 93 71 49 70 22 39\nCard   4: 76 59 23 34 55 41 47 92 58  5 | 16 70 56 19 79 30 85 58 88 75 71  5  8 64 12 23  9 46 34  4 94 37 48 82 47\nCard   5: 48 77 74 18 44 34 71 38 67  1 |  8 78 73 19 39 50 11 54 69 37 79 18 66 77 52 94 74 34 71  1 48 85 67 95 93\nCard   6:  1 30 41 34 51 23 64 14 18 74 | 38 98 13 67 39 65  1 29 28 75 95 71 60 88 20 86 59 63 36  3 15 57 58  4 42\nCard   7: 70 27 20 85  2 34 55 49 24  5 | 19 20 15 48 70 26 89  7 55 44 76 53 63 49 93 68 23 59 72 73 52 41  9 11 94\nCard   8: 64 17 56 38 85 53 88 22 51 92 | 22 10 37 24 65 25 63 82 64  5  1 88 17 73 39 78 53 36 71 92 23  9 85 33 38\nCard   9: 99  7 22 85 41 15 84 10 42 34 | 16 52 65 26 95 37 28 44 21 36 13 89 48 51 71 83 49 86  9 12 33 32 61 72 73\nCard  10: 19 86 25 64  6 95 74 55 68 12 | 51 46 95 84 27 87  7 12 18 81 19 66 33 26 94 16 97 86 74 31 55  6 30 60 85\nCard  11: 45  6 14 25 88  1  5 26 91 28 | 10 42 34 19 28 18 91 47 71 29 66 94 43 82 65 70  3 30 64 52 83 27 85  4 60\nCard  12: 33 47 56  8 42 95 24 15 83 93 | 93 56 53 95 43 55 73 77 67 47 81 27  3 19 15 79 46  7 42 54 91 10 24  6  5\nCard  13:  2 18 45 43 56 82  7 23 16  4 | 70 56 74  4 83 23 98 57 20 86 87 30 28 89 77 37 75 10 41 58 32 21 35 84 66\nCard  14: 33 91 58 32 75 37 88 51 83  8 | 92 35 91 56 10 75 52 64 97 16 58  9 26 15 86 99 13 69 70  6 40 12 51 93 95\nCard  15: 18 94 82 39 93 70 90 85 37 91 | 29 94 68 22 47  4 64  1 37 75 90 95 54 56 12 48 80  6 40 38 55  2 30 49 92\nCard  16: 78 98 80 34 43 51 90 25 26 59 | 83 31 37 79 54 99 98 96 27 16 50 36  4 15 14 80  2  6 33 81  3 24 92 52 45\nCard  17:  6 74 89  4 22 95 54 97 28 99 | 32 24 60 83 89 62 79 82 91 25 43 40 52 23 50 71  6 86 64 51 58 63 36  1 41\nCard  18: 28 73 36 17 42 26 15 79 13 80 | 11 24 85 84 93 63 42 16  7 19  1 38 44 54 98 59 88 91 35 81 82 95 77 30 26\nCard  19: 45 38 16 35 25 72 97 19 96 46 | 21  9 83 49 93 50 92 88 62 46  4 61 69 85 82 51 43 86 81 47 20 53 15 84 91\nCard  20: 36  9  7 26 53 48 25 66 76 59 | 90 16 20 79 27 40 86 77 41 15 67 52 34 51 95 64 29  2 47 57 58 24  4 50 84\nCard  21: 26 89 64 53 45 95 32 90 24 65 | 80 46 34 33  8 19 94 47  5 21  9 68 73 29 48 82 26 36  4 15 10 74 14 42 79\nCard  22: 95 78 69 14 44 54 97 58 66 43 | 75 95 64 54  3 53 20 69 86 22 52 23 59 31 78 45 61 90 50 66 76 63 91 38 79\nCard  23: 46 59 36 40 60 10 38 72 20 91 | 21 40 99 22 27 20 57 59 76 78 10 85 97 71 98  1 24  6 72 58 60 36 38 63 46\nCard  24: 75 92 32 12 23 89 48 35 28 95 | 23 75 59 58 25 70 18 48 27 92 35 32 53 83 89 64 79 87 10 68 28 30 95 61 78\nCard  25: 64 30 37 36 70 35 26 75 80  7 | 11 10 28 40 64 94 31 98 73 57 70  8 88 30 20 80 85 75 92 14 37 27 77 41 76\nCard  26:  9 15  4 90 10 67 44 72  3 20 | 64 41 96  2 69 73 61 67 84 58 34 13  3 46 99 48 55 79 31 38 75 12  8 76 32\nCard  27: 48 15 97 86 38 37 75 64 27 10 | 96 85 54 88 80 64 11 70 37 50 86 24 75 63 15  3 48 27 17 65 83 97 22 74 10\nCard  28: 15 48 89 62 35 81 17 77 16 28 | 92 22  2 78 74 80 12 85 73 42 17 38 11 46 79 69 65 82 47 28 30 62 96 76 66\nCard  29: 97 84 88  6 87  4  9 23 43 39 | 64 35 18 36 33 32 39 61 63 93 84 23 49  3 31 60 81 97 17 37 57 79 74 30 65\nCard  30: 83 80 61 52 28 84 98 91 79 57 | 62 40 82 31  8 23 95  2 71 93 48 36 43 39 32 87 81 60 18  6 64 90 26 47 85\nCard  31: 98 40 94 66 28 32 46 88 36 24 |  4 50  3 21 61 57 63 85 39 11 27 52  7 96 25 91 34 95 71 76 67 23 22 19 99\nCard  32: 58 64 75 63 21 77 74 47 71 87 | 71 82 95 17  6 18 14 87 63 65 39 97 79  2 90 21 48 15 23 33 62 67 31 57 88\nCard  33: 35 53 67 16 68 20 60 39 47 13 | 71 38 80  7 94 95 44 18 27 64 86 23 81 46 31 56 52 73 97 37 58 29 79 40  6\nCard  34:  8 44 93 30 31 81 10 51  1 96 | 73 99 72 32 36 53 28 44 42 29 48 19 34 15 92 75 60 97 39 78 63 43  4 91 95\nCard  35: 74 83 62 26 55 81 84 90 53  2 | 77  3 75 54 71 32 18 21 56 70 65 61  4 96 31 72 11 35  6 91 64 38 87 73 30\nCard  36: 51 54 86 95 90 64 41 18 83  9 |  2 45  4 92  1 62 50 63 78 44 27 58 94 74 30 59 36 71 79 93 52 77 66 80 65\nCard  37: 94 67 88 44 25 18 99 14 63 89 | 17 89 32 71 18 63 19 85 88 91 65 25 14 30 75 48 94 72 99  9 67 36 44 16 62\nCard  38: 59 19 11 51 28 64 91 93 60 85 | 93 95 35 84 58 12 15 85 28 56 59 94 27  6 29 51 41 18 22  7 19 11 13 97  4\nCard  39: 19 47 29 82 31 27 44 66 67 45 |  1 36 31 67 11 54  8  3 45 56 66 73 27 47 53 14 86 82 30 29 44 60 77  7 19\nCard  40: 93 99 27 65 16 26 72 42 71 76 | 16 96 72 68 15 27 89 26 51 29 69 65 98 93 37 22 99 76 50 91 88 71 47 32 42\nCard  41: 23 42 80 53 72 98 95 11 21 93 | 47 80  4 30 23 27 82  3 58 93 66 54 35  8  2 53 14 42 75 61  7 17 36 45 89\nCard  42:  8 28 34 38 71 92 60 51 23 80 | 60 12 15 67 47 97 86 26 90 80 85 54 92 31 64 98  7 55 66  9 82  1 10 35 34\nCard  43: 77 83 18 61 56 78 46 48 80 45 | 41 61 93 45 16  9 38 51 11 48 99 22  3 27 56 66 46 24 80 78 83 75 77 67 18\nCard  44: 43 88 33 17 40 90  5  9 94 42 | 97 42 37 62 32 92 43 64 29 88 40 45 18 58 14 36 46 94 77 82 87 52 71 17  9\nCard  45: 26 76 46 27 66  8 63 67  2 99 | 11 76  8 80 62 46 92 67 74 18 54  2 63  9 99 66 57 27 26 51 58 73 12 50 59\nCard  46: 47 77 74 14 85 90 60 17 53 54 | 98  6 96  8 67 24 74 50 97  7 42 81 20 17 26 16  1  3 62 92 41 90 83 78 44\nCard  47: 52 48 72  1 47 55 36 91 89 82 | 35 62 93 40 36 47 43 82 48 72 89 13 69 99  1 52  2 97 18 55 24 86  9 91 90\nCard  48: 76 75 21 23 91 58 26  7 86 16 |  6 27 86 85 75 21 24  9 46 84 79 89 65 69 53 10 64 28 74 66 43 20 67 99 87\nCard  49: 13 53 58 15 69 68 19 30 48 43 | 13 48  1 41 68 93 34 43 26 15 53 17 91 51 50 19  6 79 39 61 47 30 96 69 58\nCard  50: 24 44 29 16 92 57 86 76 88  3 | 46 30 10 55  4  6 48 41 21  8 67 64 59 13 72 77 22 19 15 27  7 66 84 96  1\nCard  51: 90 36 71 21 76 64 86 79 48 98 | 76 64 53 42 71 59 23 90  9 79 98 27 48 91 13 96  7 21  5 36 33  8  6 86 31\nCard  52: 98 86 23 13 94  8  4 16 96 58 | 23 11 32 34 37 28 76 87 96 42 99 67 35 98 26 36 81  8 65 33 24 60 25 43 45\nCard  53: 81 16  7 78 24 48 84 26 42 61 | 81 78 90 18 24 96 62 61 65 38 54  3 84 26 73 30  6 43 20 49 10 36  8 16 89\nCard  54: 30 80 89 63  7 25 39 68 37 27 | 46 92 78 50 14 33  9  3 95 81 88 98 67 90 94 29 60 39 21 79 11 75 64 61 23\nCard  55: 87 43 58  6 69 78 56 19 64 16 | 87 48 69 53 77 26 31  2 78 19 73 57 76 23 70 44 29 13 80 56 92 82 79 45 12\nCard  56:  6 45 94 77 64 44 74  1 22 37 | 63 45 97  2 13 12 62 11 58 46  4 79 70 53 49 24 68 56 87 34 99 32 67 92 28\nCard  57: 34  1 73  9 87 21 65 39 37 69 | 83 86 41 18 13 32 10 73 75 39 96 52 30 31 63 20 48 33 23 58 17 85 82 71 68\nCard  58: 41 16 68 44 72 62 34 39 81 79 | 78 87 16 27  1 73 68 60 95 59 42 14 89 92 83 94 75 50  6  3  8 48 26 13 76\nCard  59: 45 57 86 29 44 51  6 42 88 31 | 22 13 59 94 83  5 66 17 78 92 64  3 72  8 10  2 12 52 27 79 54 58 18 39 70\nCard  60: 78 56 95 89 68 18 98 42 44 52 | 76 20 51 71 12 22  3 54 70 84  7 39 64 87 86 30  4 83 15 74 37 94 21 82 13\nCard  61: 18 84 14 96 43 38 85 73 71 53 | 92 98 94 23 32  5 30 58 51 68 78 47 75 36 61 89 34 81 35 37 80 44 93 76 69\nCard  62: 73 61 14 52 47 97 93 29 40 37 | 94 27 73 29 47 71 52 22 61 81 93 65 78 35 79 75 99 97 72 14 40  2 30 37 55\nCard  63: 34 13 11 98 36 78 96 31 74 20 | 14 20 85 57 84 88 96 36 50 13 78 34 82 28 62 98 11 52 33 74 55 90 61 31 93\nCard  64: 98 23 79 37  7 21 14 83 12 87 | 86 30 64 90 34 52 97 42 69 81 79 59 63 36  8 21 44 23 13 87 98 76 49 56 37\nCard  65: 11 73 35 16  6 27 63  9 74 51 | 54 84 35 11 49 19 91  6 32 73 99 26 53 16 63 27  9 51  7 85 58 59 33 78 74\nCard  66: 98 95  7 47 92 66 97 11 62 71 | 14 95 11 62 20  4 42 90 51 99 58 97 60 47 71  7 76 66 30 98 57 36 35 92 94\nCard  67: 33 36 32 60 74 54 41 27 88 93 | 22 82 86 58 30 13  9 61  2 15 80 66  5 29 77 78 53 72 24 89 19 12  1  7 73\nCard  68:  1 56 31 24 87  4 49 57 72 91 | 61 40 82 34 55 27 57 73 24 31 47  4 90  6 56 91  1 49 32 98 75 72 94 87 63\nCard  69: 95 32 15 58 27 45 79 23  6 98 | 69 63 18 95 91  8 48  7 38 10 75 26 61  2 12 34 62 22 81 94 67 40 14 25 52\nCard  70: 98 80 82 66 65 41 42 27 94 77 | 77 41 98 27 42 80 79 62 33 63 82 34 14 61 81 94 59 51 52 65 71 57 39 12 66\nCard  71: 69 34 98 15 16 82 49 44 10 19 | 43 96 17 53 89 76 94 45  5 81 29 77 83 75 11 60 87 67 47 22 64 88 18 59  1\nCard  72: 77 18 36 40 80 63 65 14 29 55 | 79 58  7  4 38 85 63 53 65 91 89  2 14 44 55 20 40 26 84 80 35 57 76 74 18\nCard  73: 63 23 39 12 22 35 48 40 84 75 | 79 61 40 58 23 48 75 97 87  4 81 29 84 68 63 51 74 53 35 39 33 24 22 12 60\nCard  74: 35 81 48 36 33 42 82  6 30 31 | 35 31  6 82 59 98 97 53 78 96 46 64 94 79 23 14 74 13 16 56 48 47 81 41 32\nCard  75: 62 43 47  1 15 50 77 14 85  4 | 70 46 16 69 85  3 30 96 62 99 27 47 59 49 26  9 57  1 50 73 94 97 28 20 29\nCard  76: 95 35 81 12 94 26 61 41 38 29 | 45 16 82 99 40 32 17 86 29 91 21 63 67 19 36 20  2 71 50 89  9 44  8 90 85\nCard  77: 74 85 93 55 27 86 16 54 73 82 | 13  3 19 49 11 62 68  7  2 77 25 79 71 61 81 29 84 47 78 32 91 34 15 43 20\nCard  78: 73 62 42 85 54 15  6 95 97 47 | 30 33 51  1  6 47 72 31  5 97 54 17  2 65 49 38 78 82 27 21 36 22 42 24 18\nCard  79: 20 51 62 17 82 37 90 45 98 95 | 20  2 90 40 43 71 60 62 75 16 77 14  6 15 17 52  8 95 32 66 54 45 84 61 70\nCard  80: 64 26 54  2  9 18 92 30 97 48 | 30 64 61  7 37 83 89 36  5 46 17 59 87 51 88 50 15  1 71 35 43 11 14 95 28\nCard  81: 63 57 72 69 11 90 85 30 64 71 | 37 77 13  9 61 60 23 54 62 64  7 56 48  1 85 73 41 68 29 10  3 92 35 12 26\nCard  82: 33 40 45 39 19 41 57 81 73 30 | 97 62 18 89 17 73 46 63 30  6 59 93 82 69 76 39 13 38 23  8 51 57 68 27 48\nCard  83: 92 96 72  5 13  6 45 52 57 54 | 56 14 63 29 19 39 62 76 34 91 43 61 42 27 72 71 89 25 99 23  6 12  7 97 30\nCard  84: 24 62 78 70 93 79 31 95 51 71 | 83 64 12 11 59 29 39 53 26 45 28 74 41  9 89 15 13 37 79 68 95  8 57 96 77\nCard  85: 71 31 76 93 84 57 72 48 73 74 | 51 11 53 68 87 67 31 91 92 15 24 65 58  2 82 42 18 97 61  7 10 47 75 38 27\nCard  86:  9  2 73 47 29 25 53 43 32 22 | 46 15 56 94 80 77 16 12 51 23 78 74 71 35 57 96 41 26 62 63 67 17 61 70 99\nCard  87: 68 37 86 81 50 77 79 76 52 57 |  3 23 65 50 28 29 97 20 48 37 52 38 82 31 66  8 81 86 68 92 79 57 18 76 77\nCard  88: 35 62 52 81 69 49 50 17 84 44 | 96 75 35 39 47  9 88 79 97 13 21 12  2 31 53 67 71 99 77 24 45 84 40 51 94\nCard  89: 87 64 77 62 95 22 21 34 40 49 | 82  6 52 87 34 49 86 63 72 40 22 77 56 62 10 37 64 67 21 73 99 91  2 95 17\nCard  90: 95 78 72 12 23 42 45 73 31 22 | 78  7 10 22 47 29 73 31 97 40 12 15 50 16 87 42 95 45 81 63 69 79 37 23 92\nCard  91: 37 80 51 67 32 59 40  8 38 25 | 38  8 26  1 20 67 80 54 40 51 85 21  3 37 52 32 14 66 13 25 15 23 59 56 48\nCard  92: 87 51 29 92 17 55 18 88 73 33 | 33 37 62  7 19 29 16 57 87 18 60 17 93 73 39 92 63 32 48 65 13 51 70 55  1\nCard  93: 31 40 98 94 45 46 44 83 78 10 | 31 40 68 21 97 45 11 59 98 17 55 10 71 37 46 93 96 78 32 76 39 44 83 48 56\nCard  94: 50 66 26 72  1 77 41 19 97 81 | 49 59 53 42 86 54  6 35 33 91 85 15 12 45 92 38 96 77 73 65 95 46 50 48 19\nCard  95:  2 20 92  4 66 97 30 87 17 14 | 20  2 29 46 97 72 93 60 89 39  6 94 12 13 33 96 30 59  1  5 53 22 83 77 78\nCard  96: 30 73 25 16 48 86 50 54 33 41 | 21 33 26 45 86 37 41 16 48 13 60 58 28 61 76 54 96 25 50 95  2 67 65 68 73\nCard  97: 54 37 39 24 21 62 26 35 25  2 | 10 11 97 16 39 73 35 55 40 93 87 21 14 90 41 36 61 63 13 23 86 96  6 12 38\nCard  98: 25 28 75 32 58 13  4 26 43 71 | 86 33 30 28  4 54 26 21 56 75 17 79 69 58 24 13 81 60 32 84 71 18 10 25 43\nCard  99: 25 86 74 99 26 98 38 59 18 73 | 99 95 10 24  4 20 91 14 46 78 53 34 98 41 73 84 22 43 45 57 86 26 25 74 59\nCard 100: 58 62 97 63 96 95  2 78 17 11 | 59 20  7  2 43 37 28 69 77 33  1 64 63 82 17 51 42 41 75 95 25 83 14 32 22\nCard 101: 84 10 35 37 61 80 65 77 13 92 | 87 80 77  7 58 62 26 35 24 96 37 15 36 91 65 84 83 76 32 94 78 31  6 59 48\nCard 102: 93 24 66 34 86 79 18 68 14 21 | 65 28 80 40 99 67 31 58 71 34 21 19 50 84 64 70 98 74 68 29 87 41 14  5 89\nCard 103: 11 24 96 69 54 77 33 80 87 34 | 77 63 24 56 58 26 93 86 94 27 33 96 36 92 75 49 43 16 54 29 87 81 28 80 34\nCard 104: 13 73 49 36 89 35 76 54 66 83 | 71 41 81 72 61 83 70 76 67 64 26 88 19 10 20 16 35 45 12 73 38 66 92 74 79\nCard 105: 18 74 53 37 19 30 72 84 41 86 | 24 49 23 36 61 12 56 64 85 15 66 40 94 76  2 69 67 38 45  9 48 21 99 20 60\nCard 106: 39 64 95 30 75 41 17 63 84 94 | 54 41 95 55 74 69 17 85 46 27  6 25 83 93 56 48 49 76 22 61 33 34 31 84 37\nCard 107: 42 15 62  4 44 48 14 82 97 70 | 19  9 28 77 70 83 71 85  4 76 38 89 30 21 87 65 13 29 97 31 27 64 74 54 93\nCard 108: 81 38 35 41 74 87 65 46 50 17 | 79 11 58 34 88 35 93 26 84 71 53 56 16 97 77 94 67 54 62  2 90 98 63 28 61\nCard 109: 29 11 71 84 90 94  1 23 54 88 | 84 77 12 87 14 35 49 89 75 63 37 64 10  1 91 97 98 25 86  3 27 57 58 50 96\nCard 110: 29 68  4 60 82 97 38 72 78 75 | 33 50 61 25 44  8 13 46 87 83 49 74 76 39 66 36  6 70 73 81 64 18 24 30 79\nCard 111: 13 86 29 24 16 78 88 98 46 93 | 72 87 69 34 76 56 66 35 81  7 36 95  8 15 53 11 25 99 74  9 67 30 85 91 82\nCard 112: 33 68 45 62 50 42 38 58 22 34 |  4 78 35 42 50 79 52 77 27 75 38 58 34 68 30 62 39 40 33 22 19 37 15  3 45\nCard 113: 59 45 81 42 67 36 32 86 66  6 | 42 62 21 14 38 33 55 36 18 78 49 37  6 10 44 19 73 77 97  1 67 43 25 81 13\nCard 114: 79 82 15 39  3  7 24 71 93 61 | 93 37  3 47 24 31 29 61 68 40 71 34 58 82 79  7 50 83 98 80 74 30 39 18 15\nCard 115: 11 93 43 52 49 88 28 14 55 39 | 55 28 43  1 16 93 42 49 78 31 11 84 52  3 15 72 88 39 14 85 89 36 19 58  8\nCard 116: 18 16 75 88 25 62 33 22 97 98 | 40 38 23 34 37 56 68 80 16 75 81 22 85 12 61  4 27 69  1 83 26 98 76 78 29\nCard 117: 77 39 53 44 81 90 98 52 38  5 | 80 90 69 20 61 35  4 18 83 39 56 36 95 44 98 81 76 23 60 43 38 17 77 55 51\nCard 118: 13 20 72 41 52 73 17 86  2 84 | 10 22 75 54 33 46  9 18 64 27 56 72 42 67 70  1  2 71 94 40 35 73 55 83 68\nCard 119: 48 52 33 58  7 56 71 89 10 18 |  7 66 69  5 70 58 84 92 71 89 57 52 37 18 21 31 12 75 62 79 56 30 26 48 11\nCard 120: 83 74 37 86 32 14 68 60  6 49 | 31 36 83 40 39 47 24 49 68 27 15 82 60 13 38 89 91 85 46 86 37 74 32  6 22\nCard 121: 24 66 45 22 23 36 70 43 11 80 |  9 56 26 33  8 73  4 18 72 69 78 30 17 96 95 89 12 45 91 77 84 28 79 50 19\nCard 122: 74 83 69 12 24 60 61 62 70 76 | 91 24 60 43 84 80 53 16 50 71 61 70 83 33 92  4 59 68 99 31 74 67 22  2 36\nCard 123: 13 79 14 97 25 94 53 99 12 61 | 96 40 67 80 79  1 56 22 25 83  2 72 43 28 64 14 66 65  4 94 59 31 11 21 19\nCard 124:  9 37 93 79 63 83 85  8 34 91 | 28 31 27 69 17 56 15 34 16 90 25 81  4 52 36 68 93 55 97  2 58 10 66 41 14\nCard 125:  9 13  1 15 34 77 14 27 69 45 | 11 28 31 76 39 44 47 96 93  5 91 80 17 68 87 98 24 71 34 36 63 72 49 70 30\nCard 126: 55 85 91 63 19 25 99 48 20 16 | 32 73 77 81 15 19 86 21 29 49 26 33 24 34 69 42 79 11 40 85 18  1 48 90 52\nCard 127: 41 35 53 27 30 82 23 56 58 84 | 79  9 46 95 32 11 56 82 49 19 72  8  7 13 93  1 67 33 66 18 12 59 28 98 96\nCard 128: 78 89 61 31 74 19 81 22 24 90 | 94  7 10 52 76 13 51 23 48 79 34  4 66 45 30 82 96 84 16  5 81 57 37 83 35\nCard 129: 76 15 41  7 79  4 73 12 88 92 | 64  8 58 70 29 56 87 94 59 48 71 53 22 39 81 36 26 45 63  6 54 27 20 47 62\nCard 130:  9 37 30  6 69 20 72 91 22 50 | 83 91 40 50 72 26 94 29 18  1 65  7 79 31 98 47 63 77 97 89 84 60 82  6 61\nCard 131:  4 84 24 97 12 27 68 40 71 21 | 69  6 81 50 18 88 59 54 29 32 71  3  8 75 41 68  4 17 99 79 20 27 24 40 21\nCard 132: 18 17 10 91 62 28 19 97 26 80 | 20 11 95 18  9 38  5  2 97 62 12 30 72 79 86 81 37  7 45 41 17 16 34 52 51\nCard 133:  2 20 42 44 38 99 78 83 25 30 |  3 59 84 66 12 30 14 76 20 78 45 97 42 79 99  8 16 91  2 40 38 56 89 81 90\nCard 134: 38 53 13 31 62 39 15 92  6  5 | 38 84 31  1 11 66 12 50  9 35 41 10 20 89 54 82 63 46 39 43 91 32 90 86 34\nCard 135: 52  5 88  6 18 45 16 19 23  9 | 82 50  3 21 23 64 96  5 17  6 53 36 78 44 66 31 72 15 79 27 86 88 48 18 81\nCard 136: 21 80 86 17  5  8 27 85 31  7 | 49 18 54  7  2 84 44 43 95 40 87 24 17 81 78 56 30 79  9 71 46 76 33 29 85\nCard 137: 46 28 18 88 71 63 78 58 50 33 | 75 20 53 56 30 64 10 11 47 59 91 24 67 76  8  1 43 37 87 52 16 39 84 69 89\nCard 138:  1 95 44 97 17 20 46 40  3 18 | 43 64 44 29 36 61 95 62 50 41 10 72 67  5 82 42 70 55  3 30 24 12 78 81 47\nCard 139: 87 57 36 27 16  3 53 79 66 69 | 83 16 77 41 50 87  8 66  5 91 30 61 82 38 67 24 96 11 17 89 36 45 65 12 27\nCard 140: 45 94 91 85 24 52 16 76 96 75 | 15 35 87 57 23 56 68 97 70 17  3 83 89 60 11 95 79  5 63 80 66 30 72 25  2\nCard 141: 32 34 70 25 16 98 59 64 69 62 | 87 34 22 96 20 19  8  9 61 68 35 28 75 16 88 42 77  6 43 85 14 66 44 67 36\nCard 142: 72 73 81 37 90 31 83 91 95 32 | 82 14 62 45 77 31 17 46 20 36 92  8  1 74 42 84 26 60 88 48 66 95 18 85 30\nCard 143: 23 94 85  5 75 22 39 80 34 58 | 73 40 64 54 42 56 93 26 94 33 71 55 82 72 31  2 59 60 29 41 15 17 76 99 52\nCard 144:  1 26 98  7 44 92 87  6 37 24 | 13 39 11 95  3 93 74 43  8 60 30 40 15  5 78 19 57 99 64 16 83 90 80 63  4\nCard 145: 69 82  7 40 94 28 75 85 74 10 | 98 36 56 86 95  9 16 20 49  6 24 84 83 15 17 57 19 72 89 34  4  2 61 77 44\nCard 146:  9 69 16 74 25 27 11 79 20 10 | 85 69 27 31 21  4  7 13  9 20 37 11 43 83 10 74 16 48 56 79 33 58 96 70 25\nCard 147: 75 14 66 51 86 50 34 57 16 18 | 83  4 68  1 38 84 73 58 86 76 74 66 75 72 44 22 26 87 34 60 95 14 45 40 90\nCard 148: 59 44 21 64 50 60 71 43 11 86 | 66 64 44 85 90 16 74 60 71  6 32 21 91 24 95 36 89 77  7 50 27 86 22 65 43\nCard 149: 64 70 95 44 86 90 19 87 47 15 | 98  9 14 82 17 67 25 60 26 10 95  5 81 39 76 85 52 43 49 23 27 99 50 19  6\nCard 150: 82 35 98 97 53 81 83 96 92 25 | 92 30 57 88 81 68 22 98 82 24 35 53 96 50 36 51 55 83 34 25 56 14 46 54 97\nCard 151: 68 82 83 72 49  5 78 25  4  9 |  4 27 79 49 68 84 34 78 32 82 21  3 77 86  5 48 33 11 53 19 62 26 52 57 87\nCard 152: 64 91 43 65 86 72 35 45 60 97 | 45 62 72 22 41 96 43 76 64 86 92 73  2 21 77 91 27 35 63 71 65 10 97 60 36\nCard 153: 13 82 94 65 49 61 32 31 48 97 |  7 86 75 65 89 22 51 49 77 81 97 37 61 24 34 82 57  6 46 84 12 70 63 94 13\nCard 154: 51 18 36 95 83 99  7 13  9 31 | 95 54 32 48 15 63 85 51 76 36  6 39 73 58 84 27 99 87 31 50 46  9 52 13 18\nCard 155: 73 26 15 84 93 70 91 54 92 12 | 22 92 54  6 67 36 13 15 93 89 55  5 70 71 26  9 16 27 91 21 25 73 82 12 84\nCard 156: 66 88 92 46 57 48 80 40  3 28 | 80 53 66 78 71 95  3 24 90 62 57 64 46 48 88  4 26 31 28 63 19 32 40 23 92\nCard 157: 14 98 81 93  3 94 39 32 12 25 | 58 30 88  8 54 18 50 78 52 36 68 73 74  9 79 49 39 35 15 86  2 10  3 44 65\nCard 158: 72 40 66 34 87 20 54 79 69 16 | 53 65 38 67 51 75 99 39 66 76 21 79 77 13 93 48 17 88 85 35 47 58 72  8 83\nCard 159: 10 83 69 13 53 41 39 37 55 74 |  9 27 90 53 52  2 42  3 62 37 32 61 35 39 95 36 83 26 69 28 29 71 77 16 54\nCard 160: 63 90 68  4 36 61 56 49 64 32 | 36 18 19 37 42  2 23 39 26 40 96 33 55 94 31 51 54 67 89 76 86 95 24 68 11\nCard 161: 38  7 25 30  8 39  9 34 19 28 |  3 10 86 85 13 73 61  9 31 43 40 74 60 67 83 70 57 78 81 63 34 27  8 28 97\nCard 162: 61 38 82 86 51 16  9 17 69 60 | 81 82 12 80 46 65 97 16 49 72 73 71 92 18  1 88 30 26 66 60 74 54 34 13  8\nCard 163: 61 58 38 73 62 21 25 71 49 44 | 79 21 93 85 90 65 36 78 74 94 24 20 39 14 13 63 75 99 42 28 55 40 86 38 89\nCard 164: 25 83 54 70 30 76 50  3 36 21 | 86  3 59 66  9 92 81 48  1 71  6 65 69 50 13 25 88 72 32  2 99 70 61  7 58\nCard 165: 98 70 26 66  7 42 78 93 84 60 | 30 31 38 22 11 25 10 75 46 41 72 60 40 65 37 33 63 51 36 52 76 73 32 58 79\nCard 166: 92 53 96 58  8 65 80 90 88 23 |  9 77 98 21 34 60 31 14 44 26 81 90 91 45 69 99 50 12 36 55  8 48 47 24 54\nCard 167: 14 88 33 30 20 99 64 48 60  5 | 68  2 58 90 63 36 12 94  9 71 96 10 29  1 91 53 67 17 85  8 49 57 69 25 59\nCard 168: 32 18 96 90 74 64  4 86 25 85 | 98 27 95 22 54 40 59 82 19 10 91 87 60 66 45 43 16 72 47 92 62 29 73 88 93\nCard 169:  3 47 80 78 17 68 20 36 54 87 | 75 52 73 43 45 29 53 10 65 89 84 37 90 13 15 40 76 91 88 74  9  7  4 22  1\nCard 170: 28 89 99 67 32 94 21 65 83  1 | 94  2 11 52 27 56 87  1 33 68 99 17 28 44 65 49 83  4 67 32 89 59 23 96 82\nCard 171: 20 76 49 15 91 67 50 97 96  3 | 70 21 96  8 22 34 67 41 48 20 33 56 47 29 37  3 14 63 17 32 51 76 12 52 65\nCard 172: 56 58 86 18 16 79 41 67 12 42 | 20 80 89 33 38 76 48 37 64 57 45 27 36 86 58 41 73 50  7 83 51 43 99 97 17\nCard 173: 15 48 73  6 92 20 50 75  8 32 |  7 55  3 79 44 85 35 30 12 81 60 33 80 56 59 84 70 98 65 61 51 45 99 38 29\nCard 174: 30 50 22 15 20 99 34 28 72 56 | 20 15 99 28  8 50 40 30 83 56  7 10 74 68 39 58 67 70 47 35 38 37 34 22 72\nCard 175: 41 77  9 57  1 24 48  6 92 61 | 75 24 61 92 22 84 76 20 88  1  6 14 74 12 59 71 40 77 41 68 57 64 58  9 63\nCard 176: 18 83 76 28 68 52 50 99 67 90 | 28 99 50 65 90 67 83 76  7 66 38 81 60 36 51 18 27 40 52 56 80 68 91 43 61\nCard 177: 95 28 89 86 65 42 41 44 92 21 | 93 28 22 86 97 18 14 84  7 42 66 72 33 95 76 69 49 59 45 98 26 57 67  1 24\nCard 178: 61  7 31 44 69 71 41 65 27  1 | 41 57 75 32 61  4  1  2 65 64 71 81 87 60 67 47 31 69 29 99 45 43 84 15 28\nCard 179: 80 61 21 75 10 86 36 84 71 43 | 77 80 82 43 84 63 99 21 93 86 60 46 61 36 76 19  3 69 57 75 71 10 13 20 95\nCard 180: 66 16  8 74 36  9 51 40 20 42 | 82 16  8 51 36 32 20 11 79 13  9  3 97 98 33 68 69 29 66  5  7 25 42 40 74\nCard 181: 36 32 49 85 15  6  4 56  1 62 | 80 77 45 83 35 62  9 48 43 17 36 27 32 85 11 89 15 49 56  6 47  1  4 22 20\nCard 182: 15 30 92  9 78 16 38  8 12 34 | 98 52 60 24 80 87 46 13  5 54 23 49 97 89 39 48 40 86  7 32  3 69 81 41  8\nCard 183: 83 16 69  4 53 41 11 65  6 81 | 12 92 35 51 67 71 55 14 73  1 74 80 82 17 94 43 23 78 63 66 96 30  7 61 29\nCard 184: 19 92 71 25 97 80 69 96  3 52 | 98 96 56 69 58 13 65 37 19  3 16 71 43 10 14 21 18 92 97 80 38 25 87 66 57\nCard 185: 38 95 97 10 59 93 98 37 43 81 | 12 34 18  2 14 48 35 86 27 96 82 23 37 21 61 63 68  9 17 69 13  5 43 10 32\nCard 186: 39 40 17 54 99 94 43 46 28 92 | 82 53 71 25 24 51 97 11 33 16 63 41  9 42 69 88  5 96 73 70 21 95 15 47 19\nCard 187: 87 31 45  8 75 30  7 62 22 79 | 86 72 36  8 60 63 40  7 38 65 11 29 92  2 28 59 14 19 87 35 91 12 16 41 57\nCard 188: 97 21 10  3 26 27 15 37 75 62 | 17 16 67 74 76  5 90 95 37 25 33 84 40 10 23 12 98 79 27  3 66 82 97 54 58\nCard 189: 89 21 23  2 19 93 12 67 58 88 | 66 79 21 16 78  5 12 30 88 83 58  1  6 45 76 95 46 39 31 77 33 19  7 51 69\nCard 190: 82 94 59 34 86 52 85 29 41 63 | 64 78 89 34 12 22 68 24 30 46 18 84 86 73 23 58 21  8  1 25 42 74 67 62 38\nCard 191: 71 80 45 39 12 15 24 83 53 33 | 96 23 86 70 52 57 37 75 35 82 61 13  5 87 62 54 16 85 32 53 63 66 30 22 67\nCard 192: 29 54 14 10 45 83 59 50 95 77 | 60 33 93 82 73 78  4 91 65 29 70 16 69 40 64 36 22 26 77 34  8 17 49 63 99\nCard 193: 62 71 81 41 93 98 42 73 34 96 | 89 86 51 60  8 87 34 72 35 45 43 67 38 28 46 24 95 97 47 77 20 80 74  2 85\nCard 194: 13  3  2 66 96 63 94 17 43  4 | 70 82 54 83 77 40  6 38 11  9  7 19 68  1 84 92 56 97 80 75 49 33 27 34 23\nCard 195: 92  7 61 33 40 95 63  6 96 93 | 41 80 64 81 63 40 57 33 49 24 95 26 89 61 39 92 74  6  1 31 93 29  7 48 56\nCard 196: 51 16 52 67 39 57 82 71 76 94 | 61 69 82 70 25 52 56 28 31 19 65 16 13 59 74 90  1 99 88 44 85 91  6 62 54\nCard 197: 87 32 97 31 84 79 24 99 62 12 | 80  3 35 12 32 66 81 62 22  8 20 30 95 61 93 16 73 51 96 15 31 84 19 24 58\nCard 198: 93 38 58 96 22 29 97 84 56 25 |  5 84 42 56 25 22 10 97 41 58 96 38 64 88 35 93 54 29 81 19 30 91 62  8 47\nCard 199: 34 58  6 57 29 99 79 47 94 37 | 61 86  4 23 97 47  9 35 53 34 30 13 25 56 79 89 81 93  8 18 91 43 16 80 90\nCard 200: 87 43 48 95 20 10 51 89 35 21 | 74 75 20 87 50 68 89 12 78 35 10 43 21 95 48 41 51 52 84 42  2  9 26 17 29\nCard 201: 97 38 88  9 17 29 34 64 20 72 | 39 79 30 17 78 72  4  5 20 95 60 69 28 62 32 85 43 38 87 12 96  7 27 10  6\nCard 202: 10 77 45 36 43 32 73 75 47 41 | 32 84 45 21 83 87 62 47 10 43 64  7 75 49 42 61 77 19 73 41 23 44 37 27 60\nCard 203: 97 44 48 40  2 31 28 27 83 73 | 58 82 83 99 17 40 97 96 95 90 72 69 63 21 14 59 62  2 84  6 48 35 93 27 55\nCard 204: 64 66 23 63 79 99 49 44 39 69 | 12 62 92  9 51 43 31 36 42 20 48 99 16 46 81 93 57 50 32 97 59 73 14 76 10\nCard 205: 28 52 50 53 43 32 98 97 61 72 | 62 16 18 71  8 44 11 36 59 41  1 57 84 24 15 56 19 81 55 26 30 85 94 52 75\nCard 206: 93 90 72 22 44 52  8 75 68 73 | 74 33 10 97 99 11 25 36 27 87 79 47 81 95  6 91 55 34 59 67 92 56 23 98 24\nCard 207: 29 92 17 56 98 84 96 71 13 61 | 68 80  1 66 36 30 46 58 40 12  3 10 82 25 74 97 61 53 56 22 95 57 86 63 11\nCard 208: 22 30 79 95 51 11 54 23 29 78 |  6 95 18 29 26 54 12 34 87 40 77 90 73  7  5 22 97 43 81 14 33 59 82 23 20\nCard 209: 58  1 51 44 83 17 70 95 26 66 | 79 62 91 74 25 53 68 87 23 96 88 93 27 21 61 24 75 57 92 46 97 38 59 64 42\nCard 210: 31 59  3 38 30 69 84 24 48 20 | 82 87 98 38 13 64 63 55 68 49  8 26 76 58 81 22 54 31  3 80 84  4 52 53 41\nCard 211: 99 37 92 70  2 88 33 84 63  9 | 50 24 57 65 51 15 21 12  7 23 49 77 60 71 67 56 90 69 95 96 18 81 93 82 53\nCard 212: 38 22 26 25 62 17 71 88 31 86 | 66 64  9 75 74 35 15 33 56 59 98 70 94 73 24 13 20 27 78 28  6 79 51 90 97\nCard 213: 67 96 40 18 19 51 28 23 36 47 | 61 99 58 43 95 81 16 24 65  9 54  4 87 84 32 42 69 64 45 52 20 72 13 66 62\nCard 214: 11 74 92 36 26 68 78 73  5 80 | 67 15  3 22 46 41 87 64 53 89 52 85 99 61 84 31 28 86 77 19 75  1  9 72 82\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_04_questions.txt",
    "content": "--- Day 4: Scratchcards ---\n\nThe gondola takes you up. Strangely, though, the ground doesn't seem to be coming with you; you're not climbing a mountain. As the circle of Snow Island recedes below you, an entire new landmass suddenly appears above you! The gondola carries you to the surface of the new island and lurches into the station.\n\nAs you exit the gondola, the first thing you notice is that the air here is much warmer than it was on Snow Island. It's also quite humid. Is this where the water source is?\n\nThe next thing you notice is an Elf sitting on the floor across the station in what seems to be a pile of colorful square cards.\n\n\"Oh! Hello!\" The Elf excitedly runs over to you. \"How may I be of service?\" You ask about water sources.\n\n\"I'm not sure; I just operate the gondola lift. That does sound like something we'd have, though - this is Island Island, after all! I bet the gardener would know. He's on a different island, though - er, the small kind surrounded by water, not the floating kind. We really need to come up with a better naming scheme. Tell you what: if you can help me with something quick, I'll let you borrow my boat and you can go visit the gardener. I got all these scratchcards as a gift, but I can't figure out what I've won.\"\n\nThe Elf leads you over to the pile of colorful cards. There, you discover dozens of scratchcards, all with their opaque covering already scratched off. Picking one up, it looks like each card has two lists of numbers separated by a vertical bar (|): a list of winning numbers and then a list of numbers you have. You organize the information into a table (your puzzle input).\n\nAs far as the Elf has been able to figure out, you have to figure out which of the numbers you have appear in the list of winning numbers.\nThe first match makes the card worth one point and each match after the first doubles the point value of that card.\n\nFor example:\n\nCard 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53\nCard 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19\nCard 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1\nCard 4: 41 92 73 84 69 | 59 84 76 51 58  5 54 83\nCard 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36\nCard 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11\n\nIn the above example, card 1 has five winning numbers (41, 48, 83, 86, and 17) and eight numbers you have (83, 86, 6, 31, 17, 9, 48, and 53).\nOf the numbers you have, four of them (48, 83, 17, and 86) are winning numbers!\nThat means card 1 is worth 8 points (1 for the first match, then doubled three times for each of the three matches after the first).\n\n    Card 2 has two winning numbers (32 and 61), so it is worth 2 points.\n    Card 3 has two winning numbers (1 and 21), so it is worth 2 points.\n    Card 4 has one winning number (84), so it is worth 1 point.\n    Card 5 has no winning numbers, so it is worth no points.\n    Card 6 has no winning numbers, so it is worth no points.\n\nSo, in this example, the Elf's pile of scratchcards is worth 13 points.\n\nTake a seat in the large pile of colorful cards. How many points are they worth in total?\n\n--- Part Two ---\n\nJust as you're about to report your findings to the Elf, one of you realizes that the rules have actually been printed on the back of every card this whole time.\n\nThere's no such thing as \"points\". Instead, scratchcards only cause you to win more scratchcards equal to the number of winning numbers you have.\n\nSpecifically, you win copies of the scratchcards below the winning card equal to the number of matches.\nSo, if card 10 were to have 5 matching numbers, you would win one copy each of cards 11, 12, 13, 14, and 15.\n\nCopies of scratchcards are scored like normal scratchcards and have the same card number as the card they copied.\nSo, if you win a copy of card 10 and it has 5 matching numbers, it would then win a copy of the same cards that the original card 10 won: cards 11, 12, 13, 14, and 15.\nThis process repeats until none of the copies cause you to win any more cards. (Cards will never make you copy a card past the end of the table.)\n\nThis time, the above example goes differently:\n\nCard 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53\nCard 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19\nCard 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1\nCard 4: 41 92 73 84 69 | 59 84 76 51 58  5 54 83\nCard 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36\nCard 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11\n\n    Card 1 has four matching numbers, so you win one copy each of the next four cards: cards 2, 3, 4, and 5.\n    Your original card 2 has two matching numbers, so you win one copy each of cards 3 and 4.\n    Your copy of card 2 also wins one copy each of cards 3 and 4.\n    Your four instances of card 3 (one original and three copies) have two matching numbers, so you win four copies each of cards 4 and 5.\n    Your eight instances of card 4 (one original and seven copies) have one matching number, so you win eight copies of card 5.\n    Your fourteen instances of card 5 (one original and thirteen copies) have no matching numbers and win no more cards.\n    Your one instance of card 6 (one original) has no matching numbers and wins no more cards.\n\nOnce all of the originals and copies have been processed, you end up with 1 instance of card 1, 2 instances of card 2, 4 instances of card 3, 8 instances of card 4, 14 instances of card 5, and 1 instance of card 6.\nIn total, this example pile of scratchcards causes you to ultimately have 30 scratchcards!\n\nProcess all of the original and copied scratchcards until no more scratchcards are won.\nIncluding the original set of scratchcards, how many total scratchcards do you end up with?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_05.adb",
    "content": "--  Solution to Advent of Code 2023, Day 5\n------------------------------------------\n--  If You Give A Seed A Fertilizer\n--\n--  https://adventofcode.com/2023/day/5\n--  Copy of questions in: aoc_2023_05_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_05 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  type Mapping_Rule is record\n    dest_start, source_start, length : Integer_64;\n  end record;\n\n  max_list : constant := 50;\n\n  type Mapping_List is array (1 .. max_list) of Mapping_Rule;\n\n  type Map_Type is record\n    top  : Natural;\n    list : Mapping_List;\n  end record;\n\n  type Relation is\n    (seed_to_soil,\n     soil_to_fertilizer,\n     fertilizer_to_water,\n     water_to_light,\n     light_to_temperature,\n     temperature_to_humidity,\n     humidity_to_location);\n\n  map : array (Relation) of Map_Type;\n\n  seed : array (1 .. max_list) of Integer_64;\n  top_seed : Natural;\n\n  procedure Read_Data is\n    --  input : constant VString := +\"mini.txt\";\n    input : constant VString := +\"aoc_2023_05.txt\";\n    --\n    seed_header : String (1 .. 7);\n    f : File_Type;\n  begin\n    top_seed := 0;\n    --\n    Open (f, input);\n    while not End_Of_File (f) loop\n      Get (f, seed_header);\n      while not End_Of_Line (f) loop\n        top_seed := top_seed + 1;\n        Get (f, seed (top_seed));\n      end loop;\n      Skip_Line (f);\n      for r in Relation loop\n        map (r).top := 0;\n        Skip_Line (f, 2);\n        while not End_Of_Line (f) loop\n          map (r).top := map (r).top + 1;\n          Get (f, map (r).list (map (r).top).dest_start);\n          Get (f, map (r).list (map (r).top).source_start);\n          Get (f, map (r).list (map (r).top).length);\n          exit when End_Of_File (f);\n          Skip_Line (f);\n        end loop;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Walk_down_Maps (x : in out Integer_64; start_rule : in Relation) is\n    offset : Integer_64;\n  begin\n    for r in start_rule .. Relation'Last loop\n      for li in 1 .. map (r).top loop\n        if x in\n          map (r).list (li).source_start ..\n          map (r).list (li).source_start + map (r).list (li).length - 1\n        then\n          offset := x - map (r).list (li).source_start;\n          x := map (r).list (li).dest_start + offset;\n          exit;\n        end if;\n      end loop;\n    end loop;\n  end Walk_down_Maps;\n\n  procedure Walk_up_Maps (x : in out Integer_64; start_rule : in Relation) is\n    offset : Integer_64;\n  begin\n    for r in reverse Relation'First .. start_rule loop\n      for li in 1 .. map (r).top loop\n        if x in\n          map (r).list (li).dest_start ..\n          map (r).list (li).dest_start + map (r).list (li).length - 1\n        then\n          offset := x - map (r).list (li).dest_start;\n          x := map (r).list (li).source_start + offset;\n          exit;\n        end if;\n      end loop;\n    end loop;\n  end Walk_up_Maps;\n\n  r : array (Part_Type) of Integer_64;\n  lowest_1, lowest_2 : Integer_64 := Integer_64'Last;\n\n  procedure Lowest_Location_Part_1 is\n    x_down : Integer_64;\n  begin\n    for s in 1 .. top_seed loop\n      x_down := seed (s);\n      Walk_down_Maps (x_down, seed_to_soil);\n      lowest_1 := Min (lowest_1, x_down);\n      if s mod 2 = 1 then\n        lowest_2 := Min (lowest_2, x_down);\n      end if;\n    end loop;\n    r (part_1) := lowest_1;\n  end Lowest_Location_Part_1;\n\n  procedure Lowest_Location_Part_2 is\n\n    procedure Test (start_point : Integer_64; r : Relation) is\n\n      --  We use the fact that the optimal path (the path that goes from a\n      --  seed to the minimal location number) touches the left bound of\n      --  at least one range (of those explicitly stated in the Almanac,\n      --  including seed ranges, or of implicit ones: for each transition\n      --  level, between two explicit ranges, or from 0 to the first range,\n      --  or from the last range to the infinity).\n\n      --  Proof (Reductio ad absurdum):\n      --  -----\n      --         Let s -> L(s) the function that associates stem s\n      --         to its location following the Almanac's rules.\n      --         Assume we have sm such as L(sm) is minimal, but the path\n      --         from sm to L(sm) doesn't touch any left bound.\n      --         In that case, sm - 1 is in the same seed range as sm and\n      --         in the same seed-to-soil source range as sm; the soil number\n      --         for (sm - 1) is the same soil-to-fertilizer source range as\n      --         for sm, and so on. The path from (sm - 1) down to the\n      --         location number is the same as the path from sm, but shifted\n      --         by - 1 at each level.\n      --         So, L(sm - 1) = L(sm) - 1.\n      --         Therefore, L(sm) is not the claimed minimum. QED.\n\n      x_up, x_down : Integer_64 := start_point;\n    begin\n      --  1) We check if x_up in source can stem from any seed range.\n      --     The test assumes injectivity in the whole mapping.\n      --     Otherwise we could have cases where the Walk_up_Maps' result\n      --     is in no seed range but some way down from some seed range\n      --     could still lead to start_point.\n      if r > Relation'First then\n        Walk_up_Maps (x_up, Relation'Pred (r));\n      end if;\n      for s_idx in 1 .. top_seed loop\n        if s_idx mod 2 = 1 then\n          if x_up in seed (s_idx) .. seed (s_idx) + seed (s_idx + 1) - 1 then\n            --  Ok, x_up (now, a seed number) is in the considered seed range.\n            --  2) We follow x_down down to category \"location\",\n            --     like for part 1.\n            Walk_down_Maps (x_down, r);\n            --  x_down is now a location number.\n            lowest_2 := Min (lowest_2, x_down);\n            exit;\n          end if;\n        end if;\n      end loop;\n    end Test;\n\n  begin\n    --  The case with the left bound of seed ranges is already\n    --  treated by Lowest_Location_Part_1.\n    for r in Relation loop\n      for li in 1 .. map (r).top loop\n        --  Test left bound of explicit range \"li\" for category \"r\":\n        --  Note: this test is sufficient to find the solution\n        --  for data aoc_2023_05.txt, but is certainly due to luck.\n        Test (map (r).list (li).source_start, r);\n        --  Test left bound of the implicit range that is right\n        --  after the explicit one:\n        Test (map (r).list (li).source_start + map (r).list (li).length, r);\n      end loop;\n      --  Test the remaining implicit range, which starts with 0.\n      Test (0, r);\n    end loop;\n    r (part_2) := lowest_2;\n  end Lowest_Location_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n\n  Read_Data;\n  Lowest_Location_Part_1;\n  Lowest_Location_Part_2;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 261668924\n    --  Part 2: validated by AoC: 24261545\n  end if;\n\nend AoC_2023_05;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_05.txt",
    "content": "seeds: 2041142901 113138307 302673608 467797997 1787644422 208119536 143576771 99841043 4088720102 111819874 946418697 13450451 3459931852 262303791 2913410855 533641609 2178733435 26814354 1058342395 175406592\n\nseed-to-soil map:\n1270068015 1235603193 242614277\n13415696 1478217470 21049126\n825250550 1160341941 75261252\n3786189027 1971702238 242038712\n3191605340 3433644052 172752250\n2389904665 3088515862 345128190\n0 1499266596 13415696\n1197451933 0 72616082\n2139929050 1721726623 249975615\n900511802 222541761 147014452\n1047526254 72616082 149925679\n34464822 980591812 179750129\n2735032855 2631943377 456572485\n3364357590 3606396302 421831437\n214214951 369556213 611035599\n1721726623 2213740950 418202427\n\nsoil-to-fertilizer map:\n226793587 358613369 356867344\n0 1838890301 226793587\n2741010192 0 358613369\n2257843811 715480713 173982825\n3099623561 1264222741 3082010\n1810570233 2912833547 326150077\n4038242924 3815312886 256724372\n2431826636 3268919687 279247493\n866869902 1671637223 167253078\n3102705571 889463538 374759203\n1615333950 2646894858 125679350\n2136720310 1550513722 121123501\n3477464774 2772574208 140259339\n1034122980 2065683888 581210970\n2711074129 3238983624 29936063\n583660931 1267304751 283208971\n1741013300 3548167180 69556933\n3815312886 4072037258 222930038\n\nfertilizer-to-water map:\n2197389106 1911800263 305927673\n3117278994 244526473 20512291\n2957263700 4069704360 136102838\n1536592951 2749121858 245216219\n3093366538 840656765 23912456\n815267737 2718368501 30753357\n3137791285 3392529258 82147206\n3770129899 390297301 198889495\n2168252150 2217727936 29136956\n770420674 2367771416 44847063\n3304122356 4205807198 44047643\n94626393 318562852 71734449\n2518697514 2262245627 10899396\n1967704281 265038764 53524088\n846021094 2994338077 264934624\n1215514867 3881882833 187821527\n1781809170 2556752263 100818318\n1882627488 1690877042 85076793\n208796777 631622731 209034034\n2583608714 3508227847 39876494\n519341481 1587040614 19652563\n599791964 104559149 139967324\n3430004623 1246915338 340125276\n1110955718 0 104559149\n2623485208 3548104341 333778492\n1403336394 3259272701 133256557\n0 2273145023 94626393\n2529596910 1857788459 54011804\n166360842 589186796 42435935\n3219938491 1606693177 84183865\n2165362153 3505337850 2889997\n2021228369 2412618479 72557496\n538994044 2657570581 60797920\n739759288 3474676464 30661386\n417830811 1154801218 92114120\n509944931 864569221 9396550\n2093785865 2485175975 71576288\n3969019394 873965771 280835447\n2503316779 2246864892 15380735\n3348169999 1775953835 81834624\n\nwater-to-light map:\n3059617387 1101868951 93963271\n2772853640 2098642805 169363292\n193287974 683814429 1482323\n3780234682 1734000399 364642406\n194770297 193287974 490526455\n3550500423 902417243 199451708\n3466829263 2268006097 83671160\n3379471616 2976813583 87357647\n2283311570 2369871058 489542070\n3768145932 1195832222 12088750\n1202605712 3064171230 1080705858\n2942216932 2859413128 107440729\n3749952131 2351677257 18193801\n3049657661 2966853857 9959726\n902417243 1433811930 300188469\n3153580658 1207920972 225890958\n\nlight-to-temperature map:\n1088722200 1345179841 10000894\n4202170199 3029124889 92797097\n3016749137 3130683307 53232372\n534766220 331633133 9297796\n190275035 286706851 44926282\n3069981509 1355180735 96127340\n1579189291 3913052943 379484702\n3918942962 3793498681 21754451\n262413801 377451173 88614642\n2452226090 2443004441 143726844\n1958673993 2586731285 188604820\n2595952934 3815253132 97799811\n882433672 754981589 206288528\n608195463 3121921986 8761321\n393888178 145828809 140878042\n3166108849 1530740045 97835767\n351028443 139489318 6339491\n3410232629 961270117 222147493\n2449796439 4292537645 2429651\n2401067597 1890048598 48728842\n3263944616 2376148398 66856043\n3330800659 1451308075 79431970\n3632380122 2019388074 205952206\n1548873457 1323582243 21597598\n2693752745 2225340280 142089882\n357367934 340930929 36520244\n0 493278299 50785717\n768194739 645497224 68742488\n2876584504 1183417610 140164633\n235201317 466065815 27212484\n1570471055 2367430162 8718236\n2147278813 2775336105 253788784\n874238988 3335153634 8194684\n2835842627 714239712 40741877\n3838332328 1938777440 80610634\n50785717 0 139489318\n616956784 3183915679 151237955\n836937227 608195463 37301761\n1098723094 3343348318 450150363\n3940697413 1628575812 261472786\n\ntemperature-to-humidity map:\n3865679795 3411240257 137388137\n0 569718370 128927628\n2284256983 1093255418 349419361\n2189606444 2745948834 16886013\n3861728218 3796217004 3951577\n700036088 2134161201 67667679\n2639129496 1078899666 14355752\n4003067932 4146768977 27598493\n569558723 2311178479 130477365\n4125126694 3887925067 11822916\n1884679865 1442674779 129657290\n2633676344 1572332069 5453152\n862461784 1577785221 531688422\n4030666425 4120171499 26597478\n195554894 115268399 39538402\n235093296 235252943 334465427\n2132287170 698645998 57319274\n4158735055 3550090086 136232241\n2206492457 157488417 77764526\n3562496130 3899747983 220423516\n2653485248 2201828880 109349599\n2014337155 154806801 2681616\n1580787383 2536413861 97415145\n3453031511 3880534101 7390966\n1394150206 2633829006 45492562\n4057263903 3686322327 7821024\n4157273363 3548628394 1461692\n3460422477 3694143351 102073653\n4136949610 3800168581 20323753\n1678202528 872422329 206477337\n1556099825 2109473643 24687558\n128927628 2679321568 66627266\n2017018771 0 115268399\n4065084927 3820492334 60041767\n3411240257 4253176042 41791254\n767703767 2441655844 94758017\n1439642768 755965272 116457057\n3782919646 4174367470 78808572\n\nhumidity-to-location map:\n347042062 4204488573 2962316\n877642375 2878291222 23518224\n3638916554 3484768713 5466055\n2890676240 3280663590 83564486\n201731623 3228655138 52008452\n1692198890 1946017811 25211210\n1717410100 1270737209 92827656\n3598929376 3630765534 39987178\n2226479211 1578430526 262844314\n687169155 3670752712 117494406\n3884728324 1515480569 62949957\n3494186405 1841274840 104742971\n2753482998 2630924017 120642845\n572458731 2235388494 114710424\n3947678281 3490234768 140530766\n3433348031 3167816764 60838374\n350004378 2406580589 222454353\n804663561 1442501755 72978814\n4132461733 2901809446 35781203\n4088209047 2937590649 38937925\n1441554453 2350098918 56481671\n3644382609 201731623 240345715\n2489323525 1971229021 264159473\n2974240726 3086380958 81435806\n4127146972 3364228076 5314761\n901160599 4207450889 87516407\n988677006 442077338 350976352\n1498036124 3369542837 115225876\n1810237756 3788247118 416241455\n1613262000 1363564865 78936890\n253740075 2993078971 93301987\n3055676532 894954785 375782424\n1339653358 793053690 101901095\n2874125843 2976528574 16550397\n3431458956 2629034942 1889075\n4168242936 2751566862 126724360\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_05_questions.txt",
    "content": "--- Day 5: If You Give A Seed A Fertilizer ---\n\nYou take the boat and find the gardener right where you were told he would be: managing a giant \"garden\" that looks more to you like a farm.\n\n\"A water source? Island Island is the water source!\" You point out that Snow Island isn't receiving any water.\n\n\"Oh, we had to stop the water because we ran out of sand to filter it with!\nCan't make snow with dirty water.\nDon't worry, I'm sure we'll get more sand soon; we only turned off the water a few days... weeks... oh no.\"\nHis face sinks into a look of horrified realization.\n\n\"I've been so busy making sure everyone here has food that I completely forgot to check why we stopped getting more sand!\nThere's a ferry leaving soon that is headed over in that direction - it's much faster than your boat. Could you please go check it out?\"\n\nYou barely have time to agree to this request when he brings up another.\n\"While you wait for the ferry, maybe you can help us with our food production problem.\n The latest Island Island Almanac just arrived and we're having trouble making sense of it.\"\n\nThe almanac (your puzzle input) lists all of the seeds that need to be planted.\nIt also lists what type of soil to use with each kind of seed, what type of fertilizer to use with each kind of soil, what type of water to use with each kind of fertilizer, and so on.\nEvery type of seed, soil, fertilizer and so on is identified with a number, but numbers are reused by each category - that is, soil 123 and fertilizer 123 aren't necessarily related to each other.\n\nFor example:\n\nseeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4\n\nThe almanac starts by listing which seeds need to be planted: seeds 79, 14, 55, and 13.\n\nThe rest of the almanac contains a list of maps which describe how to convert numbers from a source category into numbers in a destination category.\nThat is, the section that starts with seed-to-soil map: describes how to convert a seed number (the source) to a soil number (the destination).\nThis lets the gardener and his team know which soil to use with which seeds, which water to use with which fertilizer, and so on.\n\nRather than list every source number and its corresponding destination number one by one, the maps describe entire ranges of numbers that can be converted.\nEach line within a map contains three numbers: the destination range start, the source range start, and the range length.\n\nConsider again the example seed-to-soil map:\n\n50 98 2\n52 50 48\n\nThe first line has a destination range start of 50, a source range start of 98, and a range length of 2.\nThis line means that the source range starts at 98 and contains two values: 98 and 99.\nThe destination range is the same length, but it starts at 50, so its two values are 50 and 51.\nWith this information, you know that seed number 98 corresponds to soil number 50 and that seed number 99 corresponds to soil number 51.\n\nThe second line means that the source range starts at 50 and contains 48 values: 50, 51, ..., 96, 97.\nThis corresponds to a destination range starting at 52 and also containing 48 values: 52, 53, ..., 98, 99.\nSo, seed number 53 corresponds to soil number 55.\n\nAny source numbers that aren't mapped correspond to the same destination number.\nSo, seed number 10 corresponds to soil number 10.\n\nSo, the entire list of seed numbers and their corresponding soil numbers looks like this:\n\nseed  soil\n0     0\n1     1\n...   ...\n48    48\n49    49\n50    52\n51    53\n...   ...\n96    98\n97    99\n98    50\n99    51\n\nWith this map, you can look up the soil number required for each initial seed number:\n\n    Seed number 79 corresponds to soil number 81.\n    Seed number 14 corresponds to soil number 14.\n    Seed number 55 corresponds to soil number 57.\n    Seed number 13 corresponds to soil number 13.\n\nThe gardener and his team want to get started as soon as possible, so they'd like to know the closest location that needs a seed.\nUsing these maps, find the lowest location number that corresponds to any of the initial seeds.\nTo do this, you'll need to convert each seed number through other categories until you can find its corresponding location number.\nIn this example, the corresponding types are:\n\n    Seed 79, soil 81, fertilizer 81, water 81, light 74, temperature 78, humidity 78, location 82.\n    Seed 14, soil 14, fertilizer 53, water 49, light 42, temperature 42, humidity 43, location 43.\n    Seed 55, soil 57, fertilizer 57, water 53, light 46, temperature 82, humidity 82, location 86.\n    Seed 13, soil 13, fertilizer 52, water 41, light 34, temperature 34, humidity 35, location 35.\n\nSo, the lowest location number in this example is 35.\n\nWhat is the lowest location number that corresponds to any of the initial seed numbers?\n\n--- Part Two ---\n\nEveryone will starve if you only plant such a small number of seeds.\nRe-reading the almanac, it looks like the seeds: line actually describes ranges of seed numbers.\n\nThe values on the initial seeds: line come in pairs.\nWithin each pair, the first value is the start of the range and the second value is the length of the range.\nSo, in the first line of the example above:\n\nseeds: 79 14 55 13\n\nThis line describes two ranges of seed numbers to be planted in the garden.\nThe first range starts with seed number 79 and contains 14 values: 79, 80, ..., 91, 92.\nThe second range starts with seed number 55 and contains 13 values: 55, 56, ..., 66, 67.\n\nNow, rather than considering four seed numbers, you need to consider a total of 27 seed numbers.\n\nIn the above example, the lowest location number can be obtained from seed number 82, which corresponds to soil 84, fertilizer 84, water 84, light 77, temperature 45, humidity 46, and location 46.\nSo, the lowest location number is 46.\n\nConsider all of the initial seed numbers listed in the ranges on the first line of the almanac.\nWhat is the lowest location number that corresponds to any of the initial seed numbers?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_06.adb",
    "content": "--  Solution to Advent of Code 2023, Day 6\n------------------------------------------\n--  Wait For It\n--\n--  https://adventofcode.com/2023/day/6\n--  Copy of questions in: aoc_2023_06_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_06 is\n  use AoC_Toolbox, HAT;\n\n  function Find_Records (total_time, distance : Real) return Natural is\n    --  Solutions of:\n    --\n    --            distance = (total_time - t)  *  t\n    --                       ^-time for running   ^-speed\n    --\n    --  where t is the time of pressing the button\n    --\n    sqrt_discriminant : constant Real := Sqrt (total_time ** 2 - 4.0 * distance);\n    t1 : constant Real := (total_time - sqrt_discriminant) * 0.5;\n    t2 : constant Real := (total_time + sqrt_discriminant) * 0.5;\n  begin\n    return Natural (t2 - 0.5) - Natural (t1 + 0.5) + 1;\n  end Find_Records;\n\n  r : array (Part_Type) of Integer;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n\n  r (part_1) :=\n    --  Example:\n    --     Find_Records  (7.0,   9.0) *\n    --     Find_Records (15.0,  40.0) *\n    --     Find_Records (30.0, 200.0);\n    Find_Records (62.0,  644.0) *\n    Find_Records (73.0, 1023.0) *\n    Find_Records (75.0, 1240.0) *\n    Find_Records (65.0, 1023.0);\n\n  r (part_2) := Find_Records (62737565.0, 644102312401023.0);\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 393120\n    --  Part 2: validated by AoC: 36872656\n  end if;\nend AoC_2023_06;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_06_questions.txt",
    "content": "--- Day 6: Wait For It ---\n\nThe ferry quickly brings you across Island Island.\nAfter asking around, you discover that there is indeed normally a large pile of sand somewhere near here, but you don't see anything besides lots of water and the small island where the ferry has docked.\n\nAs you try to figure out what to do next, you notice a poster on a wall near the ferry dock.\n\"Boat races! Open to the public! Grand prize is an all-expenses-paid trip to Desert Island!\"\nThat must be where the sand comes from! Best of all, the boat races are starting in just a few minutes.\n\nYou manage to sign up as a competitor in the boat races just in time.\nThe organizer explains that it's not really a traditional race - instead, you will get a fixed amount of time during which your boat has to travel as far as it can, and you win if your boat goes the farthest.\n\nAs part of signing up, you get a sheet of paper (your puzzle input) that lists the time allowed for each race and also the best distance ever recorded in that race.\nTo guarantee you win the grand prize, you need to make sure you go farther in each race than the current record holder.\n\nThe organizer brings you over to the area where the boat races are held.\nThe boats are much smaller than you expected - they're actually toy boats, each with a big button on top.\nHolding down the button charges the boat, and releasing the button allows the boat to move.\nBoats move faster if their button was held longer, but time spent holding the button counts against the total race time.\nYou can only hold the button at the start of the race, and boats don't move until the button is released.\n\nFor example:\n\nTime:      7  15   30\nDistance:  9  40  200\n\nThis document describes three races:\n\n    The first race lasts 7 milliseconds. The record distance in this race is 9 millimeters.\n    The second race lasts 15 milliseconds. The record distance in this race is 40 millimeters.\n    The third race lasts 30 milliseconds. The record distance in this race is 200 millimeters.\n\nYour toy boat has a starting speed of zero millimeters per millisecond.\nFor each whole millisecond you spend at the beginning of the race holding down the button, the boat's speed increases by one millimeter per millisecond.\n\nSo, because the first race lasts 7 milliseconds, you only have a few options:\n\n    Don't hold the button at all (that is, hold it for 0 milliseconds) at the start of the race.\n      The boat won't move; it will have traveled 0 millimeters by the end of the race.\n    Hold the button for 1 millisecond at the start of the race.\n      Then, the boat will travel at a speed of 1 millimeter per millisecond for 6 milliseconds, reaching a total distance traveled of 6 millimeters.\n    Hold the button for 2 milliseconds, giving the boat a speed of 2 millimeters per millisecond.\n      It will then get 5 milliseconds to move, reaching a total distance of 10 millimeters.\n    Hold the button for 3 milliseconds.\n      After its remaining 4 milliseconds of travel time, the boat will have gone 12 millimeters.\n    Hold the button for 4 milliseconds.\n      After its remaining 3 milliseconds of travel time, the boat will have gone 12 millimeters.\n    Hold the button for 5 milliseconds, causing the boat to travel a total of 10 millimeters.\n    Hold the button for 6 milliseconds, causing the boat to travel a total of 6 millimeters.\n    Hold the button for 7 milliseconds. That's the entire duration of the race. You never let go of the button.\n      The boat can't move until you let you of the button.\n      Please make sure you let go of the button so the boat gets to move. 0 millimeters.\n\nSince the current record for this race is 9 millimeters, there are actually 4 different ways you could win: you could hold the button for 2, 3, 4, or 5 milliseconds at the start of the race.\n\nIn the second race, you could hold the button for at least 4 milliseconds and at most 11 milliseconds and beat the record, a total of 8 different ways to win.\n\nIn the third race, you could hold the button for at least 11 milliseconds and no more than 19 milliseconds and still beat the record, a total of 9 ways you could win.\n\nTo see how much margin of error you have, determine the number of ways you can beat the record in each race; in this example, if you multiply these values together, you get 288 (4 * 8 * 9).\n\nDetermine the number of ways you could beat the record in each race.\nWhat do you get if you multiply these numbers together?\n\n--- Part Two ---\n\nAs the race is about to start, you realize the piece of paper with race times and record distances you got earlier actually just has very bad kerning. There's really only one race - ignore the spaces between the numbers on each line.\n\nSo, the example from before:\n\nTime:      7  15   30\nDistance:  9  40  200\n\n...now instead means this:\n\nTime:      71530\nDistance:  940200\n\nNow, you have to figure out how many ways there are to win this single race. In this example, the race lasts for 71530 milliseconds and the record distance you need to beat is 940200 millimeters. You could hold the button anywhere from 14 to 71516 milliseconds and beat the record, a total of 71503 ways!\n\nHow many ways can you beat the record in this one much longer race?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_07.adb",
    "content": "--  Solution to Advent of Code 2023, Day 7\n------------------------------------------\n--  Camel Cards\n--\n--  https://adventofcode.com/2023/day/7\n--  Copy of questions in: aoc_2023_07_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_07 is\n  use AoC_Toolbox, HAT;\n\n  type Hand_Kind is (high, pair_1, pair_2, three, full, four, five);\n\n  subtype Hand_Type is String (1 .. 5);\n\n  type Hand_and_Bid_Type is record\n    hand : Hand_Type;\n    bid  : Positive;\n    rank : Positive;\n    kind : Hand_Kind;  --  Caching the result of the Kind function\n    --                     on the hand field.\n  end record;\n  --\n  row : array (1 .. 1000) of Hand_and_Bid_Type;\n  top : Natural := 0;\n  --\n  procedure Read_Data is\n    input : constant VString := +\"aoc_2023_07.txt\";\n    f : File_Type;\n  begin\n    Open (f, input);\n    while not End_Of_File (f) loop\n      top := top + 1;\n      Get (f, row (top).hand);\n      Get (f, row (top).bid);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer;\n\n  label : constant String (1 .. 13) := \"AKQJT98765432\";\n  joker : constant := 4;  --  Just the position of 'J'.\n\n  function Kind (h : Hand_Type; p : Part_Type) return Hand_Kind is\n    count : array (1 .. 13) of Natural;\n    sorts, count_max : Natural := 0;\n  begin\n    for i in count'Range loop\n      count (i) := 0;\n    end loop;\n    for c in 1 .. 5 loop\n      for i in count'Range loop\n        if h (c) = label (i) then\n          count (i) := count (i) + 1;\n        end if;\n      end loop;\n    end loop;\n    for i in count'Range loop\n      if count (i) > 0 and then (p = part_1 or else i /= joker) then\n        --  If the joker is used, we need *not* to count its sort!\n        sorts := sorts + 1;\n      end if;\n      if p = part_2 and then i /= joker then\n        count (i) := count (i) + count (joker);\n      end if;\n      count_max := Max (count_max, count (i));\n    end loop;\n    case count_max is\n      when 5      => return five;\n      when 4      => return four;\n      when 3      => if sorts = 2 then return full; else return three; end if;\n      when 2      => if sorts = 3 then return pair_2; else return pair_1; end if;\n      when others => return high;\n    end case;\n  end Kind;\n\n  --  Card labels for tie break of part 2, where the index' value matters.\n  label_part_2 : constant String (1 .. 13) := \"AKQT98765432J\";\n\n  function Stronger (h1, h2 : Hand_and_Bid_Type; p : Part_Type) return Boolean is\n    --  NB: \"not stronger\" can mean \"equal\"...\n    k1, k2 : Hand_Kind;\n    index_1, index_2 : Positive;\n    card : Character;\n  begin\n    k1 := h1.kind;\n    k2 := h2.kind;\n    if k1 > k2 then\n      return True;\n    elsif k1 < k2 then\n      return False;\n    else\n      --  Tie: both hands are of the same kind.\n      for c in 1 .. 5 loop\n        for i in label'Range loop\n          case p is\n            when part_1 => card := label (i);\n            when part_2 => card := label_part_2 (i);\n          end case;\n          if h1.hand (c) = card then\n            index_1 := i;\n          end if;\n          if h2.hand (c) = card then\n            index_2 := i;\n          end if;\n        end loop;\n        if index_1 < index_2 then  --  The lower the index, the higher the value.\n          return True;\n        elsif index_1 > index_2 then\n          return False;\n        end if;\n      end loop;\n      Put (\"Equal! \");  --  NB: equal hands don't happen on my data.\n      return False;\n    end if;\n  end Stronger;\n\n  procedure Do_Part (p : Part_Type) is\n    t : Natural := 0;\n  begin\n    for i in 1 .. top loop\n      row (i).kind := Kind (row (i).hand, p);\n      row (i).rank := 1;\n      for j in 1 .. i - 1 loop\n        --  Compare to previous hands:\n        if Stronger (row (i), row (j), p) then\n          row (i).rank := row (i).rank + 1;\n        else\n          row (j).rank := row (j).rank + 1;\n        end if;\n      end loop;\n    end loop;\n    for i in 1 .. top loop\n      t := t + row (i).rank * row (i).bid;\n    end loop;\n    r (p) := t;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  for part in Part_Type loop\n    Do_Part (part);\n  end loop;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 252656917\n    --  Part 2: validated by AoC: 253499763\n  end if;\nend AoC_2023_07;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_07.txt",
    "content": "467K3 95\nJK5QK 838\n44664 725\n8QAK3 134\n53A3A 945\n7QQJ7 164\nJ8J89 236\n38QAT 166\nQ7944 755\n35333 526\n5J787 482\n4K769 829\n37773 960\nQJ78K 282\n3J39Q 326\nTJ2QQ 255\nJ4338 337\nQK3KK 187\n5K8KQ 380\n93785 500\n795JT 382\nQ399Q 391\n99J99 206\nT5555 716\nQ7Q8Q 990\nQQJJQ 346\n34344 332\nK4J44 763\n2A36T 974\n77757 461\n55446 907\n99JJ9 962\nK29KQ 177\n99666 961\n688KK 249\n5A558 767\nTT6K2 630\n5Q4A4 872\nJTKQ4 969\nA5AAA 421\nJAA4Q 680\n55K69 29\n96ATJ 144\n3Q462 523\n73646 203\n5A96A 550\nK84TQ 4\n7278T 406\nKQQT5 395\n54567 197\nT53TA 355\nAQA99 601\n88KQQ 968\n55J5J 727\n73TJ9 466\n99799 843\n324QQ 36\n84AAA 190\n7J366 511\nJK938 667\nKKQJQ 762\n722J4 110\n9TKT9 84\n33JJ3 458\n6K444 498\n4279T 23\nK5T28 467\n3KKKK 871\nKQAQK 492\n44AKK 865\n5638T 932\nA89AK 24\n29K92 403\nA69K6 596\nKKK84 400\nQA748 616\n55AAA 504\n9255Q 684\n56646 330\n6J6J7 222\nA59J5 370\n3AA4J 940\nK9K38 302\n2AK58 735\n68K4K 422\n95599 324\n8K88J 987\n845Q5 478\n72KQ7 263\n8TJ83 751\n96TTQ 935\nAQ6AQ 445\nQKQQA 321\nA5644 769\nQQ5QJ 801\nAA574 436\n333QQ 605\nJ5982 71\nQT8A5 956\n2Q46A 982\nJ3773 317\n3KK93 485\n3A76A 926\n338JJ 502\n8KAQ6 737\nKKK28 520\n644Q5 850\n2T6TT 397\n34JA7 549\n743J7 747\n34843 103\n6KKKK 204\nQ2J22 548\nJKKKK 995\n42446 704\n8732A 238\nTT9J2 109\n4758T 33\nTTTT7 914\n787J7 647\n59T59 62\n9Q989 985\nT886J 554\n543QJ 75\n77637 857\n8888T 83\n92T52 939\n9832A 620\n3TT39 81\n84353 18\nA8Q8A 824\nT4597 425\nK3635 949\nKAAA2 320\n42224 243\nAA8A3 565\nKK63K 114\nTT3TT 133\n33T77 141\nJ868J 774\n422QT 369\n24T2K 344\nKK3Q3 8\n424J2 967\n8J6J6 666\nK6927 887\n36666 366\n78KT8 867\nAT66T 761\n72AT6 155\n2Q6QQ 440\n64J64 594\nA2JT8 578\nQQAJQ 383\n8Q333 963\n9A22A 503\nK86K6 55\n66899 899\n4744J 210\n72K54 860\nKQKK4 723\n6TK62 607\n9J955 652\nA45A5 766\n4J333 744\n5K555 277\n7777J 657\n7853A 147\n75QQQ 356\nT6T93 818\n8T342 643\n498A7 232\n96A2A 471\nJ55KK 583\nKJ7Q6 849\n36A36 707\n23655 290\nK444K 371\n5858K 688\nKJK8J 258\nQ3699 910\n79T64 864\nKAQ44 536\nT4TJ5 239\n8KK88 589\n42AA4 127\nQQ4Q4 746\nJ9868 472\n95493 170\nJK6T5 428\nKAATA 775\nTK3KT 886\n36633 858\n67767 590\n86A2Q 175\nJ7J7J 659\n7J457 796\n55335 65\n9288A 664\n88899 499\n7TKTA 327\n6QJ36 701\nK7KQK 943\nQQAQ2 681\nQ9948 444\n85923 335\n82832 283\nTQ5QT 92\nTK8A3 191\nA957K 614\n8877T 623\n5JTT9 253\n2K626 248\n757Q7 817\nJJ6T5 827\nKJ796 367\n895AQ 608\nAA666 950\nTT4T2 135\nQQQKK 600\nA9KK9 925\n49AA7 972\n73TAT 60\n5K49Q 74\nAAJ6A 753\n42222 470\nJ99KK 722\nA9AA9 514\n36636 581\n7T5Q9 690\nTTK7K 496\n277J4 665\n782TQ 662\n3AK57 734\n29KJ7 343\n72726 378\n67656 541\n22A29 229\nJJ5AA 336\nQTTJQ 979\nJ73K6 473\n55AK9 19\n46466 610\n8AAK4 408\n27227 181\n55525 214\n444Q4 505\n65K55 506\nKJ84T 529\n82225 250\n59TKA 32\n83J53 178\n599K4 988\n55TTT 759\n59999 431\nT44A4 828\nA888T 874\nJ3533 619\n9979K 981\nKK998 101\n64965 799\n9A999 934\n9A299 942\n5KKKA 862\n4A865 802\n64QQ4 837\nATATA 98\n6TJQ7 807\nK6997 585\n57T5T 457\nJT66T 938\nJJQK9 105\nJJ278 804\nJJ5AQ 661\nQ2597 930\nAAQAQ 31\n5A974 427\nTTQQK 868\n7KT7T 730\nK4999 112\nA8KAQ 672\n6AQQ6 447\n32J32 297\n4QA2J 915\nT2Q3Q 712\n34KQT 121\n98379 617\n487QK 44\n55TAJ 909\n6686T 28\n22922 805\nT846A 556\nJ5A6A 399\n55Q55 347\n8488J 593\nJKKTT 708\n8288J 768\nJKK66 1\n22999 586\n85398 334\n77KK6 782\nK34JJ 674\n39K4K 653\nQA6K3 720\n78878 715\nQA9Q4 745\n3333J 226\n3TT32 686\n44999 401\nA2J32 531\nQ65A9 905\nJ6AA7 194\n8J888 163\n7JT74 624\nJKKAK 568\n239J2 919\nAA4AA 52\n222JJ 184\n546AQ 894\nK2KK9 631\n45TQ2 375\nTTTT2 146\n26Q77 989\n9866K 851\nT3332 292\n66469 758\n48J48 889\n4A4QA 185\nJ6626 68\n46T4A 660\n83T52 151\n7T7T7 407\n73758 479\n63A44 291\n66QT6 875\n6645J 738\n94Q97 638\nT5KT5 411\nTJ3J3 866\nQT6TQ 842\nA448A 433\n556JJ 533\nT3TKT 161\n6JT43 265\nT5TTT 393\nK7KK4 386\n53J6A 845\nK7777 756\n63399 685\nJ85AQ 87\n88585 906\nQJTQQ 270\nTKKTK 131\n3J3JQ 797\nK7Q34 836\nK4499 362\n53555 651\n9888T 435\n2J299 557\n8J999 964\n96TQ2 293\n8KTJ8 137\nKA6Q7 442\n2J6KQ 900\n446A4 294\nAJAA3 671\nQ427T 116\n9JQ99 398\n59929 392\n822J8 192\nQ92Q7 420\nKKJK6 171\nTAJ37 487\n8A2J5 10\n22TTT 220\n33623 111\n7Q7AJ 491\nA3JJ2 650\nJ4J23 299\n396KA 896\nK3K3J 486\nQKKKK 20\n9A2AJ 713\n746K4 56\n96996 885\nJTK77 312\nQ8888 826\n3T4AJ 771\n97977 219\n9354K 788\n5Q5KK 455\nT3734 325\nTK26A 156\n7AAAA 924\nKJ622 183\n5QTAQ 642\nAAAAQ 488\nTTTJT 953\nQ2222 145\n4A9TJ 245\nTT3JK 588\nJ5555 284\n94AQT 193\n97325 196\n74A8J 37\n24AAA 847\n22A32 381\n4KJ59 542\nT6QK4 673\n77877 922\nQ2Q66 49\n66688 792\n9T9T9 918\nJ8878 552\n6A63A 221\nAA559 780\n9T47Q 300\nAKKA4 501\n33QQ4 64\n6K375 965\nT7Q43 82\n3689Q 569\nA6A3A 462\nT5Q3J 689\n49Q99 895\nKA262 490\n87497 13\n4449A 973\n92453 430\n5QA5A 149\n69666 247\nK6AJA 992\nA4444 729\n44494 298\nJ5993 927\n26662 555\n4J6A5 613\nKK77K 855\n73222 315\n2A2J2 719\nK7KT7 43\n98T64 998\n23282 528\n449T7 130\n6QK24 424\nAAAA3 179\nJA42K 53\n6A6KK 211\nJ55JJ 742\nJ5T93 304\nTQA23 358\n8J257 240\n39393 522\n68A38 450\nQQAK8 970\nJ77QT 341\nT68AA 242\n99933 310\n425KA 69\n99A9J 535\nJ35JK 113\n4A37T 360\n63333 791\n78J5T 34\n46T46 883\nT8JQ3 50\nKKKK5 519\nT29J8 640\nKKK88 646\n3A32A 228\n7A77T 57\n2QQ2J 971\n7Q777 438\n5J545 21\nT4AAJ 432\nQQJAA 570\nKJ79J 853\nT3JKA 359\n676K6 724\n4TATT 931\nJKKT2 629\nJ338T 469\n9939J 743\n85A93 241\n945TA 363\n5JK5A 493\nQ5JT5 815\n76378 12\nT3T53 157\nJAA24 732\n55757 200\nK727J 115\n259KK 510\n2J739 786\n288AA 598\nQJ233 100\nQQ56Q 25\n6333J 702\n86797 839\n47T77 361\nK4823 3\n6K446 54\n94J75 543\nQQQQA 980\n55J66 923\nAQT55 645\n55593 314\nJ6776 379\nJ23T6 102\n7K7K7 911\nJQ5A3 227\nKK66K 279\nAJJAQ 396\nJA252 39\n555KK 714\nKJ56K 637\nKJ64K 928\n6Q66Q 85\nTJTT2 273\nK634J 854\n66662 576\n6Q6J6 212\nKAAT2 696\n76663 793\nT3AQ3 632\n2J994 966\nTTTJA 63\n4QJQ4 165\nAAAJ8 331\nTT666 158\n2KKA2 453\n54444 563\n7KK88 675\n47777 832\n6JJQ9 475\n55275 876\n63489 794\n7K7Q3 208\n6J585 820\n3Q89T 524\n92AK2 6\n66JK9 655\n7J4KQ 139\n666A5 711\n4JTK9 117\n88AJA 368\n34T5T 602\n9933J 278\n97Q63 448\nA5555 892\nQJ7A2 726\n5KKJ2 917\nA5238 108\n33343 663\nK33T3 285\n6Q655 937\n38383 880\n47834 252\nQJA49 692\nA6926 547\n48Q8Q 288\n72J86 107\n5T5T9 449\n2JK25 305\n667T6 136\n7JJ88 429\nQ5KQK 394\nATAAA 952\n66949 296\nTT222 933\nAQ4AK 948\nKQJJ7 209\n3465K 709\n74775 126\n8TJ6T 402\n82Q3J 816\nQ7855 354\nJJ3KK 9\n22223 351\n2K7TA 831\n555AA 984\n83539 168\n444T4 140\n4A8Q4 693\nJA8AK 890\n29QTQ 308\nKJKKJ 389\nA86AK 649\nJ898T 14\nA6AAA 352\n2J222 176\nA4669 958\n333K8 635\nT4269 844\nJ4Q54 603\n44AAA 349\nQT575 413\nAA2J2 859\n7T395 648\nK3Q68 251\n7T2T2 790\nQQQ33 446\n428A4 879\n36J2Q 434\n69955 991\n7J5A4 812\nQQ445 789\n7A69A 93\n4K979 537\nK6K73 518\n45555 79\n45A6A 833\nKAAA5 307\n48887 80\nKK2KK 38\nATJJ5 11\n5K325 388\n42TJA 353\n66J3T 611\nA758A 728\nTJT77 644\n5JQQ2 898\n9KQT2 404\nK42A2 303\nQ6QTA 124\n58Q5J 670\nK6JTJ 409\nT3333 731\nJ73JK 463\n4A288 452\n79AAJ 41\n2K7T7 15\n7AAA7 888\n44J94 286\n8938K 328\nTKKKA 633\n22JT7 577\nQQQQ7 683\n66665 89\nT72J4 955\nJ66J6 877\n99433 509\n9K92J 776\nJQ7Q2 78\nA6T2Q 122\n69Q6A 153\nJ5JQ5 218\n25KAJ 416\n7A47A 513\n62T26 1000\n96449 281\nKKTKK 977\n35642 921\n9K4K9 778\nJ4244 993\nJJAAA 573\n7AA27 626\nA685T 376\n4JA9A 957\nT886T 267\n737J7 538\n999KK 579\n75KK7 76\nQ737Q 809\nQ3393 901\n2734Q 754\nJ2T9K 216\n89859 695\n63343 35\n7JK7K 700\n8828A 765\n29AT5 615\nQ838Q 410\nA3235 622\nTKJKQ 810\n45454 224\n77737 869\nJA9T9 333\n2772K 276\n5535A 350\nTT5QT 821\n46JKJ 986\n9T8KK 125\n6JAJ7 595\n74647 464\n499A4 612\n4KT7A 22\nJ3233 891\n44555 959\n8KQ8A 271\n33443 182\n37373 27\n88828 997\nQ2Q22 189\n3635A 373\nT66TT 717\nA4469 207\n2T2KT 749\n4244Q 90\n9234T 348\n33TJ3 289\nQAA63 562\n2A2A2 199\nJ6JK7 929\nTT99J 234\nT3JQ2 798\n65Q66 154\nJTTJT 975\n22699 705\nQ6Q6Q 618\n99929 811\n389J6 920\n585Q5 852\nA2255 477\nTJTJJ 30\nK5AK5 772\n2QQ3Q 323\n6888J 454\n7J8K3 609\nJ463J 572\n32323 223\n686J6 534\nQ25J4 47\n29996 882\nTTQ8Q 944\n42265 480\n2JQ96 287\nQQ868 517\nAK447 994\n8J3Q3 897\n42QK5 489\nA8A88 384\n3AT3A 941\n44T8T 88\nQQ8QQ 787\n488TJ 996\n6KK66 313\n2J262 764\nK6KK5 275\nK572T 893\n7T7QQ 215\n76965 773\n59575 800\n586QJ 309\nQQQQ4 721\n9A9A4 40\n8JJJJ 128\nQATA6 162\nK6TAQ 415\n95JJ8 72\n9TQ97 319\n2AK22 61\nT2TJ2 465\nT5274 195\nQ4587 266\nJ97QT 441\n52384 17\nQ7J77 414\nQQQ6Q 903\n4444J 532\nQQKQQ 904\nQJ467 16\n25525 785\nATA8A 205\n65542 261\n9QKKK 512\n48844 231\nJTJAK 99\nQJ8AT 571\n68A88 878\n5353J 94\n2Q33Q 311\nKJJ69 946\nJ83A8 634\nQQT6Q 884\nKK74J 374\n77474 781\n38888 527\n29457 329\n52452 73\n2K776 256\nQJQQQ 268\nJ24K6 913\n42K88 861\n29QQQ 733\n4J546 806\nK2K98 841\nQ4644 697\n44K94 834\nQAAQT 830\nJ666T 750\n3T335 437\n9594T 694\n8QQQ3 682\n88887 269\nJ3KKQ 641\n99993 551\n2K437 699\n75775 710\n5963J 870\nTTKT5 582\n2Q82A 439\nKJ4Q9 301\nQ3558 152\n32333 999\nT77TT 599\n3T6JT 627\n2J3T5 560\n25442 86\n8888K 257\n5QJ45 96\nQQ7AA 658\n88JJ8 863\n98948 202\n2QJ3J 803\nJ6488 66\n59559 160\nJJKK7 484\n7J223 254\n68889 364\n555J9 822\nKKAAA 525\nK7557 5\n3Q33A 814\n2384J 587\nKK8Q2 777\n494K2 426\n2TJ22 507\nQQQ2Q 698\n7229T 954\nJJ757 142\n2882A 530\nKKTQT 539\n72222 621\n99A5A 736\n22887 936\n3377Q 779\n6A6J6 740\nA7AAJ 840\n44JJ4 2\nQQTQT 51\n6666A 669\nT9279 908\nK9J7Q 856\n2AAAJ 748\nJ3K25 947\nTT65T 377\nKK2K6 752\nK7KKK 150\n9J6J8 120\n72AK6 656\nTT6TT 757\nQQ9TT 412\n3AA3J 365\n84477 783\nKK4K2 591\nAK79J 654\nJ77J7 951\nQ7664 606\n7QQ59 59\nJ2725 795\n96989 417\n7TT64 387\n47JJK 91\n228AA 201\nAJJ63 902\nA5AKJ 123\n37Q33 741\n8J358 483\nQ88QQ 508\n43A33 340\nQ9QQQ 516\n232JT 148\n666J6 159\n38363 97\n42285 322\n4Q944 233\nTT4TT 342\nK8TQA 566\nKJKK2 213\nQJQJJ 339\n5K932 559\n86888 494\n2QQJQ 70\n7A772 167\n5659T 881\nT43A6 186\nA2Q22 739\n55K95 679\n2T5QQ 262\n47797 419\n52522 357\n2J734 597\nAA3Q3 678\n3Q9A3 567\nKJAAJ 813\nK8794 495\n7JT77 198\n4KT2A 564\n55QQ5 497\n5K558 272\nT2A25 318\nK58Q2 825\n7KKJK 628\n6A6A7 676\nJ7T96 706\nA4A96 625\n6KTQ7 372\nJAAJ3 916\n99699 106\nQ7Q77 468\n8Q88J 545\n2A2J8 983\n777A7 246\n329TA 546\n38388 48\nKKKQQ 316\nKKKK8 460\n33K8Q 77\nA9A29 691\n8J859 237\nA9599 540\n23J67 390\nJT43J 668\n8J8JQ 338\nJQQQ8 456\nK9KKK 129\n8KJ8K 67\n7555Q 169\n9QJQ9 459\n7A8Q9 718\n7J765 760\n94744 173\nAA35A 264\nQKQQ5 423\nA6JJ9 819\n4AA44 848\n88385 180\nA4T7Q 259\n7J757 584\nA96T3 474\nJJJJJ 42\n9K372 604\nJ333Q 118\nJ7A37 451\nQ4447 515\nQQ77Q 274\n73333 553\n6747J 521\nJ56K2 405\nKKJJQ 575\nQT86A 592\n75A73 476\n29925 295\nA778A 823\nAAAAJ 580\nTT99T 636\nQQ3JQ 235\nA8778 244\nK6638 784\n87Q5A 574\n99499 46\nAK7Q7 172\nKKK33 443\n38J88 345\n7976K 58\n59669 558\n6659J 217\n7557J 143\n5549K 306\nJ3982 639\nJ249A 677\n55955 418\nQQQQT 7\n77A47 770\n66K4K 104\nQ9T5A 976\n2673Q 230\nQ75TK 26\nJKJ9K 225\n9TAAT 188\n55JQA 119\n9Q9Q9 385\n24K42 260\nT9222 873\n99989 45\n88448 544\nT9784 808\n43454 846\nTA674 174\n3T3AT 687\n38929 561\n22QQK 912\nKQJQQ 978\n23223 481\nJ7772 835\n3999Q 703\n74K44 280\n4K444 138\nKJ53K 132\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_07_questions.txt",
    "content": "--- Day 7: Camel Cards ---\n\nYour all-expenses-paid trip turns out to be a one-way, five-minute ride in an airship.\n(At least it's a cool airship!)\nIt drops you off at the edge of a vast desert and descends back to Island Island.\n\n\"Did you bring the parts?\"\n\nYou turn around to see an Elf completely covered in white clothing, wearing goggles, and riding a large camel.\n\n\"Did you bring the parts?\" she asks again, louder this time.\nYou aren't sure what parts she's looking for; you're here to figure out why the sand stopped.\n\n\"The parts! For the sand, yes! Come with me; I will show you.\" She beckons you onto the camel.\n\nAfter riding a bit across the sands of Desert Island, you can see what look like very large rocks covering half of the horizon.\nThe Elf explains that the rocks are all along the part of Desert Island that is directly above Island Island, making it hard to even get there.\nNormally, they use big machines to move the rocks and filter the sand, but the machines have broken down because Desert Island recently stopped receiving the parts they need to fix the machines.\n\nYou've already assumed it'll be your job to figure out why the parts stopped when she asks if you can help. You agree automatically.\n\nBecause the journey will take a few days, she offers to teach you the game of Camel Cards. Camel Cards is sort of similar to poker except it's designed to be easier to play while riding a camel.\n\nIn Camel Cards, you get a list of hands, and your goal is to order them based on the strength of each hand.\nA hand consists of five cards labeled one of A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, or 2.\nThe relative strength of each card follows this order, where A is the highest and 2 is the lowest.\n\nEvery hand is exactly one type. From strongest to weakest, they are:\n\n    Five of a kind, where all five cards have the same label: AAAAA\n    Four of a kind, where four cards have the same label and one card has a different label: AA8AA\n    Full house, where three cards have the same label, and the remaining two cards share a different label: 23332\n    Three of a kind, where three cards have the same label, and the remaining two cards are each different from any other card in the hand: TTT98\n    Two pair, where two cards share one label, two other cards share a second label, and the remaining card has a third label: 23432\n    One pair, where two cards share one label, and the other three cards have a different label from the pair and each other: A23A4\n    High card, where all cards' labels are distinct: 23456\n\nHands are primarily ordered based on type; for example, every full house is stronger than any three of a kind.\n\nIf two hands have the same type, a second ordering rule takes effect.\nStart by comparing the first card in each hand.\nIf these cards are different, the hand with the stronger first card is considered stronger.\nIf the first card in each hand have the same label, however, then move on to considering the second card in each hand.\nIf they differ, the hand with the higher second card wins; otherwise, continue with the third card in each hand, then the fourth, then the fifth.\n\nSo, 33332 and 2AAAA are both four of a kind hands, but 33332 is stronger because its first card is stronger.\nSimilarly, 77888 and 77788 are both a full house, but 77888 is stronger because its third card is stronger (and both hands have the same first and second card).\n\nTo play Camel Cards, you are given a list of hands and their corresponding bid (your puzzle input). For example:\n\n32T3K 765\nT55J5 684\nKK677 28\nKTJJT 220\nQQQJA 483\n\nThis example shows five hands; each hand is followed by its bid amount.\nEach hand wins an amount equal to its bid multiplied by its rank, where the weakest hand gets rank 1, the second-weakest hand gets rank 2, and so on up to the strongest hand.\nBecause there are five hands in this example, the strongest hand will have rank 5 and its bid will be multiplied by 5.\n\nSo, the first step is to put the hands in order of strength:\n\n    32T3K is the only one pair and the other hands are all a stronger type, so it gets rank 1.\n    KK677 and KTJJT are both two pair. Their first cards both have the same label, but the second card of KK677 is stronger (K vs T), so KTJJT gets rank 2 and KK677 gets rank 3.\n    T55J5 and QQQJA are both three of a kind. QQQJA has a stronger first card, so it gets rank 5 and T55J5 gets rank 4.\n\nNow, you can determine the total winnings of this set of hands by adding up the result of multiplying each hand's bid with its rank (765 * 1 + 220 * 2 + 28 * 3 + 684 * 4 + 483 * 5).\nSo the total winnings in this example are 6440.\n\nFind the rank of every hand in your set. What are the total winnings?\n\n--- Part Two ---\n\nTo make things a little more interesting, the Elf introduces one additional rule.\nNow, J cards are jokers - wildcards that can act like whatever card would make the hand the strongest type possible.\n\nTo balance this, J cards are now the weakest individual cards, weaker even than 2.\nThe other cards stay in the same order: A, K, Q, T, 9, 8, 7, 6, 5, 4, 3, 2, J.\n\nJ cards can pretend to be whatever card is best for the purpose of determining hand type; for example, QJJQ2 is now considered four of a kind.\nHowever, for the purpose of breaking ties between two hands of the same type, J is always treated as J, not the card it's pretending to be: JKKK2 is weaker than QQQQ2 because J is weaker than Q.\n\nNow, the above example goes very differently:\n\n32T3K 765\nT55J5 684\nKK677 28\nKTJJT 220\nQQQJA 483\n\n    32T3K is still the only one pair; it doesn't contain any jokers, so its strength doesn't increase.\n    KK677 is now the only two pair, making it the second-weakest hand.\n    T55J5, KTJJT, and QQQJA are now all four of a kind! T55J5 gets rank 3, QQQJA gets rank 4, and KTJJT gets rank 5.\n\nWith the new joker rule, the total winnings in this example are 5905.\n\nUsing the new joker rule, find the rank of every hand in your set. What are the new total winnings?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_08.adb",
    "content": "--  Solution to Advent of Code 2023, Day 8\n------------------------------------------\n--  Haunted Wasteland\n--\n--  https://adventofcode.com/2023/day/8\n--  Copy of questions in: aoc_2023_08_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_08 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  subtype Pos_Type is String (1 .. 3);\n\n  type Pair is record left, right : Pos_Type; end record;\n\n  subtype Para_Range is Integer range 1 .. 10;\n  type Multi_Pos is array (Para_Range) of Pos_Type;\n\n  starter : Multi_Pos;\n  para_top : Natural := 0;\n  direction_list : VString;\n  map : array (Upcase_Alpha, Upcase_Alpha, Upcase_Alpha) of Pair;\n\n  procedure Read_Data is\n  --  input : constant VString := +\"mini.txt\";\n    input : constant VString := +\"aoc_2023_08.txt\";\n    --\n    c : Character;\n    pos, l, r : Pos_Type;\n    fill_1 :  String (1 .. 4);\n    fill_2 :  String (1 .. 2);\n    f : File_Type;\n  begin\n    Open (f, input);\n    Get_Line (f, direction_list);\n    Skip_Line (f);\n    while not End_Of_File (f) loop\n      Get (f, pos);\n      if pos (3) = 'A' then\n        para_top := para_top + 1;\n        starter (para_top) := pos;\n      end if;\n      Get (f, fill_1);\n      Get (f, l);\n      Get (f, fill_2);\n      Get (f, r);\n      map (pos (1), pos (2), pos (3)).left  := l;\n      map (pos (1), pos (2), pos (3)).right := r;\n      Get (f, c);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Do_Part_1 is\n    c : Integer_64 := 0;\n    i : Positive := 1;\n    pos : Pos_Type;\n  begin\n    pos := \"AAA\";\n    while pos /= \"ZZZ\" loop\n      if Element (direction_list, i) = 'L' then\n        pos := map (pos (1), pos (2), pos (3)).left;\n      else\n        pos := map (pos (1), pos (2), pos (3)).right;\n      end if;\n      i := i + 1;\n      if i > Length (direction_list) then\n        i := 1;\n      end if;\n      c := c + 1;\n    end loop;\n    r (part_1) := c;\n  end Do_Part_1;\n\n  procedure Do_Part_2_Brute_Force is\n    c : Integer_64 := 0;\n    i : Positive := 1;\n    pos : Multi_Pos := starter;\n    goal : Boolean;\n    is_left : Boolean;\n  begin\n    loop\n      goal := True;\n      for p in 1 .. para_top loop\n        goal := goal and then pos (p)(3) = 'Z';\n        exit when not goal;\n      end loop;\n      exit when goal;\n      is_left := Element (direction_list, i) = 'L';\n      for p in 1 .. para_top loop\n        if is_left then\n          pos (p) := map (pos (p)(1), pos (p)(2), pos (p)(3)).left;\n        else\n          pos (p) := map (pos (p)(1), pos (p)(2), pos (p)(3)).right;\n        end if;\n      end loop;\n      i := i + 1;\n      if i > Length (direction_list) then\n        i := 1;\n      end if;\n      c := c + 1;\n    end loop;\n    r (part_2) := c;\n  end Do_Part_2_Brute_Force;\n\n  cycle_observation_max : constant := 100_000;\n\n  procedure Do_Part_2 is\n    i : Positive;\n    pos : Pos_Type;\n    cycle : Integer_64 := 1;\n    overall_cycle : Integer_64 := 1;\n  begin\n    for p in 1 .. para_top loop\n      i := 1;\n      pos := starter (p);\n      for count in 1 .. cycle_observation_max loop\n        if Element (direction_list, i) = 'L' then\n          pos := map (pos (1), pos (2), pos (3)).left;\n        else\n          pos := map (pos (1), pos (2), pos (3)).right;\n        end if;\n        i := i + 1;\n        if i > Length (direction_list) then\n          i := 1;\n        end if;\n        if pos (3) = 'Z' then\n          cycle := Integer_64 (count);\n          exit;\n        end if;\n      end loop;\n      overall_cycle := LCM_64 (overall_cycle, cycle);\n    end loop;\n    r (part_2) := overall_cycle;\n  end Do_Part_2;\n\n  verbose : constant Boolean := False;\n  brute   : constant Boolean := False;\n\n  procedure Show_Cycle (p : Para_Range) is\n    c, old_c : Natural := 0;\n    i : Positive := 1;\n    pos : Pos_Type := starter (p);\n    is_left : Boolean;\n  begin\n    for count in 1 .. cycle_observation_max loop\n      if pos (3) = 'A' or pos (3) = 'Z' then\n        Put_Line (+pos & \"  \" & c & \"  delta: \" & (c - old_c));\n        old_c := c;\n      end if;\n      is_left := Element (direction_list, i) = 'L';\n      if is_left then\n        pos := map (pos (1), pos (2), pos (3)).left;\n      else\n        pos := map (pos (1), pos (2), pos (3)).right;\n      end if;\n      i := i + 1;\n      if i > Length (direction_list) then\n        i := 1;\n      end if;\n      c := c + 1;\n    end loop;\n  end Show_Cycle;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n\n  Do_Part_1;\n\n  if verbose then\n    for p in 1 .. para_top loop\n      Show_Cycle (p);\n    end loop;\n  end if;\n\n  if brute then\n    Do_Part_2_Brute_Force;\n  else\n    Do_Part_2;\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 12737\n    --  Part 2: validated by AoC: 9064949303801\n  end if;\nend AoC_2023_08;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_08.txt",
    "content": "LRRRLRRRLRRLRLRRLRLRRLRRLRLLRRRLRLRLRRRLRRRLRLRLRLLRRLLRRLRRRLLRLRRRLRLRLRRRLLRLRRLRRRLRLRRRLLRLRRLRRRLRRLRRLRLRRLRRRLRLRRRLRRLLRRLRRLRLRRRLRRLRRRLRRRLRLRRLRLRRRLRLRRLRRLRRRLRRRLRRRLLRRLRRRLRLRLRLRRRLRLRLRRLRRRLRRRLRRLRRLLRLRRLLRLRRLRRLLRLLRRRLLRRLLRRLRRLRLRLRRRLLRRLRRRR\n\nDBQ = (RTP, NBX)\nNFX = (PXX, PLG)\nVBK = (BRV, DKG)\nBRS = (HLR, VBX)\nDDK = (SPR, TCR)\nFTS = (LJB, MDJ)\nBLH = (DFM, GGG)\nPCC = (GQR, RHD)\nQKN = (VVR, GBL)\nKHN = (FNB, LLT)\nHTD = (NPJ, BTL)\nFPL = (BRX, XQD)\nRCJ = (QKN, XPD)\nXRN = (RMQ, LQB)\nHGM = (VPV, SVR)\nRFG = (TLM, KPH)\nSSG = (QGC, KJV)\nLPA = (QQN, GNF)\nSVN = (VLM, BDX)\nVPF = (TTR, RNQ)\nVNK = (DSX, MCZ)\nKMS = (XNN, MTB)\nRLS = (NHX, CRT)\nVRS = (VBX, HLR)\nTVK = (MKG, NKB)\nCKH = (DFF, XPV)\nKBS = (LJC, PRS)\nJMT = (FPT, DLX)\nLRV = (QCD, RLF)\nTMM = (VPF, GKD)\nHKH = (PRS, LJC)\nGSM = (SVH, KRP)\nSLG = (PTL, SNJ)\nGVS = (DSN, CKH)\nQGC = (HKS, DFP)\nRFT = (VVQ, GMF)\nFDF = (JKV, JKV)\nMRL = (PKS, TKS)\nHBN = (BDX, VLM)\nCFB = (PPV, QVS)\nTFJ = (KGN, JND)\nHLB = (PFV, JXR)\nRFJ = (SKL, QCN)\nPQH = (KGN, JND)\nHGR = (FKL, XHR)\nCTB = (HNQ, HNQ)\nXMN = (CJV, LKQ)\nJVX = (FSS, CRC)\nSFH = (MXD, RHN)\nBRK = (QPL, DJB)\nHBX = (DSN, CKH)\nRFL = (VXB, FNF)\nGXP = (LHR, SMV)\nCHK = (NLQ, VCR)\nQPG = (HHL, KHB)\nVBC = (NFV, FST)\nQJF = (JXL, JJC)\nXKQ = (PCS, BSH)\nSKS = (SNN, QSN)\nGJJ = (VVG, XPR)\nDJP = (SJM, DNR)\nDQF = (MHG, BKZ)\nMSB = (BRX, XQD)\nPQR = (TLL, RVS)\nXGB = (RMT, HGF)\nHBD = (PFD, FDN)\nNSN = (RFJ, NJT)\nSNJ = (MVG, DBQ)\nNMV = (SKG, TDJ)\nPTN = (TNR, SSG)\nSBG = (CVH, LMJ)\nRDT = (SVQ, JTT)\nMRC = (BKF, QMJ)\nJKV = (CTB, CTB)\nCTX = (QHL, BDV)\nSQM = (DNR, SJM)\nMVG = (RTP, NBX)\nKKJ = (TQP, PST)\nQKX = (BRD, SFT)\nVFV = (NTL, VMQ)\nLXK = (SSL, MFR)\nHDH = (VPS, MJH)\nRTP = (CGJ, XJC)\nBXQ = (FLN, FLN)\nGKD = (TTR, RNQ)\nGPP = (SNN, QSN)\nGDQ = (JLS, TND)\nLTF = (GXP, TVB)\nGVB = (LSV, FRL)\nJCF = (HGR, GMX)\nVCR = (JTR, MCM)\nXJC = (DGP, XML)\nXKA = (SFC, CHQ)\nLJL = (VPX, PMS)\nCPH = (PCQ, QKX)\nVPV = (TFP, NJN)\nTDJ = (PRV, DBK)\nJGQ = (TPX, NMV)\nLJS = (GDQ, QPV)\nVHN = (CBJ, PFQ)\nJHT = (XHM, NRK)\nZZZ = (HJS, LRV)\nKJV = (HKS, DFP)\nHNT = (XXT, KJT)\nRHD = (KQH, TMD)\nJKG = (HXJ, MGF)\nSPL = (TTB, STB)\nMBD = (CQK, NHH)\nTPX = (TDJ, SKG)\nHRC = (LBB, JLR)\nQHN = (JHT, THC)\nSPM = (DDG, MBK)\nMFG = (JBD, GSM)\nMHR = (PTN, HVB)\nRLF = (GMG, TDQ)\nXBQ = (KKN, QTN)\nGLB = (DHS, SXC)\nPRV = (PGC, NSK)\nSJD = (BXQ, GHF)\nTHC = (XHM, NRK)\nGBL = (GGR, HTK)\nMDK = (JXX, DBD)\nNJT = (QCN, SKL)\nLLG = (KBL, LXK)\nRVS = (DDB, QRV)\nLHR = (LPL, TGJ)\nTBD = (NNB, CQH)\nDSN = (DFF, XPV)\nQQN = (HRV, PTT)\nXPP = (GSJ, RDT)\nCBJ = (JQL, RBX)\nRBX = (CNV, NKQ)\nDDG = (NBS, KTV)\nXNN = (TMC, GCG)\nDSX = (CGR, SGM)\nDFB = (RCJ, KJK)\nXTG = (RFG, XSD)\nPKQ = (DBD, JXX)\nXPD = (GBL, VVR)\nFFC = (JLR, LBB)\nGMG = (KFH, PTP)\nQHJ = (SHM, FKM)\nMXD = (XGB, LTX)\nSGM = (FTS, GXX)\nLTX = (RMT, HGF)\nRNQ = (SPL, DKH)\nNHF = (VXC, HRS)\nKFR = (JXR, PFV)\nNRP = (XNN, MTB)\nVDR = (LDL, JCP)\nFSS = (KXJ, GKL)\nQVS = (MKN, BLH)\nSNN = (SBM, PNH)\nVXB = (LLG, BHP)\nBPK = (QVS, PPV)\nSMV = (TGJ, LPL)\nCXF = (XKV, PVR)\nPGC = (NBJ, KCK)\nVLG = (DDG, MBK)\nFKL = (HFC, XPP)\nKFC = (XNM, CNR)\nFCC = (BRK, GLT)\nHQC = (JKV, JHQ)\nQQV = (CPG, HQD)\nVVG = (XGJ, XGJ)\nSVK = (HVH, HNJ)\nXQT = (LQX, HNT)\nJDB = (PXM, THR)\nJHR = (XRF, DHN)\nHRS = (TFJ, PQH)\nSVQ = (XHX, QNG)\nKGN = (FCV, SBH)\nGJX = (MFG, LMS)\nNBJ = (GVB, RMS)\nVQJ = (JPB, PDF)\nTKX = (JMT, LGM)\nFLL = (GTX, HKP)\nMFT = (FKM, SHM)\nJCP = (SSP, VMD)\nLPC = (KCD, JDB)\nXHR = (XPP, HFC)\nFKM = (DLL, XBQ)\nMGF = (NFX, MQS)\nJXJ = (MMP, CBT)\nDFP = (TGM, RHV)\nSSM = (NTC, TMT)\nDLX = (PXF, SBG)\nNNB = (TNT, MMF)\nQNG = (RHP, QBT)\nFLR = (CJK, QRL)\nRCP = (KKG, NTD)\nGJV = (SLG, DGN)\nFDN = (TBR, QDT)\nJTG = (RFT, PRC)\nLGM = (DLX, FPT)\nQDT = (CXV, SGD)\nHKP = (BLB, PCL)\nGXB = (MNH, GXT)\nQDS = (LTF, FDX)\nLMJ = (GJV, HVV)\nTDQ = (PTP, KFH)\nSGD = (HTT, PNR)\nXPV = (BPM, CPH)\nPTP = (MKL, KSP)\nDKG = (DKK, KNQ)\nQCN = (XTD, GQM)\nLSV = (GDK, VVD)\nMLG = (RLS, RKG)\nGMX = (FKL, XHR)\nQSN = (PNH, SBM)\nCHQ = (KSB, CXF)\nRHN = (LTX, XGB)\nLVX = (JSF, MLT)\nXHM = (FLR, QVK)\nNCJ = (CPG, HQD)\nMQV = (HBD, LDK)\nVVD = (QBV, FKF)\nQCD = (GMG, TDQ)\nGTH = (DLJ, DQF)\nKFH = (KSP, MKL)\nNFC = (PKQ, MDK)\nNCD = (FNB, LLT)\nMKG = (HNS, DDK)\nBTV = (KBS, HKH)\nQGL = (QTF, CVS)\nDDB = (DVF, HXV)\nPXF = (CVH, LMJ)\nNFV = (XMN, BQR)\nDGN = (SNJ, PTL)\nHHL = (PHC, QQJ)\nXPR = (XGJ, LVQ)\nPCQ = (BRD, SFT)\nMMT = (RDS, SRS)\nDMR = (GJM, BQS)\nQPL = (XNQ, CMN)\nPDF = (JBH, CTX)\nCVR = (STX, MBQ)\nLPL = (SFL, PHQ)\nFXX = (PNX, PQL)\nKLS = (NHG, CHF)\nNHX = (TMN, JLJ)\nNND = (QHN, XBR)\nJTT = (QNG, XHX)\nLML = (FDX, LTF)\nPCS = (LKV, LXX)\nSRV = (KCD, JDB)\nNSK = (NBJ, KCK)\nMRF = (NKP, JKG)\nVPX = (NSN, SMB)\nGFT = (FPL, MSB)\nDFM = (XKQ, PPQ)\nPPQ = (PCS, BSH)\nJJC = (JHR, RQG)\nJBH = (BDV, QHL)\nKNQ = (KNP, MRL)\nTBS = (NTD, KKG)\nJXL = (RQG, JHR)\nGKL = (MJC, QBM)\nBQR = (LKQ, CJV)\nDGP = (VNT, JRB)\nDKR = (VBJ, GVF)\nJXN = (BXD, XLT)\nTVG = (HGR, GMX)\nXSD = (TLM, KPH)\nRMT = (GXB, DPT)\nFRL = (VVD, GDK)\nPNX = (NCD, KHN)\nVGK = (CNR, XNM)\nMQB = (KSF, LJS)\nKDC = (MSB, FPL)\nGCD = (CXS, PCC)\nXML = (VNT, JRB)\nTBL = (GCV, HDH)\nBRV = (DKK, KNQ)\nJKS = (XXB, ZZZ)\nTMC = (MDQ, QJF)\nTNT = (NQJ, SSM)\nFLF = (XSD, RFG)\nJRB = (FDF, HQC)\nPTL = (DBQ, MVG)\nBGQ = (KFR, HLB)\nXTD = (VRS, BRS)\nQXX = (SJD, CSH)\nFRX = (BQS, GJM)\nPQL = (NCD, KHN)\nLKV = (PNK, DKR)\nHQS = (VVG, XPR)\nVPQ = (NTL, VMQ)\nTHR = (CBV, CVR)\nFST = (BQR, XMN)\nDMD = (CVS, QTF)\nHXV = (RCP, TBS)\nSTM = (RFX, BFR)\nJTR = (JTL, JXN)\nFLG = (PFQ, CBJ)\nCKM = (KFB, HTP)\nNCT = (KJK, RCJ)\nDKH = (STB, TTB)\nQGA = (CGR, SGM)\nXNQ = (HJM, MLG)\nRGF = (LFN, FGC)\nQBV = (VPJ, RMN)\nQKJ = (KFC, VGK)\nCSB = (FDL, FDL)\nHFK = (DHS, SXC)\nSVP = (NPJ, BTL)\nGGR = (XTG, FLF)\nXKV = (NDH, JXJ)\nBMR = (FRX, DMR)\nVVQ = (BFN, TVK)\nHJM = (RKG, RLS)\nRLK = (PDF, JPB)\nDCX = (HNQ, BRZ)\nTBG = (RTL, SML)\nRMS = (FRL, LSV)\nFCV = (STM, HTC)\nSPR = (TBL, JGG)\nBHP = (LXK, KBL)\nNPJ = (XLV, PQR)\nNKF = (TBD, DKP)\nPDK = (JTK, JTK)\nPFQ = (RBX, JQL)\nLBB = (SVP, HTD)\nGTX = (BLB, PCL)\nSBH = (HTC, STM)\nBFR = (RJN, BTN)\nTCR = (TBL, JGG)\nMQS = (PXX, PLG)\nFRG = (XXB, XXB)\nSTX = (XQL, HGM)\nHNJ = (HBN, SVN)\nSSL = (RDL, NST)\nHJS = (QCD, RLF)\nKBL = (SSL, MFR)\nCXS = (RHD, GQR)\nDFD = (NFP, FCC)\nVBJ = (HFK, GLB)\nDKP = (NNB, CQH)\nQSK = (TKX, CQT)\nBNV = (JTK, GTH)\nNBH = (LVX, GQB)\nQBM = (VNC, VPK)\nDBD = (HHR, RVQ)\nDFF = (BPM, CPH)\nLQX = (KJT, XXT)\nFGC = (QKQ, QSK)\nPXM = (CBV, CVR)\nJHQ = (CTB, DCX)\nNJN = (BGQ, FBP)\nTLL = (DDB, QRV)\nXSN = (THS, KJQ)\nKXJ = (QBM, MJC)\nGSC = (TQG, QXX)\nQJP = (PQL, PNX)\nPHH = (MXD, RHN)\nSSC = (NQX, FCH)\nXDF = (NLQ, VCR)\nBRD = (MQV, FRQ)\nAAA = (LRV, HJS)\nPTT = (FFC, HRC)\nVKF = (BFG, TGQ)\nHHA = (FLG, VHN)\nCNR = (TQX, VDV)\nTGM = (FLL, TNV)\nGLT = (DJB, QPL)\nMBK = (NBS, KTV)\nJPB = (JBH, CTX)\nRHP = (SQM, DJP)\nCHF = (CLQ, JGQ)\nFTL = (PRC, RFT)\nSKL = (XTD, GQM)\nRBN = (SPM, VLG)\nHGF = (GXB, DPT)\nBQS = (NSP, BTV)\nXHX = (RHP, QBT)\nCGR = (GXX, FTS)\nBLB = (QJP, FXX)\nCRT = (JLJ, TMN)\nPLG = (SLC, PDD)\nHRV = (FFC, HRC)\nMCM = (JXN, JTL)\nJGH = (MFG, LMS)\nNSP = (KBS, HKH)\nMFR = (NST, RDL)\nGMF = (TVK, BFN)\nSML = (LJL, XFP)\nMPL = (RDS, SRS)\nQHP = (SPM, VLG)\nFCH = (GDC, XRN)\nNRQ = (FTL, JTG)\nHMB = (CRC, FSS)\nKPH = (BNH, SLK)\nSRS = (MQB, GCN)\nRQM = (TGQ, BFG)\nFLN = (CSB, CSB)\nBSH = (LKV, LXX)\nCRC = (KXJ, GKL)\nCJV = (XDF, CHK)\nCGJ = (DGP, XML)\nSFL = (GJJ, HQS)\nPMR = (VPF, GKD)\nQTN = (MMT, MPL)\nKJQ = (RLK, VQJ)\nPBJ = (LFN, FGC)\nBTL = (PQR, XLV)\nSBX = (KFC, VGK)\nQQJ = (PDK, BNV)\nBRZ = (GNF, QQN)\nJTL = (XLT, BXD)\nSKG = (PRV, DBK)\nRQG = (DHN, XRF)\nDRC = (SFC, CHQ)\nTJQ = (NQX, FCH)\nPKS = (TMM, PMR)\nTRP = (GVD, FBL)\nLKQ = (XDF, CHK)\nRTL = (XFP, LJL)\nPPV = (MKN, BLH)\nMTB = (GCG, TMC)\nFPT = (PXF, SBG)\nLDK = (FDN, PFD)\nTND = (PPX, SVK)\nVPK = (NHF, JDX)\nHTP = (NKF, RPV)\nPMS = (SMB, NSN)\nGGG = (XKQ, PPQ)\nDLL = (KKN, QTN)\nJXX = (HHR, RVQ)\nKSF = (QPV, GDQ)\nXQD = (FGK, BNJ)\nRJF = (CSB, KTM)\nGCN = (KSF, LJS)\nJKP = (LML, QDS)\nXFP = (VPX, PMS)\nDPT = (GXT, MNH)\nDKK = (KNP, MRL)\nNKB = (DDK, HNS)\nCJK = (GSC, GBQ)\nNLM = (LDL, JCP)\nVMD = (DFD, XFM)\nNBX = (XJC, CGJ)\nPRS = (NLM, VDR)\nRMQ = (FRG, FRG)\nXNM = (TQX, VDV)\nLJC = (VDR, NLM)\nPHQ = (GJJ, HQS)\nKXN = (KHB, HHL)\nBXD = (CKM, XVL)\nKFB = (NKF, RPV)\nNFS = (PRL, RFL)\nRJN = (SFV, RRG)\nGQM = (VRS, BRS)\nKQH = (VBC, BSJ)\nDNR = (BMR, LJQ)\nHHR = (LPC, SRV)\nDLJ = (MHG, MHG)\nSMB = (RFJ, NJT)\nRHV = (FLL, TNV)\nNTD = (HBX, GVS)\nVNT = (FDF, HQC)\nPRC = (GMF, VVQ)\nFBP = (HLB, KFR)\nKTM = (FDL, LRZ)\nTQP = (QGL, DMD)\nSBM = (QPG, KXN)\nQVK = (CJK, QRL)\nXRF = (RGF, PBJ)\nNDH = (CBT, MMP)\nGVL = (RTL, SML)\nLRZ = (VHN, FLG)\nCQH = (MMF, TNT)\nSLK = (TJQ, SSC)\nQBT = (SQM, DJP)\nFNF = (LLG, BHP)\nSTB = (KMS, NRP)\nHVV = (SLG, DGN)\nRFX = (BTN, RJN)\nMKL = (GVM, LVP)\nVDV = (BPK, CFB)\nCBT = (GJX, JGH)\nPPX = (HVH, HNJ)\nNQJ = (TMT, NTC)\nMJH = (MHP, XQT)\nLTA = (KLS, BFV)\nCSH = (BXQ, GHF)\nHTK = (XTG, FLF)\nVNC = (JDX, NHF)\nBFG = (MRC, NKK)\nKKG = (GVS, HBX)\nPNK = (GVF, VBJ)\nXXB = (LRV, HJS)\nDVF = (TBS, RCP)\nPNR = (NCJ, QQV)\nQKQ = (CQT, TKX)\nTTR = (SPL, DKH)\nBTN = (RRG, SFV)\nVLM = (PHH, SFH)\nTQG = (SJD, CSH)\nMHP = (LQX, HNT)\nNQX = (GDC, XRN)\nTQX = (BPK, CFB)\nTVB = (LHR, SMV)\nMBQ = (XQL, HGM)\nHXJ = (MQS, NFX)\nDHN = (PBJ, RGF)\nBFN = (MKG, NKB)\nPVR = (JXJ, NDH)\nQRL = (GBQ, GSC)\nGJM = (NSP, BTV)\nKQV = (NHH, CQK)\nKNP = (TKS, PKS)\nPDD = (FND, JKP)\nGXT = (VKF, RQM)\nXDC = (FTL, JTG)\nMMF = (SSM, NQJ)\nBFV = (CHF, NHG)\nDHS = (PHX, PHX)\nVXC = (PQH, TFJ)\nXLV = (TLL, RVS)\nPXX = (SLC, PDD)\nGVD = (DRC, DRC)\nTHS = (VQJ, RLK)\nDBK = (PGC, NSK)\nKHB = (PHC, QQJ)\nTKS = (PMR, TMM)\nSVR = (NJN, TFP)\nHNQ = (QQN, GNF)\nMKN = (GGG, DFM)\nKRP = (NFM, NFC)\nSHM = (XBQ, DLL)\nNTL = (NCT, DFB)\nNRK = (QVK, FLR)\nHXL = (DSX, DSX)\nKSB = (XKV, PVR)\nNKK = (BKF, QMJ)\nMHG = (KLS, BFV)\nPNP = (XBR, QHN)\nCLQ = (TPX, NMV)\nRSG = (XDC, NRQ)\nBPM = (PCQ, QKX)\nPHC = (PDK, BNV)\nTNR = (KJV, QGC)\nXQL = (VPV, SVR)\nMHV = (QTS, RSG)\nXBR = (THC, JHT)\nBDX = (PHH, SFH)\nTBR = (CXV, SGD)\nRVQ = (SRV, LPC)\nNFM = (PKQ, MDK)\nFBL = (DRC, QSZ)\nTLM = (BNH, SLK)\nNHH = (SKS, GPP)\nFKF = (RMN, VPJ)\nXVL = (HTP, KFB)\nNHG = (CLQ, JGQ)\nFGK = (NBH, KBX)\nVMQ = (DFB, NCT)\nLXX = (DKR, PNK)\nSMJ = (QGB, NFS)\nLVP = (KDC, GFT)\nQGB = (PRL, RFL)\nBRX = (BNJ, FGK)\nBDV = (MRF, RXX)\nSJM = (BMR, LJQ)\nGBQ = (TQG, QXX)\nJXR = (XJT, CVX)\nTMN = (XSN, PQM)\nCQT = (LGM, JMT)\nCPG = (QHP, RBN)\nBKZ = (BFV, KLS)\nVVR = (HTK, GGR)\nXFM = (NFP, FCC)\nCVH = (GJV, HVV)\nVPS = (XQT, MHP)\nMDJ = (QHJ, MFT)\nSNF = (QTS, RSG)\nNKQ = (HMB, JVX)\nPRL = (FNF, VXB)\nCMN = (MLG, HJM)\nJQL = (NKQ, CNV)\nQSZ = (CHQ, SFC)\nHLR = (MHV, SNF)\nRDL = (TBG, GVL)\nGVM = (KDC, GFT)\nKTV = (CKK, VBK)\nSLC = (JKP, FND)\nQHL = (MRF, RXX)\nKKN = (MPL, MMT)\nTNV = (HKP, GTX)\nQMJ = (TVG, JCF)\nBSJ = (NFV, FST)\nBNJ = (NBH, KBX)\nXXQ = (GCD, CMQ)\nTGQ = (NKK, MRC)\nSVH = (NFC, NFM)\nLQB = (FRG, JKS)\nGNF = (HRV, PTT)\nPFV = (CVX, XJT)\nJTK = (DLJ, DLJ)\nKSP = (LVP, GVM)\nPFD = (TBR, QDT)\nMLT = (KSQ, KKJ)\nGVF = (HFK, GLB)\nJLS = (PPX, SVK)\nTBK = (CMQ, GCD)\nLJB = (QHJ, MFT)\nKSQ = (PST, TQP)\nSXC = (PHX, TRP)\nTTB = (NRP, KMS)\nVBX = (MHV, SNF)\nCXV = (PNR, HTT)\nXCT = (NFS, QGB)\nJBD = (KRP, SVH)\nJDX = (HRS, VXC)\nBNH = (TJQ, SSC)\nHQD = (RBN, QHP)\nRXX = (NKP, JKG)\nNTC = (NND, PNP)\nQTF = (TVQ, MHR)\nJND = (FCV, SBH)\nRDS = (MQB, GCN)\nFDL = (FLG, VHN)\nTGJ = (SFL, PHQ)\nKBX = (GQB, LVX)\nGQR = (TMD, KQH)\nLMS = (JBD, GSM)\nVPJ = (SMJ, XCT)\nLVQ = (HXL, VNK)\nGDK = (QBV, FKF)\nKCD = (PXM, THR)\nJGG = (GCV, HDH)\nNFP = (BRK, GLT)\nSFV = (TBK, XXQ)\nKJK = (QKN, XPD)\nCVX = (SBX, QKJ)\nGCG = (QJF, MDQ)\nFNB = (VFV, VPQ)\nCBV = (STX, MBQ)\nPNH = (QPG, KXN)\nHFC = (GSJ, RDT)\nGHF = (FLN, RJF)\nCKK = (BRV, DKG)\nLFN = (QKQ, QSK)\nMNH = (VKF, RQM)\nMMP = (GJX, JGH)\nHVB = (SSG, TNR)\nTMD = (BSJ, VBC)\nQTS = (NRQ, XDC)\nTVQ = (PTN, HVB)\nHTT = (QQV, NCJ)\nPQM = (KJQ, THS)\nXJT = (QKJ, SBX)\nPST = (QGL, DMD)\nXXT = (MBD, KQV)\nPCL = (QJP, FXX)\nMJC = (VPK, VNC)\nQPV = (JLS, TND)\nJLJ = (PQM, XSN)\nBKF = (TVG, JCF)\nSFT = (FRQ, MQV)\nXGJ = (HXL, HXL)\nJSF = (KKJ, KSQ)\nRMN = (XCT, SMJ)\nRPV = (TBD, DKP)\nXLT = (CKM, XVL)\nDJB = (CMN, XNQ)\nKCK = (GVB, RMS)\nLLT = (VFV, VPQ)\nCVS = (MHR, TVQ)\nNBS = (VBK, CKK)\nLJQ = (DMR, FRX)\nHKS = (TGM, RHV)\nHTC = (BFR, RFX)\nLDL = (VMD, SSP)\nQRV = (HXV, DVF)\nNST = (TBG, GVL)\nGQB = (JSF, MLT)\nKJT = (MBD, KQV)\nGSJ = (SVQ, JTT)\nFDX = (TVB, GXP)\nSSP = (XFM, DFD)\nFRQ = (LDK, HBD)\nJLR = (HTD, SVP)\nHNS = (SPR, TCR)\nMCZ = (SGM, CGR)\nGCV = (VPS, MJH)\nMDQ = (JJC, JXL)\nRKG = (NHX, CRT)\nTMT = (NND, PNP)\nSFC = (KSB, CXF)\nCQK = (SKS, GPP)\nFND = (LML, QDS)\nHVH = (HBN, SVN)\nCNV = (HMB, JVX)\nCMQ = (CXS, PCC)\nNLQ = (JTR, MCM)\nGDC = (RMQ, RMQ)\nPHX = (GVD, GVD)\nNKP = (HXJ, MGF)\nRRG = (XXQ, TBK)\nTFP = (BGQ, FBP)\nGXX = (LJB, MDJ)\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_08_questions.txt",
    "content": "--- Day 8: Haunted Wasteland ---\n\nYou're still riding a camel across Desert Island when you spot a sandstorm quickly approaching.\nWhen you turn to warn the Elf, she disappears before your eyes!\nTo be fair, she had just finished warning you about ghosts a few minutes ago.\n\nOne of the camel's pouches is labeled \"maps\" - sure enough, it's full of documents (your puzzle input) about how to navigate the desert.\nAt least, you're pretty sure that's what they are; one of the documents contains a list of left/right instructions, and the rest of the documents seem to describe some kind of network of labeled nodes.\n\nIt seems like you're meant to use the left/right instructions to navigate the network.\nPerhaps if you have the camel follow the same instructions, you can escape the haunted wasteland!\n\nAfter examining the maps for a bit, two nodes stick out: AAA and ZZZ.\nYou feel like AAA is where you are now, and you have to follow the left/right instructions until you reach ZZZ.\n\nThis format defines each node of the network individually.\nFor example:\n\nRL\n\nAAA = (BBB, CCC)\nBBB = (DDD, EEE)\nCCC = (ZZZ, GGG)\nDDD = (DDD, DDD)\nEEE = (EEE, EEE)\nGGG = (GGG, GGG)\nZZZ = (ZZZ, ZZZ)\n\nStarting with AAA, you need to look up the next element based on the next left/right instruction in your input.\nIn this example, start with AAA and go right (R) by choosing the right element of AAA, CCC.\nThen, L means to choose the left element of CCC, ZZZ.\nBy following the left/right instructions, you reach ZZZ in 2 steps.\n\nOf course, you might not find ZZZ right away.\nIf you run out of left/right instructions, repeat the whole sequence of instructions as necessary: RL really means RLRLRLRLRLRLRLRL... and so on.\nFor example, here is a situation that takes 6 steps to reach ZZZ:\n\nLLR\n\nAAA = (BBB, BBB)\nBBB = (AAA, ZZZ)\nZZZ = (ZZZ, ZZZ)\n\nStarting at AAA, follow the left/right instructions.\nHow many steps are required to reach ZZZ?\n\n--- Part Two ---\n\nThe sandstorm is upon you and you aren't any closer to escaping the wasteland. You had the camel follow the instructions, but you've barely left your starting position.\nIt's going to take significantly more steps to escape!\n\nWhat if the map isn't for people - what if the map is for ghosts? Are ghosts even bound by the laws of spacetime?\nOnly one way to find out.\n\nAfter examining the maps a bit longer, your attention is drawn to a curious fact: the number of nodes with names ending in A is equal to the number ending in Z!\nIf you were a ghost, you'd probably just start at every node that ends with A and follow all of the paths at the same time until they all simultaneously end up at nodes that end with Z.\n\nFor example:\n\nLR\n\n11A = (11B, XXX)\n11B = (XXX, 11Z)\n11Z = (11B, XXX)\n22A = (22B, XXX)\n22B = (22C, 22C)\n22C = (22Z, 22Z)\n22Z = (22B, 22B)\nXXX = (XXX, XXX)\n\nHere, there are two starting nodes, 11A and 22A (because they both end with A).\nAs you follow each left/right instruction, use that instruction to simultaneously navigate away from both nodes you're currently on.\nRepeat this process until all of the nodes you're currently on end with Z.\n(If only some of the nodes you're on end with Z, they act like any other node and you continue as normal.)\nIn this example, you would proceed as follows:\n\n    Step 0: You are at 11A and 22A.\n    Step 1: You choose all of the left paths, leading you to 11B and 22B.\n    Step 2: You choose all of the right paths, leading you to 11Z and 22C.\n    Step 3: You choose all of the left paths, leading you to 11B and 22Z.\n    Step 4: You choose all of the right paths, leading you to 11Z and 22B.\n    Step 5: You choose all of the left paths, leading you to 11B and 22C.\n    Step 6: You choose all of the right paths, leading you to 11Z and 22Z.\n\nSo, in this example, you end up entirely on nodes that end in Z after 6 steps.\n\nSimultaneously start on every node that ends with A.\nHow many steps does it take before you're only on nodes that end with Z?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_09.adb",
    "content": "--  Solution to Advent of Code 2023, Day 9\n------------------------------------------\n--  Mirage Maintenance\n--\n--  https://adventofcode.com/2023/day/9\n--  Copy of questions in: aoc_2023_09_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_09 is\n\n  use AoC_Toolbox, HAT;\n  --\n  --  input_name : constant VString := +\"mini.txt\"; m : constant := 3; n : constant := 6;\n  input_name : constant VString := +\"aoc_2023_09.txt\"; m : constant := 200; n : constant := 21;\n  type Row_Type is array (1 .. n) of Integer;\n  data : array (1 .. m) of Row_Type;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name);\n    for i in 1 .. m loop\n      for j in 1 .. n loop\n        Get (f, data (i)(j));\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer;\n\n  verbose : constant Boolean := False;\n\n  procedure Do_Parts is\n    check, val, left, right : Integer;\n    last : Positive;\n    --   ____\n    --  |   /\n    --  |  /  <- diff\n    --  | /\n    --  |/\n    diff : array (0 .. n) of Row_Type;\n  begin\n    r (part_1) := 0;\n    r (part_2) := 0;\n    for i_data in 1 .. m loop\n      for j in 1 .. n loop\n        diff (0)(j) := data (i_data)(j);\n      end loop;\n      for round in 1 .. n - 1 loop\n        check := 0;\n        for j in 1 .. n - round loop\n          val := diff (round - 1)(j + 1) - diff (round - 1)(j);\n          diff (round)(j) := val;\n          check := check + abs (val);\n        end loop;\n        last := round;\n        exit when check = 0;\n      end loop;\n      left  := 0;\n      right := 0;\n      for i in reverse 0 .. last loop\n        right := right + diff (i)(n - i);\n        left  := diff (i)(1) - left;\n      end loop;\n      if verbose then\n        --  Out of curiosity: we want to plot the data with the extrapolated values.\n        Put (left);\n        for j in 1 .. n loop\n          Put (data (i_data)(j));\n        end loop;\n        Put (right);\n        New_Line;\n      end if;\n      r (part_1) := r (part_1) + right;\n      r (part_2) := r (part_2) + left;\n    end loop;\n  end Do_Parts;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Parts;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1884768153\n    --  Part 2: validated by AoC: 1031\n  end if;\nend AoC_2023_09;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_09.txt",
    "content": "25 43 75 138 255 455 773 1250 1933 2875 4135 5778 7875 10503 13745 17690 22433 28075 34723 42490 51495\n15 22 50 114 229 410 672 1030 1499 2094 2830 3722 4785 6034 7484 9150 11047 13190 15594 18274 21245\n25 37 45 57 103 257 670 1617 3564 7271 13964 25633 45561 79327 136917 237555 421062 774117 1488793 2987794 6182124\n3 17 54 120 230 425 791 1489 2829 5466 10872 22355 47064 99648 208537 426194 845159 1622279 3014202 5428018 9491866\n25 47 77 111 155 235 402 724 1251 1932 2462 2054 -809 -8433 -23232 -45063 -64008 -43580 115154 646196 2060426\n9 15 39 95 208 426 851 1716 3546 7461 15730 32813 67431 136877 276189 557604 1131039 2306127 4713741 9615035 19476706\n1 -6 -8 15 106 342 853 1867 3810 7496 14449 27435 51408 95395 176521 328632 620115 1188930 2308050 4502051 8746226\n12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97 102 107 112\n17 18 18 15 3 -16 -9 122 585 1754 4236 8949 17211 30840 52265 84648 132017 199410 293030 420411 590595\n-4 10 52 139 306 624 1231 2386 4556 8546 15682 28057 48850 82728 136341 218920 342988 525194 787280 1157191 1670338\n-1 9 22 33 37 29 4 -43 -117 -223 -366 -551 -783 -1067 -1408 -1811 -2281 -2823 -3442 -4143 -4931\n12 25 38 51 64 77 90 103 116 129 142 155 168 181 194 207 220 233 246 259 272\n4 13 46 121 263 512 939 1685 3051 5677 10848 20953 40109 74975 135876 238622 407970 684713 1140118 1904165 3218119\n9 5 4 10 27 59 110 184 285 417 584 790 1039 1335 1682 2084 2545 3069 3660 4322 5059\n11 17 31 60 115 216 406 790 1625 3499 7665 16678 35706 75431 158678 335480 716439 1544189 3341367 7207300 15395413\n1 3 12 42 111 241 458 792 1277 1951 2856 4038 5547 7437 9766 12596 15993 20027 24772 30306 36711\n8 14 20 26 32 38 44 50 56 62 68 74 80 86 92 98 104 110 116 122 128\n2 17 45 90 167 309 573 1045 1844 3125 5081 7944 11985 17513 24873 34443 46630 61865 80597 103286 130395\n3 5 8 25 83 230 541 1117 2066 3459 5278 7432 10045 14499 26326 62366 167432 451676 1172223 2907858 6925638\n15 31 53 81 115 155 201 253 311 375 445 521 603 691 785 885 991 1103 1221 1345 1475\n24 43 79 142 248 434 777 1425 2670 5120 10065 20208 41107 84069 172095 352295 721984 1483393 3057187 6314066 13037102\n13 27 44 74 134 244 434 784 1532 3314 7658 17954 41277 91663 195742 402030 795687 1521173 2815992 5059618 8842760\n-5 6 26 65 149 320 644 1246 2412 4831 10091 21583 45992 95545 191119 366158 671073 1177364 1980064 3196213 4955871\n14 20 31 51 92 179 352 674 1274 2485 5189 11576 26705 61603 139298 306401 655034 1363686 2771955 5514593 10757022\n8 20 31 43 76 193 546 1449 3498 7798 16438 33501 67151 133785 266032 527840 1042692 2046618 3989373 7731849 14939606\n-2 13 44 108 239 501 1024 2092 4340 9158 19454 40995 84625 169752 329602 618857 1124426 1980243 3387144 5639046 9156835\n15 23 45 84 135 188 234 271 307 357 431 510 507 210 -796 -3231 -8249 -17597 -33807 -60424 -102273\n19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99 104 109 114 119\n16 22 33 66 144 295 567 1067 2029 3920 7606 14625 27670 51529 95095 175938 330930 640746 1285035 2662828 5646480\n18 20 33 73 155 290 482 725 1000 1272 1487 1569 1417 902 -136 -1891 -4594 -8516 -13971 -21319 -30969\n9 23 52 101 177 296 489 820 1443 2739 5588 11845 25103 51840 103061 196560 359941 634551 1080492 1782893 2859637\n23 37 52 75 129 267 593 1301 2757 5675 11489 23130 46640 94494 192307 391989 796663 1606149 3197006 6258585 12016967\n5 25 58 104 163 235 320 418 529 653 790 940 1103 1279 1468 1670 1885 2113 2354 2608 2875\n7 22 47 94 178 326 611 1226 2620 5742 12503 26703 55923 115304 234789 472363 937173 1828238 3496871 6544044 11967856\n-2 6 24 52 90 138 196 264 342 430 528 636 754 882 1020 1168 1326 1494 1672 1860 2058\n15 36 70 118 185 296 529 1079 2385 5385 12023 26230 55766 115612 234193 464886 907519 1748686 3336864 6320194 11893675\n18 42 88 181 356 667 1211 2170 3871 6868 12079 21090 36899 65655 120396 228459 445184 877830 1725338 3341795 6334262\n10 26 46 67 86 100 106 101 82 46 -10 -89 -194 -328 -494 -695 -934 -1214 -1538 -1909 -2330\n1 1 13 54 148 337 710 1457 2948 5823 11054 19900 33617 52703 75349 94627 93771 38693 -133381 -530574 -1330094\n7 18 39 90 201 408 744 1225 1831 2482 3009 3120 2361 72 -4662 -13065 -26729 -47678 -78437 -122106 -182439\n7 0 1 27 100 247 500 896 1477 2290 3387 4825 6666 8977 11830 15302 19475 24436 30277 37095 44992\n0 0 1 1 -1 -2 7 42 127 297 606 1144 2068 3653 6370 10999 18786 31654 52479 85443 136477\n24 34 41 55 97 200 413 808 1490 2610 4381 7097 11155 17080 25553 37442 53836 76082 105825 145051 196133\n6 4 19 65 166 375 815 1766 3846 8378 18116 38645 80997 166359 334236 656234 1259234 2365352 4364329 7951905 14404284\n11 12 16 29 58 106 167 221 229 128 -174 -803 -1924 -3746 -6527 -10579 -16273 -24044 -34396 -47907 -65234\n14 27 63 147 328 703 1456 2923 5710 10912 20507 38030 69668 125958 224316 392676 674574 1136073 1874991 3032965 4810960\n13 25 30 25 4 -32 -43 124 895 3293 9553 24231 56132 121576 249820 491898 934777 1723609 3096048 5434165 9341508\n8 16 42 96 184 318 544 1000 2022 4316 9216 19077 37959 73044 137896 260121 498946 984006 1997384 4140260 8659152\n4 20 57 125 234 394 615 907 1280 1744 2309 2985 3782 4710 5779 6999 8380 9932 11665 13589 15714\n18 36 76 154 300 567 1040 1845 3158 5214 8316 12844 19264 28137 40128 56015 76698 103208 136716 178542 230164\n6 17 34 72 167 394 893 1903 3804 7167 12812 21874 35877 56816 87247 130385 190210 271581 380358 523532 709363\n16 17 14 0 -26 -49 -17 202 891 2575 6106 12709 23985 41967 69541 111931 180570 301613 532678 993222 1916376\n24 36 60 106 189 342 632 1188 2268 4418 8811 17901 36591 74202 147651 286411 540048 989424 1763038 3060468 5185497\n14 21 28 35 42 49 56 63 70 77 84 91 98 105 112 119 126 133 140 147 154\n8 14 15 5 -26 -94 -224 -454 -840 -1462 -2431 -3897 -6058 -9170 -13558 -19628 -27880 -38922 -53485 -72439 -96810\n9 8 8 30 120 366 922 2039 4103 7680 13568 22856 36990 57846 87810 129865 187685 265736 369384 505010 680132\n2 3 14 59 175 416 867 1692 3257 6397 12943 26699 55168 112478 224162 434708 819124 1500167 2673372 4642595 7869461\n14 22 53 124 254 464 777 1218 1814 2594 3589 4832 6358 8204 10409 13014 16062 19598 23669 28324 33614\n4 15 31 65 143 306 624 1245 2523 5296 11418 24688 52364 107501 212409 403590 738582 1305213 2233849 3713307 6011197\n20 29 45 77 136 238 423 800 1644 3609 8197 18762 42564 94764 205819 434557 890356 1769397 3411997 6390651 11641728\n2 -5 -12 -3 49 194 530 1239 2632 5201 9676 17085 28815 46672 72938 110423 162510 233191 327092 449485 606285\n27 48 74 110 170 277 463 769 1245 1950 2952 4328 6164 8555 11605 15427 20143 25884 32790 41010 50702\n15 28 57 105 168 238 317 459 883 2244 6224 16734 42234 100024 223888 477248 975079 1919332 3654603 6753375 12143460\n16 34 66 112 172 246 334 436 552 682 826 984 1156 1342 1542 1756 1984 2226 2482 2752 3036\n10 12 26 68 166 373 788 1585 3050 5626 9966 16994 27974 44587 69016 104039 153130 220568 311554 432336 590342\n9 33 82 178 362 705 1335 2492 4623 8529 15576 27982 49192 84353 140901 229272 363749 563457 853518 1266378 1843318\n10 8 21 71 194 447 915 1718 3018 5026 8009 12297 18290 26465 37383 51696 70154 93612 123037 159515 204258\n2 17 51 109 205 370 663 1197 2198 4121 7853 15039 28573 53302 96997 171651 295170 493529 803471 1275833 1979589\n12 20 44 98 202 398 780 1550 3128 6369 12986 26380 53305 107260 215363 431941 864440 1720854 3393084 6597914 12607128\n21 51 110 218 400 684 1110 1765 2865 4914 8996 17324 34313 68700 137643 274332 541473 1054089 2016438 3779482 6927242\n18 32 46 60 74 88 102 116 130 144 158 172 186 200 214 228 242 256 270 284 298\n-8 -12 -10 0 23 86 280 848 2350 5938 13767 29549 59223 111662 199265 338185 547820 849040 1260436 1791654 2432615\n18 35 57 78 83 57 7 -3 196 939 2801 6684 13917 26369 46575 77875 124566 192067 287097 417866 594279\n6 9 15 24 43 93 223 543 1291 2952 6450 13437 26706 50758 92556 162502 275676 453379 725025 1130430 1722549\n11 12 20 55 160 420 998 2194 4525 8817 16309 28822 49187 82417 138630 239583 431979 812594 1572886 3074249 5969622\n13 20 31 46 58 58 47 59 217 882 3020 9022 24420 61383 145852 332290 734422 1589037 3386318 7129763 14840179\n-3 3 20 48 87 137 198 270 353 447 552 668 795 933 1082 1242 1413 1595 1788 1992 2207\n16 30 55 106 201 363 639 1146 2154 4216 8355 16318 30907 56397 99051 167742 274692 436338 674335 1016706 1499149\n18 37 74 140 247 401 590 765 826 655 298 511 4079 18621 62034 172324 424330 956761 2014010 4008334 7609119\n11 17 23 29 35 41 47 53 59 65 71 77 83 89 95 101 107 113 119 125 131\n21 34 52 89 171 342 674 1282 2364 4316 8023 15535 31590 67018 146244 323350 715118 1566195 3372779 7110296 14643524\n4 14 29 52 97 209 496 1173 2618 5440 10559 19298 33487 55579 88778 137179 205920 301346 431185 604736 833069\n17 23 38 66 104 143 181 269 628 1909 5729 15718 39484 92203 203086 427013 865693 1706967 3299762 6300778 11967458\n6 15 27 46 88 204 522 1314 3104 6852 14277 28419 54586 101887 185616 330825 577506 987893 1656495 2723580 4392948\n8 13 24 43 71 112 173 263 401 662 1333 3330 9154 24851 63700 152696 343334 728747 1469918 2834485 5252601\n15 28 54 115 244 488 911 1597 2653 4212 6436 9519 13690 19216 26405 35609 47227 61708 79554 101323 127632\n21 36 66 119 213 398 801 1708 3700 7863 16095 31536 59150 106491 184688 309687 503791 797542 1231992 1861413 2756499\n11 37 85 163 276 427 625 916 1462 2699 5608 12133 25777 52401 101242 186154 327061 551593 896855 1411255 2156290\n-8 3 34 100 228 459 847 1467 2465 4216 7711 15396 32890 72420 159609 346723 738050 1537353 3134140 6255932 12229220\n8 19 35 63 128 277 592 1224 2460 4835 9301 17465 31908 56597 97402 162730 264288 417987 644999 972979 1437464\n-6 -10 -20 -45 -104 -225 -441 -771 -1154 -1267 -94 4992 20051 58048 145352 333842 723414 1503576 3029356 5957273 11483438\n14 23 37 65 133 309 745 1746 3887 8218 16642 32656 62862 120056 229382 440113 847236 1629345 3112587 5874795 10909747\n5 -2 -10 -5 46 203 566 1294 2628 4921 8693 14759 24538 40772 69130 121701 224611 434984 879612 1844031 3975938\n3 21 52 98 164 258 391 577 833 1179 1638 2236 3002 3968 5169 6643 8431 10577 13128 16134 19648\n7 8 19 43 82 153 318 734 1746 4081 9271 20562 44795 96170 203655 425577 878602 1795615 3640864 7335774 14692157\n21 30 39 48 57 66 75 84 93 102 111 120 129 138 147 156 165 174 183 192 201\n-4 8 31 65 110 166 233 311 400 500 611 733 866 1010 1165 1331 1508 1696 1895 2105 2326\n18 41 91 193 391 753 1374 2377 3912 6153 9293 13537 19093 26161 34920 45513 58030 72489 88815 106817 126163\n-4 -13 -21 -20 7 104 372 1011 2374 5033 9857 18102 31513 52438 83954 130005 195552 286735 411047 577520 796923\n10 21 38 65 122 269 649 1560 3571 7704 15715 30537 57037 103464 184452 327378 585520 1064159 1969964 3700241 6997588\n11 25 53 95 151 221 305 403 515 641 781 935 1103 1285 1481 1691 1915 2153 2405 2671 2951\n19 27 37 67 155 366 799 1594 2939 5077 8313 13021 19651 28736 40899 56860 77443 103583 136333 176871 226507\n9 15 21 27 33 39 45 51 57 63 69 75 81 87 93 99 105 111 117 123 129\n3 2 4 8 26 103 342 932 2177 4524 8588 15172 25280 40121 61102 89808 127967 177398 239940 317360 411238\n0 7 22 49 97 192 400 861 1834 3753 7294 13453 23635 39754 64344 100681 152916 226219 326934 462745 642853\n11 5 1 12 65 214 560 1278 2651 5111 9287 16060 26625 42560 65902 99230 145755 209417 294989 408188 555793\n-3 -7 -1 22 71 172 404 980 2426 5953 14170 32348 70514 146728 291973 557166 1022875 1812401 3108953 5177706 8393585\n4 9 33 104 270 605 1221 2293 4106 7135 12171 20508 34208 56463 92075 148077 234520 365453 560125 844440 1252698\n3 13 32 65 140 331 798 1866 4176 8959 18520 37081 72229 137365 255798 467604 841455 1496343 2644958 4686847 8416272\n-4 9 37 80 138 211 299 402 520 653 801 964 1142 1335 1543 1766 2004 2257 2525 2808 3106\n5 0 -5 -5 5 30 75 145 245 380 555 775 1045 1370 1755 2205 2725 3320 3995 4755 5605\n25 43 78 151 294 549 981 1731 3161 6185 12948 28136 61426 132001 276787 565292 1125873 2191223 4175226 7799525 14296726\n9 23 54 104 171 247 318 383 521 1055 2904 8310 22339 55989 132571 300568 658990 1406445 2934993 6008892 12105512\n7 15 24 30 43 106 335 996 2636 6286 13755 28035 53838 98287 171784 289079 470565 743825 1145458 1723212 2538453\n0 -1 10 60 204 537 1214 2494 4829 9024 16499 29689 52623 91728 156909 262961 431374 692597 1088832 1677434 2534998\n17 40 84 169 335 649 1215 2194 3851 6665 11565 20397 36818 68040 128383 246740 482281 956726 1918286 3863249 7757949\n24 34 37 44 77 177 417 926 1945 3956 7950 15941 31926 63720 126631 251103 498806 996122 2002039 4041362 8157171\n10 7 20 65 159 334 677 1412 3045 6604 14025 28763 56755 107970 199046 358139 634506 1118355 1982836 3573131 6593957\n-5 -9 -13 -17 -21 -25 -29 -33 -37 -41 -45 -49 -53 -57 -61 -65 -69 -73 -77 -81 -85\n3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43\n5 9 28 84 209 461 953 1906 3755 7374 14556 29001 58243 117200 234373 462165 893353 1686439 3103444 5564706 9726413\n-3 0 6 27 91 255 623 1366 2741 5106 8928 14781 23331 35305 51441 72416 98749 130676 167994 209871 254619\n19 35 54 75 105 168 319 665 1404 2927 6101 12983 28438 63494 141816 311463 665149 1373687 2739636 5282855 9880339\n9 21 42 94 206 409 729 1184 1806 2730 4424 8196 17247 38823 88604 199621 440159 948983 2002842 4141990 8396292\n2 10 25 52 109 229 473 974 2037 4330 9220 19343 39571 78721 152826 292003 555888 1069234 2103267 4256230 8838981\n7 13 27 53 113 265 622 1380 2878 5733 11118 21281 40438 76213 141843 259416 464465 812301 1386533 2310293 3760759\n2 4 18 66 183 417 835 1536 2679 4547 7696 13317 24160 46931 98382 220159 513320 1214890 2860322 6614548 14921901\n20 42 89 187 375 705 1247 2114 3529 5965 10401 18760 34661 64809 121837 230509 441382 860016 1706553 3431097 6926055\n-6 5 41 118 257 497 927 1758 3479 7170 15084 31669 65309 131290 256992 491376 923096 1716263 3182439 5926360 11139249\n15 28 50 104 234 511 1047 2038 3883 7461 14703 29703 60831 124753 254153 512771 1025137 2036155 4031423 7980034 15819960\n10 6 9 29 78 167 305 517 915 1884 4505 11474 29080 71443 169472 389344 869428 1891498 4013213 8306107 16769254\n10 9 13 26 47 67 72 60 80 301 1119 3310 8237 18119 36370 68016 120198 202769 328993 516354 787483\n11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51\n22 49 104 198 350 603 1059 1958 3838 7824 16114 32786 65193 126523 240683 451628 840658 1556967 2868476 5240830 9450668\n16 39 79 153 287 511 853 1343 2046 3153 5181 9391 18683 39591 86823 193521 433828 970699 2153123 4705917 10086151\n5 16 35 58 78 83 57 -1 -19 264 1480 4880 12692 28852 61020 126369 267104 588917 1350257 3159230 7390503\n18 28 39 54 85 169 397 952 2164 4623 9465 19094 38871 80748 170523 361426 758214 1557966 3116451 6052430 11406697\n3 5 19 48 91 146 221 356 666 1430 3272 7505 16736 35857 73572 144631 272957 495859 869521 1475942 2431473\n30 41 45 51 93 250 668 1574 3282 6229 11158 19698 35791 68696 138673 286929 592006 1195521 2341043 4430925 8107113\n11 22 53 115 230 453 910 1857 3765 7436 14155 25883 45496 77075 126252 200617 310191 467970 690545 998803 1418714\n5 15 35 70 138 276 563 1187 2595 5777 12747 27296 56104 110310 207651 375293 653489 1100211 1796915 2855610 4427414\n13 15 18 28 59 132 275 532 1003 1974 4268 10067 24633 59605 138881 308521 652641 1317921 2550134 4747030 8532991\n19 31 39 37 30 50 187 653 1901 4825 11071 23493 46792 88380 159515 276757 463799 753731 1191799 1838725 2774658\n4 -4 -5 12 63 178 426 964 2108 4408 8686 15974 27291 43265 63797 88353 118140 162456 252973 471660 1000479\n8 26 56 102 170 269 420 688 1275 2754 6596 16260 39305 91285 202677 430899 880826 1739482 3334372 6231134 11396188\n11 23 35 47 59 71 83 95 107 119 131 143 155 167 179 191 203 215 227 239 251\n17 23 29 48 111 275 640 1382 2809 5447 10163 18332 32055 54435 89918 144706 227249 348823 524201 772424 1117679\n5 12 24 46 90 177 332 567 849 1058 963 297 -884 -1191 4419 29378 104397 293136 718466 1604688 3343062\n10 24 38 53 80 146 294 583 1116 2156 4430 9770 22312 50621 111465 236805 487438 980612 1946642 3844527 7595464\n4 -1 2 29 103 254 519 942 1574 2473 3704 5339 7457 10144 13493 17604 22584 28547 35614 43913 53579\n5 3 8 25 54 90 123 138 115 29 -150 -457 -932 -1620 -2571 -3840 -5487 -7577 -10180 -13371 -17230\n19 30 46 85 184 416 929 2025 4306 8935 18119 36059 70900 138785 272218 537010 1065858 2123285 4228117 8378734 16457241\n4 12 21 29 29 14 -11 -8 139 735 2539 7342 19120 46167 104805 225519 462686 909470 1719953 3141179 5558519\n12 17 33 83 215 524 1191 2554 5245 10458 20461 39545 75752 144023 272029 511254 958606 1799275 3392061 6437763 12305329\n10 26 62 133 273 562 1163 2376 4720 9059 16803 30264 53379 93309 164006 293873 541334 1024736 1976820 3839359 7420837\n26 38 50 62 74 86 98 110 122 134 146 158 170 182 194 206 218 230 242 254 266\n17 33 59 102 172 282 448 689 1027 1487 2097 2888 3894 5152 6702 8587 10853 13549 16727 20442 24752\n14 31 60 120 251 526 1063 2037 3692 6353 10438 16470 25089 37064 53305 74875 103002 139091 184736 241732 312087\n23 39 58 80 105 133 164 198 235 275 318 364 413 465 520 578 639 703 770 840 913\n21 45 93 181 329 569 959 1612 2762 4916 9199 18122 37251 78725 168410 359900 760925 1581649 3221326 6423446 12558361\n-5 -6 8 60 185 441 929 1831 3495 6640 12841 25616 52734 110904 234974 495463 1031149 2108352 4226908 8307194 16017545\n13 24 53 117 244 473 854 1448 2327 3574 5283 7559 10518 14287 19004 24818 31889 40388 50497 62409 76328\n23 40 64 104 189 396 894 2017 4403 9279 19055 38564 77656 156620 317410 646440 1319635 2688726 5441230 10887612 21461091\n15 35 59 84 104 107 73 -29 -252 -702 -1606 -3439 -7137 -14428 -28318 -53774 -98651 -174915 -300219 -499894 -809422\n0 7 22 50 96 165 262 392 560 771 1030 1342 1712 2145 2646 3220 3872 4607 5430 6346 7360\n2 12 37 84 178 378 809 1720 3572 7147 13653 24792 42771 70275 110468 167082 244466 346870 474873 614196 707420\n19 35 73 159 337 676 1293 2416 4518 8558 16368 31226 58654 107477 191174 329545 550709 893437 1409811 2168185 3256407\n9 10 18 54 150 354 744 1462 2789 5290 10064 19142 36094 66946 121586 215974 375689 641674 1079510 1794198 2953294\n-8 -9 1 44 170 476 1137 2452 4909 9283 16817 29640 51840 92218 171054 335896 696763 1501852 3296020 7246003 15797579\n27 37 57 108 228 494 1063 2249 4674 9561 19276 38271 74625 142426 265316 481736 852989 1476613 2510427 4218046 7056162\n0 4 9 15 22 30 39 49 60 72 85 99 114 130 147 165 184 204 225 247 270\n24 41 71 123 206 329 501 731 1028 1401 1859 2411 3066 3833 4721 5739 6896 8201 9663 11291 13094\n16 28 54 121 284 652 1429 2986 6003 11753 22654 43318 82532 157006 298461 566931 1075374 2034406 3832134 7174207 13325792\n9 2 -1 22 122 403 1062 2465 5288 10752 20979 39509 72072 127838 221613 377857 638023 1073610 1808547 3056140 5177882\n8 6 -4 -16 -3 97 412 1212 3075 7218 16131 34785 72949 149641 301604 599185 1175500 2278885 4365104 8255185 15396599\n-1 0 -2 -4 0 18 58 136 333 985 3169 9798 27930 73457 180383 418770 928688 1983079 4101909 8255993 16225829\n10 7 18 60 154 341 715 1481 3050 6188 12243 23483 43588 78348 136624 231626 382546 616549 971064 1496222 2257150\n-2 2 23 87 236 541 1124 2188 4054 7204 12329 20381 32628 50711 76702 113162 163198 230518 319483 435155 583340\n-4 -5 -9 -13 -5 34 136 384 1018 2657 6697 15957 35657 74824 148234 279010 502008 868135 1449755 2347351 3697623\n16 14 9 16 60 175 409 841 1620 3040 5669 10554 19528 35649 63805 111523 190024 315570 511153 808580 1251012\n-10 -17 -26 -37 -50 -65 -82 -101 -122 -145 -170 -197 -226 -257 -290 -325 -362 -401 -442 -485 -530\n-2 -3 2 27 101 292 744 1727 3700 7387 13866 24671 41907 68378 107728 164595 244778 355417 505186 704499 965729\n14 19 26 35 46 59 74 91 110 131 154 179 206 235 266 299 334 371 410 451 494\n7 12 28 64 131 242 412 658 999 1456 2052 2812 3763 4934 6356 8062 10087 12468 15244 18456 22147\n14 28 39 55 110 281 718 1708 3804 8057 16389 32139 60822 111236 197437 343264 594082 1047282 1927607 3762071 7762782\n5 25 56 98 154 234 364 613 1160 2436 5396 12008 26111 54967 112318 225021 448287 900835 1843624 3848550 8143064\n10 35 77 139 224 335 475 647 854 1099 1385 1715 2092 2519 2999 3535 4130 4787 5509 6299 7160\n7 14 17 19 45 153 454 1150 2598 5424 10768 20884 40634 81060 167480 356960 774538 1685999 3640496 7744350 16177032\n0 2 19 63 160 370 813 1711 3477 6920 13712 27414 55642 114484 237295 492021 1015343 2080463 4232825 8563395 17259507\n12 41 89 163 277 462 780 1342 2329 4016 6810 11357 18909 32508 60437 125397 287091 694318 1698939 4095063 9606004\n21 27 27 26 46 130 358 886 2028 4432 9463 20008 42069 87719 180272 362870 712127 1359001 2519699 4540166 7958576\n16 12 8 10 25 61 127 233 390 610 906 1292 1783 2395 3145 4051 5132 6408 7900 9630 11621\n4 20 49 89 144 249 517 1225 2979 7045 16029 35280 75762 159850 332827 685291 1396165 2814424 5613910 11087815 21714227\n6 22 55 114 213 377 658 1168 2136 3996 7513 13954 25311 44583 76124 126064 202810 317634 485355 725122 1061305\n1 3 7 17 57 186 511 1189 2411 4377 7310 11626 18478 31019 56865 112353 229233 464339 912461 1721971 3111595\n27 41 63 115 229 447 829 1486 2678 5049 10112 21147 44734 93211 188424 367222 689245 1247657 2183589 3705179 6112227\n22 38 68 121 204 333 552 971 1841 3684 7487 14956 28841 53475 96109 170733 308506 583836 1174568 2492081 5448060\n1 14 38 81 162 330 694 1461 2976 5757 10528 18293 30599 50369 84163 147660 277931 559352 1175870 2512485 5345816\n2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62 66 70 74 78 82\n10 23 57 123 244 483 982 2019 4099 8102 15522 28868 52407 93688 166813 299382 546656 1019041 1932855 3699937 7079518\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_09_questions.txt",
    "content": "--- Day 9: Mirage Maintenance ---\n\nYou ride the camel through the sandstorm and stop where the ghost's maps told you to stop.\nThe sandstorm subsequently subsides, somehow seeing you standing at an oasis!\n\nThe camel goes to get some water and you stretch your neck.\nAs you look up, you discover what must be yet another giant floating island, this one made of metal!\nThat must be where the parts to fix the sand machines come from.\n\nThere's even a hang glider partially buried in the sand here; once the sun rises and heats up the sand, you might be able to use the glider and the hot air to get all the way up to the metal island!\n\nWhile you wait for the sun to rise, you admire the oasis hidden here in the middle of Desert Island.\nIt must have a delicate ecosystem; you might as well take some ecological readings while you wait.\nMaybe you can report any environmental instabilities you find to someone so the oasis can be around for the next sandstorm-worn traveler.\n\nYou pull out your handy Oasis And Sand Instability Sensor and analyze your surroundings.\nThe OASIS produces a report of many values and how they are changing over time (your puzzle input).\nEach line in the report contains the history of a single value. For example:\n\n0 3 6 9 12 15\n1 3 6 10 15 21\n10 13 16 21 30 45\n\nTo best protect the oasis, your environmental report should include a prediction of the next value in each history. To do this, start by making a new sequence from the difference at each step of your history. If that sequence is not all zeroes, repeat this process, using the sequence you just generated as the input sequence. Once all of the values in your latest sequence are zeroes, you can extrapolate what the next value of the original history should be.\n\nIn the above dataset, the first history is 0 3 6 9 12 15. Because the values increase by 3 each step, the first sequence of differences that you generate will be 3 3 3 3 3. Note that this sequence has one fewer value than the input sequence because at each step it considers two numbers from the input. Since these values aren't all zero, repeat the process: the values differ by 0 at each step, so the next sequence is 0 0 0 0. This means you have enough information to extrapolate the history! Visually, these sequences can be arranged like this:\n\n0   3   6   9  12  15\n  3   3   3   3   3\n    0   0   0   0\n\nTo extrapolate, start by adding a new zero to the end of your list of zeroes; because the zeroes represent differences between the two values above them, this also means there is now a placeholder in every sequence above it:\n\n0   3   6   9  12  15   B\n  3   3   3   3   3   A\n    0   0   0   0   0\n\nYou can then start filling in placeholders from the bottom up. A needs to be the result of increasing 3 (the value to its left) by 0 (the value below it); this means A must be 3:\n\n0   3   6   9  12  15   B\n  3   3   3   3   3   3\n    0   0   0   0   0\n\nFinally, you can fill in B, which needs to be the result of increasing 15 (the value to its left) by 3 (the value below it), or 18:\n\n0   3   6   9  12  15  18\n  3   3   3   3   3   3\n    0   0   0   0   0\n\nSo, the next value of the first history is 18.\n\nFinding all-zero differences for the second history requires an additional sequence:\n\n1   3   6  10  15  21\n  2   3   4   5   6\n    1   1   1   1\n      0   0   0\n\nThen, following the same process as before, work out the next value in each sequence from the bottom up:\n\n1   3   6  10  15  21  28\n  2   3   4   5   6   7\n    1   1   1   1   1\n      0   0   0   0\n\nSo, the next value of the second history is 28.\n\nThe third history requires even more sequences, but its next value can be found the same way:\n\n10  13  16  21  30  45  68\n   3   3   5   9  15  23\n     0   2   4   6   8\n       2   2   2   2\n         0   0   0\n\nSo, the next value of the third history is 68.\n\nIf you find the next value for each history in this example and add them together, you get 114.\n\nAnalyze your OASIS report and extrapolate the next value for each history.\nWhat is the sum of these extrapolated values?\n\n--- Part Two ---\n\nOf course, it would be nice to have even more history included in your report.\nSurely it's safe to just extrapolate backwards as well, right?\n\nFor each history, repeat the process of finding differences until the sequence of differences is entirely zero.\nThen, rather than adding a zero to the end and filling in the next values of each previous sequence, you should instead add a zero to the beginning of your sequence of zeroes, then fill in new first values for each previous sequence.\n\nIn particular, here is what the third example history looks like when extrapolating back in time:\n\n5  10  13  16  21  30  45\n  5   3   3   5   9  15\n   -2   0   2   4   6\n      2   2   2   2\n        0   0   0\n\nAdding the new values on the left side of each sequence from bottom to top eventually reveals the new left-most history value: 5.\n\nDoing this for the remaining example data above results in previous values of -3 for the first history and 0 for the second history.\nAdding all three new values together produces 2.\n\nAnalyze your OASIS report again, this time extrapolating the previous value for each history.\nWhat is the sum of these extrapolated values?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_10.adb",
    "content": "--  Solution to Advent of Code 2023, Day 10\n-------------------------------------------\n--  Pipe Maze\n--\n--  https://adventofcode.com/2023/day/10\n--  Copy of questions in: aoc_2023_10_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_10 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 20; nx3 : constant := 60;\n  input_name : constant VString := +\"aoc_2023_10\"; n : constant := 140; nx3 : constant := 420;\n\n  map : array (1 .. n, 1 .. n) of Character;\n  si, sj  : Positive;\n\n  procedure Read_Data is\n    f : File_Type;\n    c : Character;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        Get (f, c);\n        if c = 'S' then\n          si := i;\n          sj := j;\n        end if;\n        map (i, j) := c;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer;\n\n  type State is (clean, path, outside);\n\n  visited    : array (1 .. n,   1 .. n)   of State;\n  visited_x3 : array (1 .. nx3, 1 .. nx3) of State;\n\n  path_length : Natural := 0;\n\n  procedure Do_Part_1 is\n    i, j : Positive;\n    iii, jjj : Natural;\n    i3, j3 : Integer;\n    p : Character;\n    procedure Go is\n    begin\n      i := iii;\n      j := jjj;\n      visited (i, j) := path;\n      path_length := path_length + 1;\n    end Go;\n  begin\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        visited (i, j) := clean;\n      end loop;\n    end loop;\n    for i in 1 .. nx3 loop\n      for j in 1 .. nx3 loop\n        visited_x3 (i, j) := clean;\n      end loop;\n    end loop;\n    i := si;\n    j := sj;\n    p := map (i, j);\n    main :\n    loop\n      scan :\n      for ii in -1 .. 1 loop\n        for jj in -1 .. 1 loop\n          if abs (ii) + abs (jj) = 1 then\n            iii := i + ii;\n            jjj := j + jj;\n            --  Try next move on iii, jjj\n            i3 := 1 + (iii - 1) * 3;\n            j3 := 1 + (jjj - 1) * 3;\n            if iii in 1 .. n\n               and then jjj in 1 .. n\n               and then visited (iii, jjj) = clean\n            then\n              case map (iii, jjj) is\n                when '|' =>\n                  if        (ii =  1 and then (p = 'S' or else p = '|' or else p = 'F' or else p = '7'))\n                    or else (ii = -1 and then (p = 'S' or else p = '|' or else p = 'L' or else p = 'J'))\n                  then\n                    Go;\n                    --  Draw on 3x3 square. Here we have:\n                    --\n                    --    .#.\n                    --    .#.\n                    --    .#.\n                    --\n                    visited_x3 (i3,     j3 + 1) := path;\n                    visited_x3 (i3 + 1, j3 + 1) := path;\n                    visited_x3 (i3 + 2, j3 + 1) := path;\n                    exit scan;\n                  end if;\n                when '-' =>\n                  if        (jj =  1 and then (p = 'S' or else p = '-' or else p = 'L' or else p = 'F'))\n                    or else (jj = -1 and then (p = 'S' or else p = '-' or else p = '7' or else p = 'J'))\n                  then\n                    Go;\n                    --  Draw on 3x3 square\n                    visited_x3 (i3 + 1, j3)     := path;\n                    visited_x3 (i3 + 1, j3 + 1) := path;\n                    visited_x3 (i3 + 1, j3 + 2) := path;\n                    exit scan;\n                  end if;\n                when 'L' =>\n                  if        (ii =  1 and then (p = 'S' or else p = '|' or else p = 'F' or else p = '7'))\n                    or else (jj = -1 and then (p = 'S' or else p = '-' or else p = '7' or else p = 'J'))\n                  then\n                    Go;\n                    --  Draw on 3x3 square. Here we have:\n                    --\n                    --    .#.\n                    --    .##\n                    --    ...\n                    --\n                    visited_x3 (i3,     j3 + 1) := path;\n                    visited_x3 (i3 + 1, j3 + 1) := path;\n                    visited_x3 (i3 + 1, j3 + 2) := path;\n                    exit scan;\n                  end if;\n                when 'J' =>\n                  if        (ii =  1 and then (p = 'S' or else p = '|' or else p = 'F' or else p = '7'))\n                    or else (jj =  1 and then (p = 'S' or else p = '-' or else p = 'L' or else p = 'F'))\n                  then\n                    Go;\n                    --  Draw on 3x3 square\n                    visited_x3 (i3,     j3 + 1) := path;\n                    visited_x3 (i3 + 1, j3)     := path;\n                    visited_x3 (i3 + 1, j3 + 1) := path;\n                    exit scan;\n                  end if;\n                when '7' =>\n                  if        (ii = -1 and then (p = 'S' or else p = '|' or else p = 'L' or else p = 'J'))\n                    or else (jj =  1 and then (p = 'S' or else p = '-' or else p = 'L' or else p = 'F'))\n                  then\n                    Go;\n                    --  Draw on 3x3 square\n                    visited_x3 (i3 + 1, j3)     := path;\n                    visited_x3 (i3 + 1, j3 + 1) := path;\n                    visited_x3 (i3 + 2, j3 + 1) := path;\n                    exit scan;\n                  end if;\n                when 'F' =>\n                  if        (ii = -1 and then (p = 'S' or else p = '|' or else p = 'L' or else p = 'J'))\n                    or else (jj = -1 and then (p = 'S' or else p = '-' or else p = '7' or else p = 'J'))\n                  then\n                    Go;\n                    --  Draw on 3x3 square\n                    visited_x3 (i3 + 1, j3 + 1) := path;\n                    visited_x3 (i3 + 1, j3 + 2) := path;\n                    visited_x3 (i3 + 2, j3 + 1) := path;\n                    exit scan;\n                  end if;\n                when 'S' =>\n                  if        (ii = -1 and then (p = '|' or else p = 'L' or else p = 'J'))\n                    or else (jj = -1 and then (p = '-' or else p = '7' or else p = 'J'))\n                    or else (ii =  1 and then (p = '|' or else p = 'F' or else p = '7'))\n                    or else (jj =  1 and then (p = '-' or else p = 'L' or else p = 'F'))\n                  then\n                    if path_length > 1 then  --  Avoid immediate return to Start.\n                      --  put(\"back!\");\n                      Go;\n                      --  Draw a cross on 3x3 square\n                      visited_x3 (i3,     j3 + 1) := path;\n                      visited_x3 (i3 + 1, j3)     := path;\n                      visited_x3 (i3 + 1, j3 + 1) := path;\n                      visited_x3 (i3 + 1, j3 + 2) := path;\n                      visited_x3 (i3 + 2, j3 + 1) := path;\n                      exit scan;\n                    end if;\n                  end if;\n                when others =>\n                  null;\n              end case;\n            end if;\n          end if;\n        end loop;\n      end loop scan;\n      p := map (i, j);\n      exit main when p = 'S';\n    end loop main;\n    r (part_1) := path_length / 2;\n  end Do_Part_1;\n\n  verbose : constant Boolean := False;\n\n  --  PPM picture output, adapted from AoC_2022_12.\n  --\n  procedure Dump_PPM is\n    d : File_Type;\n    i, j : Integer;\n  begin\n    Create (d, input_name & \".ppm\");\n    Put (d, \"P6\" & Chr (10));\n    Put (d, nx3); Put (d, ' ');\n    Put (d, nx3); Put (d, Chr (10));\n    Put (d, \"255\" & Chr (10));\n    for i3 in 1 .. nx3 loop\n      for j3 in 1 .. nx3 loop\n        i := (i3 - 1) / 3 + 1;\n        j := (j3 - 1) / 3 + 1;\n        case visited_x3 (i3, j3) is\n          when clean =>\n            if visited (i, j) = clean then\n              --  \"inside\" tile\n              Put (d, Chr (230));\n              Put (d, Chr (255));\n              Put (d, Chr (110));\n            else\n              --  partly \"inside\" tile\n              Put (d, Chr (160));\n              Put (d, Chr (240));\n              Put (d, Chr (190));\n            end if;\n          when path =>\n            Put (d, Chr (0));\n            Put (d, Chr (0));\n            Put (d, Chr (0));\n          when outside =>\n            if visited (i, j) = outside then\n              --  \"outside\" tile\n              Put (d, Chr (255));\n              Put (d, Chr (255));\n              Put (d, Chr (255));\n            else\n              --  partly \"outside\" tile\n              Put (d, Chr (220));\n              Put (d, Chr (220));\n              Put (d, Chr (220));\n            end if;\n        end case;\n      end loop;\n    end loop;\n    Close (d);\n  end Dump_PPM;\n\n  procedure Do_Part_2 is\n    procedure Flood_Fill (i, j : Integer) is  --  Taken from aoc_2022_18.\n    begin\n      if i in 1 .. nx3\n        and then j in 1 .. nx3\n        and then visited_x3 (i, j) = clean\n      then\n        visited_x3 (i, j) := outside;\n        Flood_Fill (i - 1, j);\n        Flood_Fill (i + 1, j);\n        Flood_Fill (i, j - 1);\n        Flood_Fill (i, j + 1);\n      end if;\n    end Flood_Fill;\n    c : Natural := 0;\n    i3, j3, sq : Natural;\n  begin\n    --  Flood fill the outside part, starting\n    --  from the (1, 3) point of the detailed map.\n    --  The big path never touches the detailed map's border\n    --  (otherwise, the path would not be closed).\n    --  Consequently, the set outside the path is connected\n    --  and we are fine starting with the (1, 3) point only.\n    --  Why not (1, 1)? It is to handle the case where the\n    --  start point (S), drawn as a cross, is in the top left corner.\n    --\n    Flood_Fill (1, 3);\n\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        sq := 0;\n        i3 := 1 + (i - 1) * 3;\n        j3 := 1 + (j - 1) * 3;\n        for ii in 0 .. 2 loop\n          for jj in 0 .. 2 loop\n            if visited_x3 (i3 + ii, j3 + jj) = outside then\n              sq := sq + 1;\n            end if;\n          end loop;\n        end loop;\n        if sq = 9 then\n          --  The entire 3x3 square is marked as \"outside\".\n          --  Then it is neither an inside tile, nor a tile with\n          --  the giant loop on it.\n          --  In the latter case, we have, for instance for a 'L',\n          --  only 8 squares set as visited:\n          --\n          --      OpI\n          --      Opp\n          --      OOO\n          --\n          --  O = outside, set by Flood_Fill\n          --  p = path of the giant loop, set by part 1\n          --  I = inside; not set.\n          --\n          c := c + 1;\n          visited (i, j) := outside;  --  This is just for the visualisation\n        end if;\n      end loop;\n    end loop;\n    --  Inside = surface - path's length - outside.\n    r (part_2) := n * n - path_length - c;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if verbose then\n    Dump_PPM;\n  end if;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 6897\n    --  Part 2: validated by AoC: 367\n  end if;\nend AoC_2023_10;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_10.txt",
    "content": "|J.7F7-L--77F7-J-F-77FF-7FLLJ7F-J-F---7-J-L-FJ-FJFJ7-7-FF--L7.L--|.FJ-J77FFF|77-7F-7-FFL7-|7-F7-L7F7FF7.|----LL-77FF.F--F-J-LFFL-F-LF7--F-FL\nL.---7FF--LJ7J7..L7LFJ.||FJL|LJ.|77.LJ|F|||7J|.|7|JJFF-L--F-|7..L.F-J7JLL--7|J|7.|L-7-7J|F-7-L|J|||-F7F-FJ|..|LFJLJ.-.|||JJ-LFL.||.L|L-JLJJ.\n.|L|7|FJJ7L-7F777L|FLJ-FFL-FL-7FJ.|F-LLLJ||.L--77J7-FLJ.L-F-F-7.LFLJ-|L||..77.|F77-L7JL-7JFJ7|FF-L7-LL--|-L.|-7L-J|7..L7||.LFJ7L7JF7.7J7-7-|\nLFF--7F|FJLLLJL|7J||.LF-JLL|J.|77F-J7.LJ-|--7F7|L7--|.L.7J||F7L7L7F|FF7-J|7||7F||J7-7.LJJ7J--L7JL7||.LL-||L77||-LF-7FF7L--F-LFJJJF|L7L---JJ|\n.LL|L7JF|||..L7|.FF-77|||77.LL7-JJJLL.F..LF-FJLL-L7L|7|F|FF7F7JF7JF7|||7--|7FFFJ|FF7F777..F-J-|.LJ|FFF-7FF.|L-J.FJ.|7LJ.L7|FLFJJF||LL.|.|J.J\nJJL7F|FL-77-L-7F7-|.|F-JJL777L|FLJ..|---FF..|.L-7FF||-LFF7||||-|JFJ|FJ|J7L|JFFL7L7||||-F7FJL7L777LJ-|JF||J7F-J77||.L|7J--J|L.-.77FJ.L7-7L.-L\nFF.LJ-JLFJ|-|F-|JF77-F7JF|JF7||7J7F-7.LFJL-77.L7|F7F77.FJ||||L7JF|FJL7|F|F7F---JFJ||||-77LL-|7|FJ-|..F--7|FF7|L-F-J..|J|.LF||F-.LJ|7.|.||||.\nLJ.|FJ|-|JJJ|LL--|JL-LJ7L||L-LF7LFF7F77JJ7JF7-F-7||||F7L7LJ||FJFFJL--JL7F-7L7F-7L-JLJL7.7||F77JJF-J--LJL-F-7F7.||7F7-7-L7F-7L|J-F|L7LL-F-L7.\nLLF--JFF.L.F|J.|LL----F77JF7||LL-FJLJL7.F7.|L7|FJ|LJ|||-L-7LJ|F7L-7F---JL7L7LJFL7F----J-F7FJL7JF|LJJ-.F-J|FJ||F7F777.|LLFJLL-J-|FJ-|L|-|.L|7\n||||-F.F7.FF--7L-J7.J.LJJ7L|-7.LFL-7F-JF-LFL7||L-JF-J||F7-L7FJ|L7-|L-7|LF|FJ7FL.||JF7.LFJLJF-J.F|-LJ|.LFFJL7|||LJ|F7-F..7J7.FJ.|J..LLJJ||-7.\nFFL.FF-F7.F|-..-.7FJ7.J7LL-LFL-7-|FJL7-|J-F7||L--7L--JLJ|7FJL-JFJFJF-J-.FJ|F7JLFJ|FJL77L--7|JF7F77L|F77LL-7|||L7FJ||7F.F7L|JLFJJ|.7--7.JJ|.|\n--JF|J7L--FJLLJL-|-||-.L-|.FJJLJFF|F-JF-7FJLJ|F7FJF-----JFL7F-7|FJFJF7LFL7|||FFJFJL-7L7.F-JL7||||FFF77-LF-J||||||FJL--7|L-7JJ|-FL-J.FF-JL7JJ\nL7FJ.LF77||.7F|FFJ.L7.F-F|.JJ..F7|||F7|FJ|F-7LJ|L7|F--77F-7LJ7|||FJFJL77FJ|||FJFJF7|L7L7L-7FJ||||FFJ|77|L-7||L7|||F---JL7FJ..|-FF7L-|.J-7JF-\n-|F-77L77FF-JLJ-|FFJF.7FLL7.FF-JL-JLJ||L7LJFJF7L-J||F7L7L7L7F-J|||-L7FJFJFJ|LJFJL|L--JFJF7|L-JLJL7L7|77-L-|||FJ|||L-7F--JL7F77FF|.-JF7|F7FFL\nFJ|-.-7|FJJFFL7JL-L7|-LL-|L-FL-7F7F7FJ|FJJ|L-JL7F-JLJL7|FJFJ|F7LJL7FJL-JFJ-L7FJJFL---7L7|||F7F---J.||F7|-FJLJL-J||F7|L--7FJ||F77JJ||L|LFJ|J.\nJJJJ.|FLJLFL7L|-7|LF|7LLLJ|7F.LLJLJ||FJ|JF7F7FFJL7F7F-J||FJ7LJL-7FJL---7|F7F|L-77F7F-JFJ||||LJF7F7F|LJL7FJF--7F-J||LJF7FJL-JLJ|-J|FJ7LF.L|J-\nL|FFJJJJ..L7.F|.F77.|J-F7F|F|7FF-7L|||FJFJLJL7L7FJ||L7FJ||-F7F7L||.F7F7||||FJF-JFJ|L-7L-JLJ|JFJ||L7L--7|L-JF7||F-JL7FJ||F-----JL7-|J..L7||..\nF-7|7J|JFF-77L-7FF|-||.|.F7F-7LL7L-JLJ|JL-7F-JFJ||||FJL-JL7||||FJL7|||LJLJLJFJF7L7|F-JF7F-7L-JFJL7L-7FJL7LFJLJLJF--JL7||L-7F7F7F77|-.77FLF-|\n.L|LJ-FJ|L-7L.L-.L|.F--FL||7-F7|L---7FJF7J|L7.L7L7||L----7|||||L-7LJ|L7F7F7FJ7||FJ||F7||L7L---JF7|F-J|F7L7L--7F-JF-7FJLJF7LJLJLJL7-.FJFL|J.L\n7L|J-FL--7.-...L77L-JLF7J|L7F||F----JL7||FJFJF7L7|||F--7F||||||F7L-7L-J|||LJF7||L7|LJ||L-JF7JF7|LJL-7LJL7|F7FJ|F7L7|L7F7||F7F7F--J--.F-J|JFJ\n|J|7..J|F77.77-FJF--F-J|FJFJF||L--7F7FJ||L7L7|L-J|||L-7|FJLJ||LJ|F7|F--JLJF7|||L7||F-JL77FJL7||L-7F-JJF-J|||L7||L7||L||LJLJ|||L-7|FLL|F-7||J\nL-|L-J.7-J|-LJLJ-|JLL-7LJFJF7|L7F7LJ||F||FJFJL--7LJL-7||L--7||F-J|LJL----7|LJ||FJ||L-7FJFJF-J||FFJL--7L-7|||||LJFJ||FJL77F7LJL-7|777L|LJLF7.\nLFLJ...L7.L7.F7J7F.FLL|F7L-JLJFJ||F-JL-JLJFJF7F7L-7F-J||F7FJLJL-7L7F--7F7||F7LJL-JL7J||7L7L7FJ|FJF---JF-JLJL7L-7L-JLJF-JFJL7F7LLJL|7-F.|-J77\nFF-FL-7LJ.L|77|FF|JJ7LLJL7F--7|FJ|L----7F-JF|LJL7L|L-7|LJLJF-7F-JL||F7LJLJLJL-7F---JFJ|F7|FJ|FJ|FJF-7FJF7F7FJF7L7F7F7L--JF7LJL--77|J.|LF-L7J\n-F-F-JJ7L-FLJ7F|F-7||-|F7LJF-J||FJF-77FJL--7L-7FJFJF-JL----JFJL7LFJLJL7F7F7F7FJL--7-|FJ|LJL-JL7|L7L7|L-JLJ|L-J|FJ|LJL----JL-----JF777L7J--J|\nJJ.LFLL------J7-JLF-FF7||F7L-7|||FJFJFJF--7|F-JL7L7L7F7F7F--JF7L7L7F--J||||||L7F--JFJL7L----7FJ|FJFJL-7F--JF--JL7L--7F7F7F7F7F7F-JL-7||.-J-7\nFJ-FFF7J-JF|.|JL||LF7||||||F-JLJ|L7L7L7|F7LJL--7|||FJ||||L7F-J|FJFJL7F7|||LJL7|L7FFJF7L7F7F-JL7||F|F--JL--7|F---JF--J|LJLJLJLJLJF---J7J.LJ||\n--F-|JJ.|-|7-7.FJF-J||||LJLJF--7L7|FJ-|LJL7LF77||FJ|F|LJ||LJ-FJL7L7FJ||||L--7|L7|FJFJL-J||L--7LJL7|L7F7F7FJLJF7F7L---JF--7F7F--7L7|FLJL7|LFJ\n.|..L77FF-JJF-777L-7LJ||F---JF7|FJ|L-7|F--JFJL-J|L7|FJF-JF77FJF-JFJ|J||||F77||FJ||FJ7F-7|L7F7|F--J|FJ||||L-7FJLJL-----JF7LJ|L-7L-J-F-J-FJ|||\n-L7.F-FFJ||LL7|F-77L-7|LJF7F-J|||FJF-J||FF7L---7L7||L7L-7|L7L7|F7L7|FJLJ|||FJLJFJ||F7L7||FJ|LJL7F7||FJ|||F7|L7JF7F7F---JL-7|F7L----7LJLJ7L-7\nL7|J7|J||F-7FJLJFJF--JL7FJ|L-7||||FJJFJL-J|F7F7|FJ||-|F-JL7|FJLJ|FJ||F--J||L--7|FJ||L7|LJL7L-7FJ|LJ|L7LJ|||L7L-JLJLJF-----J||L7F---J7.FFLJ||\nLF|-77-L7L7|L--7L-JF7F7||FJF-J|||||F7L7F-7||LJ|||FJ|FJL7F7||L--7LJFJ|L7F7||F7FJ|L7|L7||F7FJF7||LL-7L7L-7|||FJF7F-7F7L--7F7LLJFJL--7.77F7|F-.\nF7L-JJLFLJ|L7F7L--7||||LJL7L-7|||||||FJL7LJL-7LJ||FJL7FJ||||F7FJF-JL|FJ|LJ|||L7|FJL7||LJ|L7|LJL7F7|FJF-J||||FJLJJLJL--7LJL7F7|F---J7J-JL77.L\nF|-.||FFL-L7LJL---J|||L-7FJF-JLJ|||||L-7L7F7|L-7|||F-J|FJ|||||L7|F7FJL7L7FJ|L7||L-7||L7FL7||F--J|||L7L-7||||L7F------7L7F7LJ|LJF--7JF7.LJF-7\n.LJF-7J..JFL--7F-7FJLJF-JL-JF--7|||||F7|FJ||F7J||||L-7|L7|||||F||||L7FJL||.|FJ||F7|||FJF7||||F7J|||FJF7|||||FJL7F---7|.LJL--JF7|F-J.|7FLFL-7\n||.-7|.L|FF.|FJ|.S|LF7L----7|F-JLJ|||||||FJ|||FJ|||F7|L7||||||FJ|||FJ|F-JL7|L7|||||||L7|||||||L7|||L7|LJLJLJL--JL7F7LJF7F-7LFJLJL--7JJ7.--7|\nJ7FL-J77L-J.LL-JFJ|FJL----7||L-7F7LJLJ|||L7LJ|L7|||||L7||LJ||||FJ|||FJL-7FJL7||||||LJFJ|||||LJFJ|||FJL7F7F7F7F7F-J||F7|||FJFJF7F7F7|.FL7LFJJ\n|L|7||7-|J.FJLF-JFJL-----7|LJF7||L---7LJL7|F7L7||||||FJ|L-7LJLJL7||||F-7|L7FJ||LJ|L-7L7|LJ|L-7|FJ||L7FJ|LJLJLJLJF7|||LJ||L-JFJLJ||LJ7-|.FJL.\nF7|FF|J---L|.FL7FJF--7JF7|L7F||LJF---JF--JLJL7LJ||LJ||FJF-J|F---J|LJ||J|L7|L7|L7FJF7L7LJF-JF-J||F||FJL7L---7F7F7|||||F-J|F--JF-7LJ||J7LF7--F\n|LL|.LL--7.7-F7||JL-7L7||L7L7|L7JL---7|F7F7F7L7FJL-7||L7L--7L7F7FJF-JL7|FJL7||FJL7|L7|F-JF7|F-JL7||L7FJFF-7||||||LJLJL-7||F7LL7L7F-77||||F|.\nL...--LL.LF-7||LJF7LL7LJL7L7|L7L--7F7|LJ||||L7||F7FJ||7L7F-JF||||.L-7FJ|L7FJ||L7FJ|FJ|L-7|LJL7F7|LJ-LJF7L7|||LJLJF-7F7FJ|LJ|F7|FJ|FJ--FJL-77\n.-F-.-7LF-L7||L--JL77L7F7L-JL-JF-7LJLJF7||||FJ|LJ||FLJF-J|F-7LJ|L7F-JL7|FJ|FJ|FJL-J|FJF-JL-7-||||F-7F7|L-JLJ|F7F-J7||LJFJF-J|LJL-JL-7|L7F-J7\nFJL7.F7-LF-J|L----7|F7LJL7F----J7L-7JFJ|||||L7L7FJL7F7|F7LJFJF7L-JL-7FJ|L7|L7LJF--7|L7|F7F7L7LJLJL7LJ|L---77||LJF-7|L--JFJF-JF------JF7|L7JL\n|--|FL7|JL-7|F7.F7||||F--J|F----7F7L-JFJLJ||FJFJL-7|||LJ|F7L-JL7F---J|J|FJL7|F7L-7LJFJ|||||FJF----JF7L----JFJL--JFJL----JFJF-JF7|F---JLJFJ.|\nL7F|7JLF7||||||FJLJLJLJF7FJL---7LJL---JF7LLJL7L-7FJ||L--J||F-7FJ|F7F7|FJL-7|LJ|F-JF7L7LJ|||L7|F7F--JL7F---7|F-7F7L--7|F-7L7L--JL-JF-7F-7L-7J\nLLFJLJFJ|F-JLJ|L---7F-7|LJF----JF7F--7FJL--7LL--JL-J|F7F-JLJFJL7LJLJ||L-7FJL7FJ|F7|L7L-7|||FJLJLJF---J|F--J|L7||L7F7L7L7|FJF-7F7F-JFJ||L7FJJ\n.|..L-L7|L-7F7|-F-7LJJLJF7L-7F7FJLJF7LJF---JF--7LF-7LJ|L---7L-7L-7F-JL7FJL7L|L7||||FL7FJLJ||F7F7FJF7F-JL---JFJ|L7||L7L-JLJFJ7LJLJF7L7L-7LJJJ\nFF|-FLFJL-7|||L7L7L7F7F-JL-7LJLJFF7||F7L-7|FJF7L7L7L--JF-7FJF-JF-JL-7FJL7FJFJFJ||||F-J|F-7|||LJ|L-J||F--7F7FJ|L-JLJ7|F--7FJF7F7F-JL7|F7L-7-7\nFFJF|LL--7LJ|L7L7|FJ||L---7|F----JLJLJL--JFJFJL-JFL7F-7L7|L7|F7L7F--JL-7LJFL7L7|||||F7LJFJLJ|F7|F7LLJL-7LJLJ|F---7F7LJ7FJ|7|LJLJF7FJLJ|F7|7F\n.FJ-F---7L--J|L7LJL7||F7F-JLJF7F7F----7F-7L7L7F7F7|LJ7L7||FJ|||FJ|F7F-7|F--7|FJLJLJ|||F7L--7LJ|LJL-----JF-7F7|F--J|L--7L7L7L7F--J|L--7||LJ-L\nF|F-L--7L7JF7F-JF-7||||LJF7F7|||||F---J|FJFJFJ|||L-7FF7LJ||FJ|LJFJ||L7LJL-7LJL-7-F-J||||F--JF-JF7F7F----JFJ|||L---JF-7L7L7L7|L--7L7F-JLJ7JFL\nF7-L|JJL7L-J|L--JFJLJ|L--JLJLJLJLJL-7F-JL7|FJ.|||F-JFJL-7LJL7L7J|FJL7L-7F-JF7F7L7L7FJ||||F--JF7|||||F----JFJLJF7F-7L7|FJ|L7LJF--J|LJ7L|FF.F|\n77J-|F7.L--7|F7F7L--7||F7F7F--------J|F--J|L-7||||F7L7F7L7F-JFJFJL-7|F7||F7|LJ|FJ|LJFLJLJL-7FJLJ||LJL-----JF--JLJFJFJLJF7-|F7L------77|F77FF\n|JJ7L-.LF--JLJLJL7F7|L7||||L--7F-----JL---JF-J|LJLJL7||L7||F7L7|F-7|||||||||F-JL7F7F----7F7LJLF7LJFF7F7F7F7L---7JL7L---JL7LJ|F7F----J-7J.7--\n||.|-|-L|F7F7F-7FJ||L7|||||F7FLJF----7F-7F7L--JF7F-7LJL7LJLJ|FJ||FJ|||||||LJL7F7||LJF-7FJ||F7FJL7F-JLJLJLJL7F--JF7L7F----JFFJ|||7F7JJJ|J7LL|\nF|J|.F.F||LJLJFJL-JL-JLJLJLJ|F7FJF--7|L7|||F-7FJ||FJF-7L---7||FJ|L7|||||LJFF-J|||L7FJ-|L-JLJ|L-7|L--------7||F--JL7|L7F7F7FJFJ|L-J|L||FF77L|\nJL||7.FLLJ7F--JF-7F7F---7F-7|||L-JF-J|FJ||||7LJJLJ|FJ-|F---JLJ|FJLLJ||LJ.F-JF7|LJFJ|F-JF-7F7L--JL---------JLJ|F--7|L7LJLJ|L-JLL7F7L--77JLFL|\n|.JJL7J..F-JF-7|FJ|||F7FJ|-||||7F7L-7LJFLJ|L-----7|L7FJL---7F7LJF---JL--7L-7|LJF7|FJ|F7L7||L7F7F7F7F7F-------JL-7LJ7|F--7|F-7F7LJ|F-7L7-F7||\nF7L-J|F-FL-7|JLJL7|||||L-JFJLJL-JL--JF7F-7|F-----JL7|L7F7F-J||F-JF7F-7F7|JFJL7FJLJ|-||L-JLJFJ|LJLJLJ||F------7F7L7F7|L7FJLJFJ|L7LLJ.L-JJL|--\nJJ7.F7|L|J.LJF--7LJLJ|L-7FJF7F7F-----JLJFJ|L-77F7F7LJJ||||F7||L--J||FJ|LJFJF7||F-7|FJ|F----JFJF----7LJL--7F-7||L7LJ|L-JL7F7L7|FJF-77J.|7.LJ.\n|.FF|77|F----JF7L----JF7LJFJ||LJFF------J-L-7L-JLJL7F-J||LJLJL-7-LLJL7L7L|FJ|||L7LJL-JL----7|7L-7F7L--7F7LJFJLJLL7FJF7|L||L7LJL7|FJ|JF7|7F|7\n|-L-L-JFL7F--7||F7F7F7|L-7L7LJF-7L-7F7F7F7F7L-7F---JL7FJ|F-7F7FJF-77FJFJJLJJLJ|FJF-7F7F-7F7|L7F7LJL--7LJL--JF7JF7||J|L7FJL7|F-7LJL-77|LJJ---\n|.|L|L-7JLJ|7LJLJLJLJ||F-JFJF7L7|LFJ|LJLJLJL-7|L---7FJ|||L7|||L7L7L7L7L777J-FFLJ.L7|||L7||||FJ|L-----JF-----JL7||LJFJFJ|F7|||FJF---JL||7.L|7\nJ-77|J|||.|F7JF-----7LJL-7|FJL-JL7L7|F-7F7F--JL----JL7L7|FJ||L7L-JFJ-L7L-7-|FF----JLJL-JLJ|LJFJF------JF--7F7FJ||F7|FJ7||LJLJL-JF7JJ.|--77LL\nL-J|J.7-|7L|||L----7L-7F7|||F--7FJ7LJL7|||L--------7FJFJLJFJ||L7F7|J-FJF7|J|JL-----7F7F--7|F7L-JF7F----JF7LJLJ7|LJLJ|F7LJ.F-7F7J||.|7J-LFL.|\n|L7JF-|LLJJ|L---7F7L-7|||LJLJF7|L7F---J|||F7F---7F-J|FJF-7L-J7L||LJ||L-JLJ7J|-F-7F-J|LJF-J|||F7FJLJF----JL--77FJF7F7LJL7F7|FJ|L-JL--77.|J|.|\nL..LF--7|F-L---7LJL--JLJL----JLJFJL---7||LJLJF7FLJF-JL7L7|-J7F.||FLJ77J7|.-.|7|FJL--JF7L-7LJ|||L---JF------7L-JFJ||L7F7LJLJL-JF-----J-F.F77|\n.77.|FJ-F7|J|JLL7F7F7F7F7F7F-7F7|F----JLJF---JL--7L--7L-JL7||.FLJ-|F-F.7.F---FJL-7F--JL--JF7|||F7F-7L----7J|F7FJJLJFJ||F7F7F-7L----7J..L||.-\n7.F||L7LL7J||J||LJLJLJ||LJLJ7LJ||L-------JF---7F7L--7|F7F7L-77.|LFFJJL-J.J7|LL-7FJL7F7F---J|LJ||LJFJF---7L7|||L---7|FJ||LJ|L7|F-7F-JJFFJL777\nJ-FJF.LF|||-||FF7F--7LLJ-F--7F7||F----7F--JF7F||L---JLJLJL7FJ--JJF-..L--L-7-F--JL--J|LJF7|FJF-JL-7|7L--7L-JLJL----JLJFJL-7|FJ|L7LJLL-L.77LLF\n.F7JLF|.L|.FF7FJLJF7L7LF7L-7LJLJ|L---7LJF--JL7LJF--7F----7||7J-|-J|-.L-|LF--L7F7F---JF7|L7L7|JF--JL7JF7L-7F7F7F---7F7L7F-J|L7L7|JL7L7F|JL-|J\n7LLJFF7FF7-L||L---JL7L-JL77L---7L----JLFJF--7L-7|F7LJF7F7|LJ-.F|--JL7.L|J.LJ-||LJFF7L||L7L-JL7L---7L-JL--J|||LJF-7LJL7LJF7L7L7|L7--7LJ.FL|.L\nJ-|LF7L-F7FFJL--7F7.L---7|F7F--JF7F7LF7L7|F7L--J||L--JLJLJ.LJFL|.F|FJFFLF-F|.LJF--JL-JL7|F--7L7F7.L7F-----JLJF7L7L---JF-JL7|FJ|FJFF|-LJ77L-.\nFJJ7|||.|L7L--7FJ|L-----J||LJF--JLJL-JL-JLJL-7F7||F------77J-J-F.L7JFJ|J|7|LFLJL7F7F--7|LJF7L7LJ|F7LJF----7F-JL7L-7F--JF--JLJ-||JL-.F|L--JL7\nL..F7F7FL7L7F-JL7L------7|L-7|FF----7F7F7F---J|LJLJF---7FJ.7..FF7.LF|-FF7-FJJ.7LLJLJF7|L7FJL7L-7||L--JF7F7|L--7|F7LJF-7|FF--7-||-..|-7.|.FLF\n.L|LLJLLLL7LJF-7L7F7F---JL--J|FJF7F7|||||L----JF---JF7F|L---7-|LJ77LJ7FLJJJ--7|-|F--J|L7|L-7L-7||L-7F7|LJ|L-7FJLJ|F7L7|L-JF7L7||J-F|J|-J.7JL\nF---|7J|.L|F7L7L7LJ|L-----7F7|L7||||LJLJ|F7F7F7L----JL7L----JL|J|J|LL-F-J|L--|JFFJF-7L-JL--JF7LJL--J|LJF7L7FJL-7FLJ|FJ|F7FJL-JLJJ7L7.7|.-JFL\nLJ.FL7.J-FLJL-JJL-7|F-7F77LJLJ.LJ||L-7F7LJLJLJ|F7F7F-7L-7LF7JFF-77JF.|.F.|-|FF7FJFJFJF----7FJL-7F--7L7FJL-J|F-7L--7LJJLJ||F7F7||7|F|7LF-JFJ7\nL..JJ.JJ.F7F7F7|F7||L7||L7F--7FF7LJF7LJL-7F--7|||||L7|F-JFJ|FL|FJJF|-F-7-F---J|L7L7L-JF---J|F--JL7FJFJL--7FJL7L-7FJF7F7FLJ|LJL-7JJ-F77|-77LJ\n|-|.77JJFJLJLJ|FJLJL7|LJFJL-7|FJL--JL----J|F-JLJLJ|FJLJF7L7L7||L7|F7JL7|.L--7FJ-L-JF-7L7F7FJL7F7FJL7|F7F-JL-7L-7|L-JLJL---JF---J.|F||FJ7LJ-J\nJ-J7JL.-L-7F-7|L---7|L-7L-77||L-----------JL-7F7F7|L7F-JL7|FJFJFJF||F-J|F7-FJ|F-7F7L7|FJ|LJ-FJ|||F-J||LJF7F7|F7||F7F---7F-7L---7.|7JL|.J7.L7\n.F7|7JF|J.LJFJL7F7FJL--JF7L-J|LF7F-----------J||||L-JL--7LJL7L7|F-J|L7FJ||FL7|L7||L-JLJFJF-7L7|||L7FJL--JLJ|LJLJLJ||F-7|L7L7F7FJ7L--||7.L7.L\n.L-LJ-7JLFF7L-7|||L----7|L7F7L7||L----7F------JLJL-7F7F7L--7L7|||F-JF||||L7FJ|FJ|L-----J7L7|LLJLJ.LJF7.F7F7L--7F7|LJ|FJL-JJLJLJ---J.77F7J|FJ\n-J.F|7.|FFJL--JLJL-----J|FJ|L7LJL-----J|F---7F-----J|||L-7||FJ||||LFFJ|FJFJL7|L7L7F-7-F---JL7F-77F7FJ|FJLJL7F7LJL7-FJL7.F7FFF7-FJ|..--J|.LJJ\n|F-7F|JF-L7F7F----7F7F--JL7||L7F-------JL--7||F-7|F7||L-7|FJL7||||F7L7|L7|7FJL7L7|L7L7L----7|L7|FJ|L7|L--7.LJL--7L-JF-JFJL--JL7|L|-FJ|FJJJ7.\n|.J-.7L-7LLJ||F---J|LJ7F7LLJF7LJF7LF7F7F---JLJ|FJFJLJ|F7|||F-J|LJ|||FJL7|L7|F-JFJ|JL7|F7|F7||FJLJFJFJL7F7L---7F7L--7L--JF-----JF7J..FLJ.LLFJ\n|7LF|L7JF---J|L7F7FJF--JL-7FJL--JL-JLJLJF-----JL7|F--J||||||F7|F-J||L-7|L7LJL-7L7L-7||||FJLJ|L--7L7L-7LJL----J|L--7L7F--J.F7F7L||--77..L.7J|\n7-F---7-L----JFJ|||FJF7F-7|L--7F7F------JF------J|L7F-J||||LJ|||F-J|F-JL7L-7F-J-L-7LJLJ|L--7|7F7L7L--JF7F7F--7|F--JJLJF--7|||L-JL7|J|F-|.J-J\nF7L--7|F7F-7F-JFJ||L7|LJJ||F7FJ|||F--7F--JF-7F7F-JFJL-7LJLJF-J|||F-JL7F7|F7|L7F--7L7F-7L---JL-JL-JF7F-J||LJF-J|L--7F7FJF-J|LJF---J7-FJ7|..|.\nL|J.FJ|||L7LJF7|FJ|FJ|F--JLJLJFJLJL-7|L--7|FJ|LJF-JF7FJF--7|F-J||||F7LJ|||||FJL7FJ-LJFJF7F7F-7F7F-JLJF7LJF-JF7|F--J|||FJF7|F7L-7F7F-7--7-|77\nF7--L7LJL-JF7|||L7|L-JL-7F7F-7|F----JL--7LJL-JF7L-7||L-J7FJ|L-7|||FJL7FJLJ|||LFJL7F7JL-JLJ||FJ|||F---J|F7L7FJ||L---JLJL7|LJ||F-J|||FJ7J|.LFJ\n||-LJL7F--7||||L7||7F---J|||.LJL----7F7||F7F--JL--J||F7F7L7L7||LJ|L7FJL-7FJ|L7|F-J|L7JF7F7LJL-J|||F7F7LJL-J|FJ|F----7F-J|F-JLJ|FJLJL77F|7.7J\nJJ7L-LLJ-FJ|||L-JLJFJF7F7|||F-------J|L7LJLJF-7F-7FJ|||||FL7L7L7FJFJL7F7||FJFJ|L7FJFJFJLJL7F7F7LJ||LJL7F---JL-JL---7||F7||F7F7FJF---JJF--FJ|\n||F-|.LF-JFJLJF----JFJ||LJLJL----7F7-|FJF7F7L7|L7|L7LJ|||F7L7L7|L7L7FJ|LJ|L7L7L7||FJ7L--7FJ|LJ|F7LJF--J|F--7F------JLJ|LJLJ|||L7|F7-|-|.|JL|\nF7|F77.L-7L--7L7F---JJ||F-7F7F--7LJ|FJL-JLJL-J|FJL-JF-J|||||L7|L7|FJL7|F7L-JFJFJLJL-7F--JL-JF-J||LFJF7FJL-7LJF7F7F7F77|F7F7LJL-JLJL-77|.|.F-\nLF-----7J|F--J|LJ7F7F7LJL7|||L7FJF7LJF7F7F----JL7F--J7FJLJ|F7|L7|||F-JLJL--7L7L--7F-JL-----7L7F|L7|FJLJF--JF-JLJLJ||L-J|LJL---------J7LLL7J|\nLL----7|7LJJF777F7|LJ|F7FJLJ|FJ|FJL--JLJ|L7F7LF7||F7F7L7F-J|||FJ|LJL--7F7F-JFJF--JL7F--7FF7L7L7|FJLJF77L---JF7F--7LJF-7L7LF7F-7F-----77J-J-|\nF7.|FL||F77FJ|F7|||F-J|LJF-7LJFJL------7L7||L7|LJ||LJ|FJL7FJLJL7|F7F--J|LJF7L7L7F--JL-7|FJ|FJFJ||F7FJ|F7F---JLJF7L--JLL7L-JLJFJ|F---7|7FF-L|\nL-LF--JLJL7L7LJLJLJL7FJF7L7L-7L-----7F7L7||L7||F-JL7FJL-7|L-7F-J||LJF7LL--JL7L7|L-7F-7|||FJL7L-J|||L7LJ|L----7FJL----7LL-----JFJL--7||-.|..F\n|FLL7F-7F7L-JF7F---7|L7|L-JF-JF7F7F7LJL-JLJFJLJ|F-7|L-7|||F7|L7FJ|F7||F7F---JFJ|F-JL7LJ|||F7|F--J||LL-7L7F-7FJL7F----JF7F--7F-JF7F7|LJ-LF7F-\nFF-FLJL||L7F7|||F--JL-J|F--JF7|||||L-7F7F7FJF--J|FJ|F7L7||||L7LJFJ||||||L---7|FJ|F7J|F-J|||LJL-7.||F77L7LJ7|L--JL7F7F7|||F-J|F-JLJLJJL7J.L-.\n|LF-.F-JL7LJ||LJ|F---7FJL7F-JLJLJLJF7|||||L7|F--JL7LJL7|||||||F-JFJ||LJL77F-J|L7||L7||F7||L-7F-JFJ|||F7L--7L7F7F7LJLJLJLJL--JL----7J--J.-L.L\n--|-FL7F-J|FJ|F7LJLF-JL-7LJF7F-----JLJ|LJ|FJLJF7F-JJF7||||||FJL-7|FJL--7L7L-7|7|LJFJ||||||F-JL-7L7||LJ|F--JFJ|||L-7F7F7F7F-7F7F7F7|FL.FJJJ.|\n.|.L|.||F--JFJ||7F7L-7F-JFFJLJF--7F--7|F7||F7FJLJF-7|||LJ|||L7F-J||F7F7|FJJFJL7L-7L7|||LJ|L-7F-JFJ||F-JL-7.L-J|L-7LJ||LJ|L7LJ||LJLJJ7F-7.-LJ\nFLJ77.LJL-7FJFJL-JL--JL-7FJF7FJF-J|F-JLJ||LJ||F7||FJ||L-7|||J||F7||||||||F7L7FJF7|FJ|||F-JF7||F7L7|||F7F7L--7FJF-JF-JL-7L7L-7LJ7JJ|--7LL7-|.\nF-LJ|J.JJFJ|LL---7F7F7F-JL-JLJFL-7||F-7FJL7FJ||L7|L7|L7FJ||L7|||||||||||||L7|L7||||FJ|||F-JLJ|||FJLJ|||||F--JL7|F7L----J7L-7L7F7F-7J..LL|.LJ\n7..-7LJ7FL-JF7F-7||LJLJF7F7F---7FJ|||FJ|F-JL7||FJL7LJF||JLJFJ|||||||||LJ||7||FJ|LJ|L7|||L--7F|||L7F-J|LJ||F7F7|LJ|F-------7L-J|||FJF7-.F7-||\n|.FF--LJ.|JF|||FJLJ-F--JLJLJF-7LJFJLJL7|L-7FJ|||F7L7F-JL--7L7|LJLJ|||L7FJL7||L7L7FJFJLJL7F7|FJ||FJ|F7|F-JLJLJ|L--J|F------JF--JLJ|FJ|.FFJFL7\n77.LJ.|7L77FJLJL--7FJF7F7F--JF|F7L-7F-JL7FJL7|||||FJL7F7F-JFJL---7|||FJL7FJ||LL7||FJF-7FJ|||L7||L7||LJ|F7F---J-F--JL-------JF7F--J|FJ-FJLF-|\n|||--7LLJ|LL--7F-7|L-JLJ||F---J||F7||F7FJL7FJ||||||F-J||L7FJF-7F-J||||F7|L7||F-J||L7L7LJFJ||FJ|L7|LJF-J||L-----JF7F7F7F7F-7FJ|L7F7|L7-7-F--J\nFFLJL|-L.7JFLFJ|FJL--7F7LJL7F7FJ||LJLJ|||-||7||LJ||L-7|L7|L7|FJL-7||LJ|LJFJLJL7FJ|FJFL-7|FJ||FJF||F-JF7||F7F-7F7|LJLJ||LJFJL7L7LJLJFJ.J7L7J7\nL.|7.|.|.||FLL-JL7F-7LJL---J||L7||F---JL7FJL7||7FJL-7||FJ|F||L-7FJLJF-JF7L--77LJ-||F7F-J|L7|||F7LJ|F-JLJ|||L7|||L--7JLJF7L--J-L--7FJ77|7.JF7\n|7.FJ-F|FJ|F-F-7FJ|FJF7F7F7FJL7|LJL7F-7FJL7FJ|L7|F7FJ||L7L7LJF-JL--7L-7||F-7|F---JLJ||F7L7LJ|LJL-7LJF---J||FJLJ|F--JF--JL-------7||F7-F77FJ7\nJ-F|JL||-L7--L7LJFJL7|||LJ||.FJ|F--J|L||F-J|JL-J||||FJ|FL7L-7L-7F-7|F-J||L7|||F7F7F7|||L7L7FL7F-7|F-JF7F7||L7LFJL---JF7F7F7F-7F-J|LJL7JJ|J-7\n||LL7-JLLLL7|LL-7L-7||||F-JL7L-JL--7L7||L-7L---7||LJL7L7FJF7|F-JL7||L7FJ|FJLJ||||LJ||LJ7L7L-7LJ|LJL7FJ||LJ|FJFJF7F7F-JLJLJ||FJL-7L---J7-|JF|\nFJ7-|-|7|LLFL-.FJF7|LJ||L-7FJF-----JFJ|L7FJF-7FJ|L--7|FJ|FJ||L-7FJLJ-LJ7||.F-J||L7FJL--7FJF7L--7F--J|FJ|F-JL7L7|LJ|L-----7||L7F7L7LF|-7-.7JL\n||F7JF-7-J.|-.F|FJ|L7J||F-JL7|F7F-7FJJL7|L7L7LJFL7F7||L7||7||F-JL-7F7F--JL7L--J|FJL7F7FJL7||F-7||F-7||FJ|F7FJFJL-7L7F-7F7|LJFJ||FJF-77JLF||7\nLJJ7.LJ||F|.|.F|L7|FJ7LJL-7FJLJ||FJL-7||L7L7L7LF-J||||FJLJFJ|L-7F-J|LJF7F7L---7LJF-J||||FJ|LJFLJ||-LJLJJ||LJFJF7FJ.|L7||LJF7L7||L77LL-F-|J-F\n.|LJFJF7FL7.|F-JFJLJ--F---JL-7.LJL7F-JFJFJ-L7L7L--JLJ|L--7L7|F7||F7L--J|||F---JF-JF7||L7L7L-7F7FJL7.F---JL-7|FJ|L-7L7||L7FJL7||L7L7..|LF.||L\nF7F---|J-7.LLL--J|LL7.L-7F--7|F---JL-7L7L7F7L7L7F--7FL7F7L7LJ|LJ||L7F--J||L-7F7L-7|||L7L7|F7||LJF7L7L--7F7FJ||FJF7L7||L7||F-J|L7L7L-77.|.7-|\n|-|-|F7|F-7.|-|JF77LL7LL||F-J|L7F7F7FJFJFJ|L7|FJL-7|F7||L7|F-JF7LJFJL7F7||F7LJL-7LJLJFJFJ||||L7FJ|FJF--J||L7LJL7||FJ||||LJL-7|FJF|F7|--L7F7|\n|7|-LJ.-J.F-|.J.JL-.|LF.LJL-7|FJ||||L7L7|LL7LJL-7FJLJ|||FLJ|F-J|F7|LFJ|||LJ|F7F-JFF--JFJ|LJLJFJ|F|L7L-7FJ|FJ-F-J|||FLJFJF-7FJ|L-7LJLJJ|F-L7-\nF7L..F||7.|FJ-FL--|---J7L|J.LJL-J||L7|FJ|F-JF7F7LJF7FJLJF7FJ|F-J||L7|FJ|L-7||||7F7L--7|F-----JFJFJFJF7|L7|L-7|F-J|L-7FJFJFJL7L-7||LJ.FFF7||.\n|J.L7L7J7FJL7J|J-LLFJ.LL-77..|.F-JL7||L7|L7FJ|||F-JLJF7L|LJFJL7FJL-JLJ|L7FJ|||L-JL-7FJ||F-7F-7L7L7L-J|L-J|F7|||F-JF-JL7L7L--JJ|LJJJ7FL-J7|7L\nL-J--7|LF7L---FF.F||J.JF-|.J77FJF7FJ||FJL7|L7||||F---J|FJF7L7FJL----7F7L|L7||L7F-7FJL7|||FJL7L7|L|F-7L--7LJLJLJ|F7L-7FJFJ.|-|-L.LLJFFJ|.F7-.\nLF.-7|JFL---|FLJFF|JJF.F.|FLF-JFJ||FJ|L-7|L7||||LJF-7FJL7|L7|L-7F-7FJ||7|FJ||FJ|J|L-7LJ||L7FJ-||FJ||L7F7|F7F7F-J||F-J|FJLF-7-7-F|.FF|-7FL|J7\nF|F|L.-JJL7|F77L-JFJ.LJJFL--L7FJFJ|L-JF-J|FJ|||L7FJFJ|F-JL7|L7FJL7|L-J|FJL7||L7L7|F-JF7|L7|L-7||L7L-7|||LJLJ||F7||L-7|L7-J||FJ--.FF7|FF7-L.F\nF-7J-JJF7.-|.FJFL7JFL|J-|J|FL||7L7L7JFL-7||FJ|L7|||L-J|F-7||FJ|F7||F--JL7FJLJLL7||L--J||FJL7FJLJFJF7|LJ|F-7FJ|||||F7||FJJ.|7L|J.FL--F-7--LJJ\nJJ|7F.F77-LJF-7L7LJ|.77.|.LL-LJF-JFJ7|.FJ|||FL7||L-7F-JL7LJ|L7|||||L--77|||LJ|.LJ|F--7|||FFJ|F7-L7|LJF7||L||FJ|LJ||||LJJF7.FJ|7-F-|.LJL|.|L7\n|-77||LL7FLLL.F|FJ-|FJ.7F7.F|F-JF-J.F.FL-J|L-7LJ|F-J|F7FJ-FJFJLJLJL7F7L7||FJF7-LFJL7-LJ|L7L7||L--JL--J||L7LJL7L7|LJLJJL-JJF77|77LF77J|--7-|7\n7F7-|-JF7J|.L|--JJ.FJ.7LF7-|FL--JJLJJ|.LF-JF-J7J||JL|||L-7L-J7L77LLLJ|FJ|L7JF77.L-7L-7LL7|-||L7F7F7F7FJL7L--7|FJ7|J|F||.|JL|L|-7.J.L7-FJF-J7\nF-L-LL7-LJ|7.|J.L|F|FF7FLL7.JFLJ.F7|F7.L|F7|J||-|L7-LJ|F-JJ.F-JF-.LLF|L7L7L-J|FFF-JF7|JFLJ.LJL||LJ||LJJFJF7FJLJJF|7.JLF-JJLL-|L-J|LFL.LLJJ.7\n|JL77FL7J.|-.|L7-JJLJJJL7.--||7.FLFFJ|7.LJLJ-LLFJFJ-L.LJJ.|F|L7|.L77LL-J7L---J77|F-JLJFFJFFL|-LJJLLJJ|||FJ||F7.||LLF--7F|JF|-F7J.L-FJ.L-7|-|\n--LL-|7LFJLL-|-|L|.FL7LLF7|F7LJ-7.LL-LF.FJ||.L|L-JJJL-L7LF7J--|-77L7JJ|LF|-JF|LFJ|LJ7FLF7-|J|FLLJ-|J|--LJFJLJ|7LJ-||.FL--FJ-7|LFF.-.F|J.J7-|\nL-|LFLJ7|.FLF-7|7JL|7F-F7|FL7FJ..7-LL-J-|FFF--J|J|JFF|-7.FJ|..|-F|J|LFJFF7FL|LFL-J77|7.L--|7.L777.LJL-JLLL---J-77F-J-JF7-|.JF7.FJ-J7|L--L--L\n|--.FJFJ|L|-7F|..7.LF-..|7FJL|L-LL7F7|L|.|.|L7JF7J7-F---.--77.|-LJ-J||--JJ|7|F7J7|F|FJ7.J-L-LFL-J-|.|JFJJ7LL|.|L-F|J..F|7F7F777.7-7F-J77..FJ\nL7L-|JFLF7|7L|..L7-FJLF-JLJ7|L.||.7L-F.LF7-7.|FJ|.||J|7J7..F-7-FJ||.J7FLJ7LLJ7J|FFJ|L----7JF7LJLJLF7|FJ|F7.L-7-J-JJ.|-LJFF-|J.---7L7.|FJ-FL7\n|L7J.|.L|J|F.L-.JJFJ|F|.L|.L-FJ||-|7F--.FF-7-|7-F7F--FF-J7.JL|-J7.L-LLJL--7J|JF|7|L|LFJ|.--J-JFJ.F--|L--777.LJ|7F||F7.F7||7|.F7..|.L-LJJ.L.|\nFJ-J-77..J7JF-JJJJLFJ|7--7-|.LJ|J.JJ-7-FFJ|.L||F7J|.|L|7|L77||LL-7|7F|||.F|7-----FJ|.||L7JFJ77|.-|7||FF|L7F7.-J-F-|L77FJ-|-|7L-JF77JLL7J|..|\nLJ.LF-FJ-L7-7JJL--F7-LFJ-L.7.L-J-|-L--.F7LJ---JJJ-L-FLLJ-.L|J|.L.L7-L7-F-LJLJ-|-|L-|--JJ|LJ-L-JFJL-JJL7-|LL7JJJL-LLFLFLJLJJLL-J-JL-.LLF-J--J\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_10_questions.txt",
    "content": "--- Day 10: Pipe Maze ---\n\nYou use the hang glider to ride the hot air from Desert Island all the way up to the floating metal island.\nThis island is surprisingly cold and there definitely aren't any thermals to glide on, so you leave your hang glider behind.\n\nYou wander around for a while, but you don't find any people or animals.\nHowever, you do occasionally find signposts labeled \"Hot Springs\" pointing in a seemingly consistent direction; maybe you can find someone at the hot springs and ask them where the desert-machine parts are made.\n\nThe landscape here is alien; even the flowers and trees are made of metal.\nAs you stop to admire some metal grass, you notice something metallic scurry away in your peripheral vision and jump into a big pipe!\nIt didn't look like any animal you've ever seen; if you want a better look, you'll need to get ahead of it.\n\nScanning the area, you discover that the entire field you're standing on is densely packed with pipes; it was hard to tell at first because they're the same metallic silver color as the \"ground\". You make a quick sketch of all of the surface pipes you can see (your puzzle input).\n\nThe pipes are arranged in a two-dimensional grid of tiles:\n\n    | is a vertical pipe connecting north and south.\n    - is a horizontal pipe connecting east and west.\n    L is a 90-degree bend connecting north and east.\n    J is a 90-degree bend connecting north and west.\n    7 is a 90-degree bend connecting south and west.\n    F is a 90-degree bend connecting south and east.\n    . is ground; there is no pipe in this tile.\n    S is the starting position of the animal; there is a pipe on this tile, but your sketch doesn't show what shape the pipe has.\n\nBased on the acoustics of the animal's scurrying, you're confident the pipe that contains the animal is one large, continuous loop.\n\nFor example, here is a square loop of pipe:\n\n.....\n.F-7.\n.|.|.\n.L-J.\n.....\n\nIf the animal had entered this loop in the northwest corner, the sketch would instead look like this:\n\n.....\n.S-7.\n.|.|.\n.L-J.\n.....\n\nIn the above diagram, the S tile is still a 90-degree F bend: you can tell because of how the adjacent pipes connect to it.\n\nUnfortunately, there are also many pipes that aren't connected to the loop!\nThis sketch shows the same loop as above:\n\n-L|F7\n7S-7|\nL|7||\n-L-J|\nL|-JF\n\nIn the above diagram, you can still figure out which pipes form the main loop: they're the ones connected to S, pipes those pipes connect to, pipes those pipes connect to, and so on. Every pipe in the main loop connects to its two neighbors (including S, which will have exactly two pipes connecting to it, and which is assumed to connect back to those two pipes).\n\nHere is a sketch that contains a slightly more complex main loop:\n\n..F7.\n.FJ|.\nSJ.L7\n|F--J\nLJ...\n\nHere's the same example sketch with the extra, non-main-loop pipe tiles also shown:\n\n7-F7-\n.FJ|7\nSJLL7\n|F--J\nLJ.LJ\n\nIf you want to get out ahead of the animal, you should find the tile in the loop that is farthest from the starting position.\nBecause the animal is in the pipe, it doesn't make sense to measure this by direct distance.\nInstead, you need to find the tile that would take the longest number of steps along the loop to reach from the starting point - regardless of which way around the loop the animal went.\n\nIn the first example with the square loop:\n\n.....\n.S-7.\n.|.|.\n.L-J.\n.....\n\nYou can count the distance each tile in the loop is from the starting point like this:\n\n.....\n.012.\n.1.3.\n.234.\n.....\n\nIn this example, the farthest point from the start is 4 steps away.\n\nHere's the more complex loop again:\n\n..F7.\n.FJ|.\nSJ.L7\n|F--J\nLJ...\n\nHere are the distances for each tile on that loop:\n\n..45.\n.236.\n01.78\n14567\n23...\n\nFind the single giant loop starting at S.\nHow many steps along the loop does it take to get from the starting position to the point farthest from the starting position?\n\n--- Part Two ---\n\nYou quickly reach the farthest point of the loop, but the animal never emerges.\nMaybe its nest is within the area enclosed by the loop?\n\nTo determine whether it's even worth taking the time to search for such a nest, you should calculate how many tiles are contained within the loop. For example:\n\n...........\n.S-------7.\n.|F-----7|.\n.||.....||.\n.||.....||.\n.|L-7.F-J|.\n.|..|.|..|.\n.L--J.L--J.\n...........\n\nThe above loop encloses merely four tiles - the two pairs of . in the southwest and southeast (marked I below).\nThe middle . tiles (marked O below) are not in the loop. Here is the same loop again with those regions marked:\n\n...........\n.S-------7.\n.|F-----7|.\n.||OOOOO||.\n.||OOOOO||.\n.|L-7OF-J|.\n.|II|O|II|.\n.L--JOL--J.\n.....O.....\n\nIn fact, there doesn't even need to be a full tile path to the outside for tiles to count as outside the loop - squeezing between pipes is also allowed! Here, I is still within the loop and O is still outside the loop:\n\n..........\n.S------7.\n.|F----7|.\n.||OOOO||.\n.||OOOO||.\n.|L-7F-J|.\n.|II||II|.\n.L--JL--J.\n..........\n\nIn both of the above examples, 4 tiles are enclosed by the loop.\n\nHere's a larger example:\n\n.F----7F7F7F7F-7....\n.|F--7||||||||FJ....\n.||.FJ||||||||L7....\nFJL7L7LJLJ||LJ.L-7..\nL--J.L7...LJS7F-7L7.\n....F-J..F7FJ|L7L7L7\n....L7.F7||L7|.L7L7|\n.....|FJLJ|FJ|F7|.LJ\n....FJL-7.||.||||...\n....L---J.LJ.LJLJ...\n\nThe above sketch has many random bits of ground, some of which are in the loop (I) and some of which are outside it (O):\n\nOF----7F7F7F7F-7OOOO\nO|F--7||||||||FJOOOO\nO||OFJ||||||||L7OOOO\nFJL7L7LJLJ||LJIL-7OO\nL--JOL7IIILJS7F-7L7O\nOOOOF-JIIF7FJ|L7L7L7\nOOOOL7IF7||L7|IL7L7|\nOOOOO|FJLJ|FJ|F7|OLJ\nOOOOFJL-7O||O||||OOO\nOOOOL---JOLJOLJLJOOO\n\nIn this larger example, 8 tiles are enclosed by the loop.\n\nAny tile that isn't part of the main loop can count as being enclosed by the loop.\nHere's another example with many bits of junk pipe lying around that aren't connected to the main loop at all:\n\nFF7FSF7F7F7F7F7F---7\nL|LJ||||||||||||F--J\nFL-7LJLJ||||||LJL-77\nF--JF--7||LJLJ7F7FJ-\nL---JF-JLJ.||-FJLJJ7\n|F|F-JF---7F7-L7L|7|\n|FFJF7L7F-JF7|JL---7\n7-L-JL7||F7|L7F-7F7|\nL.L7LFJ|||||FJL7||LJ\nL7JLJL-JLJLJL--JLJ.L\n\nHere are just the tiles that are enclosed by the loop marked with I:\n\nFF7FSF7F7F7F7F7F---7\nL|LJ||||||||||||F--J\nFL-7LJLJ||||||LJL-77\nF--JF--7||LJLJIF7FJ-\nL---JF-JLJIIIIFJLJJ7\n|F|F-JF---7IIIL7L|7|\n|FFJF7L7F-JF7IIL---7\n7-L-JL7||F7|L7F-7F7|\nL.L7LFJ|||||FJL7||LJ\nL7JLJL-JLJLJL--JLJ.L\n\nIn this last example, 10 tiles are enclosed by the loop.\n\nFigure out whether you have time to search for the nest by calculating the area within the loop.\nHow many tiles are enclosed by the loop?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_11.adb",
    "content": "--  Solution to Advent of Code 2023, Day 11\n-------------------------------------------\n--  Cosmic Expansion\n--\n--  https://adventofcode.com/2023/day/11\n--  Copy of questions in: aoc_2023_11_questions.txt\n--\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_11 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --\n  --  input_name : constant VString := +\"mini\"; n : constant := 10;\n  input_name : constant VString := +\"aoc_2023_11\"; n : constant := 140;\n\n  gala_max : constant := 500;\n  gala_top : Natural := 0;\n\n  pt_compact, pt : array (1 .. gala_max) of Point;\n\n  empty_row, empty_col : array (1 .. n) of Boolean;\n\n  new_x, new_y : array (1 .. n) of Integer;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n  begin\n    for xy in 1 .. n loop\n      empty_row (xy) := True;\n      empty_col (xy) := True;\n    end loop;\n    Open (f, input_name & \".txt\");\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        if c = '#' then\n          gala_top := gala_top + 1;\n          pt_compact (gala_top).x := x;\n          pt_compact (gala_top).y := y;\n          empty_col (x) := False;\n          empty_row (y) := False;\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Expand_Universe (new_gap : Positive) is\n  begin\n    for xy in 1 .. n loop\n      new_x (xy) := xy;\n      new_y (xy) := xy;\n    end loop;\n    for xy in reverse 1 .. n loop\n      if empty_col (xy) then\n        for idx in xy .. n loop\n          new_x (idx) := new_x (idx) + new_gap - 1;\n        end loop;\n      end if;\n      if empty_row (xy) then\n        for idx in xy .. n loop\n          new_y (idx) := new_y (idx) + new_gap - 1;\n        end loop;\n      end if;\n    end loop;\n    for i in 1 .. gala_top loop\n      pt (i).x := new_x (pt_compact (i).x);\n      pt (i).y := new_y (pt_compact (i).y);\n    end loop;\n  end Expand_Universe;\n\n  procedure Do_Part (p : Part_Type) is\n  begin\n    case p is\n      when part_1 => Expand_Universe (2);\n      when part_2 => Expand_Universe (1_000_000);\n    end case;\n    for i in 1 .. gala_top - 1 loop\n      for j in i + 1 .. gala_top loop\n        r (p) := r (p) + Integer_64 (Dist_L1 (pt (i), pt (j)));\n      end loop;\n    end loop;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n\n  Read_Data;\n\n  for p in Part_Type loop\n    Do_Part (p);\n  end loop;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 10173804\n    --  Part 2: validated by AoC: 634324905172\n  end if;\nend AoC_2023_11;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_11.txt",
    "content": ".......................#.........#...............#....................................#..............#......#...............#...............\n.#........#.................................................................#.........................................................#.....\n.............................#..............................................................#..............................................#\n...............#.....................................#..........................................................#......#....................\n.......#....................................#.............#..............#......#..............................................#............\n.......................................#.................................................#..................................................\n..........................#......#...........................................................................#..............................\n...................#........................................................#............................................................#..\n.......................................................#.........#..........................#......................#................#.......\n...........#........................#.................................#.....................................................................\n...............................#..............#......................................#............#..........................#..............\n..#..................#..................................................................................#.......#...........................\n.........................................#..................................................................................................\n...........................#...............................................................#.........................#......................\n...................................................#............#..........................................#...............#............#...\n...........................................................#.............#..................................................................\n...........#.........................................................................#......................................................\n......................................................................................................#...........................#.........\n...#..............#..........#...................#......#..........#.............................#...............#........................#.\n.....................................#........................................#.............................................................\n........................................................................................#...................................................\n..........#..................................................................................................#.............#..........#.....\n........................#............................#......................................................................................\n....#....................................#........................#.................................#.......................................\n.................................................#..........................#.............................#.................................\n............................#...................................................................#..............................#...........#\n.................#..........................................#..........#.................#..................................................\n......................................................................................................#............#........................\n........................#..........#............................#..........................................................#................\n................................................................................#..............................#............................\n.......#......#..........................................................................................................................#..\n............................................................................#...................................................#...........\n...................#.............#.....#...............#................................................#.........#.........................\n..#.......................................................................................#.................................................\n............#..............................#.........................#............#.............#...........................................\n....................................................#.........................................................#............#................\n.....................#.......................................#.......................................................................#......\n#.........................................................................#............#....................................................\n......#..............................#........................................................................................#.............\n........................#.....................#.............................................................................................\n..........................................................#...........#......#.......................................#......................\n...#.........................#....................................................................#.........................................\n..................................#...........................#....................#......#...............#.................................\n..................................................................................................................#...................#.....\n......................................................#.......................................#.........................#...................\n.........#...........#............................................#.........................................................................\n............................................................................................................................................\n..............#.............#....................................................#.......................#......................#.......#...\n...................................#........................................................................................................\n............................................................................................................................................\n...#.............................................#..............................................#...........................................\n........#................#.....#..........................#.................#..............#......................#.........................\n..................#....................................................................................................#....................\n...............................................................#.....#......................................................................\n....................................................................................................#........#.............................#\n..........#...................................................................#.....#...............................................#.......\n...#....................#............................#.....#.........................................................#......................\n............................................................................................................................................\n.............................................#....................................................#......................................#..\n...................................................................#......................................#.....................#...........\n................#...............#.......................................................#...................................................\n.........................................................#...................................#....................#.........................\n...#.............................................#...................................................................................#......\n...................#..........................................#................#.............................#..............................\n.....................................................................#.....................................................#................\n.........#.....................#.......................................................#.........#..................#.......................\n.........................................................................................................#........................#.........\n...........................#...............................................................#............................#...................\n...............#.................................................#..........................................................................\n..#...................#..............................#.....#...............#..........................#.........#...........................\n............................................................................................................................................\n..........#.................................#...............................................................................................\n..................#....................#..............................................................................#..............#......\n.........................................................#..................................#..................................#............\n..............................#...............................................#..............................#..............................\n#.............#...................................#.........................................................................................\n.................................................................#.....................#...............#....................................\n......#...................#...........................................#..................................................#..................\n...........#.......#...................#......................................................#.............................................\n..#.................................................#.........#.....................#....................................................#..\n.................................#.................................................................#..................#.....................\n..........................................................................#...............#...................................#.............\n............................................................................................................................................\n#.........#..........................#.................#.................................................#..................................\n.....#..........#............#....................................................#...........................#..................#.....#....\n............................................................................................................................................\n.........................#.......#.........................#.........................................................#......................\n............................................................................................................................................\n.......#...............................................................#.................#..................#...............................\n............................................................................................................................................\n...........................................#.........................................................#......................................\n.........................................................#...................#................#................#....................#.......\n.#...........................#.......................................................#...................................................#..\n.....................................................................#..................................................#...................\n...........#.......#................................#..........#............................................................................\n........................#.......#.........................................#.....#.......................#...................................\n.....#.....................................#........................................................................#.........#.............\n...................................................................................................................................#........\n...............#..................................#........................................#.......#........................................\n.....................................#..................................#...................................................................\n.....................#.....#.........................................................#.........................#............................\n...........#..........................................................................................................#.....................\n.......................................................#....................................................................................\n.............................................................#.....#............................#.......................................#...\n...#.......................................................................#.......#....................#...................................\n...........................................#.................................................................#.....................#........\n.........................#..................................................................................................................\n............#......#..............#.................#......................................................................#................\n.......#......................................#....................................................#...............#........................\n......................................#.................#..........#......#.................................................................\n#........................................................................................#..................................................\n............................#.................................#....................................................................#.......#\n.......................................................................................................#....................................\n.........#.....#.....................................#..........................................#...........................................\n....................................................................................#...........................#...........................\n.......................#.........#.........................................................#..................................#.............\n...........................................#......#........#.............................................#............#.....................\n......................................................................#............................#........................................\n......#......................#...................................#.............#..............................#.....................#.......\n...............#...................................................................................................#........................\n.......................................................................................................#....................................\n....................................................................................#......#................................................\n.........................................................#........................................#........#....................#.......#...\n.........................#.........#...............#.....................#.................................................#................\n...................#..............................................#.........................................................................\n........................................#......................................................#............................................\n.....#..............................................................................................................#.........#.............\n.....................................................................#......................................................................\n............#...........................................#...........................#.......................................................\n.#.......................#............#..........................#.......................#...............................................#..\n..............................................#.....#.....................................................#......#..............#...........\n...............#............................................................................................................................\n.............................................................#........#.....#..............................................#................\n..........#......................................#...................................................................................#......\n..#.....................#......#.........#............#.............................................#...............#.......................\n............................................................................................................................................\n.......#..................................................................................................#.................................\n............................#.............................#..............................#................................................#.\n............#......................................................#.......#.............................................#.....#............\n..................#................................................................................................#........................\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_11_questions.txt",
    "content": "--- Day 11: Cosmic Expansion ---\n\nYou continue following signs for \"Hot Springs\" and eventually come across an observatory.\nThe Elf within turns out to be a researcher studying cosmic expansion using the giant telescope here.\n\nHe doesn't know anything about the missing machine parts; he's only visiting for this research project.\nHowever, he confirms that the hot springs are the next-closest area likely to have people; he'll even take you straight there once he's done with today's observation analysis.\n\nMaybe you can help him with the analysis to speed things up?\n\nThe researcher has collected a bunch of data and compiled the data into a single giant image (your puzzle input).\nThe image includes empty space (.) and galaxies (#).\nFor example:\n\n...#......\n.......#..\n#.........\n..........\n......#...\n.#........\n.........#\n..........\n.......#..\n#...#.....\n\nThe researcher is trying to figure out the sum of the lengths of the shortest path between every pair of galaxies.\nHowever, there's a catch: the universe expanded in the time it took the light from those galaxies to reach the observatory.\n\nDue to something involving gravitational effects, only some space expands.\nIn fact, the result is that any rows or columns that contain no galaxies should all actually be twice as big.\n\nIn the above example, three columns and two rows contain no galaxies:\n\n   v  v  v\n ...#......\n .......#..\n #.........\n>..........<\n ......#...\n .#........\n .........#\n>..........<\n .......#..\n #...#.....\n   ^  ^  ^\n\nThese rows and columns need to be twice as big; the result of cosmic expansion therefore looks like this:\n\n....#........\n.........#...\n#............\n.............\n.............\n........#....\n.#...........\n............#\n.............\n.............\n.........#...\n#....#.......\n\nEquipped with this expanded universe, the shortest path between every pair of galaxies can be found.\nIt can help to assign every galaxy a unique number:\n\n....1........\n.........2...\n3............\n.............\n.............\n........4....\n.5...........\n............6\n.............\n.............\n.........7...\n8....9.......\n\nIn these 9 galaxies, there are 36 pairs. Only count each pair once; order within the pair doesn't matter.\nFor each pair, find any shortest path between the two galaxies using only steps that move up, down, left, or right exactly one . or # at a time.\n(The shortest path between two galaxies is allowed to pass through another galaxy.)\n\nFor example, here is one of the shortest paths between galaxies 5 and 9:\n\n....1........\n.........2...\n3............\n.............\n.............\n........4....\n.5...........\n.##.........6\n..##.........\n...##........\n....##...7...\n8....9.......\n\nThis path has length 9 because it takes a minimum of nine steps to get from galaxy 5 to galaxy 9 (the eight locations marked # plus the step onto galaxy 9 itself). Here are some other example shortest path lengths:\n\n    Between galaxy 1 and galaxy 7: 15\n    Between galaxy 3 and galaxy 6: 17\n    Between galaxy 8 and galaxy 9: 5\n\nIn this example, after expanding the universe, the sum of the shortest path between all 36 pairs of galaxies is 374.\n\nExpand the universe, then find the length of the shortest path between every pair of galaxies.\nWhat is the sum of these lengths?\n\n--- Part Two ---\n\nThe galaxies are much older (and thus much farther apart) than the researcher initially estimated.\n\nNow, instead of the expansion you did before, make each empty row or column one million times larger.\nThat is, each empty row should be replaced with 1000000 empty rows, and each empty column should be replaced with 1000000 empty columns.\n\n(In the example above, if each empty row or column were merely 10 times larger, the sum of the shortest paths between every pair of galaxies would be 1030.\nIf each empty row or column were merely 100 times larger, the sum of the shortest paths between every pair of galaxies would be 8410. However, your universe will need to expand far beyond these values.)\n\nStarting with the same initial image, expand the universe according to these new rules, then find the length of the shortest path between every pair of galaxies.\nWhat is the sum of these lengths?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_12.adb",
    "content": "--  Solution to Advent of Code 2023, Day 12\n-------------------------------------------\n--  Hot Springs\n--\n--  https://adventofcode.com/2023/day/12\n--  Copy of questions in: aoc_2023_12_questions.txt\n--\n--  HAC 0.26 \"nice to have\"'s detected in this exercise:\n--    *     Replace_Element for VString\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_12 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  Each data row has two lists:\n  --    - a list of spring conditions\n  --    - a list of sizes of contiguous groups of damaged springs\n  --\n  --  Here we set for HAC a maximum for the second list (HAC knows\n  --  only constrained array types):\n\n  max_sizes : constant := 100;\n\n  --  Size of a contiguous group of damaged springs:\n  subtype Size_Type is Natural;\n\n  type Size_Array is array (1 .. max_sizes) of Size_Type;\n\n  type Row is record\n    code  : VString;     --  No actual limit in storage\n    size  : Size_Array;\n    sizes : Natural;     --  Number of sizes\n  end record;\n\n  map : array (1 .. 1000) of Row;\n  top : Natural := 0;\n\n  --  Idea: on a given list of spring conditions of length x\n  --  (possibly truncated from the right), and a list of contiguous\n  --  groups of damaged springs, of length y (also possibly truncated\n  --  from the right), if the contents of the lists are intact, the\n  --  result of the problem for the truncated pair is unique,\n  --  so we can memoize it.\n\n  max_length : constant := 120;  --  Spring conditions\n\n  type Memo_Type is array (1 .. max_length, 1 .. max_sizes) of Integer_64;\n\n  memo, zero : Memo_Type;\n\n  unknown : constant := -1;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2023_12\";\n  --\n  procedure Read_Data is\n    c, sep : Character;\n    i : Integer;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      top := top + 1;\n      map (top).code := Null_VString;\n      loop\n        Get (f, c);\n        exit when c = ' ';\n        map (top).code := map (top).code & c;\n      end loop;\n      i := 0;\n      loop\n        i := i + 1;\n        Get (f, map (top).size (i));\n        exit when End_Of_Line (f);\n        Get (f, sep);\n      end loop;\n      map (top).sizes := i;\n    end loop;\n    Close (f);\n    for i in memo'Range (1) loop\n      for j in memo'Range (2) loop\n        zero (i, j) := unknown;\n      end loop;\n    end loop;\n  end Read_Data;\n\n  r : array (Part_Type) of Integer_64;\n\n  verbose : constant Boolean := False;\n\n  procedure Do_Part (p : Part_Type) is\n\n    --  We erode the pair of lists from right to left, so the\n    --  index 1 remains through recursion.\n\n    function Count (r : Row; are_remaining_lists_intact : Boolean) return Integer_64 is\n      head : Row;\n      --  `head` is a copy of `r` with at least the last item of the spring\n      --         condition list removed.\n      len : Natural;\n      c : Integer_64;\n\n      procedure Expected_Size_One is\n      begin\n        if len = 1 then\n          --  The current code (condition list) is just a lone \"#\".\n          if r.sizes = 1 then\n            --  ^ A single '#' is expected and has been found.\n            c :=  1;\n          else\n            --  This group is OK, but there are other series of \"#\"\n            --  expected left to current one -> not a solution!\n            c :=  0;\n          end if;\n        elsif Element (r.code, len - 1) = '#' then\n          c := 0;  --  We have a trailing \"##\", but size 1 is expected.\n        else\n          head := r;\n          --  We have a possible separator ('?' or '.') left\n          --  to the len-th element.\n          --  Fine, just drop last element of the list.\n          head.sizes := head.sizes - 1;\n          --  Remove the separator and the last '#'.\n          Delete (head.code, len - 1, len);\n          --  We do a recursive call with the knowledge that\n          --  contents of both shortened lists are again intact.\n          c :=  Count (head, True);\n        end if;\n      end Expected_Size_One;\n\n      procedure Expected_Size_Two_or_More is\n      begin\n        if len = 1 then\n          --  The current code (condition list) is just a lone \"#\",\n          --  but we expect >= 2 of them, only in the current group!\n          --  -> Not a solution!\n          c := 0;\n        else\n          case Element (r.code, len - 1) is\n            when '?' =>\n              head := r;\n              --  Shorten expected string of ###'s by one '#'.\n              head.size (head.sizes) := head.size (head.sizes) - 1;\n              --  Exclude the '?' = '.' case since 2 or more\n              --  '#' are expected in current group. Concretely,\n              --  the trailing \"?#\" becomes \"##\".\n              Delete (head.code, len - 1, len);\n              head.code := head.code & '#';\n              c := Count (head, False);\n            when '.' =>\n              --  Element of size >= 2 expected, but size 1 found.\n              c := 0;\n            when '#' =>\n              head := r;\n              Delete (head.code, len, len);\n              --  Shorten expected string of ###'s by one '#'.\n              head.size (head.sizes) := head.size (head.sizes) - 1;\n              c := Count (head, False);\n            when others =>\n              Put (\"??? [1]\");\n          end case;\n        end if;\n      end Expected_Size_Two_or_More;\n\n    begin\n      len := Length (r.code);\n      if len = 0 then\n        if r.sizes = 0 then\n          --  List exhausted\n          return 1;\n        else\n          return 0;\n        end if;\n      end if;\n      --  From here we know that length l is >= 1.\n      if are_remaining_lists_intact and then r.sizes > 0 then\n        c := memo (len, r.sizes);\n        if c /= unknown then\n          return c;\n        end if;\n      end if;\n      case Element (r.code, len) is\n        when '.' =>\n          head := r;\n          Delete (head.code, len, len);\n          --  The last '.' (an operational spring) can be removed\n          --  without changing the result.\n          c := Count (head, are_remaining_lists_intact);\n        when '?' =>\n          head := r;\n          Delete (head.code, len, len);\n          --  Cases when '?' is a '.' :\n          c := Count (head, are_remaining_lists_intact);\n          head.code := head.code & '#';\n          --  Cases when '?' is a '#' :\n          c := c + Count (head, False);\n        when '#' =>\n          if r.sizes = 0 then\n            --  We have at least one guy in the condition list,\n            --  but the size list is exhausted -> not a solution.\n            c := 0;\n          elsif r.size (r.sizes) = 1 then\n            --  Last element on the size list is a size = 1.\n            Expected_Size_One;\n          else\n            --  Last element is a size > 1.\n            Expected_Size_Two_or_More;\n          end if;\n        when others =>\n          Put (\"??? [2]\");\n      end case;\n      if verbose then\n        Put (r.code & \"  \");\n        for i in 1 .. r.sizes loop\n          Put (r.size (i), 0); Put (',');\n        end loop;\n        Put_Line (\"   comb:\" & c'Image);\n      end if;\n      if are_remaining_lists_intact and then r.sizes > 0 then\n        memo (len, r.sizes) := c;\n      end if;\n      return c;\n    end Count;\n\n  begin\n    r (p) := 0;\n    for line in 1 .. top loop\n      memo := zero;\n      r (p) := r (p) + Count (map (line), True);\n      if verbose then\n        Put_Line (\"-------------------------------------\");\n      end if;\n    end loop;\n  end Do_Part;\n\n  procedure Prepare_Part_2 is\n    orig : VString;\n  begin\n    for line in 1 .. top loop\n      --  Apply the unfolding, literally, as explained:\n      --    - replace the list of spring conditions with five copies\n      --      of itself (separated by ?)\n      orig := map (line).code;\n      map (line).code := 4 * (orig & '?') & orig;\n      --    - replace the list of contiguous groups of damaged springs\n      --      with five copies of itself.\n      for i in 1 .. 4 loop\n        for j in 1 .. map (line).sizes loop\n          map (line).size (map (line).sizes * i + j) := map (line).size (j);\n        end loop;\n      end loop;\n      map (line).sizes := map (line).sizes * 5;\n    end loop;\n  end Prepare_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n\n  Do_Part (part_1);\n  Prepare_Part_2;\n  Do_Part (part_2);\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 7007\n    --  Part 2: validated by AoC: 3476169006222\n  end if;\nend AoC_2023_12;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_12.txt",
    "content": "#?#???????#?.? 3,1,2,2\n.??.##.?#????.??#? 2,2,1,2,4\n.?.??#?##??#????.. 8,1\n??????????#.. 6,1\n.#.##????.??.? 1,6,1\n?#??#???.??.??? 3,1,1,1,1\n?#???????#? 2,1,5\n##?#??#?????.??? 5,1,4,2\n????.?#??.# 2,1,1\n???????##?????##???? 1,1,11,3\n.####??.??#??????#? 6,6,1\n??#..##?...?#. 2,3,2\n..??##?#?#???#??.??. 12,1\n??.?#???#? 1,3,1\n??.#??????????#.??? 4,1,1,3,1\n???##??.?##? 5,1,2\n???..???..?. 1,1,1,1\n.?????#?#??? 1,1,1,1\n##???????????# 5,3,2\n??..????###?#?.? 1,8\n????????#???.##?? 1,2,1,2,3\n????##.?#????.? 1,4,2,1,1\n##???#.##?.#????? 2,2,3,2,3\n?????.????? 2,3\n?#?#??.##???.?#?. 3,5,2\n?#?..?##???#?????? 1,12\n.??#?????????.?.#.? 11,1,1,1\n???????????#??????. 7,1,1,3,1\n??????????#?????## 1,1,2,1,1,6\n.##?.##?????????? 2,4,1,1\n??#?##????? 5,1\n??#????????????? 5,2,2\n?#.#??##??#???#????? 1,2,13\n#??.????#.?? 1,2,2,1\n#.#?#???????.???#. 1,4,1,1,1,4\n????#??..?.. 2,1,1,1\n.??.#????#?????????? 3,8\n?...#??..??.?? 3,1\n?????#?.?.? 2,2,1\n..?...#?#????#?#???? 4,5\n??.?#???#? 2,2\n.?#?#.???..?? 3,3\n.??.#???#?? 2,3,2\n???##??#??#.?..???? 4,4,1,2\n?????????. 4,1\n????.???.#??# 4,2,4\n?????.?##?#??##?#.?? 4,4,5\n??#?????????????#?# 1,6,1,2,2,1\n#??.??????#..#??#? 1,1,3,1,1,2\n???#????.???? 5,3\n????#????#? 1,2,2\n?#.?.??.?.?????#?? 2,1,1,2,1,2\n???.???#??.?? 2,3\n?.??#?#???#?.????#?? 1,3,1,3,2,2\n?.??.??#?????.? 2,3,2\n??##??????????? 3,3,3\n???##?.#???????? 1,3,2,1,1\n?.???#????????##. 1,2,1,1,3\n.?#.##????##??. 2,3,5\n????#??#?.?# 5,1,2\n..?.??????..? 1,6\n##??..????#?#?# 3,1,6\n?#?.?#????.?#?#???? 2,2,1,5,1\n????###??..??#. 7,1\n??..??..?? 1,2,1\n.?.?.?#??????#??. 1,9\n???????.#?#??????. 2,3,5,2\n.##?????#?## 4,1,1,2\n?#?#.???#?#???? 3,7,1\n#??.??.?#??????? 2,1,8\n?#???#?#??#.?? 8,1,1\n?#??????.?#???? 6,2,2\n##.?????.??? 2,1,3,2\n??????.?#? 1,3,3\n.?..?#?#?#. 4,1\n??#?????.??#???? 1,4,3\n.?#??#??.??#. 5,2\n?.#?.????? 2,1,1\n#?###?????#?.?#? 6,5,2\n#??#?.?#???????.??? 5,1,2,2,1,1\n..???#?#??????#.?#?? 12,3\n?????.??#??????? 2,1,6\n#??.#??#?#? 3,1,4\n???.?????#?#.????? 2,7,3\n???.?.#?#?? 2,3\n???..?????##? 1,1,3\n#?.???#???#??????. 1,2,7,1\n????.????#?#??#??? 1,1,9\n??#?.?#?#???###???? 1,1,10,2\n#??????????.##?? 1,1,1,2,3\n.?.?????.???????? 1,5\n???#?##???????? 1,7,1,1\n?????????#??? 1,1,1,4\n???.??#.????? 1,1,1,2\n.???.???..???. 1,3,1\n????????#??#?? 3,1,1,3\n????.?..#?#??? 2,1,3\n#?#???????#??.? 4,2,2,1\n?????###??? 1,6\n???.?#?????? 1,2,4\n?##????????????. 6,2,1\n??##?????..??????? 9,1,1,3\n???#?#???.#. 7,1\n.????#????????#.? 5,7\n##?#???????????.??# 5,2,5,1,1\n??????#?.???#?? 1,1,3,4,1\n.??#???##??...??.? 10,1,1\n.???.??#????????? 2,2,7\n????.????###? 1,1,1,4\n#?#??#?##????##? 1,1,11\n???.#??????#..?#??# 2,3,1,1,1,2\n?????#?#???#?? 1,5,1,2\n???##.?##?#?????.? 1,2,4,1,2\n??????##??. 1,4\n?#??.?????? 2,1,1\n?#?#???###?#?????#?? 14,2,1\n???#?.#???#?.? 1,1,1,3\n???.???#?#.#?# 1,5,3\n??.#??#????#. 2,2,4,1\n??#?#?..?. 3,1\n?????#????#.????#?# 1,2,4,1,1,4\n?.???#.??? 1,2,1\n.???.???#??.? 1,1,2,1\n.??????.???? 2,3,1\n#.##?????? 1,2,2\n.#?#??#???? 3,3\n??#??.#??????????##? 1,3,1,1,7\n.?#.???????##? 1,2,1,4\n#.???#..#..???.?# 1,2,1,2,2\n?#???.??##.?? 4,2\n??..?????.????#.?? 2,2,1,1,1,1\n??????.?#.##?? 2,1,1,3\n#???.?.??? 1,1,1\n.?##??????#? 3,5\n???#.##???. 1,2,1\n##??######.????#.?? 10,1,1,1,1\n.?.??#?.#. 1,2,1\n???????##?.??? 3,3,3\n.?.#.?.##?#.??? 1,1,2,1,1\n.??#???#?????????? 1,10\n??.?#.?.?? 1,2,1\n??.?#???.??#? 5,2\n#??#???#?##????#?? 5,10\n?#???#??#?#?? 2,7\n??###????????#??#?. 5,12\n??.???#????. 1,6\n??#?#???#.???? 1,3,1,3\n???????#?? 4,2\n??#?.??#???#??#. 1,1,5,1\n??.#.?.??? 2,1,2\n??##???#??????. 1,6,1,1\n?#????#..????#??? 1,2,7\n?#??#??#??#?.? 3,1,5,1\n??#?.#????.# 1,1,3,1\n#???#?????????.??? 13,3\n##?.???????#???# 2,2,5,1\n?#.????.????. 2,1,1,1\n???#.??.???? 1,1,1,2\n?#???#???#?????#? 2,8,1\n?##?.????????.??#? 3,6,4\n?????##??.?#?????? 2,2,8\n??.?##?#???# 1,5,1,1\n?.??#???##??#???# 12,1\n.#.#???#????????? 1,12\n???.?#.???#.???#. 1,1,1,3,2\n.#??#??.??? 1,1,1\n?#???#?..? 2,1,1\n?#????.?#? 1,3,3\n???##??#?#???? 2,6\n#????##???#????????# 2,8,6\n?.?###?..#????# 1,4,2,2\n????#?#...#?#?? 1,2,1,1,1\n.#???????#? 1,1,2\n???.??.#.?? 1,2,1\n.??##?#?????????? 6,4\n?#?#?..#??###?.? 1,2,1,5,1\n.#.??????#?????????? 1,7,1,1,1,1\n???.???#?.#.?? 1,1,1,1\n##..#.?##??? 2,1,6\n?.???.???#??#?#??#.? 1,3,1,6,2,1\n?#?##?????????????? 1,3,7,1\n?#???????.????#.???. 8,4,1\n???#..#??#??? 1,1,1,4\n##???????? 5,1\n???###.?#??..???#? 4,4,1,2\n?.?#??###.??????# 1,6,1,5\n.?????????# 7,1\n?.#.?????? 1,1,1\n??#?.#??#??#? 3,7\n??#?.????#?#??? 3,1,1,1,1\n?.#???????.#??? 1,1,2,2,2\n???????#???..? 1,1,3,1\n?#???#???.#???#??.?# 1,1,3,1,5,2\n?.?####.???? 1,4,1,1\n??#???#?????#?.? 7,1,1,2\n.#?#????.???????.? 5,7,1\n???#.????#?#?????. 1,1,11\n???.#??????#??#? 2,1,1,6\n.?#?????.#. 3,1,1\n.???##.?????.?? 5,1,2\n??#????.??.??##?? 6,2,5\n????????#???? 3,4\n???.?..?#?#?? 1,1,1,2\n?????.?.?????##?? 1,1,1,1,7\n?????#####???.?. 10,1,1\n??????..#?#??? 2,2,3,1\n.???.??.?? 1,1,1\n??##..??.?#??.?? 3,1,3,2\n??????#..??.? 3,1,1,1\n#???#??#?????? 1,4,2,1\n??#????..#????#?#??? 2,1,9\n.?????.?????.#??? 3,1,2,2,1\n?#.#?.??.???? 2,1,1,1\n?..?#??#.?#? 1,2,1,2\n??.???#####? 2,1,5\n.#?#?.??.?? 4,1,2\n???.#?#?#.#??.??#??? 1,3,1,1,1,4\n???#????.??.? 1,4,1,1\n.?.?.????##???. 1,6\n.???.????? 1,1\n#?????#??#??#?.?? 1,1,4,3,2\n????.?#??#??##???. 2,8\n#?.??#????##??#?.## 2,5,6,2\n#.#.???#?#?#.??.??. 1,1,1,5,1,1\n????#?.????#?# 6,5\n.???##?????.???.? 7,3\n???#????##?#?.???#?? 11,2\n?#???#????#???.?#?? 7,2,1,1,1\n???#?????#?..?? 7,1,1\n?##?#???????????#??. 4,1,4,1,2\n???????#???.#????. 8,3\n.??#?.?.?.##?????? 1,1,1,6,1\n???#.???#.?.##? 2,1,1,1,3\n#??#??????#????.? 1,2,6,2,1\n.??#?#?.????.?? 5,1,1\n???????#?? 4,3\n?????.?#????#?????.? 1,11\n???##?##?##????#???# 2,2,5,1,2,2\n???.???#??#??#??#?? 3,1,1,5,1,1\n##???.??#??#? 2,1,6\n?#??????#?????#?? 10,2\n???##?.?.?? 1,3\n.???????##??#.#??#? 3,5,1,5\n.#???..##?? 3,4\n????.#??.??.? 1,1,2,1\n?#?..???#??#?.?### 1,1,4,4\n#..??#..?.??###?#??? 1,2,1,5\n.##.#?..#? 2,2,1\n??#?#?#??#??#..? 5,4\n???.?.???#???##? 1,9\n?????????#??##?##? 1,1,13\n.??????#????. 2,4\n.?#.??#???. 1,2,1\n????????????? 10,1\n####????????????.#?? 7,1,2,2,2\n??#.#??????? 2,3,1,2\n#??????#?#.?.. 4,4\n.?#??#.?#??#??#??? 4,1,6\n#??#.?.?##.?#??? 4,2,4\n?#?##????.#??.???. 5,1,1,1,1,1\n???..?#???#???###? 1,1,8\n?###???.??. 6,2\n?##?..??????? 3,6\n?????##?????###.? 6,3\n#.??????????##?#??? 1,1,1,2,1,6\n??????.????? 2,1,1\n??#???????.??????? 8,3\n???????????##?? 4,1,3\n??.????????#?# 2,1,8\n???#?#.##?????.? 1,1,1,7,1\n#??##?#??##?#????#? 7,6,3\n####?#???###??#??.?? 4,7,2,1,1\n#?.?#.??.#?? 1,1,1,1\n???#??????#?.?????? 1,1,3,3,2,1\n???.????#?. 3,6\n??????.?######?? 5,7\n?#??##??#??????. 1,12\n???#?#####?#?..??#. 10,1\n?#.?#.????#? 1,1,2,2\n??.?.????#?#.?.?#.? 2,7,2\n??#????.?????#.?? 1,1,2,6,2\n??#???.??????????? 1,7\n??.?.?.????. 2,1,2,1\n??#?????????#??#???# 1,1,2,5,4,1\n###..##?#??????? 3,11\n?#????#?#??#? 2,4,2\n.??..##?#?..????? 4,3,1\n????.????? 3,1,1\n.???????????.????# 2,4,1,1,1,1\n??#?#???.??# 5,3\n???????#.?#?#?##?##. 4,1,9\n....???#??#???? 7,1\n?.??#??.?#?????.# 1,1,1,7,1\n?????.?#??? 3,3,1\n??#???????.??? 5,3\n.???#????????#??.? 4,1,6\n..?.?????. 1,2\n.??????????#?????#? 11,3\n?.?????#??????? 1,9\n.?????##??.?? 6,1\n?#?.??#.?? 1,2,1\n#????????????? 1,6,3\n.??????..???#??. 4,1,1\n??????????????. 1,1,1,3,1\n?.???????. 1,2\n?#?????..??.???. 2,2,1,2,1\n#????#???? 4,3\n?????????????. 8,2\n.?##.??#.??#.?? 3,1,1,3,2\n???????##???????#? 10,5\n????#??????.?.?? 7,1,1\n?????????#????#.?# 1,1,1,2,1,2\n??#.?##????.??? 2,6,2\n.??#???.???????.#? 6,1,1,1,1,2\n#?#?.?????#???? 4,6,2\n?##?????#????#?#.#? 2,1,1,6,1\n????????.??????#. 4,1,1,1,1\n??.?#????#.#? 1,4,2,1\n???#.???#? 3,1,2\n?##???????#?? 2,1,4\n?.?.??#?.#??.?????# 1,1,1,3,6\n???#?????#?#?.?###? 1,1,1,2,1,5\n?.##??##?#??#???## 6,1,7\n?.?.????.?# 1,2\n????.#??#??#???? 1,1,9,1\n?.?#????.????#?.. 5,1\n?.??????????#??? 2,7\n#???#?##?????.? 5,2,3,1\n#????????. 5,3\n??#??#??#? 1,3,1\n???#???#?##?###.?? 3,8\n?#????#????#??# 2,9,1\n?.??#??.?.??#?? 1,4,4\n??#?#?#?#?? 3,6\n?#?.?.?##??.###?#? 2,4,5\n????#???.#??.??.??? 7,2,2,1\n?#?????#???.#?? 9,1,1\n#?.?#.#?#???????. 2,1,6,1\n?????#?????? 2,1,2\n.???#???.? 5,1,1\n.?#???.????? 4,1,2\n???????##???? 3,1,2,2\n?????##???? 4,2\n.???#????????## 2,1,1,1,2\n?????????.?#. 3,5,2\n?.???.???#????#??#? 1,3,9,2\n?#???????.??#??????? 2,1,1,1,3,4\n??#??#??#..#???.#?? 8,1,1,1,1\n????.?#????.#?.??? 3,2,1,1,2\n??.?#??????# 1,5,2\n?????.?.????? 3,1,4\n???#?????..?..? 9,1\n?????????#?.?. 2,1,1,3\n#.??#??????.#??. 1,1,7,1,1\n??#.??#??????#..???? 3,3,2,1,2\n.#???????????# 5,1,1,1\n?.?..?????. 1,3\n?????#?#????.??? 3,5,1\n???#???#?.??#?##??? 3,1,2,1,1,4\n??.?#????? 1,4,1\n?..#?.??###. 1,5\n???##?..???? 6,2\n#.??.???#?#.#????? 1,1,3,1,1,1\n??#??#???#??#?? 6,3,2\n???#???????##?#??. 2,3,7\n?????.??.??# 1,1,1,1\n?#??#?###? 2,5\n?#?#?#?.?.#?#?.?? 5,3\n??.??#.????? 1,1,1\n?#.?#.#?##??#???#?? 2,1,5,2,2,1\n..?????.??.???..#??? 1,2,1,2,4\n.???#?????.???????. 1,4,2,1,3\n???#?????.#???#..?. 4,5\n???#?????##?#?# 3,1,2,1,1\n??#???.??????? 3,3\n??.??.???#??? 1,1,1,2\n#???????##.?#?. 1,2,5,1\n???#???.?? 5,1,1\n?.###?##????????? 1,8,1,1\n?##???#??????##. 11,2\n.???#?????#??? 3,3\n.##?#?#???? 4,5\n??#??????? 1,6\n???##??.??.? 2,4\n.??#??##.??.???# 2,3,1,1,1\n???#???#???????? 12,1\n#.?#???##????????#? 1,1,13\n?????#????.?#???#? 1,1,4,7\n?????#???????#????? 8,3\n?#??#.????????. 5,3,1\n?##?#?.#?????? 5,6\n?.??#??#.???#.????# 1,3,1,1,1,2\n???.???##????.??#??? 1,2,2,2,5\n??##?#????????.?.# 8,1,1,1\n???##??..?##.?...?. 2,2\n#.?.?.????.????#?#?# 1,1,1,9\n??.????#?????? 1,10\n.??.##.?#? 2,1\n?#??????.#.? 2,3,1,1\n??????.???. 1,1,1\n.???.??..#? 2,2,1\n??.??????.????. 4,3\n#.?#?????.. 1,2,3\n??#??#????#? 5,4\n??#?????.?. 2,2,1\n??#?#??..##?#???#?. 6,9\n?#??#??#####.???#? 5,5,4\n???#?..??#??#?### 2,8\n.???#.???????#????.? 3,1,6,1,1\n???#?????#????## 5,2,4\n#?#?.?????.????? 1,1,3,1,2\n?????#??????.?#???. 4,4,1,1,1\n##????#?.???????. 8,1,1\n???.??#????#????#? 1,1,1,1,4,3\n#?#?##??#????????? 9,6\n?#???????????? 5,1,1,2\n?.?????#?.??. 5,2\n??.??..????#? 1,1,1,4\n??#?.?#?#??.?? 2,6\n.???..?.?..? 1,1,1,1\n??#...??##?????.??? 1,1,4,3,1\n??#.#?????????????? 1,1,1,8,1,1\n?##??#???????# 2,1,3,1\n?#??#.??..?#?? 4,1,2,1\n?#?????#????.. 3,3\n#??#???###??#?????? 2,2,6,2\n#?#??#???? 1,4,2\n.???.?.?#? 2,2\n??#??##?.?? 6,1\n#???#??.#??# 1,4,1,2\n???????#??? 2,1,1\n?##????????????? 2,2,5\n.##?#?.?#? 5,2\n???????##.???#????? 8,3,1,1\n?...??.?.. 1,1\n#????#?##????? 1,7,1\n?.?..##?#.??##?#?.? 4,5\n??.??.????????# 1,2,1,5\n#??#??#??###?????##? 1,4,12\n??#.?#???.?????#?# 2,3,3,4\n???###?.?? 1,4\n?#????#???. 2,3,1\n?##?#.????#??##.#. 5,2,6,1\n?#?#??.????#??# 4,1,5,1\n????.#.????????##?. 1,1,1,2,6\n.???..??#?..??..#??? 1,1,4,1,2,1\n????##?##?##.???? 11,1\n??.???#?#?#????.#??. 1,9,1,1\n.???#??.????? 1,1,1,3\n??.???#??# 2,1,4\n??????.??? 1,1,1\n?#?#???????.???.?#? 6,2,2,2\n#???#?##??#????#? 1,2,10\n?.##??.??.?#???#?.?? 2,1,2,7,2\n.????#..???? 1,3,1,1\n?.?#??????????#???? 3,9\n???#????#.?.? 4,1,1,1\n.???.#????. 1,1,2\n?#?##?????? 2,3,3\n????????##??? 1,5\n???###??.?#????#?? 1,4,8\n?.?#????.???.#.?.# 1,5,3,1,1,1\n?????##???#?.???#?? 2,4,1,2,2,2\n#????.?.#.?#??? 1,2,1,1,1\n??#?.#?#####????.?? 1,1,8,2,1\n??????#???.#?.. 1,1,1,1,2\n.??.##?.??.#????.??? 2,2\n?#??#??#??.??#.???# 1,5,1,1,1,4\n.?##?.?#???? 2,3\n????#?#??????..#? 2,5,3,2\n????????#????#..? 10,1,1,1\n#?????#???????.??#? 8,1,2\n#??###???.????###??? 1,6,1,7\n?????.?.??# 2,1\n??.???..#????. 2,2,2,2\n#?.#???..#..? 1,4,1\n?#???##?.#???????#?? 7,10\n?????#?#????#??? 9,1\n????????##?.###?? 1,1,4,5\n.???#??#.? 1,4,1\n?????.??#???. 1,3\n???#.??###?#???#???? 2,10\n..#??#.???#??.?. 4,1\n??????#?#??.??.???. 1,2,1,3,1,1\n?##??#?????? 7,1\n?.?#???.??????????? 1,1,2,4,1,1\n??????.?##??? 1,3\n?.?.????##?.????? 1,5,3\n?.#???##?#????#?#.?? 1,2,8,1,1,1\n??.?##???.#.?.?#???# 1,6,1,1,1,1\n??#??????..# 4,1,1\n?.#?.???#??#????#? 1,5,1,2,1\n?###.??#???#.?#?# 3,1,3,1,3\n??#??##????#.??? 3,4,1,1\n#?##?#####?#?#??. 1,12,1\n?##??#????#??..?#?? 4,1,6,2\n?????..???? 1,1,1\n????#?????#?? 4,3\n???#?#???#?? 1,1,5\n??#????????????? 4,5,2\n?##???##?#??.???#? 10,1,3\n.???#??????????#???. 4,2,7\n#????#???#??#?#?.?? 8,2,1,1,1\n?.??#??#??? 1,7\n??????#.????? 2,3,5\n###??..?????#??? 5,1,5,1\n?#?????#?.???.?? 1,4,1,2\n???#???#????????..?# 1,7,1,1,2\n?###???#?????#? 8,2\n.?.???#??? 1,1,3\n#####???#???#?? 5,4,2\n.?#?#?.?.??? 4,1,2\n?????????#??#.?.?#?? 3,6,2\n.?###?##?????????# 4,2,4,2,1\n#?????###???????#??? 1,13\n.#?#?????#?. 3,1,1\n.?#?#???#????#.#.? 1,1,6,1,1\n.##??#??#?##?.?.#?? 3,2,5,1,1,1\n.?#??#.??#?#??#?#??? 5,3,4,1\n??.????.?.##???????? 2,3,6,1\n?#?##??###.??#???#?? 2,2,4,1,1,1\n?#.#..????#?#?#??#?? 1,1,1,1,5,2\n??##????#????..# 3,2,2,2,1\n??.???#?..? 1,2,1\n?##?????#. 3,2\n#?#??????.??##.?? 9,4\n.?????#????? 6,1\n?.?.????#? 1,1,1\n???###??#?...??#??#? 1,4,2,1,1,1\n.??#?????..?#? 4,1,1,2\n??.#?...#?##.?#???# 1,1,4,1,1,1\n????.?.????? 1,1,1,1\n????#????#.?. 8,1\n??#?.?#?##.?. 3,4\n?#????#.##??..?? 1,1,1,4,1\n???????#??????.? 1,1,3\n.?????##..? 1,4,1\n.??.####???? 1,7\n.##??.???.?#?.?? 2,1,3,2,1\n#???#?#?????#.. 1,1,7,1\n.?.?#????????????? 1,4,6,1,1\n???.#?????? 2,3,1\n?##????..?##??#. 2,2,6\n?#.??#??.??#?# 1,2,2,1\n.#??#..?#?????. 4,2\n??#???????#?.???? 3,6,1,1\n.??.??.????### 1,1,5\n#.?#.#????????????? 1,1,12,1\n??#????#????.??#?#? 4,1,2,1,1,4\n??????????##? 1,2,4\n##???#??????.???#??? 7,3,2,1,2\n??.???.#?##... 2,4\n.#??#???#????####?# 10,6\n???#??.????? 1,1,1,1\n.?#?????#???? 3,2\n???#???.?.#???## 2,3,1,6\n?#???..???? 4,2\n??#??.???.# 2,2,1\n??????##?##?#?.?. 12,1\n???#???#?.????.?? 2,6,1,1,1\n#?.???.???????##?#?? 1,1,1,1,10\n?????.?##?#???? 3,5\n?????#.???#?? 4,3\n?##??????... 4,1\n?##??#?.????#.#? 3,1,2,1,2\n.?.?????#. 1,1,4\n??????#?.? 3,3\n#.?#?#.?##?????? 1,1,1,6,1\n?#?.?#?..??. 1,2,1\n???????#?? 3,2\n??#???????#.# 3,2,2,1\n..???.#????.??#??? 3,2,1,1,1,2\n?#?###????.#.???? 7,1,1,1\n??#.?.##?.???.. 3,2\n?????#??..#..??? 3,3,1,3\n???##???????? 6,1\n????#????? 1,1,1\n?#?##.??.??# 4,1,1,1\n?#?.??##??.?#??#?# 2,3,2,4\n????????????#? 2,7,2\n?????#?#.????? 1,3,1,1\n.??.????###??? 1,6,1\n?.?#???.#?. 4,1\n???#?#?#?#????.? 11,1,1\n#??.??????###???#?## 1,1,1,1,3,6\n?????.#?##?..?? 4,4\n.??#?#????.?#.??? 4,1\n.?#.?#???#??##??? 2,2,7\n.#????.?????##?##### 1,1,1,13\n???.??.##?.#? 1,2,3,2\n???#?.???.? 2,2\n?##??###????#?#? 3,10\n?????#????##?#?..??? 7,6\n.#?##.??#???? 4,5\n?.???????#??#? 1,2,1,5\n??.#.#?#??###?? 2,1,1,1,5\n?.???#???#?? 5,3\n???#?##.????#??.??? 1,5,3,2,1,1\n?#??.###????#???# 1,5,2,1\n.???.???????#???. 1,1,6\n?##.#???#.#??? 3,5,1,1\n.???????.?#?#? 1,1,2,4\n??.?.??#.? 2,1,1\n???#??#..#?????. 1,2,1,2,1\n.???.??????.#?.? 1,2,2,2,1\n..?????.????.#??#. 1,2,2,1,1,1\n?#???.????? 1,1,3\n?##???#??#??????? 10,3\n??????????.???#? 3,3,1,5\n??...?????????.. 1,3,4\n#???###?#??..#??#?. 7,2,5\n#.#..#??????#?#????# 1,1,15\n?.??#?..????#?.? 2,5\n????????.?? 1,6,1\n??.???.???.#?#.? 2,2,1,1,3\n..#..??##?? 1,4\n##??#??????.#?? 8,2\n?????.?#?.? 2,2\n##.???#??????. 2,5,2\n???##??.?#?#?? 3,5\n#.?????#????#?? 1,9\n#??##?.?#????#????? 1,2,10\n?..?..??#???? 1,6\n??.???#?#?# 1,5,1\n??####??#? 4,1\n?.????????????.? 1,3,1\n???.??????#..#?.?? 2,1,3,2,1\n????#??.???????#???? 6,8\n??#.?#?#??#?.???? 1,1,1,3,3\n.##??????.##????? 5,5\n#??..???#.#? 2,3,2\n?.???.??#??????#???. 1,2,6,2,1\n?.?#?????? 5,1\n??????#?#????. 1,9\n?????.#??.?.?#?.# 2,3,3,1\n????##?#??.??#?. 5,3,3\n?.??????.#. 1,2,1\n?.##?.??.# 2,1,1\n????#???.????#? 3,2,1,2\n.????##??# 1,5\n?????#?.#..## 2,1,1,2\n??.###?????.???. 7,2\n????????.?.?.#??.??# 7,1,1,1,1,1\n#??##????#??? 8,1,1\n##????#?#?##?#?.??. 2,11,1\n???#???????????#?? 6,5\n?.???..#??.??.?.#?? 2,1,1,2,1,3\n?.??.?##????? 1,2,2\n.??#???#?????#? 6,2,2\n..?????#.. 1,1\n?##?..????. 4,1\n??#????????#?? 2,9\n??????.???###? 4,6\n????..#???#? 1,2,2,3\n??##?.??#???# 5,2,3\n#.??????..?. 1,1,2,1\n.#.???.??#.?#?#?. 1,2,1,1,4\n.??.?.??#???????? 2,1,2,1,3\n#???#.??..?#.???? 5,2\n???.???.?.#? 2,1,1,1\n?.#??.???#??. 1,4,1\n????##?#?#???#???.? 14,1,1\n???.??##?#?#? 1,8\n???????.?##?.??? 3,1,3,1,1\n#???#???.???.???? 1,5,1,2\n?????#???#?#?#? 8,1,1\n??#?#???.#? 6,1\n.??????????.?##???#. 8,3,2\n??.##.?..?. 2,1,1\n.???????#???#?#???? 12,3,1\n??#???.???# 5,1,1\n?##?#?##???? 3,6\n??.#???.????#?. 1,1,1,2,2\n???.#?#????#?#?# 3,1,1,3,1\n...?#.?????#? 2,2\n??..?#.?#???## 2,1,2,2\n????#????.???. 1,6,1\n.???#.#?#?#?. 4,1,1,2\n.??????#??##??#?# 1,5,4\n??#?.??????#?? 1,1,8\n??#??.#?#?????# 1,1,2,1,1\n?#????#???????# 1,1,1,6\n?##??????#. 2,1,1\n????.?????#?.?# 1,1,6,1\n?###??????#?#?. 4,8\n.??.?.??????#. 1,1,2,1\n?#.???#????.? 1,3\n?#???.#?????#?#??? 1,1,1,8\n?#.????????.#?? 1,7,1\n?????????#...?? 1,6,2\n#?.?#??#????.#???.?? 2,5,1,1,1,2\n??????..#?. 2,1,1\n.??###?#??. 4,1,1\n#????#??##???? 10,1\n??#??#?###? 3,1,3\n????.??????#.?##?? 1,1,1,2,1,5\n??#?.?.?#?? 2,1,1\n##.?###??? 2,3,1\n.?.??..?#?.?? 1,3,1\n.#?????.#???? 3,2,2,1\n??.?#??.?#???#??? 1,2,2,5\n#??.???#????##? 1,1,1,1,2\n???????###.? 3,3\n????????.. 1,2,1\n.?#?##?.#??#??.?? 5,5,1\n???????#?#. 4,4\n??#?#???.?? 5,2\n?.?#??#?#?#????? 1,10,1\n?...#????? 2,1\n???..????..?.?#? 2,1,1,1,2\n..?#?????#???# 9,1\n???.#??.?#?.?##???? 3,3,2,3,1,1\n??#???#??#???#..#.? 5,4,1,1,1,1\n.?#.??#??#?#. 1,1,1,3\n..?.???##????.??.?? 5,1\n.??.????#??..#???.?? 1,1,5,2,1,1\n##????##.#???? 3,3,2,1\n????##.???#?????#??. 1,2,1,3,6\n..???##.#?.??#?#?#? 4,1,8\n.?#.????#??#?##??#?? 1,2,2,1,7\n?#?#.?#????#??? 2,1,3,2,1\n?.?##?#?#?????????? 10,2,1\n?????###????????..? 1,6,2,1,1,1\n???#.??#.???##.?## 1,1,1,1,4,2\n????..?#?###? 3,6\n??#.#???.?.? 1,1,1,1\n???????????#?????#. 6,4,2\n...?#??????.?. 4,1\n?##???????.?.??.#. 9,1,1,1\n?#?#?##???...? 3,2,2,1\n.##?.?..#??????#? 2,1,1,3,1\n#??##??#?#?????.?? 5,7,1\n??#?????#?.?#.# 1,1,5,1,1\n???.?#???#?.?? 3,6,1\n?.???#????? 4,1\n?#..??.??? 1,1,1\n?.#???.??? 1,3,1\n#?#????#???? 1,1,3,3\n?#??????????.? 2,4\n#???????.??. 1,1,1,1\n??.?#??#??..??.?## 1,6,1,2\n????#??#?# 3,2,1\n??.#?#..??#???? 1,1,3,2\n.#?...??#????.????#? 1,3,2,6\n#?#?.#..?.??.?.?#?? 3,1,1,2,1,3\n#????.??##? 1,4\n?.?.???????#?. 2,1\n#??#..?#????#???.?.? 1,1,10,1,1\n#????????#?.?... 6,3,1\n????###????? 5,2\n#??.?????. 3,4\n?.?????????#?#.??? 6,3,2\n?????..?.? 3,1\n??#??##??.???. 4,3,2\n.?.????#?? 1,2\n??#??.????.? 3,2,1,1\n????#??.??##? 7,3\n?????#..???? 4,1\n?.??#??##? 3,3\n??.???.?#? 1,3\n??.#?.?#..?? 1,2,1,2\n??..?#???. 2,4\n.#.???#???###?#??.? 1,1,2,3,1,1\n?.##???#???.?????.? 8,4\n????.??.#???.#??? 1,1,4,1,1\n.??#?#?...#?.??? 3,2,1,1\n??.?????#??# 2,1,4,1\n???#??#???#?# 3,7\n?.??#..?????#????#? 1,1,1,2,7\n#?.??.#?.?#?.???###? 2,1,1,2,1,3\n#????#?#??.???. 1,6,1,1,1\n????.???#???#?????? 1,2,6\n.?.???????#???.??? 9,2\n?##??.??##. 2,3\n?#?????#???.#???##? 3,3,1,4\n#??????#?###???#?? 2,13\n???#??#???????? 6,1,1\n??#??##????? 1,3,1\n.??..#??#? 1,1,2\n?.??###???#.?????. 8,2\n#..???#??.???? 1,1,3,1\n??????.??? 2,1,1\n?#???.???# 1,1,1\n?###??.?????# 6,1,1,1\n??????????? 1,1\n?##???#????????#.?#. 4,1,7,1\n.?.#??.??#?#? 3,3\n????.#?.?# 1,2\n?#??.????.???.? 4,3,2,1\n.???#??#???#?.???..? 3,3,3,1,1\n???.???.????#???#? 1,1,1,1,8\n????#??#?.?## 7,2\n#??????.???#?#??#? 6,7,2\n.???..?#?# 1,3\n?????#?#?#?#?????? 12,1\n#?..?.????????#??? 2,1,1,1,2,1\n??#???...??#??? 1,5\n?.??????#.??? 3,2,1\n.?#.?#..??.#??? 1,2,3\n.??????#?#...?#?.? 5,2\n??.???#??#? 1,1,2\n???#??#?????#?##???? 8,4,1\n.#??#????????.????. 6,3,3\n.#?#?.?.#??.?? 4,2\n?#???##??##???? 2,10\n???.???????#?? 2,1,3\n?#???#?##??.#?? 4,5,1\n???????????????#??? 4,1,1,1,2,2\n??#???#?#??????#? 2,5,6\n??#?.??#..?#??? 3,1,1,5\n?#???#.???.#..# 2,2,1,1,1\n#???????##??.#?.? 1,1,1,3,2\n?????#??###??? 2,7\n#????????##.?.??. 2,7,1\n?.??#?..???#?#????. 3,10\n??????#?..???????.? 5,2\n???#????????????? 1,1,2,2,3\n????.#???#?.. 1,6\n??.??.#??#????????? 1,2,9,3\n????.?..##??? 1,1,2,1\n?#?#????.?#??#??? 8,5\n##?#???#???#?#.??? 5,2,4,2\n??.??#?????#? 1,3,1,2\n??.???#?.##? 1,2,2\n..??.?????# 1,6\n?##??#???#??? 3,2,3,1\n?????#???#?###?##??? 1,2,13\n#?#?#??????#.??#?? 12,3\n???.???#?????????? 2,6\n#??##????????????# 10,2,1,1\n.?.?.???????? 2,1\n.?????????##????? 1,4,7\n#????#?##?? 1,5\n??.??#??????..#?. 1,1,2,4,2\n#..???..?.#?? 1,1,1,2\n.#??#?#?.?.????? 1,4,1,3\n#?????????.???#??? 7,1,4,2\n#???##?#??# 2,5,1\n????.#.?..?#?#. 1,1,4\n?#???#?#?????????? 1,1,1,1,4,1\n??????..???????. 1,2\n#????#?.??##.????#? 2,3,4,1,4\n??###???#?.???####? 9,4\n?.?#?#??.?#??## 6,2,2\n?#?.????#???#.?#.? 1,1,5,2\n?.??.???.??? 1,1,1,1\n.??#?????#?? 5,2\n????.?.?#...? 1,2\n.?#...?#??#?#??#?#? 2,12\n???.?????##?? 1,9\n#?#??????.????? 7,1,2\n???#??..#?. 1,2\n???????#?.?.???. 9,1,1\n#???#???????# 1,1,1,5\n???#?????? 3,2,1\n.##.?????.?.#?????? 2,2,1,1,1,2\n.????..##?#?##????# 1,1,10,1\n??#?????#???#?.???# 1,2,1,2,2,1\n##??.?#?#?##?.???.?. 3,7,2\n.#???..???????? 4,4\n?#?##.?.?? 5,2\n??#??..?.??? 3,1,1\n?.#.??#????#??????# 1,1,1,1,10\n????.#?#???? 1,3,1\n????..???#?#?#???? 1,1,1,6,1\n.###???????#????.?? 3,8\n.#??????.. 1,1,1\n???.??#??????. 2,1,3,1\n?#??#?.?????##???.?# 6,1,2,1,1\n.??.#?????.??????. 5,6\n.???.#?##? 1,1,4\n???????.?##? 3,1,2\n.?#??#????? 5,1\n??????#??.##??#?. 7,6\n.????..????## 1,1,2,2\n?..#?.##?#?#????#?.. 2,8,2\n??##.????????#?? 3,5,2\n#?????????##?.?? 2,1,1,3,2\n.?#?.#?????##???? 2,2,7\n.?.?????????## 1,1,9\n?????.?#??. 3,3\n?#?#??..?? 1,1,2\n?.??.?#??.#????.#??? 1,1,2,5,1,2\n???.?.?##????# 1,1,8\n???##???##.???.? 5,1,2,1,1\n.????????#???###? 3,8\n???#??#??.??## 5,1,1,2\n#.????????.#? 1,4,1,2\n?????????? 4,1\n##?#?.???#?#???.?? 5,1,3,1,1\n??.?#????. 1,1,1\n???.?.?????#?????#. 1,1,1,6,1\n?.?????..?### 1,1,1,4\n??##???##???#??.??# 8,1,1,1,1,1\n?.#??#??##?.?.?.???? 1,1,5,1,1,4\n?.??##?.???.? 4,1\n..?#?????? 3,1\n????#??.?????#???#.? 5,1,1,3,3,1\n???????##?#?.#?????? 2,5,1,4\n??.?#??#??#?????##? 1,11,2\n.???????.???###?? 1,1,2,5\n.???#??#????##??? 6,5\n##?#??.??#.. 2,2,1\n.???.????? 2,1,1\n?...??.?.?#?###?##?# 1,1,1,1,8\n??????#?#?#??#.?... 2,9\n??????###???.#???# 1,4,2,1\n.?..??.???.# 1,2,1,1\n.???..?#??#?#??. 1,9\n???.????###?? 3,6\n?##????###???.. 2,8\n???#?#.??#?? 5,4\n??##?###???#???????? 9,1,1,1,1,1\n?..###??????????.? 1,3,2,4\n#??##????###??????? 14,2\n?###?#??#??#??.???# 4,2,5,1,1\n??.###?#???.. 6,1\n#?#?#?..??#? 1,1,1,4\n?#.???#??.#???##???? 2,1,2,2,6\n.?##.?##??#?????..? 2,8\n????.?#.?.?? 2,2,1,1\n#??.??????#? 3,1,5\n??.#???.??#?#? 2,1,1,5\n???.??#?????? 2,1\n???.?????#?.#. 1,3,1,1\n??..??..???????? 1,1,2\n??????#?????#???? 9,2\n??????#???#? 1,1,7\n???#???.????..? 1,3\n?????.???## 1,4\n.##???.##??.???.?#. 4,2,1,3,2\n.#?#?.??????????? 4,4,2,1\n?#???.???. 5,1\n?##????..##?..?#? 7,3,2\n????????????? 5,1,1,1\n.??#??#????????????? 1,1,1,5,1,1\n???.???#??. 1,5\n???.??.#.???. 3,1,1,1\n???...?#?? 2,2\n.?.#??##.??.?? 5,1\n?..????.?#?##?# 1,4,7\n.#.??????. 1,5\n.??????#...?? 3,1,1\n.????#..?.????? 5,2\n#?#???????#???##?.. 9,7\n###???????#.????#??# 3,1,4,3,1,2\n.?.##????#???#??? 1,4,7\n??????????#???#? 1,4,1,4\n??#??#.##????#? 5,3,3\n??.?##???????.?.#?? 1,3,1,1,1,2\n.?#???#?#?????#??##? 7,7\n#..??.???#?????. 1,1,1,5\n??.#.?#???##??.# 1,1,9,1\n???.??#??????##???? 1,4\n???.???#??.?#????#?? 1,4,7\n#???#??#?#.#??.?# 2,7,3,1\n.??.???????#??#? 1,1,9\n.?#?.????.???? 2,2,4\n.????.#????.?? 1,1,3,1\n??????#????#?...?? 12,1\n?##???#????#?#?.#??? 9,1,2,2,1\n??##??..#.? 5,1\n.???.?.???????.. 2,2,4\n#???#?.?????#? 6,1,1,1\n??#??#.?#?. 3,2,2\n?.??????#?#??#?????? 1,12\n?....??????# 1,2,1,1\n.?????#?????#.?.# 1,6,1,1,1\n????#?####???????? 1,10,1,1\n??#?.??.?? 2,1\n?.?.#.?.????#???.? 1,3\n.#?.#?#???#??#?? 1,3,1,3\n..?#???..?????.? 4,2,1,1\n??###?#???.?????#..? 8,6,1\n???.?#???##???#? 2,10\n?##??#???????????? 10,1,2\n????#???.??? 3,1,2\n?.???.????????#????? 3,1,7,1\n.?.?#??#???? 5,1\n?..???#?.?????? 4,1,1\n??#?#?.???.##?### 2,2,2,6\n.???.?#?#?#???# 1,1,7\n???#??..#???. 4,1,1\n?#.????.????#??.. 2,2,7\n????????#.?#.? 1,5,1\n?.?#..??#??? 1,1,3\n?????#???????#???#. 6,1,1,3\n.#.??#??.?# 1,4,1\n.##??.?##?#. 2,5\n????##??#?#?#?#?#?# 1,15\n?#?.#?.##?#?????##? 2,1,6,4\n..?????#?##???. 9,1\n????.#?###???????? 1,7,1,1\n.?#????????.??????? 9,4\n?.?#??#???????# 4,1,2,1\n???#?#?????.?##??# 8,6\n?#????#??. 1,2\n.??????.?.# 5,1,1\n?##??#.???#??.? 5,1,1,1\n?.?????????#? 1,1,1\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_12_questions.txt",
    "content": "--- Day 12: Hot Springs ---\n\nYou finally reach the hot springs!\nYou can see steam rising from secluded areas attached to the primary, ornate building.\n\nAs you turn to enter, the researcher stops you.\n\"Wait - I thought you were looking for the hot springs, weren't you?\"\nYou indicate that this definitely looks like hot springs to you.\n\n\"Oh, sorry, common mistake! This is actually the onsen! The hot springs are next door.\"\n\nYou look in the direction the researcher is pointing and suddenly notice the massive metal helixes towering overhead.\n\"This way!\"\n\nIt only takes you a few more steps to reach the main gate of the massive fenced-off area containing the springs.\nYou go through the gate and into a small administrative building.\n\n\"Hello! What brings you to the hot springs today? Sorry they're not very hot right now; we're having a lava shortage at the moment.\"\nYou ask about the missing machine parts for Desert Island.\n\n\"Oh, all of Gear Island is currently offline!\n Nothing is being manufactured at the moment, not until we get more lava to heat our forges.\n And our springs. The springs aren't very springy unless they're hot!\"\n\n\"Say, could you go up and see why the lava stopped flowing?\n The springs are too cold for normal operation, but we should be able to find one springy enough to launch you up there!\"\n\nThere's just one problem - many of the springs have fallen into disrepair, so they're not actually sure which springs would even be safe to use!\nWorse yet, their condition records of which springs are damaged (your puzzle input) are also damaged!\nYou'll need to help them repair the damaged records.\n\nIn the giant field just outside, the springs are arranged into rows.\nFor each row, the condition records show every spring and whether it is operational (.) or damaged (#).\nThis is the part of the condition records that is itself damaged; for some springs, it is simply unknown (?) whether the spring is operational or damaged.\n\nHowever, the engineer that produced the condition records also duplicated some of this information in a different format!\nAfter the list of springs for a given row, the size of each contiguous group of damaged springs is listed in the order those groups appear in the row.\nThis list always accounts for every damaged spring, and each number is the entire size of its contiguous group (that is, groups are always separated by at least one operational spring: #### would always be 4, never 2,2).\n\nSo, condition records with no unknown spring conditions might look like this:\n\n#.#.### 1,1,3\n.#...#....###. 1,1,3\n.#.###.#.###### 1,3,1,6\n####.#...#... 4,1,1\n#....######..#####. 1,6,5\n.###.##....# 3,2,1\n\nHowever, the condition records are partially damaged; some of the springs' conditions are actually unknown (?). For example:\n\n???.### 1,1,3\n.??..??...?##. 1,1,3\n?#?#?#?#?#?#?#? 1,3,1,6\n????.#...#... 4,1,1\n????.######..#####. 1,6,5\n?###???????? 3,2,1\n\nEquipped with this information, it is your job to figure out how many different arrangements of operational and broken springs fit the given criteria in each row.\n\nIn the first line (???.### 1,1,3), there is exactly one way separate groups of one, one, and three broken springs (in that order) can appear in that row: the first three unknown springs must be broken, then operational, then broken (#.#), making the whole row #.#.###.\n\nThe second line is more interesting: .??..??...?##. 1,1,3 could be a total of four different arrangements.\nThe last ? must always be broken (to satisfy the final contiguous group of three broken springs), and each ?? must hide exactly one of the two broken springs. (Neither ?? could be both broken springs or they would form a single contiguous group of two; if that were true, the numbers afterward would have been 2,3 instead.)\nSince each ?? can either be #. or .#, there are four possible arrangements of springs.\n\nThe last line is actually consistent with ten different arrangements!\nBecause the first number is 3, the first and second ? must both be . (if either were #, the first number would have to be 4 or higher).\nHowever, the remaining run of unknown spring conditions have many different ways they could hold groups of two and one broken springs:\n\n?###???????? 3,2,1\n.###.##.#...\n.###.##..#..\n.###.##...#.\n.###.##....#\n.###..##.#..\n.###..##..#.\n.###..##...#\n.###...##.#.\n.###...##..#\n.###....##.#\n\nIn this example, the number of possible arrangements for each row is:\n\n    ???.### 1,1,3 - 1 arrangement\n    .??..??...?##. 1,1,3 - 4 arrangements\n    ?#?#?#?#?#?#?#? 1,3,1,6 - 1 arrangement\n    ????.#...#... 4,1,1 - 1 arrangement\n    ????.######..#####. 1,6,5 - 4 arrangements\n    ?###???????? 3,2,1 - 10 arrangements\n\nAdding all of the possible arrangement counts together produces a total of 21 arrangements.\n\nFor each row, count all of the different arrangements of operational and broken springs that meet the given criteria.\nWhat is the sum of those counts?\n\n--- Part Two ---\n\nAs you look out at the field of springs, you feel like there are way more springs than the condition records list.\nWhen you examine the records, you discover that they were actually folded up this whole time!\n\nTo unfold the records, on each row, replace the list of spring conditions with five copies of itself (separated by ?) and\nreplace the list of contiguous groups of damaged springs with five copies of itself (separated by ,).\n\nSo, this row:\n\n.# 1\n\nWould become:\n\n.#?.#?.#?.#?.# 1,1,1,1,1\n\nThe first line of the above example would become:\n\n???.###????.###????.###????.###????.### 1,1,3,1,1,3,1,1,3,1,1,3,1,1,3\n\nIn the above example, after unfolding, the number of possible arrangements for some rows is now much larger:\n\n    ???.### 1,1,3 - 1 arrangement\n    .??..??...?##. 1,1,3 - 16384 arrangements\n    ?#?#?#?#?#?#?#? 1,3,1,6 - 1 arrangement\n    ????.#...#... 4,1,1 - 16 arrangements\n    ????.######..#####. 1,6,5 - 2500 arrangements\n    ?###???????? 3,2,1 - 506250 arrangements\n\nAfter unfolding, adding all of the possible arrangement counts together produces 525152.\n\nUnfold your condition records; what is the new sum of possible arrangement counts?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_13.adb",
    "content": "--  Solution to Advent of Code 2023, Day 13\n-------------------------------------------\n--  Point of Incidence\n--\n--  https://adventofcode.com/2023/day/13\n--  Copy of questions in: aoc_2023_13_questions.txt\n--\n--  HAC 0.26 \"nice to have\"'s detected in this exercise:\n--    *     Unsigned_X and logical operators on it.\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_13 is\n\n  use AoC_Toolbox, HAT;\n\n  maxi : constant := 31;\n\n  subtype Max_Range is Natural range 0 .. maxi;\n\n  map : array (Max_Range, Max_Range) of Boolean;\n  row, col : array (Max_Range) of Integer;\n  m, n : Integer;\n\n  procedure Prepare_Binary_Numbers is\n    a : Natural;\n    x : Positive;\n  begin\n    for i in 1 .. m loop\n      a := 0;\n      x := 1;\n      for j in reverse 1 .. n loop\n        if map (i, j) then\n          a := a + x;\n        end if;\n        x := x * 2;\n      end loop;\n      row (i) := a;\n    end loop;\n    for j in 1 .. n loop\n      a := 0;\n      x := 1;\n      for i in reverse 1 .. m loop\n        if map (i, j) then\n          a := a + x;\n        end if;\n        x := x * 2;\n      end loop;\n      col (j) := a;\n    end loop;\n  end Prepare_Binary_Numbers;\n\n  function Calc_Ref_Code (old_rc_to_avoid : Natural) return Natural is\n    sym : Boolean;\n    ref_code : Integer;\n    s1, s2 : Integer;\n  begin\n    --  Find vertical reflection:\n    for j in 1 .. n - 1 loop\n      sym := True;\n      for jj in 0 .. n loop\n        s1 := j - jj;\n        s2 := j + jj + 1;\n        exit when s1 not in 1 .. n or else s2 not in 1 .. n;\n        sym := sym and then col (s1) = col (s2);\n        exit when not sym;\n      end loop;\n      if sym and then j /= old_rc_to_avoid then\n        return j;\n      end if;\n    end loop;\n    --  Find horizontal reflection:\n    for i in 1 .. m - 1 loop\n      sym := True;\n      for ii in 0 .. m loop\n        s1 := i - ii;\n        s2 := i + ii + 1;\n        exit when s1 not in 1 .. m or else s2 not in 1 .. m;\n        sym := sym and then row (s1) = row (s2);\n        exit when not sym;\n      end loop;\n      if sym then\n        ref_code := 100 * i;\n        if ref_code /= old_rc_to_avoid then\n          return ref_code;\n        end if;\n      end if;\n    end loop;\n    --  Hummm... No reflection found ?\n    return 0;\n  end Calc_Ref_Code;\n\n  r : array (Part_Type) of Integer;\n\n  bit_flipping_method : constant Boolean := True;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2023_13\";\n  --\n  procedure Read_Data_and_Solve is\n    f : File_Type;\n    s : VString;\n    rc, rcs : Natural;\n    mem_row, mem_col : Integer;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      m := 0;\n      n := 0;\n      loop\n        Get_Line (f, s);\n        exit when Length (s) = 0;\n        m := m + 1;\n        n := Length (s);\n        for j in 1 .. n loop\n          map (m, j) := Element (s, j) = '#';\n        end loop;\n        exit when End_Of_File (f);\n      end loop;\n      --\n      --  Map is loaded.\n      --\n      Prepare_Binary_Numbers;\n      rc := Calc_Ref_Code (0);\n      r (part_1) := r (part_1) + rc;\n      --\n      --  Part 2: after the correction on the mirror\n      --  there are one *or two* reflection lines!\n      --  So, if we go for correcting the smudge and\n      --  check the new reflection line, we have to be\n      --  sure that we don't report the old line!\n      --\n      --  Variant: we could cumulate 1-bit differences\n      --  in a variant of the function Calc_Ref_Code and\n      --  spot *the* new reflection with an aberration of\n      --  exactly 1. This would save the double loop below.\n      --\n      Smudge :\n      for i in 1 .. m loop\n        for j in 1 .. n loop\n          --  Test flipping the bit on cell (i, j) of the map.\n          if bit_flipping_method then\n            mem_row := row (i);\n            mem_col := col (j);\n            --  All this would be easier with Unsigned_X and an \"xor\" mask...\n            if map (i, j) then\n              row (i) := row (i) - 2 ** (j - 1);\n              col (j) := col (j) - 2 ** (i - 1);\n            else\n              row (i) := row (i) + 2 ** (j - 1);\n              col (j) := col (j) + 2 ** (i - 1);\n            end if;\n            rcs := Calc_Ref_Code (rc);\n            exit Smudge when rcs > 0;\n            row (i) := mem_row;\n            col (j) := mem_col;\n          else\n            map (i, j) := not map (i, j);\n            Prepare_Binary_Numbers;\n            rcs := Calc_Ref_Code (rc);\n            exit Smudge when rcs > 0;\n            map (i, j) := not map (i, j);\n          end if;\n        end loop;\n      end loop Smudge;\n      if rcs = 0 then Put (\"New axis not found !!!\"); end if;\n      r (part_2) := r (part_2) + rcs;\n    end loop;\n    Close (f);\n  end Read_Data_and_Solve;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data_and_Solve;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 33728\n    --  Part 2: validated by AoC: 28235\n  end if;\nend AoC_2023_13;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_13.txt",
    "content": "#..#.#........#\n#..######..####\n.##..#.#.##.#.#\n#..##..........\n######........#\n#..####......##\n.##.##.#...##.#\n\n..######.\n..######.\n....#..##\n##.....##\n##..#...#\n..##.....\n.#..#.#..\n.#..###..\n..##.....\n\n###..#....#####..\n.#........#.#.###\n.#........#.#.###\n###..#....#####..\n#.#.#####....####\n.#.###..####.#..#\n#..#..#.####...#.\n#..#..#.####...#.\n.#.###..##.#.#..#\n\n..###..######..\n...#####.##.###\n##....#..##..#.\n##.......##....\n.#.##..#....#..\n#########..####\n..###.##.##.##.\n..##.#.######.#\n#####.#.#..#.#.\n..##.##..##..##\n###.###########\n..#...###..###.\n..#.#.#.####.#.\n###.#.########.\n...#.##.#..#.##\n\n..#.###\n.###..#\n.###..#\n..#.###\n.#..#..\n.##.#.#\n####.##\n#.##.##\n#.#..##\n####.##\n.##.#.#\n.#..#..\n..#.###\n\n....#..#.#...\n.#.#..#..##..\n.#.#..#..##..\n.#..#..#.#...\n..####...##..\n..####.#.#.##\n.#..##..#.#..\n#..#..##..###\n.###.##.###.#\n.###.##.###.#\n#..#..##..###\n.#..##..#.#..\n..####.#.#.##\n\n.##.#.##.\n..##.####\n..#######\n###......\n..##.####\n....##..#\n###.#....\n.....####\n###.#.##.\n....#.##.\n..#######\n...##.##.\n##..#####\n##..##..#\n..#...##.\n...###..#\n..###....\n\n....#..#######..#\n......#.#.###.##.\n.##.#.#..#...#..#\n#########.##.....\n####..##.##..#..#\n######.#....##..#\n####..#...#...##.\n.##.##.....#.####\n.##.##..##.###..#\n#..####.##..##..#\n.##..###.#..##..#\n#..##...#####....\n#..####.#.#.#.##.\n.##..#..##..#####\n#..#.#...#.#..##.\n######..########.\n....###.##...#..#\n\n...#..#........\n.#.#..#.#.##.#.\n..#....#..##..#\n.#..##..#....#.\n..######......#\n...#..#..#..#..\n...#..#........\n#...##...#..#..\n.##.##.##....##\n...#..#...##...\n#..####..####..\n..#.##.#......#\n..#.##.#......#\n###....###..###\n#........####..\n\n...##..##.#.#\n.##.#####.###\n##.#....####.\n#.#....#.#..#\n.#..#.#...#.#\n.#..#.#...#.#\n#.#....#.#..#\n##.#....####.\n.########.###\n...##..##.#.#\n#.#.###.....#\n#.#.###.....#\n...##..##.#.#\n\n....#.#.##.\n....#######\n######....#\n#..#....###\n#..#..#..#.\n####...##..\n#..#...#..#\n#..##..#..#\n####...##..\n#..#..#..#.\n#..#....###\n\n.#..##..##..#..#.\n..#...##...#.....\n##...####...#####\n#.##......##.#..#\n#.##......##.#..#\n##...####...#####\n..#...##...#.....\n.#..##..##..#..#.\n.#..#.##.#..#.#..\n.##...##...##.#.#\n.#...#..#...#.#..\n#.#........#.#...\n.#...####.#.#.#.#\n#.##.####.##.##..\n#............##.#\n##...####...##...\n#............####\n\n#..#.#..#\n####.....\n.##.##..#\n.##.#.##.\n#####.##.\n.##.#.###\n#..#.#..#\n\n###..##.####..###\n###..##.####..###\n##..###.#.#...###\n#.#.#..##..####.#\n#.#..#...#..###..\n..#....####.#.###\n#..#...##.###.#..\n.###......####.##\n#..#.#...########\n\n#.##.#..#...#..\n.#...#.....#...\n#.#..#.#.##.###\n.#####.#.#..#.#\n.#####.#.#..#.#\n#.#..#.#.##.###\n.#...#.#...#...\n#.##.#..#...#..\n#.#.#.###.####.\n#..###....###..\n#..###....###..\n\n#...##......##.\n..###..#..#..##\n###.#.##..##.#.\n.##.####..####.\n..###..#..#..##\n...#...####...#\n###....#..#....\n###....#..#....\n...#...####...#\n..###..#..#..##\n.##.####..####.\n###.#.##..##.#.\n..###..#..#..##\n#...##......##.\n.##.####..####.\n....##.####.##.\n.#...##.##..#..\n\n.....#.##\n...###.#.\n...###.#.\n.....#.#.\n..#.#####\n..##..##.\n...#...#.\n..##.#.##\n####.....\n.....##.#\n##.##.###\n####.#...\n##...##.#\n\n..#..#....#..##..\n#.#.#.#####..####\n..#....#..#..#..#\n.##.#############\n##.###.#..#..#..#\n...#.##.##.##.##.\n.#.#..##.#.##.#.#\n..#..#..########.\n##.####.##....##.\n#####.#..#.##.#..\n#.####..#.#..#.#.\n#.####..#.#..#.#.\n#####.#..#.##.#..\n\n#.#....##\n#...#..#.\n.##..#..#\n.#.#..###\n##.#..###\n.##..#..#\n#...#..#.\n#.#....##\n.#.#....#\n.#.######\n##.#..#..\n##..#####\n...#.#...\n...##....\n...##....\n...#.#...\n##..#####\n\n##..#####\n.#.##....\n.#.#..##.\n.....#..#\n.##.#####\n.########\n.....#..#\n.#.#..##.\n.#.##....\n##..#####\n..#.#.##.\n\n#.#.##.#.##......\n.###..###...#.##.\n.#......#.###...#\n.#......#.###...#\n.###..###...#.##.\n#.#.##.#.##......\n#.#.##.#.#......#\n.###..###.###.#.#\n####..####.##.##.\n#.#.#..#.###.####\n.#.####.#...#.#..\n.##....##....#.#.\n.##.##.##.###.#..\n.#.#..#.#.#.#.#..\n#.#.##.#.#.#####.\n\n..##.######\n##.#.#####.\n##.#.#####.\n..##.######\n..###..##..\n....###..##\n.#.#.......\n\n####.#####..#####\n#......#......#..\n....#..#......#..\n....#..#......#..\n#......#......#..\n####.#####..#####\n...#.............\n...#####.#..#.###\n.###..###...####.\n#.##..#........#.\n.#.#.#..##..##..#\n..#.#..#.####.#..\n#.#..##..#..#..##\n\n######.###...\n#..#.#.#.##..\n....#.##.....\n#..#..#.###..\n...#.#...####\n.....##.#####\n.##..#..##...\n#..#.#.######\n#######.#.###\n\n.####..##\n#.#...#..\n...###.##\n.##..#.##\n.##.###..\n.######..\n...#..#..\n#.#..#.##\n.#####...\n####.#.##\n.###.####\n.###...#.\n..#....##\n.#.######\n##..##...\n##..##...\n.#.######\n\n.##....##....##..\n.###...##...#####\n##.####..####.###\n..##.##..##.##...\n##..#.#..#.#..###\n....#..##..#.....\n.#..###..###..#..\n#.#...#..#...#.##\n...#.######.#....\n#.##........##.##\n#.#.#.####.#.#.##\n\n#..##.#......##\n#..##.#......##\n..##.###.#...##\n.#........##.##\n..########.#...\n##.#.#..##.....\n#.#..#...#..###\n##...###.#.#.##\n#..#..#.##.#.##\n#..##.....#####\n##.#.#####.####\n.###..#..#..#..\n....##....###..\n###.#.###.####.\n.#...##.#..#...\n\n.##.##.##....\n..#....#..###\n.#..##..#..##\n#..#..#..#...\n##......#####\n.#..##..#.#..\n###.#######..\n##########...\n###....####..\n..#.##.#..###\n#.######.###.\n..........#..\n..........#..\n#.######.###.\n..#.##.#..###\n\n.##...##.####\n#.###.#.#....\n....#.#.##..#\n#########.##.\n.##..#.#..##.\n....##..##..#\n#..#.#..##..#\n.##.##...####\n#..#....#....\n\n#..#..#..##.###\n#.###..##...###\n##.###....#.#..\n#.##..#.##.####\n.#..######.#.##\n#.##.##..#..#..\n##..###....#...\n##..###....#...\n#..#.##..#..#..\n.#..######.#.##\n#.##..#.##.####\n##.###....#.#..\n#.###..##...###\n#..#..#..##.###\n####..###.#....\n#.#.###....##..\n..###.###...###\n\n####.###.####\n###..#.#####.\n#.###..####..\n#.##...####..\n###..#.#####.\n####.###.####\n..##.###..#..\n#....##.#.###\n#.##.#..##.##\n#.##.#..##.##\n#....##.#.###\n..##.###..#..\n####.###.####\n\n.#.#....#\n.#.#....#\n.#.#####.\n###...#..\n...###.##\n....#.#.#\n....#.#.#\n...###.##\n##....#..\n.#.#####.\n.#.#....#\n\n##.#####...\n#..#..##...\n###...#..##\n....#.###..\n#.#..#..###\n#.#..#..###\n....#.###..\n#.#...#..##\n#..#..##...\n##.#####...\n...##...###\n.#...##.###\n...#..#....\n\n###...##..##...\n##..#.#.##.#.#.\n..##..######..#\n###.##.####.##.\n...#.###..#####\n##.###.#..#.###\n##.####....####\n...#.#..##..#.#\n..#...#....#...\n###.##########.\n##..##.####.##.\n###.#.#.##.#.#.\n#####..#..#..##\n\n#.##.##.##.\n#.#.#..#.#.\n#.#.#..#.#.\n#.##.##.##.\n#.##.##.##.\n#####..####\n.#.#.##.#.#\n....##.#...\n##..####..#\n.##......##\n.#........#\n\n####......##..#\n#####.###.##...\n....####...####\n.#......##.#...\n####.#.#..#.###\n##....#.#.#..#.\n#..#.###..#..##\n#..#.###..#..##\n##....#.#.#..#.\n####.#.#..#.###\n.#......##.#...\n....####...####\n#####.###.##...\n####......###.#\n##....####.#.#.\n...####.###....\n...####.###....\n\n..##...##..##.#\n..##...##..##.#\n####..#.#..#...\n..##..####.#.#.\n..##.#...###..#\n##...###..#.###\n##..########..#\n.#.##.#...#..#.\n...##.#.#..##.#\n#########.##..#\n..#.##.#.##....\n..#####...##.#.\n##...##..#.#...\n\n........#.#\n#.....###.#\n##....#####\n#..##..##..\n..#..#..###\n.#....#..#.\n.#....#..#.\n\n..##.##\n.#.##..\n#.###..\n..#..##\n####.##\n.####..\n#.##...\n....###\n...#...\n##..###\n#...###\n\n##.#....######..#\n..##.#.##....####\n##...#..#....#..#\n#.###..#####.#..#\n#####..###...####\n..#.######.###..#\n...#.#.####..#..#\n#...#..##.#......\n...#...#...######\n...#...#...######\n#...#..##.#......\n...#...####..#..#\n..#.######.###..#\n\n####.##.#\n.#..#..#.\n#..#.##.#\n.##......\n#..##..##\n....#..#.\n.##.####.\n####.##.#\n....####.\n.##..##..\n....#..#.\n....####.\n####....#\n....####.\n....####.\n....####.\n.##.#..#.\n\n#.######.###.##\n#..#..#..#....#\n.#......#.##...\n.#..##..#.####.\n#..####..#.##..\n##..##..######.\n.#.#..#.#.#####\n.#.#..#.#..##.#\n.#.#..#.#.###.#\n\n.###.###.\n#.#.....#\n#.#.#.#..\n.##.##..#\n...#.#.##\n#..#.#.##\n.##.##..#\n#.#.#.#..\n#.#.....#\n.###.###.\n...##.##.\n..#####.#\n..#####.#\n\n...#.####..#.####\n##........#.#.#.#\n..###...#.##.....\n..###...#.##.....\n##........#.#.#.#\n...#.####..#.####\n#..##.#...#######\n....#.##.....#..#\n###.##.#.#..##..#\n...####.#.#...#.#\n..#.#..####....#.\n....#.####...####\n###.#..#..#..#.##\n.....#######..#..\n....##......#.##.\n##.#####.....#..#\n###..##.##...###.\n\n#..##.#####\n#..##.#####\n.##.#.##...\n#...##.###.\n#..##.###.#\n#######.#.#\n#.#..#####.\n#.#..#####.\n#######.#.#\n#...#.###.#\n#...##.###.\n\n..#.####.##..##.#\n.#.##.#####..####\n#.#.###.#.####.#.\n###..###........#\n#...##..#......#.\n#..###.#.######.#\n.###...##########\n#.#.#.#.##.##.##.\n######...##..##..\n#.......#......#.\n#.###.#####..####\n###...##.#.##.#.#\n#.##..#####..####\n..###.#...####...\n.#.....##.#..#.##\n##....##.#.##.#.#\n#.....##.#.##.#.#\n\n#..#.##....##\n#..#.##.....#\n######.###...\n##########.##\n.##..#.....#.\n#..#....##.##\n......##....#\n........#....\n....##.##.#..\n.......#.#..#\n......##..#..\n.##..#.######\n.....#.#.###.\n\n...#.#..###\n...#.#..###\n.##....####\n###...#.###\n....#..#.#.\n....####...\n...#.#...##\n####.####.#\n....#.##.#.\n\n..###..##..\n.#.########\n.###....###\n..#..#####.\n####...#.##\n####...#.##\n..#..#####.\n.###....###\n.#.########\n..###...#..\n##..#...#..\n.#.....#..#\n########..#\n.#.##.#....\n.#.##.#....\n########..#\n.#.....#..#\n\n#..##..\n..#..#.\n.######\n..####.\n..####.\n##....#\n.#.##.#\n.#.##.#\n##....#\n..####.\n..####.\n.######\n#.#..#.\n#..##..\n#.#..#.\n\n.##...##.##\n..##.##.###\n###...##...\n....#..##..\n....#..##..\n###...##...\n...#.##.###\n.##...##.##\n..#....#.##\n.###..##.##\n.##....###.\n.##....###.\n.###..##.##\n..#....#.##\n.##...##.##\n\n.....#.##...#..##\n#.#...###..######\n###.#...#.#.#####\n###.#...#.#.#####\n#.#...###..######\n.....#.##..##..##\n#####.#.###.#..##\n##.#.####..######\n#.##.###.#.......\n\n###.#..#..#\n..#.#..#.#.\n..#.#..#.#.\n###.#..#..#\n...#.#..##.\n###..#.###.\n..#..###.#.\n##.#.#...#.\n.#.###..#..\n###.##..###\n..#....#.#.\n##.#.##.#.#\n..#...#...#\n....#.#...#\n..#..#.####\n\n.##.####.##.####.\n.##.####.##.####.\n..#....##..##....\n#...###......###.\n..#.#.#.#..#.#.#.\n##..##.#....#.#..\n#.#.##.#.##.#.##.\n#....###....###..\n........####.....\n.#.#.....##.....#\n###.##...##...##.\n\n#.#####.##.##\n...#...#.....\n.##.#.##..###\n.###.##...###\n#..#..##....#\n..###...#.##.\n..###...#.##.\n#..#..##....#\n.###.##...###\n.#..#.##..###\n...#...#.....\n#.#####.##.##\n#.#####.##.##\n\n.#.#.#..#..##..\n.#....##.###..#\n###..##.#.##.##\n.#####.#######.\n.#####.#######.\n###..##.#.##.##\n.#....##.###.##\n.#.#.#..#..##..\n########....#.#\n#..##.##.##.#..\n#..##.##.##.#..\n########....#.#\n.#.#.#..#..##..\n.#....##.###.##\n###..##.#.##.##\n\n..#..##....\n#..#....##.\n##.##......\n###...#.##.\n#.#..######\n#.##....##.\n.##.#####.#\n..##.#.#..#\n..##.#.#..#\n\n..##..##.....###.\n#.#....#.#..#.#..\n#...##...####...#\n..#.##.#..##..#.#\n.###..###....###.\n##.####.######.##\n..######..##..###\n#........####....\n#.#.##.#.#..#.#.#\n####..####..####.\n##.####.######.##\n.#......#.##.#...\n#..####..#..#..##\n.#.####.#.##.#.##\n.###..###....###.\n...####...##...##\n#...##...#..#...#\n\n#.#..#..#\n.###.##.#\n.###.##.#\n#.#..#..#\n#.##..###\n.####.##.\n.###..#.#\n##.#..###\n.#.#.....\n.#.#.....\n.#.#..###\n.###..#.#\n.####.##.\n\n#...###.#.##.####\n##..##.###..##..#\n..##...###...#..#\n#.##.###.##...##.\n#.##.###.#.......\n..##....#..##....\n......###....#..#\n\n.#.....##....\n.#.....##....\n......#..#...\n#..#...##...#\n#.#.#..##.##.\n##..##....##.\n##.#.##..##.#\n\n####.##..\n.##..#...\n.##..#...\n####.##..\n####..#..\n#..#..#.#\n.....#.##\n#..#.##..\n.....#..#\n#..#.#.#.\n....###.#\n#####.#.#\n####.....\n####.##..\n....#..##\n..#.###..\n#..##.#..\n\n....##.##\n..#....#.\n..#......\n....##.##\n.....##..\n##.#.##.#\n#...#.##.\n#..#.##.#\n.#.##.###\n.#..##.#.\n.#..##.#.\n.#.##.###\n#..#.##.#\n#...#.##.\n##.#.##.#\n\n#.##########.##\n.#..######..#..\n####.#..#.#####\n###.#.##.#.####\n...#..##..#....\n.##.#.##.#.##..\n..#..####..#...\n#.#........#.##\n..###.##.###...\n..#...##.#.#...\n###...##...####\n\n#.#.#.#..\n####.##..\n.#....###\n.#....###\n####.##..\n#.#.#.#..\n.#####...\n.####..#.\n..####...\n.#.......\n#..######\n\n#..#......#..\n#####....####\n#.###.##.###.\n#.###.##.###.\n#####....####\n#..#......#..\n###.######.##\n#.##########.\n..###.##.###.\n.#..#.##.#..#\n.#...#......#\n#.#..####..#.\n###.##..##.##\n\n.####..########\n#.##.#..###....\n..##..#.#..##..\n.#..#...#......\n.####...##.####\n##..##########.\n##..##..#..##.#\n##..##..#..####\n##..##########.\n.####...##.####\n.#..#...#......\n..##..#.#..##..\n#.##.#..###....\n.####..########\n######....###.#\n..##..#.#.#.###\n.#..#.....##.#.\n\n......#..#.\n.......##..\n##..##....#\n######....#\n######....#\n#.##.#....#\n#.##.#....#\n#.##.######\n...#.......\n\n##..#..#..###..\n##..#..#..###..\n.###....###..#.\n#...####...####\n####.##.#####.#\n...##..##...##.\n.##..##..#....#\n\n.#..#.##..###.#.#\n#....###.#.##.##.\n#....###.#.##.##.\n.#..#.##..###.#.#\n######.#.#...#.##\n.......##.#.#....\n#########..#.....\n.#..#...#...###.#\n.####.###.#....##\n#....##.##..#...#\n#......##.####..#\n\n.#...#.###.##\n..######.....\n###..###.####\n#...##.#...##\n.#####.#.##..\n.##..#..#.#..\n#.##...###.##\n##..#.###.###\n###..#...####\n#..#..##.....\n...##..#.####\n...##..#.####\n#..#..##.....\n###..#...####\n##..#.###.###\n#.#....###.##\n.##..#..#.#..\n\n.#..##.#..#.#.#..\n...##..##....#.##\n..#......#......#\n..##....##....#..\n.##..##..##.....#\n#.#..##..#.#...#.\n#.#..##..#.#...#.\n\n##.....\n.....#.\n.###.#.\n.###.#.\n....##.\n##.....\n#..##.#\n#....##\n#....##\n#..##.#\n##.....\n\n##..###\n..###..\n##.#.##\n.####..\n..#.#..\n.#.##..\n.#.....\n.#.....\n.#.##..\n..#.#..\n#####..\n##.#.##\n..###..\n\n####.##.....###.#\n#####.......#..#.\n#####.......#..#.\n####..#.....###.#\n#..####..#.#.##.#\n.##..#..........#\n######..#.##....#\n#..####...###...#\n####..#..###.....\n.......#.##.##...\n....##.###.##..#.\n#..##..###...#.#.\n....#...#.##...##\n.##........##....\n.....#.####..##.#\n#..#..#..#.#.#..#\n#######.#.#.#....\n\n##.##.##.\n#.#..#.##\n#.#..#.##\n##.##.###\n.#....#..\n##.##.###\n.##..##..\n.#....#.#\n#.####.##\n.######.#\n.#.##.#.#\n\n.#.#..#.#.##.\n#..#..#..####\n..#.##.#..##.\n##..##.######\n#..#..#..####\n.##....##....\n#..#..#..####\n\n#.##.####.#######\n..#.#...###.####.\n.#.#....##...##..\n..#.###.##..####.\n##.#####..#.#..#.\n.##.##.######..#.\n.##....#.#..####.\n...#..##.##.####.\n...#..##.##.####.\n\n#.#..#.\n.##..##\n###..##\n###..##\n.##..##\n#.#..#.\n.#.##.#\n#.#..##\n.#....#\n\n...#.....#.##\n..#.#.#....#.\n#####..##.##.\n####...##....\n#####.#.#..#.\n..####..###.#\n..#.#...#....\n..####..##...\n...####.#.###\n##.##.####..#\n##..#....#.##\n##.###....#.#\n..##.#....###\n..##.#....###\n##.###......#\n##..#....#.##\n##.##.####..#\n\n.##.#..#.##..\n.##.#..#.##..\n..#######...#\n.####..####.#\n..########...\n#.###..###.#.\n#...#..#...#.\n#####..#####.\n.###.##.###..\n\n#######......\n....#...####.\n####.#.#....#\n.#.#..##.##.#\n####.###....#\n#.###.#.#..#.\n...#.####..##\n.##.###......\n.#..###.#..#.\n.#.#.##..##..\n..#..##......\n#.......#..#.\n##...##..##..\n.###.........\n.##..........\n\n##..####.\n.###.##.#\n#..#....#\n#..#....#\n.###.##.#\n##..#..#.\n###......\n#..#.##.#\n...#.##.#\n\n######.....\n#..###..###\n####..##..#\n#####..#..#\n#..#....##.\n.##...#....\n####..##..#\n######.....\n.##..#..##.\n\n..###.#.####.#.##\n##.##..#....#..##\n..#..###....###..\n.....##......##..\n....#.#..##..###.\n##.#...#.##.#...#\n..##...#....#...#\n..#....#.##.#....\n####..#.####.#..#\n\n.########..####\n#...##...##...#\n#.##..##.##.##.\n##..###.####.##\n#..####..##..##\n##..##..####..#\n..##..##....##.\n...####......##\n#...##...##...#\n#.#....#.##.#..\n.#.####.#..#.##\n..##..##....##.\n.########..####\n##.#..#.####.#.\n#..#..#..##..#.\n\n##..#....\n###...###\n.###.#..#\n..###..##\n..#......\n##.#....#\n##.#....#\n\n####.#.\n#..#...\n###.###\n...##..\n.#...##\n##.#.#.\n##.#.#.\n.#...##\n...##.#\n###.###\n#..#...\n####.#.\n##.##..\n###..##\n.....##\n.....##\n###..##\n\n#####.###....##\n.######.#.##.#.\n..####..######.\n##....###.##.##\n...##...#.##.#.\n.######...##...\n#......##....##\n.#.##.#........\n..#..#..#.##.#.\n###..###.####.#\n#.####.##.##.##\n..#..#.........\n..####.........\n###..###......#\n.##..##.#.##.#.\n###..#####..###\n...##...##..##.\n\n#...#.###\n.#.##..#.\n#....###.\n....###.#\n#.######.\n#.######.\n....###.#\n#....###.\n.#.##..#.\n#...#..##\n...#...#.\n...#...#.\n#...#..##\n.#.##..#.\n#....###.\n\n#.#....\n#####.#\n.####.#\n.##..##\n......#\n###.#.#\n##.#.##\n...#..#\n...#..#\n##.#.##\n###.#.#\n...#..#\n.##..##\n.####.#\n#####.#\n#.#....\n#.#....\n\n...##.#\n###.#.#\n...#.#.\n..#.#.#\n..#.#.#\n...#.#.\n###.#.#\n...#..#\n##.#.##\n####.##\n...#...\n##.....\n...#.#.\n##.###.\n####...\n\n.#.#.#...##..\n.#.#.#...##..\n.##..##.##..#\n#.###.###.#..\n#########..#.\n..##..#..##.#\n...##...###.#\n###.####.###.\n.#####.#.##.#\n.#####.#.##.#\n###.####.###.\n..###...###.#\n..##..#..##.#\n\n.####......\n.####..#..#\n#.####.#..#\n.####..#..#\n..##..##..#\n.#..#......\n#.##.#.####\n.#..#..#..#\n.#..#.#####\n#.##.##....\n.#..#.##..#\n\n.######.##....#\n#.####.#..#..#.\n.#....#...####.\n##########....#\n........##....#\n.#....#.#.#..#.\n#.......###..##\n.#.##.#.##.##.#\n#..##..##.####.\n###..#####....#\n.######.##....#\n##....###.#..#.\n..........#..#.\n\n.##..###.##\n####.##..##\n######.##.#\n#..#...##..\n.##..#....#\n#..#...##..\n.##..######\n####.######\n.##..######\n\n..#.###\n#.#.###\n..#.###\n#.#####\n.##.#..\n##...##\n#.#..##\n#..##..\n...####\n\n......##...\n.#..#.##.#.\n##..##..##.\n.#..#.##.#.\n#....####..\n.####....##\n#....#..#..\n#....####..\n######..###\n##..#####..\n#.##.####.#\n\n##...#....#..\n...##......##\n##.#.#....#.#\n.############\n.############\n##.#.#....#.#\n...##......##\n##...#....#..\n#....#####...\n..###.####.##\n#............\n#.#..##..##..\n.#.#.######.#\n\n#.##......#.#####\n.#.#..####.#####.\n##..##.##.##.#..#\n..##.##..#.#.#.#.\n..##.##..#.#.#.#.\n##..##.##.##.#..#\n.#.#..###..#####.\n#.##......#.#####\n..#......#..#.###\n########.#...#.##\n########...##.###\n####......#.##..#\n#.##.#.###..####.\n#.##.#.###..####.\n####......#.##..#\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_13_questions.txt",
    "content": "--- Day 13: Point of Incidence ---\n\nWith your help, the hot springs team locates an appropriate spring which launches you neatly and precisely up to the edge of Lava Island.\n\nThere's just one problem: you don't see any lava.\n\nYou do see a lot of ash and igneous rock; there are even what look like gray mountains scattered around.\nAfter a while, you make your way to a nearby cluster of mountains only to discover that the valley between them is completely full of large mirrors.\nMost of the mirrors seem to be aligned in a consistent way; perhaps you should head in that direction?\n\nAs you move through the valley of mirrors, you find that several of them have fallen from the large metal frames keeping them in place.\nThe mirrors are extremely flat and shiny, and many of the fallen mirrors have lodged into the ash at strange angles.\nBecause the terrain is all one color, it's hard to tell where it's safe to walk or where you're about to run into a mirror.\n\nYou note down the patterns of ash (.) and rocks (#) that you see as you walk (your puzzle input); perhaps by carefully analyzing these patterns, you can figure out where the mirrors are!\n\nFor example:\n\n#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n\n#...##..#\n#....#..#\n..##..###\n#####.##.\n#####.##.\n..##..###\n#....#..#\n\nTo find the reflection in each pattern, you need to find a perfect reflection across either a horizontal line between two rows or across a vertical line between two columns.\n\nIn the first pattern, the reflection is across a vertical line between two columns; arrows on each of the two columns point at the line between the columns:\n\n123456789\n    ><   \n#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n    ><   \n123456789\n\nIn this pattern, the line of reflection is the vertical line between columns 5 and 6. Because the vertical line is not perfectly in the middle of the pattern, part of the pattern (column 1) has nowhere to reflect onto and can be ignored; every other column has a reflected column within the pattern and must match exactly: column 2 matches column 9, column 3 matches 8, 4 matches 7, and 5 matches 6.\n\nThe second pattern reflects across a horizontal line instead:\n\n1 #...##..# 1\n2 #....#..# 2\n3 ..##..### 3\n4v#####.##.v4\n5^#####.##.^5\n6 ..##..### 6\n7 #....#..# 7\n\nThis pattern reflects across the horizontal line between rows 4 and 5. Row 1 would reflect with a hypothetical row 8, but since that's not in the pattern, row 1 doesn't need to match anything.\nThe remaining rows match: row 2 matches row 7, row 3 matches row 6, and row 4 matches row 5.\n\nTo summarize your pattern notes, add up the number of columns to the left of each vertical line of reflection; to that, also add 100 multiplied by the number of rows above each horizontal line of reflection. In the above example, the first pattern's vertical line has 5 columns to its left and the second pattern's horizontal line has 4 rows above it, a total of 405.\n\nFind the line of reflection in each of the patterns in your notes. What number do you get after summarizing all of your notes?\n\n--- Part Two ---\n\nYou resume walking through the valley of mirrors and - SMACK! - run directly into one.\nHopefully nobody was watching, because that must have been pretty embarrassing.\n\nUpon closer inspection, you discover that every mirror has exactly one smudge: exactly one . or # should be the opposite type.\n\nIn each pattern, you'll need to locate and fix the smudge that causes a different reflection line to be valid.\n(The old reflection line won't necessarily continue being valid after the smudge is fixed.)\n\nHere's the above example again:\n\n#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n\n#...##..#\n#....#..#\n..##..###\n#####.##.\n#####.##.\n..##..###\n#....#..#\n\nThe first pattern's smudge is in the top-left corner. If the top-left # were instead ., it would have a different, horizontal line of reflection:\n\n1 ..##..##. 1\n2 ..#.##.#. 2\n3v##......#v3\n4^##......#^4\n5 ..#.##.#. 5\n6 ..##..##. 6\n7 #.#.##.#. 7\n\nWith the smudge in the top-left corner repaired, a new horizontal line of reflection between rows 3 and 4 now exists.\nRow 7 has no corresponding reflected row and can be ignored, but every other row matches exactly: row 1 matches row 6, row 2 matches row 5, and row 3 matches row 4.\n\nIn the second pattern, the smudge can be fixed by changing the fifth symbol on row 2 from . to #:\n\n1v#...##..#v1\n2^#...##..#^2\n3 ..##..### 3\n4 #####.##. 4\n5 #####.##. 5\n6 ..##..### 6\n7 #....#..# 7\n\nNow, the pattern has a different horizontal line of reflection between rows 1 and 2.\n\nSummarize your notes as before, but instead use the new different reflection lines.\nIn this example, the first pattern's new horizontal line has 3 rows above it and the second pattern's new horizontal line has 1 row above it, summarizing to the value 400.\n\nIn each pattern, fix the smudge and find the different line of reflection.\nWhat number do you get after summarizing the new reflection line in each pattern in your notes?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_14.adb",
    "content": "--  Solution to Advent of Code 2023, Day 14\n-------------------------------------------\n--  Parabolic Reflector Dish\n--\n--  https://adventofcode.com/2023/day/14\n--  Copy of questions in: aoc_2023_14_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_14 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 10;\n  input_name : constant VString := +\"aoc_2023_14\"; n : constant := 100;\n  --\n\n  type Map_Type is array (1 .. n, 1 .. n) of Character;\n\n  map_data, map : Map_Type;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        Get (f, map_data (i, j));\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer;\n\n  function Count_Load return Integer is\n    res : Integer := 0;\n  begin\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        if map (i, j) = 'O' then\n          res := res + n - i + 1;\n        end if;\n      end loop;\n    end loop;\n    return res;\n  end Count_Load;\n\n  procedure Roll_North is\n    iii : Integer;\n  begin\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        if map (i, j) = 'O' then\n          --  Roll the rock!\n          iii := 0;\n          for ii in reverse 1 .. i - 1 loop\n            if map (ii, j) = '.' then\n              iii := ii;\n            else\n              exit;\n            end if;\n          end loop;\n          if iii /= 0 then\n            map (iii, j) := 'O';\n            map (i, j)   := '.';\n          end if;\n        end if;\n      end loop;\n    end loop;\n  end Roll_North;\n\n  procedure Roll_South is\n    iii : Integer;\n  begin\n    for i in reverse 1 .. n loop\n      for j in 1 .. n loop\n        if map (i, j) = 'O' then\n          --  Roll the rock!\n          iii := 0;\n          for ii in i + 1 .. n loop\n            if map (ii, j) = '.' then\n              iii := ii;\n            else\n              exit;\n            end if;\n          end loop;\n          if iii /= 0 then\n            map (iii, j) := 'O';\n            map (i, j)   := '.';\n          end if;\n        end if;\n      end loop;\n    end loop;\n  end Roll_South;\n\n  procedure Roll_East is\n    jjj : Integer;\n  begin\n    for j in reverse 1 .. n loop\n      for i in 1 .. n loop\n        if map (i, j) = 'O' then\n          --  Roll the rock!\n          jjj := 0;\n          for jj in j + 1 .. n loop\n            if map (i, jj) = '.' then\n              jjj := jj;\n            else\n              exit;\n            end if;\n          end loop;\n          if jjj /= 0 then\n            map (i, jjj) := 'O';\n            map (i, j)   := '.';\n          end if;\n        end if;\n      end loop;\n    end loop;\n  end Roll_East;\n\n  procedure Roll_West is\n    jjj : Integer;\n  begin\n    for j in 1 .. n loop\n      for i in 1 .. n loop\n        if map (i, j) = 'O' then\n          --  Roll the rock!\n          jjj := 0;\n          for jj in reverse 1 .. j - 1 loop\n            if map (i, jj) = '.' then\n              jjj := jj;\n            else\n              exit;\n            end if;\n          end loop;\n          if jjj /= 0 then\n            map (i, jjj) := 'O';\n            map (i, j)   := '.';\n          end if;\n        end if;\n      end loop;\n    end loop;\n  end Roll_West;\n\n  procedure Do_Part_1 is\n  begin\n    map := map_data;\n    Roll_North;\n    r (part_1) := Count_Load;\n  end Do_Part_1;\n\n  verbose : constant Boolean := False;\n\n  procedure Do_Part_2 is\n\n    --  Empirical constants:\n    cycle_observation_rounds : constant := 120;\n    load_max : constant := 120_000;\n\n    --  `mem` is used for detecting cycles in load values.\n    --  Note (possible trap in this puzzle): we are\n    --  *not* interested in cycles in rock layout or\n    --  in loads measured within a full rotation!\n    --\n    mem : array (1 .. load_max) of Natural;\n\n    step : Natural := 0;\n    cycle : Positive;\n    overall_cycle : Positive := 1;\n\n    total : constant := 1_000_000_000;\n    rest : Integer;\n\n    procedure Check is\n      l : Integer;\n    begin\n      step := step + 1;\n      l := Count_Load;\n      if mem (l) in 1 .. step - 1 then\n        cycle := step - mem (l);\n        overall_cycle := LCM (overall_cycle, cycle);\n        if verbose then\n          Put_Line\n            (+\"  Step: \" & step &\n              \"  load: \" & l &\n              \"  deja vu at step: \" & mem (l) &\n              \"; length \" & cycle);\n        end if;\n      end if;\n      mem (l) := step;\n    end Check;\n\n  begin\n    map := map_data;\n    for i in mem'Range loop\n      mem (i) := 0;\n    end loop;\n    if verbose then\n      Put_Line (\"Check cycles\");\n    end if;\n    for count in 1 .. cycle_observation_rounds loop\n      Roll_North;\n      Roll_West;\n      Roll_South;\n      Roll_East;\n      Check;\n    end loop;\n    if verbose then\n      Put_Line (+\"Overall cycle: \" & overall_cycle);\n    end if;\n    rest := total - cycle_observation_rounds;\n    rest := rest mod overall_cycle;  --  Now we warp x * `overall_cycle`\n    if verbose then\n      Put_Line (\"Remaining steps : \" & rest'Image);\n    end if;\n    for count in 1 .. rest loop\n      Roll_North;\n      Roll_West;\n      Roll_South;\n      Roll_East;\n    end loop;\n    r (part_2) := Count_Load;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 113078\n    --  Part 2: validated by AoC: 94255\n  end if;\nend AoC_2023_14;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_14.txt",
    "content": ".OO..##.###..#O.O..O#.OOO.....#..O##O#.OO...O..##.O.O.......##O...O...O#O.O.#..O..O.#O..OO...#......\n....OO..#.#...O#.O..#O..#OO...OO..O......O#........O...#..OO..#.#.O#..OO...O####.O...O.O.#.O..O.O..O\n.O#.......O.OO#OO##O#O..O.O....#.OO..O...O.OO........O..#...O.O......##....O.....##.O.#.#.O..O......\n..##.#.....#..#.O#O...O..O...OOO.##O.O##...O#.OO.#....OOO.OO.#O.O.O#...OO.OO.....O#..#...O...OO#...O\nOO..#..OO#..#..O..#O..O.O##O#OOO.#...OO.#....#..#....O.####O.##..O......#O..OOO#O.#...#.O...OO...OO#\n#.O.#O.#.#..O.#.............#.#.OO......#.O.O##O###........#.....#.....#.....O.O.OO.O....O.......O.#\nO#...#...........#..OO...O..#.....#...O.#.......O#.....##O#.OO##.......#..O......#..O..O.#O.#.#..O.#\nOO...O##..O.#.......O#.........OO#..O..#O..#OO.O........#.O.O.O....OO#...#.#.#O...##O.#OO.#.....#..O\n#OO...O...O...O....O...............O.#O..OO##O##O.....#.##...OO.O.#.##.##.O..#..#.O..#.#..O.........\n.O..O.#...##..#.#OO....#.O#...OO#.......O..OO.#...OO##..O..O...O.O...O.#.O#.....O..OO.O.#.OO..#.##..\n...OO.O.O.O#....#...O...#....OO.#O.#O..O.OO..OOO.O....#O.#...#.O#.O............#......O.O....#OO##.#\n...#O......#O#..O....#.##..O.O.O#..#O.#O...O...#..#O..##.O#..O#....O##.O.#OOO.#........O##.OO.O..OO#\n#OOO....#O...O.O....O.......O...O..#....##.#..#.O#O#.O#....#.#.#O#....#.#.....##.#O..OOO....#.O.....\n#OO.O...#O.O....O..#..O.#....#....O#..O...##..#..OO#.....#O.O#O..O....#OO....##OO....#...OOOO.OO###.\nO..#..O#.O.#..OO.#.OO...O..O......#........#O......O.OO.#....#..O#O.......OO##O..##OOOO.#.#OOO.....O\n...#OO.#OO.O.##.O#.OO#...#..#.O##O#...#.#O...#.....#..O..O....O.OO.O.#..O.#.O...#.O#..O....O.#...O#.\n#....O.....O.O...#..O....#..O..O.OO...#....O..O...#.....#...#....O.#.OO...OO#...O....#O.O..O.OO.O..O\n..O#.....#O#....#.....OOO.#.......OO.O..#.#....#O......O.#.O.#..O...#.O...O..O.##O.O#O..#.O......#.#\n....#O#.#..O#.OO.#.#.O.#......#OO...O#OO.........OOO..##...#..##O#..OOO...O..O..O##O...#..#.O.O..#..\n..O#.O.......OOO..##..#...#....#.#..#O.OO..O..##..OO#.O...O..#OO...##O.#O..OO.....#O..#.....#O.....#\n...OO.O.#.O.O..##O#...OO...##.O..OOO##.O.O.#..#.OO..O...O.#....O.O.....O##.#O.O.O#.#.......OO#......\nO...#.O...O...#..OO...O..#..#........O...#...#......O#.#.....O.#.........#.#......O#O.O.........#...\n.......O#...#...........O.#O#.O#.#.O.O..O..OO.#......##.OO..#......OO#....#O#OO.O.#..O#..O.OO..O..##\n.O.....O.#.........O...O...O...O...OOOO..O....OO....#.#....O#.#..#.OO.OO....#.......#...#OO.....O.OO\nO....OO....O..O.OO.###..O##.OO.#......O.O...##...#O...O..O...##.O.O...O....O.#OO.....O.....O.O.OO.OO\n#O......OO....##..O..###.O....#.#.#.OO.............O.O.OOOO#.O.O..#O...O#..O......O.O.O.#.#.......O.\nO#O.....#...#..O#.#....#..###..O..O...#....O....##.....#...O#.#.O.O......O..OOOOO....OO..#...#.OO#..\n..O........OO....##...#O.....#.O.....O#.O..#.O.#.O......O#...OOO....O...#..OO....O..#...O.O..##.....\nO...O..O.O....O.OO.O.OO..OO...#O...O.#.O..#O...#...#...O..##...#...OO#.....##..O#O.O....#.....OO#..O\n...O#O..O..##.OO.......#.#O...O..#.#...#.O.#O##OOO.OOO...#.....O....##.....OOO.....O..O.O#.O....O...\nO#..#O.O....#.........O#.OO#...OO......#......O.#...............O##OO.....O.....O.O..##..O#....#.OO.\n#O..O.OO....##O......O.O...O#O..#.O..........O....#........O#.#..O..O............#..#...OO#.###..#.#\n...#...#.#O....O.O.....OO.O.O...O.#.#.O...OO..O#....O#O......O.O..##.#.O.....#..O.O.#.#O...O.#......\n.O...O#.O.......O.#....O.#...#.#..#O.....#..#..#.#O#..#.......O..#.#..O.OO.#OO.OOO..O....#.....OO#.O\nO#.#..#.O..O..#O.......O.#..#....#.O..#...#......O...O##....O..#...O....#O..#.....OO.O.O#..O.#..#O..\n#.#.....O...#O.#..O...#O..##..#O..#O...O.#OO...#....OO#..O.#O#O........OOO...O##..#..OO.O.O.O.O.....\n..OO...#..OOO.O#..#...O..O.......O.#.#.O#.##OO....#..O....#..#.O.#O...O.O#O........O#OOOO#.#..O#.#..\n.O....#.O#OOO.....O.#O............O...O#...O...O..O.#..O.O.....O#.O....O......O...O.O..OOO..O.##.O..\n#...#........#..........###.O....OO.#.....#OOOO.OO#.OO...##...OO...O#.......O...#.#..#O..#.....#O#O.\nO.O.#...O.#.....OO...O.O#......#........#..O...O..O.#..OO#.....#...O.##O#....O#..O#...##.O.O.#.#....\n............OO.....O........##O.O...#..#.O.#...OO..#.O.#O.............O..#O.....#...O.#....O..O#..#.\n.#..#.O.#......O..O##O.O.#..O..#O.O..O.O........O.......#.#.#O.#..O...O...O....O.O#...#..OO..O....OO\n#..#..O....OO#.#.O.#......O...O.O#O...O#...O...#...#O.#....#..#O...O...........#.#.#..O##..#........\n..O......O.#.OO.#O...O..#O...OO.#.....##...#.#....O....OO.#O.O.#....OO..#....#.#...#.O.....OO#..O...\n#..........#...O.O....##....OO..O..O..#...#..###....##..O#..#.........#.....O#...#.#.......#.##.##O.\n###.O.#..#.O.O.O..O..O...O...#O...O##.#..#O..O...#....O.....#..##......OO.#O...O#..O.O.O......#...OO\n....O#........O.O#.O#O#...O.......#..O.#..#........O.....O#..O..O.OOO....OO.....#....O#.#..O.....##.\n#.#O...#.O#O..#.#OOOO#.......#....O...O#.##.O....#..O.......O.##.#.OO...O...#O..O..#O.#......O.O.##.\n.#O...OO#......O...#..##............O...##...O.#O....#..OO......O.O##OO..OO....##O.##..O............\nO.O..OO.O.#.#....#..O.O.O.OOO...OO..#....O....O.#.#....#.O#.#.....O#O...O.OO..O.#O.#..OO#.O#........\n#..#.O.##.##...#OO..O...OOOO#O##..#...#.##....#O.#O#.O.O#.#.O#...#.OO.......O........O..#.#.OOO#....\n##....O...O#....O...O.#OO.O..O.....O#O#.#...OO.........#.......O.#.#..O..#O...#..O.#...#.##...O..O.O\n.........O...O.O...#..O.O..OO.#...O.#.O........O.O.O....O...O..O..........O....O......O..#O.O..#O...\n.......#.#....O#OOO.O.O..O.##...O..###.......O#.##...O.O....#.OOO..O...#.#.......#O.OO...O...OO.O...\n.O...O...O....#.O.#...#..##O....#..O....O#..O.#.O..#...........#..O..##OO.......##..#.....O#...O#..#\n...O....O....#....O..####.#O#.....#O.O..#..#O.OO...#...O.##.#.#....#...O...O..#.....OO.O....#..O..O.\n.OO#.#...#....O.#O#.##....OO............O.....#.OO#O.#O.#..#...#.O....O.O..#..##.......O..O.#..##O.O\nO...#.........#.O....O..O.....#.......#.OO...OO.#O#.#...OOO.O.O#.O.#...#O......#....O.......#.O.#.O.\n.....O.............O.#..#.#..#.#...#..OOO....#.OO.O...O..#.##O.#O...O.O.OO......#....OO..O..........\nO....#....#.#....#.........#...O.O#....OO.#..#O..#....OO...#....O...O#...O.......OOO...#......#...#O\n..O..##O.#O.OOO..#..O.#....#.OOOO..O.O.....##O.....O.#.O.###..##....O..OOOO..#.#OO.O.OO.#O#..#...#.O\nO#...O......#..#.....#..##.#OO#O#.....O...##....OO...O##...O....O.#...#O..#.O#..#O.O..#...#...OOO..O\nO...##.O..O..O#....#..O........O....O#...O..O......O...OO...OO.#OO.O..#....O#O....O..#..#..OO.OO....\nO..#.#O....O..O.O..O#...O.O...O..#.#.#..##.#O......#...OOO.#O...#..O.....O###O.....#.......O#.O.O...\nOOO#..#.#...O...O..O.O..O#O.....#O.#..O....O...O.#..O.#...O#.......#.....#O.#.#..O...##..#.....O...O\nO#...O#....O.#.#......O.....O.##.......#.O.......#.#.#...#..#O....##O......O..O.#.#..O..#..O.O#O.O..\nO.O...O##.O#.....O......#...O.#...O.O..#........O..O..O#.O..OO#O.OO.........O...O..#.O......O...O#.O\n..#......OO.#....O...O..O..##...#O#O#O..O..O......O..O.#O#..O......O..........OO..OOO#..#.OO....O...\n.......##......#.O..#....#.O#O..O#...O#....O.OOOO..#.O.O..O..O..O.........O...O#...O..#O..#.#..O...O\n.O#..OOOO.O......#O......OOO#.#.O.#O...##...O.O...##.O#.O.#.......#.......##...#O.O...#.#..O..##O..O\n....OO......#.#.....O.#.OOO.O#.#...O.##.O..OO....#OO..O..O.O.O#..OO....O.O..#.O.##..O...OO..OO..OO#.\n........#O.....#....O#.#OOO.O...........OO....#.#.....OO#..#OO..#..#.....O#O..OO..OO..O......#..O.O.\nO#O....#.#......O#...#.##O..OO.O.....#O..#..O..O......O##..#OO...OOOO.....O#....O..O.....OOO...#O..O\n...O..#..O......OO.#.....#.O...O.O.#.O..OO..#....#...#....O.#O.O...O.O......O......O..#...#O###.OO..\n#O###.....#....#.#O..#...#O..OO....#.O...#.##OO.#.#.#.....#....O.###...#....#.#...O.......O...O..#.O\n..#..O.O..#.........O#..OOOO###..O##.#........O...#.#O#..#...O...O#....O..#.#...O.O..OO.....O.......\n#...O..#.......O........O....#.O......#...##.##......O.....O.##.O..O.....##...#OOO..O...O##.O.O.....\n......#.OO....###.......#.###..OO#.OOO#O#.OOO#..O....OO........#...O...O#.OO.#....O#.......#..#..#..\n#..#OOO....#.#.O.O..........#O....O#...O..O..#...O....O#..##.O..O.#O...#.#.#..O..O.O.#O..O..O...#.#.\n.#...O.O##.....#..O.....OOO.#.....#OOO#.#..O.....O.#.O.O.#.#.O.O#.........O....#...#O.O##.##..O.O#.O\nOOO...#O.OO....#.OOO..O....O.OO.O.#.O.#.#...#....OO........O..#..OO....#O....#.#O##.OO#O#.##OO.O.O.#\n...O#..OO.....O#...#O........O....O#O....OO...#....O###..##.O..#..#.#..O..#O.OO..O........##O#.#..OO\n.O...#..#....O.##...#.........##.#..O.O.....#.##..O.#O.#..O#...#....#.#.........##.O...O...OO#..O..#\nO....##.O...O........O#..#...OO#O..OO..#.........##......O.......OO..O...O.O..#..........#.O..#...O.\n###.#.........#OO....##...O#...O....O........#...#.O.#O.#.....##..O..#O.##......#.#.O.......O...O...\n..#.OOOO..O......O#O.O.#.O.#..#.O...O..O.O..##O.O.......#...O#..#..O.#.#.O#.##...O......#.#...#.....\nO.#.OOO.#......O....O..O...O#........#....#.......#O..O.OO..#.O#.OO..#.OOO..#O.....#OOOO..#.........\n##.O...####OO#...O#.OO...O...O.......O...OO..####...OOOO..O##O....OOO....#..O.O........O....#.#.#O..\nO.O....O...O#...O.#....O.....OO#O#OO..O##.O..O...O.#.....#O...O..#O...O#.....O##...O.OO...#.........\n....#OO..OO..#O#......O#.O..#O..#..OO..#....#.....#.....O.O..O#....O.O..O.#..O#O###O....O...OO...#.#\n#..OO.##O..OO.O..O...#....O.....##O..#............##.O.#...O.#O..#O..#...#...O.O....#O.....O.....O..\n..O#..#...##.#.#.O#.OOO.O#.#....OO.#....#...#...#.....#O.....O..O...O.....#.O.O.O#...#O.#...##.O..O#\n#....#.O...O#...##O.#....O........O...O#.#.#...#O#..O..O.#O.....O..O....#....O.O#O#....#O#..#......#\n.O.O#.........O.....##.O.#..............O...#.#OOO.O.OO..O..O..O##....#.......OO....O....#OO#..OO...\n##.O#...OO...O.O...........O..O.##O..#.#...#..O..#.##....#..###O..##........OOO.#.O.#......#......#.\n#......O#..O#.#.#..#O##..OO#O...##O.#...#.OO...#.O..O##O.O...........O.##...###O..#.#.O.O..OO.O..O..\n#.....#.##.O.O.#....O..#O......O.O#...#..O.#O#OO...#.OO...O.O##.O...O.......#...##....#O.....O.##O#.\n...O.OO.O...O#..OO.O....#.#.O....O...#..#O.O..OO.#....O.O#.O#..O..O...O..O........#..#..#..#..OO.O#.\n.#O.O....#....#.OO.#.O...O......O....O#.....##...#O...##...#.#OO..O#O..O##.#.#..O...O.....#..O##.O..\nOOO....OOOO...#.#...#.....###...O......O.#.O.....O...#.O##...##O.#.#...O....O.O...#.O...#O....O.....\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_14_questions.txt",
    "content": "--- Day 14: Parabolic Reflector Dish ---\n\nYou reach the place where all of the mirrors were pointing: a massive parabolic reflector dish attached to the side of another large mountain.\n\nThe dish is made up of many small mirrors, but while the mirrors themselves are roughly in the shape of a parabolic reflector dish, each individual mirror seems to be pointing in slightly the wrong direction. If the dish is meant to focus light, all it's doing right now is sending it in a vague direction.\n\nThis system must be what provides the energy for the lava!\nIf you focus the reflector dish, maybe you can go where it's pointing and use the light to fix the lava production.\n\nUpon closer inspection, the individual mirrors each appear to be connected via an elaborate system of ropes and pulleys to a large metal platform below the dish.\nThe platform is covered in large rocks of various shapes.\nDepending on their position, the weight of the rocks deforms the platform, and the shape of the platform controls which ropes move and ultimately the focus of the dish.\n\nIn short: if you move the rocks, you can focus the dish.\nThe platform even has a control panel on the side that lets you tilt it in one of four directions!\nThe rounded rocks (O) will roll when the platform is tilted, while the cube-shaped rocks (#) will stay in place.\nYou note the positions of all of the empty spaces (.) and rocks (your puzzle input).\nFor example:\n\nO....#....\nO.OO#....#\n.....##...\nOO.#O....O\n.O.....O#.\nO.#..O.#.#\n..O..#O..O\n.......O..\n#....###..\n#OO..#....\n\nStart by tilting the lever so all of the rocks will slide north as far as they will go:\n\nOOOO.#.O..\nOO..#....#\nOO..O##..O\nO..#.OO...\n........#.\n..#....#.#\n..O..#.O.O\n..O.......\n#....###..\n#....#....\n\nYou notice that the support beams along the north side of the platform are damaged;\nto ensure the platform doesn't collapse, you should calculate the total load on the north support beams.\n\nThe amount of load caused by a single rounded rock (O) is equal to the number of rows from the rock to the south edge of the platform, including the row the rock is on. (Cube-shaped rocks (#) don't contribute to load.) So, the amount of load caused by each rock in each row is as follows:\n\nOOOO.#.O.. 10\nOO..#....#  9\nOO..O##..O  8\nO..#.OO...  7\n........#.  6\n..#....#.#  5\n..O..#.O.O  4\n..O.......  3\n#....###..  2\n#....#....  1\n\nThe total load is the sum of the load caused by all of the rounded rocks.\nIn this example, the total load is 136.\n\nTilt the platform so that the rounded rocks all roll north.\nAfterward, what is the total load on the north support beams?\n\n--- Part Two ---\n\nThe parabolic reflector dish deforms, but not in a way that focuses the beam.\nTo do that, you'll need to move the rocks to the edges of the platform.\nFortunately, a button on the side of the control panel labeled \"spin cycle\" attempts to do just that!\n\nEach cycle tilts the platform four times so that the rounded rocks roll north, then west, then south, then east.\nAfter each tilt, the rounded rocks roll as far as they can before the platform tilts in the next direction.\nAfter one cycle, the platform will have finished rolling the rounded rocks in those four directions in that order.\n\nHere's what happens in the example above after each of the first few cycles:\n\nAfter 1 cycle:\n.....#....\n....#...O#\n...OO##...\n.OO#......\n.....OOO#.\n.O#...O#.#\n....O#....\n......OOOO\n#...O###..\n#..OO#....\n\nAfter 2 cycles:\n.....#....\n....#...O#\n.....##...\n..O#......\n.....OOO#.\n.O#...O#.#\n....O#...O\n.......OOO\n#..OO###..\n#.OOO#...O\n\nAfter 3 cycles:\n.....#....\n....#...O#\n.....##...\n..O#......\n.....OOO#.\n.O#...O#.#\n....O#...O\n.......OOO\n#...O###.O\n#.OOO#...O\n\nThis process should work if you leave it running long enough, but you're still worried about the north support beams.\nTo make sure they'll survive for a while, you need to calculate the total load on the north support beams after 1000000000 cycles.\n\nIn the above example, after 1000000000 cycles, the total load on the north support beams is 64.\n\nRun the spin cycle for 1000000000 cycles.\nAfterward, what is the total load on the north support beams?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_15.adb",
    "content": "--  Solution to Advent of Code 2023, Day 15\n-------------------------------------------\n--  Lens Library\n--\n--  https://adventofcode.com/2023/day/15\n--  Copy of questions in: aoc_2023_15_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_15 is\n\n  use AoC_Toolbox, HAT;\n\n  function HASH (s : VString) return Natural is\n    h : Natural := 0;\n  begin\n    for i in 1 .. Length (s) loop\n      h := ((h + Ord (Element (s, i))) * 17) rem 256;\n    end loop;\n    return h;\n  end HASH;\n\n  r : array (Part_Type) of Integer;\n  data : VString;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2023_15\";\n  --\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    Get_Line (f, data);\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    c : Character;\n    s : VString;\n  begin\n    r (part_1) := 0;\n    for i in 1 .. Length (data) loop\n      c := Element (data, i);\n      if  c = ',' then\n        r (part_1) := r (part_1) + HASH (s);\n        s := Null_VString;\n      else\n        s := s & c;\n      end if;\n    end loop;\n    r (part_1) := r (part_1) + HASH (s);\n  end Do_Part_1;\n\n  verbosity : constant Natural := 0;  --  0, 1, 2\n\n  procedure Do_Part_2 is\n    --  On our data, there are 4000 rules, 530 distinct labels and\n    --  239 used boxes, so there is an average of ~2.22 labels per box.\n    --  Consequently, we choose a rigid array structure for storing\n    --  lenses. We would use a linked list if there were much longer\n    --  sequences per box.\n\n    type Lens_Type is record\n      label        : VString;\n      focal_length : Positive;\n    end record;\n\n    type Slot_Array_Type is array (1 .. 5) of Lens_Type;\n\n    type Box_Type is record\n      slot  : Slot_Array_Type;\n      slots : Natural;\n      used  : Boolean;  --  For statistics in verbose mode: has had slots > 0 at least once.\n    end record;\n\n    box : array (0 .. 255) of Box_Type;\n    --  Just for statistics in verbose mode:\n    rules      : Natural := 0;\n    used_boxes : Natural;\n    used_slots : Natural;\n\n    rule : VString;\n\n    procedure Process is\n      c : Character;\n      lens : Lens_Type;\n      i : Positive := 1;\n      b : Natural;\n      found : Boolean;\n    begin\n      rules := rules + 1;\n      lens.label := Null_VString;\n      loop\n        c := Element (rule, i);\n        exit when c not in 'a' .. 'z';\n        lens.label := lens.label & c;\n        i := i + 1;\n      end loop;\n      b := HASH (lens.label);\n      if c = '-' then\n        found := False;\n        for s in 1 .. box (b).slots loop\n          if box (b).slot (s).label = lens.label then\n            found := True;\n            for t in s .. box (b).slots - 1 loop\n              box (b).slot (t) := box (b).slot (t + 1);\n            end loop;\n            box (b).slots := box (b).slots - 1;\n            --  Lens with label was removed, we can safely leave the loop.\n            exit;\n          end if;\n        end loop;\n        if verbosity > 1 then\n          if found then\n            Put_Line (\"Removed\");\n          else\n            Put_Line (\"Nothing to remove\");\n          end if;\n        end if;\n      else\n        --  \"=n\" case.\n        lens.focal_length := Integer_Value (Slice (rule, i + 1, Length (rule)));\n        found := False;\n        for s in 1 .. box (b).slots loop\n          if box (b).slot (s).label = lens.label then\n            found := True;\n            box (b).slot (s).focal_length := lens.focal_length;\n          end if;\n        end loop;\n        if found then\n          if verbosity > 1 then\n            Put_Line (\"Replaced\");\n          end if;\n        else\n          if verbosity > 1 then\n            Put_Line (\"Added\");\n          end if;\n          --  Append new lens.\n          box (b).slots := box (b).slots + 1;\n          box (b).slot (box (b).slots) := lens;\n          box (b).used := True;\n        end if;\n      end if;\n    end Process;\n\n    c : Character;\n\n  begin\n    for b in box'Range loop\n      box (b).slots := 0;\n      box (b).used  := False;\n    end loop;\n    for i in 1 .. Length (data) loop\n      c := Element (data, i);\n      if  c = ',' then\n        Process;\n        rule := Null_VString;\n      else\n        rule := rule & c;\n      end if;\n    end loop;\n    Process;\n\n    if verbosity > 0 then\n      used_boxes := 0;\n      used_slots := 0;\n      for b in box'Range loop\n        if box (b).used then\n          used_boxes := used_boxes + 1;\n          used_slots := used_slots + box (b).slots;\n        end if;\n      end loop;\n      Put_Line (+\"Rules: \" & rules);\n      Put_Line (+\"Boxes used: \" & used_boxes);\n      Put_Line (+\"Slots used (distinct keys) on final state: \" & used_slots);\n    end if;\n\n    r (part_2) := 0;\n    for b in box'Range loop\n      for s in 1 .. box (b).slots loop\n        r (part_2) := r (part_2) +\n          --  \"focusing power\":\n          (1 + b) * s * box (b).slot (s).focal_length;\n      end loop;\n    end loop;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 513172\n    --  Part 2: validated by AoC: 237806\n  end if;\nend AoC_2023_15;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_15.txt",
    "content": "kzb=5,zzvx-,bdld=7,qprd-,zf=1,cb-,jplf=7,kcgf=6,fpllc=6,jmvh=2,xdz-,zxxf-,qjzd-,rk=8,xjqkf=6,rq-,plx=3,kr-,lrpgnl=8,clgs-,hf-,dlk-,kjndtt-,rp-,lk=5,cbgx=1,trfd=7,sc=5,zxxf=5,qbb=2,gpq=9,pvl-,dxd=1,nlptg=2,xm-,vhb=6,drj=4,gslt=6,clx-,sclb-,pgc=2,gqp-,blq=3,dsssjs-,ffv=5,zvlc-,xpvr-,xz=5,trjxl-,nsnx=8,rlfkx-,vk-,bq=3,dff-,qcg-,qzz-,sclb-,zp-,tf-,thq=4,kptg-,qtqhll-,fr=7,hz=3,pz=4,bvvs=9,bv=9,cbq=4,sshzn-,bbp=5,bqx-,nvf-,pjh=5,jkds=4,nbvb-,zdt-,psn=7,cbntnn=3,vcqxm=2,ss=4,plh=3,bbp=2,rq-,kh=7,txcvg-,cc=4,ngv-,kt=7,xczxrm-,qk=3,pptx=1,khx=3,xzs=2,vcz-,kptg-,gvl=3,zd-,mc-,skq-,dq=3,pj=2,ssm-,znl=1,svvs=8,lp=5,rrq=1,mvxp=7,pll=1,kbvgv=3,cnp-,kd-,xk=9,ljzpb-,xff=8,czf-,npqjbg-,fx=8,bb-,xff=1,pptx=3,xbhx-,pl=2,zlt=8,kjndtt-,nbdt=5,kp=3,xltd=5,dxd=4,fv=3,nqdb=7,fj=8,jspg-,hdh-,ffv-,kp=8,vrjr=8,hlh-,pjx-,dxd=8,frg=4,xph-,gsfc=4,hlk=9,pl=9,jvtfs-,xtrn=7,rs=6,rxs-,bt=7,hs-,tgr=9,qcl-,kn-,pvx-,kzb-,qcg=6,blq=7,fdh-,ccd-,ljnrz-,sg=8,ft=7,ph-,nmsc=5,gn-,mn-,rvjg-,rlfkx-,xpcm-,lk-,mfs-,kqg=9,bxn=8,llrs=7,pll=4,xvz=6,blknq=2,kx=7,bnfgrx=7,qf=1,gx-,chlqr=9,ngv=3,cssn-,jzbx=2,rq=9,bgt=6,nzs-,cnp-,dq-,ntt=8,gvl=5,zp-,svvs=5,tf-,trfd=9,mr=1,pjx=6,tx=6,zgt-,js-,xbz-,kvr=9,cbgx-,pvl=2,qz=7,nsr-,vjzjnn-,qfx-,tvfx=1,hz=6,tx=5,gvxmb=9,jqt-,rfk=1,ssm=2,ss=9,tpdq-,bb-,hlk=8,qd-,dlk=4,kdgrc-,prb-,dcsn=5,mbpn-,hm=5,mpc=8,tn=7,xxmdx=8,hdh=3,nqdb-,dsssjs=7,brdh-,klz=9,jpx-,hv=9,frnx=2,hh=5,jmvh-,ps=2,mng=2,xz-,ljm-,znl-,cc=4,qjzd=1,ht-,zb-,cl=4,jkds-,hz=4,cc-,ld-,dzz-,tl-,dg-,qprd=5,nlttf=8,mnkkl-,tzp-,ksq-,xllc-,xjqkf-,dthkz-,rh=9,xd=6,jpx=5,dthkz-,xzs=2,xpz-,zdv=4,jggftj-,dghgvv=3,zlr=3,gtbfk=8,rd=6,sv-,qcg=1,pmqcz-,fsbtv-,rp=6,hmvnp=1,tkj=3,nsr=6,bvvs=2,jxqr=1,tvgf=2,gfx=7,ngv=7,xff=1,qmh=7,xxmgh-,xb=9,rq-,sc=9,kl=4,tl=8,szb=1,lzmk-,kkt-,tc=1,nzk=4,xkmfp=9,zhjlhc=8,cssn-,gp=2,xm=7,lrpgnl-,xkp=4,ftf-,dghgvv-,tc-,xgsl-,plx-,rrq-,qcl=4,tcx=3,xxmdx=6,gkj-,rcv-,zxxf-,gz-,qz-,fblp=2,mj=8,rf-,nf=4,ss-,zm-,kn-,jpk=2,vxzj-,czz=5,jmk-,rp-,fb-,pvx=2,zgg-,dt-,jmvh-,rd=2,jkds=1,dzz=3,xjsxmj=9,rsjt-,dthkz-,rs-,kqg=1,qzz=2,cbntnn=8,nlttf=8,nj=2,jgjl=1,fv=1,nq-,sg-,tzp=6,rfk=1,fpllc-,tx=1,mng-,rd=5,pz=9,js-,ljzpb=3,gd-,qkcjt=4,jdfq-,jxqr=3,rlm=1,gsq-,dghgvv=2,fpllc=4,rvjg=8,hlh=2,bj=6,rtc-,qcg=3,nb-,dm=8,xbhx-,sdv=5,vlq-,nnjs-,nbdt=2,kjp=4,lxcf=1,ffv=5,zgg-,rq=3,zm-,bzcq-,nff-,bgt=6,hb-,rp=9,bq=5,hst-,jvtfs-,clx=7,hf-,gjz-,lrpgnl=8,gncb=6,xxb-,jzgh-,rmkm=8,bnfgrx-,ksh=6,zbbb-,nhh-,vfvj-,xdp=2,jmk-,txcvg=2,fsbtv=4,nhp-,nzk=7,fsbtv=2,jb=5,jfr-,jpx-,xjxx=3,km=6,qzlpc-,ljm-,tc=6,llrs=8,bln=2,tl=8,rrq-,vfvj-,vjzjnn=8,pvl=9,jtf=3,fj=2,rd-,jrm-,jtf-,hq-,nnjs-,fr=6,nzs-,xp=7,jbt-,lk-,vxzj-,gjz=6,gsfc-,dthkz=1,thq=3,vhb=7,vzj=3,qf=5,mm-,kknx-,nj-,bzz=3,vd=2,tcx=3,fxz=7,ds-,mvl=7,rvq-,czf=6,lmj-,xkp-,ksh=4,gkj-,hv-,vcqxm=1,tnbz-,jspg=3,xxmdx=6,sf-,gqtb-,rsjt=1,rth-,zvlc-,fxz=5,cgplp=6,zhjlhc=4,hmp-,dghgvv-,zm=2,jzgh=9,ntt-,nlttf=7,zf-,ztbmk=2,kqb=5,vrtgm=7,ksh=3,bv-,rvm-,nlttf=5,kcgf-,ts-,sclb-,fdh=7,gfbcgk-,fpllc-,jplf-,hz-,zbbb-,brdh-,zb=7,pj=6,hm-,mnkkl=4,hlk-,kjndtt-,pdz=2,qk=1,pmqcz=9,xpcm=7,rd-,cxbjsc-,xff-,rvq-,qs=7,nbvb=1,lp=2,cmn=1,dsssjs-,ght=2,npj-,nbn=5,rp-,jpx-,cn-,mnkkl=9,bjsq-,kn=2,gslt=7,tvfx=5,mhd-,dm=1,rckh-,rnx=4,lr-,gvjd=6,xbz-,kl=4,jn-,gfx=1,rh=9,hp=7,zf=1,gvl=8,gmnmd-,zgt=6,xm-,rvq-,gpq-,gq-,qf=8,qjzd=5,zrf=5,qs=1,fqg=8,gd-,tvgf-,nff=5,zf=4,xgsl=4,xkp-,jdfq=2,ftcs=8,gvjd=1,xgzfv=8,rnx=9,skq=5,bch=5,kcgf=9,qk=7,sk-,clg-,xh=5,hh-,bfv=8,kkn=7,ftf=8,sc=3,qzlpc-,nbn=9,sl-,lcs-,zcj-,ph-,zdt-,xph-,zxxf-,jzgh=5,tvgf=5,xnrqz=7,nj=5,tzp=1,mpx=4,pz-,sshzn-,fqg=1,xdvm=7,skq-,qcg-,rsjt=5,hqdgdx-,fz=9,mrx=7,lr-,rnx=9,hc-,skq-,gkj=5,jb-,bvvs=2,tx-,qh=4,ll=6,ssd-,dq=2,hh-,pjx-,kqg-,ftcs-,bsp-,nqdb-,zgg-,mpc=8,pmqcz-,kjp=8,gslt=8,rckh=6,fqg-,zp=2,zlt-,ljm=8,gz-,tvfx-,txcvg=1,rvjg-,xm=6,htsz-,ccd=7,ck-,hc=7,pvx=1,rp-,ftf-,kkt=5,qmh=2,vn=8,trc=1,vcqxm=9,hb-,hq-,gvjd-,kvr-,fdh=2,qprd=6,nq-,ffv=2,ld=2,thf=9,xzs=2,ssm=4,trjxl=2,qcg=6,hst-,hjn=7,cc-,xkmfp=7,pn=8,vn-,nlttf-,mhd-,tkj-,mnkkl=9,zlt=2,mr=1,xxb-,dsssjs=5,clg=8,jspg=8,qknkv=9,nzs=2,mpc-,jtf-,jq=9,kv-,nhh=7,bsp=5,xk-,gmnmd=9,mc=1,mnkkl-,gn-,jt=7,qjzd=7,cc-,xl=2,bjsq=2,qr=2,svvs-,zvdgs=6,pvl=3,pvcq-,sbplc-,nbdt-,hh-,rsjt-,dcg-,dxh-,dlk=5,tn=3,tgr-,clg=2,kkt-,hv=7,nxr-,jvtfs-,hddp=5,hs-,lr=6,lmj-,mrx=2,fj=2,rr=6,ksh=9,sg=3,xpz-,hmp-,tgr-,zl=9,rrq-,fv-,hdh-,czz-,plh-,jk=3,qzz=9,gjx-,xdvm=5,jmrx-,tzp-,qfg=8,clg-,blknq=6,plh=6,bmmhfl=5,gk-,rq=7,qgh=5,ph=7,qs-,ll-,ss=5,vjsv=2,kvr=7,xtrn=9,tkj-,brdh-,lnx-,hdh=8,frh=5,fblp=9,pptx=9,rtb=9,tpdq=6,jqt=5,ljnrz-,hh-,rsjt=8,nsr=9,dxh-,ck-,bldd-,jkqqkc=1,qtqhll=2,czf=7,ts-,bgt=6,hh-,qk-,ccd-,gvxmb=2,lnx=8,zdv=7,jggftj-,gvjd=3,hlk=8,vjzjnn-,nmsc-,jqt=1,gvjd-,hz-,vnnpcp-,svd=5,gqp-,xbl=8,rghth-,dm-,nmsc-,mbp=9,frg=1,xs-,frnx=1,sf-,xkqjv-,kkt-,sk-,vhb-,ljdr=1,zlr=2,jgs-,hh=4,zhjlhc=2,gd-,rr-,tx-,rtsm=3,lzmk-,gfx-,sv-,ttjs=3,pgc=5,vhb=5,xpz-,jcvt-,mmqxv=2,vjsv-,xzs=1,gsq-,mm=4,fx=7,jb-,xvz-,brdh=2,mbp-,rvq-,brdh-,gd-,gg-,bjq=1,pks-,tc-,cmn-,qfq-,btxb=5,nqdb=4,kkn-,zrf-,zgg=7,rr-,gjx-,bqpn-,rvjg-,bzc-,ksh=6,jrm-,qkcjt=7,xgzfv-,zvlc-,fblp-,qs=6,lp=3,pptx=2,cbgx=1,gjz=7,xgzfv=3,cl=3,bvvs-,vbl-,zs=7,tj-,hs-,vlq=2,kjp=1,qz-,tkj-,jmvh-,xxmgh=7,xh=3,hf-,kzb=2,hp=3,nsg=4,tx-,kqg-,dg=4,rd-,gsq=4,bjsq-,rsjt-,nsnx=4,sshzn=7,lrpgnl=4,vk=8,qjzd=7,kx=2,zxxf=7,hddp=4,kkn-,xkmfp-,hs-,brdh-,jt-,qs=9,xpvr=5,sckkk=2,hmp=1,mmqxv-,ljm=6,tl-,sk-,hc=3,jxqr=4,dq=5,kl-,xbl-,npj=2,fzg-,jk=1,zdv-,xxmdx=6,jt-,zhjlhc-,trc=1,qhdn-,kzb=9,rghth=3,mhnjv=3,rs-,pll-,blq=2,dff-,pvcq=5,ft-,tvfx=6,kqqcsn-,bxn-,ssm=9,sr=8,sg-,dg=4,rfk=7,nnp-,xm-,ts=7,xgzfv=1,sz-,mvxp-,rx-,trfd-,ljzpb=6,jggftj=7,tsj=5,ltsl=3,rqnbh-,zzvx=2,rxs=6,bt-,xgsl=2,tgr-,vmz=2,ltsl=6,rf-,zbbb-,pn=4,jpk=4,bt=4,xjqkf=1,pks=5,xr-,mbpn=6,jkqqkc=2,fdh-,zh=3,ts=8,zgt-,qsc-,dxd=3,cfczf=7,bq-,xxb-,rs-,cssn-,lmj=8,bvvs-,hh-,jzbx=3,pfk-,nsg-,rtb-,rr=6,fv=7,jxqr=2,qsg=6,pz-,pfk-,btp-,dxd=8,nzs=2,splpbg-,qfq-,plh=2,pgc=7,xxmgh=2,njj-,bxn=4,nff=4,bb=3,vn=7,bzc=5,jxqr=2,llrs=3,zm=7,lxcf-,xb=5,kzs=8,xr-,bch=4,ght=7,rx=1,blq-,pmqcz-,kv-,nzs-,xh-,blknq=7,gzgqz=3,cl=7,xpz-,kqg-,zpb=4,zdv=3,trc-,vhb-,czf-,pl-,zv-,txcvg=5,jq-,ss=1,ccd=2,fblp-,rk=9,rq=7,qkcjt=1,tj=6,kt-,qfx=2,bgt=6,pps-,hh-,lls-,zzvx=4,brdh-,dlk-,rr=1,cfczf=1,gvxmb=8,trfd=2,qmpx=7,rfk-,tf-,hg=1,nnjs-,vzj-,qcg-,hmp-,nbn=5,rcv=1,hf-,ttjs-,nff=7,zd-,tv-,npj=3,ght-,pvl-,fdh=1,pps=5,xkqjv-,sz=4,xpvr=6,hqdgdx=1,qkcjt=7,vgb-,jplf=9,zxxf-,zd-,blq=3,xxb-,qk-,mr-,dxd=5,bsp=1,ffv-,mpc-,kv=7,tn=3,vplj=3,pjx=3,cpn=7,fv=5,ph=1,pgc-,vb-,nq-,cc=8,zvlc=5,fr-,gvxmb-,lbmz=9,blq-,gsq=1,nvf=8,jmvh=4,xzm-,xvz-,vrjr-,qtqhll=1,xqb=1,rsjt=3,rxs=4,gmnmd=3,jcvt-,zm=8,pvl=5,lrpgnl=1,gp=8,xtrn-,trfd-,fktrxp-,jn-,fj=7,kknx-,hf-,kdgrc=5,vxzj=6,dff-,gk-,tnbz-,gvl-,kx=5,sb=1,vrjr=2,bqx=2,bfv-,fqg=5,kvr-,dq-,gzgqz=5,pfk=7,rqnbh=8,xktvp=7,pqxlsr-,sc-,fr-,jq-,qf=2,splpbg=7,znl=9,nzk=2,jgs-,vb=9,trjxl-,qzz-,trfd-,zvdgs=1,tnbz-,pll-,xd=1,xvz=8,nmsc=8,ds=2,bqpn=6,ftcs-,kcgf=9,xqb=5,pptx-,lr=1,nq-,xm-,mvl-,qh=5,qsc=6,dzz-,xk=4,klz-,pps=5,tnbz-,zv-,mvxp-,lcs-,hlh-,km-,bq-,lmj=1,nzs-,tjg=2,vj=7,vj-,sclb-,tv=5,lbd-,khx-,jpk-,rk=1,tpdq=3,nvf-,rtc-,xd-,mhnjv=7,xph-,xdz=3,kvr-,dmz=1,xpz-,fpllc=8,cmn=5,sr=2,fktrxp-,gqp-,cnp-,dvrg=7,tvfx=6,ssd=3,rxs=6,bx-,gmnmd=6,hs=4,gjx=9,tzp=9,qbb-,plh=3,hdg=3,nbdt=2,jpx-,skq-,ztbmk=9,bjq=7,cn=9,fv=8,rr=5,gg=2,mt=5,hlk=6,mfs=8,rf=5,btp=2,zh-,dc-,sdv-,hf-,rx=6,kzs-,kl=4,mvl-,sz-,fxz=7,mnkkl=3,zdv-,ts=9,lp-,klz-,rqgb=9,llrs-,rq-,kqb=8,pr-,vcqxm=9,rrq=8,tv=9,dmz-,bdld-,ft=9,zdt=8,fpllc-,hlh=3,bch=7,vrjr-,zxxf=4,xs-,zdt=3,cssn=8,trc=4,ttjs=8,hz-,ztbmk=7,svvs=3,rf=9,gslf-,kdgrc-,gf=4,zgg-,xjxx=4,jcvt=4,lrpgnl-,zxxf=8,lqptdz=9,skq=2,ccd=7,vlq-,dmz-,xl-,fpllc-,rh=3,dcsn=4,xb-,gslt-,hmp-,qsc=4,qprd=3,cmn-,dc-,jfr-,sb=9,sb-,zpb-,vbl=5,xltd=8,hq-,sr=8,nsnx=8,rckh-,sz=8,nvf-,vd-,qzz=2,nbvb-,rnx=5,ksh=7,gkj=6,jzbx-,pl=4,gfbcgk=6,sshzn=5,tpdq=7,nkbtq-,ds-,bln-,ph=2,bgt=5,blknq-,sk=8,qhdn=9,tv-,jplf-,rk=3,pptx=3,cc=7,pvx=5,kr=3,gsfc=9,pfk=9,pfk=5,rvm=5,lcs=7,khx-,vcqxm=2,ph=7,frg-,nlttf-,xnrqz=3,rs-,qsc=9,sr-,qjzd=6,jmk-,qtqhll=4,frnx=8,plh=6,fj-,bb=8,fzg-,clx-,ph-,mr=9,tjg=1,zv-,kvr-,frnx-,xjqkf=1,pll-,mbpn=2,qd=8,svd=6,hm-,mt=1,zpb-,xkqjv-,rtb-,nkbtq=7,fqg=3,qprd=8,kqqcsn-,jspg-,dmdp-,qfx=3,rs-,xjxx=1,xzm-,vbl-,kzb=6,gg=9,tgr=7,zxxf=3,jkds=8,fqg-,mrx=9,dmdp=5,qp=5,kr=2,gtbfk=2,bgt=9,bch=7,nxr-,qk-,bgt=3,jk-,cl=7,pmqcz-,xktvp-,mhm-,gx=1,mvl=9,tsj=6,nq=5,zhjlhc-,jtf-,qk=4,zlt=2,zhjlhc=7,qz-,mhd=8,qzlpc=5,xzm-,vrtgm-,zgg=2,rtb=7,nhp-,dff-,bgt=6,cp-,xxmgh-,dk-,jpx=4,vcz-,ps=4,tvfx-,mmqxv=8,sg=7,jcvt=6,dk=5,dff=3,nhp=5,ssm=8,xbl=5,mvl=3,gvl-,qf=9,nqdb=6,gk=1,sf=6,bqx=6,fr-,svvs-,gqp-,hjn=7,sdv-,xgsl-,spm=6,qjzd=2,rd=4,xb=5,btxb-,fblp=5,jzgh=7,fv=3,mhm=7,xz=8,jggftj=9,ft-,zlt=9,kg=1,mh=1,xgsl=7,bsp-,vd=8,bbp=8,rrq=4,dt-,ksq-,vplj=1,lls=4,lp=7,tjg-,nbdt-,hddp=6,mvl-,ngv=1,gfbcgk-,xph-,kptg=9,tx-,nsnx=2,sr=2,tvgf-,rvq-,sclb=9,bfv=9,pr-,rtc=2,mmqxv-,dcsn-,rghth=7,fr=1,bsp-,nhp-,ltsl-,plh=2,xdvm=1,hq-,pps=7,sclb-,xvz=4,gqtb-,ght=4,vgb-,xh-,nnjs-,vplj-,kkn=3,psn=2,jt=3,xb=2,fdh-,splpbg=1,pvl-,mbp-,pj=4,qk=1,ffv-,qz-,tsj=3,dxh=5,zh-,xtrn=5,frh=1,ffv-,mfs=1,fr=7,ssd-,rnx=8,btxb-,vbl-,kzs-,mhd=9,qs-,dghgvv-,cbgx=5,cl=6,lls=3,zp-,ttjs-,ssm=2,sb-,zmd=7,tn-,npqjbg-,vxzj=9,vmz-,pps-,lls-,zlr=1,bln=4,kvr-,zh-,zb-,hp=2,cbntnn=3,hf=6,jspg=7,bzcq=4,jzbx-,kd-,vn=6,cbgx-,kd=5,skq-,xp-,rr=3,lls-,npj-,xr-,vhb-,sckkk-,gpq=2,kknx-,spm-,ht=3,dxd-,pqxlsr-,sc-,hddp-,pps-,vrtgm-,mng=4,cc-,gvl=2,tz-,drj-,hqdgdx=2,thf=5,hv=1,nlttf-,kt-,xgsl-,pps=6,ht-,rx=5,xd-,qm=4,nq-,ntt-,gsfc=2,fk-,mfs=4,nkbtq=3,cmn-,clx=7,btxb-,nlttf-,zlt-,fqg=9,zlt=6,rsjt-,xczxrm=4,sdv=8,dm-,plx=5,gsfc-,xm-,nmsc-,nnp-,vjzjnn=8,gkj-,hjn-,kp-,rc=7,vjsv-,jzbx-,dmdp-,cbgx-,vn=2,nxr=5,xph=2,kt-,khx-,rc-,qsg=2,pll-,gqp=1,xkmfp=3,rc-,jrvc=5,zzvx-,qcl-,st=5,vlq-,bmmhfl-,rnx-,rfk=5,vk=7,jrm=1,qh-,pps=8,ld=7,xph-,dff-,jt-,tkj-,nlptg-,tkj=6,xkmfp-,dv=8,gncb-,rvjg-,hs=9,hdg=7,lk=2,ftf-,cp-,rr-,zgg=4,htsz=4,xff-,gqp=3,rcv-,ll-,dxh=8,sv=6,psn=6,chlqr-,kl=2,gz=3,jdfq-,hqdgdx=6,sk=1,mvl-,qp=8,xqb=5,dg-,jgs=4,gg=3,bxn=1,cfczf-,nzs=2,xllc-,rfk-,zv=6,zgg=3,xdp=2,jspg-,tvgf-,rk=3,sshzn-,mmqxv=6,ljzpb-,rrq-,kqb-,tgr=6,nhp=1,tv-,xbhx-,xltd=9,sbplc-,xqb-,nsg-,pdz=8,lzmk-,rmbn-,qsg-,cssn=9,xbl=3,hs-,mgdmqf-,vplj=5,jb=9,zgt-,ksh-,nhp-,kqqcsn=1,vk-,jnth=3,kn-,jzgh=1,qcl=5,tj-,jrvc=8,bzz-,xjxx-,kqb-,gf=8,rlfkx=9,mng=8,gz-,kkt-,rxs-,qr=8,rqgb=8,bfv-,xkqjv=5,hz-,fv=6,kd-,cp=3,pdz=4,zzvx=4,gzgqz=4,ksh-,btxb-,kcgf=2,xdp-,xd=6,zgg=4,ftcs=3,vgb=8,nsr=3,vk-,ltsl-,nhp=3,gtbfk-,nqdb-,gmnmd=6,nsnx=2,frh-,mhm-,mm-,txcvg=7,blknq=7,qknkv=2,mbpn-,dcg=6,pqxlsr=5,qzlpc-,cxbjsc=6,rqgb=9,bjq=3,zpb=9,kzb=2,ck=1,ljdr-,nnp-,dg=8,qcl=7,xktvp=4,zlr-,mldh=3,bv-,clg-,kqg-,ds=6,xktvp-,tjjbp-,vbl=4,npqjbg=1,brdh=1,xm-,nzk-,zdt-,jtf=5,ljdr=4,frnx-,js=7,xxmdx-,bsp-,dm-,sc-,hp-,lr=4,rq=2,kzb=8,jxqr-,tv=2,vfvj=3,qknkv-,jbt-,rvq-,zvlc-,pdz=6,dk=1,pdz-,pvx-,pg-,hb-,ll=7,zxxf-,ttsz=8,szb-,ht-,qf=3,rmbn=7,ltsl=9,btxb-,qtqhll=6,zl-,gn=1,cgplp-,xnrqz=7,mm=6,xjxx=5,rmbn-,cbq=6,ftf-,nqdb=6,xk-,dmz-,mvxp-,rsjt-,dghgvv=6,gqtb=3,xxmdx-,vrjr-,hg-,mhd-,pvl=5,nnp-,qzlpc=4,xzm=3,mfs=7,kcgf-,kkt-,rvq=6,tkj=1,qkcjt-,zvlc=1,rnq=1,vjzjnn=8,sv=5,zpb-,xbhx-,jgs=9,drj=2,zv=8,ll-,jpx=2,pjx-,frnx=6,lk=1,xh=9,sz-,brdh=3,bsp=8,ljm-,tkj=3,npj-,tc=7,rs=3,rvm=1,zf=3,xxmdx-,xzm=4,gvjd-,rx=1,ntt-,dvrg-,gslt=4,bjq=6,nmsc=5,kn-,ntt-,qh=1,rth=5,vgb=8,fb=1,xl=2,jtf-,hjn-,vplj=3,gx=5,vcz=5,fktrxp=4,bln-,pptx=3,gqp=3,xbhx-,rmkm-,klz=1,nvf-,ts=4,thf=2,jkqqkc=5,mhm=8,hddp-,frnx-,bmmhfl=5,dm-,jqt-,nnjs-,lk=4,bx-,zxxf-,fr-,mrx=1,mgdmqf-,jk-,zd=5,cc-,dghgvv=1,qknkv=4,ksh-,bb-,qkcjt=8,xkqjv-,zmd=4,llrs-,kknx-,qknkv=2,kg-,zgg-,ftf-,pvl-,skq-,fsbtv-,nbvb-,clgs=1,hmp-,qs=1,dcsn-,mpc-,sl=2,sl-,mfs-,fxz=2,fdh=5,zjb-,jk-,vjsv=9,js-,rnx-,qkcjt=3,fzg=5,gtbfk=5,xm=2,cpn-,tx=1,cb-,zlr-,hq-,mpc=8,thq-,gq=8,hc=1,hst=4,jpk-,ztbmk=3,kp-,tl-,fktrxp-,dlk=8,bqpn=2,gsks=1,lmj-,tkj=1,jqt-,gzgqz-,ds-,blq-,frh=1,ght-,pl-,nj=1,rsjt-,dmdp=6,vlq-,hjn=6,skq=9,rvq-,bqpn-,zlr=1,nsr-,mrx-,qhdn=3,mvl=1,zmd-,jzgh=1,tnbz-,nj=7,svd=6,xbz-,vfvj-,dq=8,gz-,pvcq-,xtrn=5,svvs=4,pks-,klz=2,trjxl=9,rp-,rvjg=3,rvq=2,ftcs-,cbq-,dmz-,rnx-,hg=5,zmd=2,ljm=7,bv=2,qknkv=3,svvs=1,kdgrc=5,vjzjnn-,gn=4,gjz-,vplj-,jt-,dm-,qzlpc=3,rh=3,psn=3,qb=6,rqgb-,dvrg=3,mlb-,cl-,kjp-,rq=3,nnjs-,pg=7,jrvc=6,cnp-,kqb-,bj-,gfx-,zvlc-,dmdp-,blz=7,jfr=8,trfd-,ld=6,mfs=9,jggftj=7,mhnjv-,bq=6,vk=1,xgsl-,kptg=8,pj=1,ht=5,dsssjs-,qf-,thq=8,xkmfp-,lqptdz-,kqb-,fdh=4,fsbtv-,cxbjsc=1,qhdn-,nf-,js=4,gjz=3,rs=4,qsg-,kbvgv-,psn-,jmrx-,kr-,xbhx-,fpllc=7,svvs-,blq-,jzbx-,kqqcsn-,tv-,xph=3,cbntnn-,tvgf=1,lmj-,zdv-,cbq-,xk=9,hz=5,ht=2,dthkz-,dcg-,zxxf=7,xjsxmj=2,bln-,fktrxp=7,sv=1,txcvg-,kx=4,bqpn=6,nhh-,cgplp-,pgc-,zgt-,gqtb-,sbplc=1,nzs-,zbbb=5,jzgh-,gvl=6,hjn-,tv-,xkp=2,rr-,jfr-,rxs=9,mnkkl=1,tsj-,pfk=6,zgg=8,fx-,zvdgs-,vj=6,pn-,jggftj-,vjsv=1,mr=6,pfk-,jzgh-,trc-,nsg=3,tjg-,kbvgv=6,ssd=9,ljdr=8,htsz-,clx=1,xdvm=5,kzs=8,sr=2,xkqjv=4,mm=2,btp-,qb=4,xgsl=7,hdh=5,cxbjsc=7,kx-,pptx=2,pjh-,hlh=6,cc=9,jvtfs-,sclb-,kvr=5,kv-,jt=7,jplf=3,klz-,frg-,jmrx=1,vplj=2,pgc=3,zxxf-,ltdl-,pgc=6,qcg-,txcvg=9,sz=3,kvr-,mpx=3,rc=4,xqb-,nb=1,bqpn=3,xxb-,dcg=3,fb=2,kg-,gvl-,cbq=3,czf=1,rvm-,ffv=8,pps=5,ttjs=2,mn=6,jtf-,tjjbp=4,jtf-,szb=3,gk-,vxzj-,bv-,nq=9,rk=3,kzs=2,lnx-,ljm-,tnbz=7,bzcq-,bdld-,zpb-,xjsxmj=8,zcj-,nqdb=6,mxd=6,pvl-,hf=2,blz=2,cbgx=8,gq=5,ps-,pptx-,mh=9,xpvr=2,ttjs=7,fqg-,kqb=5,pl-,jrvc=8,hlh-,vhb-,xvz-,trfd-,zjb=6,gt-,jq=3,bgt=5,jkds=5,fz-,xqb-,fblp-,skq-,tcx=6,hb=7,rp=6,jpk=8,vk=5,gmnmd-,jt-,jbt-,zbbb=3,kqqcsn=1,vbl=9,bj=7,fj=3,gjx=8,vjzjnn-,zm-,vk=1,bjq=1,xgzfv=9,mfs-,hc=5,kg=7,xff-,hb=4,bzz-,jfr=3,sb-,qjzd-,khx=3,ttsz=4,qcg=4,sb-,xm=5,hv-,rvm-,rrq=7,tvfx-,dff=3,bbp-,zgt=5,ht-,nbvb=2,dmdp=4,sg=5,nlptg-,vcqxm-,dvrg=7,dff-,vjsv=4,ll-,bqx-,vcqxm=7,kkt=1,hf-,pks-,xdvm=2,ph-,nq=1,nf=2,pz-,nhp-,rvjg-,tzp=7,dt-,nfppt=4,xqb-,zzvx=8,vcqxm-,bx=7,xh=2,mhm=7,xp-,ljnrz=6,cn=1,blq-,qgh-,gvl-,sbplc=7,pps=5,bj=8,gf-,mc-,xgzfv=8,rk=3,lqptdz=2,bq=3,dv=8,zd=9,mnkkl-,jnth-,jplf=5,kv=4,gjz-,kknx-,dkpn=7,fqg-,zpb-,gzgqz=6,mh=3,tgr-,kr-,qr=4,mpx=9,jnth=7,qp=9,plh-,nqdb-,gsks=3,cb=4,xczxrm-,vjzjnn-,nbdt=5,svvs-,sshzn-,dcg-,lnx-,qmh=5,jx=2,mlb=5,rxs-,ght=9,xgsl-,mpx=5,kg-,czf=7,js-,gt=7,sr=9,rh=3,ll-,kv-,dthkz=8,ztbmk=5,dghgvv-,ttsz-,zgt-,dcsn-,cp-,mxd=5,jgjl=3,pj-,lnx-,jgjl-,vnnpcp-,czz=2,tj-,nf=2,htsz-,rvjg-,ds=5,xxmgh=9,cfczf=1,gvl=1,dsssjs-,fj-,jxqr-,kr=5,qd=8,znl=1,ngv-,mvxp=3,gk-,nqdb=3,kd-,cpn-,mxd-,drj-,blz-,xllc-,rcv=3,bx=7,cl-,kptg-,zvdgs=2,znl=9,kg-,hst-,zjb-,blz=3,dk-,tnbz=6,ds-,dff=2,pfk-,fx-,kr-,jzbx=7,ht=4,gx-,jn=4,hddp-,zhjlhc=1,xjqkf-,vbl=7,jspg=9,lbd-,mhm-,trjxl=2,pqxlsr=5,bfv=6,xb=8,ccd=9,rckh=5,xr-,kptg-,jcvt=9,jzgh-,skq-,mgdmqf=7,mlb=7,js=1,lnx-,hmvnp=4,dcsn-,kn-,jxqr-,nbn=6,vnnpcp=6,nsr-,lxcf-,jdfq=5,vrtgm-,sshzn-,vlq=1,mt-,gmnmd-,kzs-,gvjd-,blz-,zl=1,zm=1,qcl=9,kn-,zd=3,hf-,rqgb=8,tf=6,mbp=2,vj-,pz-,hv-,jx=6,xkqjv-,sc=6,xxmdx-,rlfkx-,ph-,cgplp=3,zjb-,xzm-,qmh=6,thq=8,fx=3,mm=5,nbn-,ld-,mlb=6,lbd-,xktvp=6,nsnx-,ds=5,nsnx=8,jspg-,nsr=7,kr-,bvvs-,zrf-,nzs-,xff-,nnp-,kbvgv=2,mbp-,vcz=7,rfk-,rghth=7,rxs-,js=7,tf=9,jggftj=3,kh-,fb=4,xczxrm-,nsnx=5,lnx-,mm-,kjp=9,nnp-,ksg-,qz-,dm=1,vhb=2,gzgqz-,fr-,vjzjnn=2,tkj=1,tcx-,hb=8,mhb=8,rnq=5,bb-,vfvj=4,xs=8,zs=3,pvx-,sshzn-,fqg-,nq-,bzh-,clg=4,fr-,bfv-,frnx=5,xpz-,rk=2,htsz-,km-,xkp-,ld-,hf=4,fz=8,dk=4,rfk=9,cbgx-,ck=7,kr-,mldh-,fzg-,qknkv-,ld=1,gqp-,fqg=8,qhdn-,rs=8,dzz-,xltd=3,mmqxv-,ftf=8,tvgf-,dmz-,zb=3,lmj-,rr-,pvcq=4,vplj=8,zl=7,frnx=9,bvvs=1,czz-,dthkz=8,htsz=5,fj-,mbp=7,vrjr=2,jfr-,bqx-,qbb=9,kdgrc-,bjsq-,gvjd=9,tz=3,ll=9,nnjs=3,kn-,ffv-,jfr-,nlptg-,tl-,rk=9,thf-,gncb=9,xdvm=8,qzz=9,zpb-,tpdq=3,hlh=1,xbhx-,xczxrm=6,lls=3,ksq-,fk-,ft=4,gncb-,nmsc-,vzj=7,nb=5,hg=6,tvgf=7,cn=6,mbp=6,nb=1,cgplp-,pqxlsr=6,prb=7,cbq-,rckh=3,rrq=8,rlm=9,mccv-,vhb-,ttsz=1,km-,hb-,thq=7,jgs-,nb=2,lr-,sclb=8,lk=7,ltdl=7,rsjt=2,rs=4,dzz=1,qtqhll-,bx-,jmk=3,dxh-,fsbtv-,ksg=1,rghth=5,gjx=9,bqx=7,xgsl-,nbdt=8,jvtfs-,sv=3,ksg=9,dcg=6,zjb=2,vrtgm=7,svvs=2,xk=4,gd=7,mc-,qhdn=4,kknx=1,tsj=3,xvz-,rth-,pqxlsr=2,jq-,qsc-,jkds=7,bsp=6,ph-,zvdgs=9,splpbg-,rfk=8,hddp-,zv-,ht-,vd-,cssn=6,bvvs-,kx=3,xpz=2,npj-,jfr-,rc=4,trc=5,gslf=2,kd-,dvrg-,rckh=2,kbvgv=4,jzgh=6,nd=5,zlt=8,sf-,zcj=1,bdld-,zlt-,vrjr-,dlk-,zgg=2,cl=7,bq=5,kcgf=8,zvdgs=5,ntt=3,dzz-,hc=9,pr=7,tx=9,khx-,pz-,xzm=4,sg-,mbp=3,nhh=8,sv-,qgh=4,nd=4,nlttf-,mfs=3,rnx-,thf-,zvlc-,xxmdx-,gvjd=3,qd-,kdgrc-,gslt-,fpllc-,qmpx-,cgplp=8,rvm=7,mpx-,bzh=8,jvtfs=7,zdv=2,vcqxm=2,mnkkl=8,hp=8,xllc=9,hst=7,gslf=7,jgjl-,jdfq=2,jvtfs=8,plx-,lk=5,jnth=9,bdld=1,hqdgdx-,rp=8,kx=8,pgc=5,gslf=4,qtqhll=1,mbp-,xktvp=4,jpk-,ssm=4,ljm-,hv=1,kqg=4,mgdmqf=1,mpc=4,lxcf=9,jmvh=3,rh=7,km-,zxxf-,hm-,jmrx-,nxr-,bzc=9,cxbjsc-,vgb-,bqx=3,tnbz=1,jrvc=3,qzlpc-,mn=6,sg=1,dk=3,szb-,lr=2,jvtfs-,kkt=8,ljnrz=4,nvf-,vb=4,ljm=4,cp=7,czf-,sshzn-,nmsc=5,kzb=5,bgt-,hqdgdx=9,htsz-,rp-,xkmfp=5,gpq=2,hq-,zpb-,vplj-,hb=3,klz=3,cb=5,xdvm=1,cc=7,vbl=2,dg=1,rk-,bzh=1,szb=6,xxmdx-,tnbz=2,pl-,rq=1,zxxf=7,tl=9,gvxmb-,qfg-,qmh-,bvvs=2,xxmdx-,cc=2,sg-,dg-,rckh=6,hdh=6,nb=1,nbn-,zlt-,rrq-,htsz-,nfppt=3,jrm-,rtsm-,lzmk=3,fr=9,lk-,tn-,dthkz-,gfx=4,rmbn-,gmnmd=3,hh-,mc-,vbl-,prb-,tf-,blz=2,rghth=4,rghth=9,hlh=9,txcvg-,mr-,gvxmb-,kvr=9,zh-,dcsn-,znl-,sg-,qzlpc=5,rtsm-,bj-,tpdq-,tz-,qd=9,rnq-,czf=5,skq=3,bnfgrx-,vlq=9,jpx=1,gzgqz=2,fdh=7,cn=6,xk=8,qzz-,zl=2,fr-,fktrxp=9,hv-,js-,pjx=9,pptx=4,bjq-,dzz-,zcj=4,xph=2,rmbn=2,psn-,zf=9,tl=7,xh=4,blq=3,pks-,rh=2,dg=4,mj-,gsq-,kx=1,kptg=6,lqptdz=3,cpn-,xxmgh=8,kjndtt=3,jxqr-,rvjg=1,frg=3,qb-,rc=9,xllc=8,fdh-,nsnx=5,kptg-,gsks-,pvl=8,ghdhl-,ghdhl=3,ksh-,jqt=8,nzk-,bzz=8,splpbg=1,qknkv-,cssn=9,mt-,sb-,sg-,nnjs=8,dk=2,fz=8,xpvr=2,dzz=9,qk=1,qh-,dxd=2,bbp-,prb=1,pptx=5,svvs-,xjsxmj=8,ht-,rckh-,rqgb-,kbvgv=9,ds=7,rrq=7,hh=8,jtf-,zlt-,nlptg-,ngv=5,jkqqkc=8,pz=7,kkt=2,zb-,bldd-,xpz=6,dc-,bgt-,rk=5,nd=1,zb=3,rc=4,vj=2,jdfq-,ztbmk-,frg=1,vfvj=9,st=2,mpc-,hst-,mrx=5,qknkv-,ksq-,jdfq-,tn-,bch=6,mvl=4,bjq=9,ksh=5,kx=8,jt-,szb=9,nnp=6,xl-,dcsn=7,rx-,jrvc=5,dcg=8,bj-,gmnmd-,ts=4,dlk=7,rq=5,hh=5,zlr=8,vcz=3,xtrn=1,xkqjv-,qjzd-,pz-,chlqr-,rh=1,cl-,xh=4,ljm-,xgzfv=6,kv=5,tn=6,ds=1,gz=2,vgb=4,jn=9,svd-,bdld=3,bch=3,xd=6,sdv-,qzz=8,bvvs-,zgg=1,sc-,xllc=5,jkqqkc=9,frg-,xkmfp=1,kqqcsn=6,xdz=1,xzs-,gpq-,qcg-,pr-,jn=5,mbp-,frnx-,gp=1,kbvgv-,gpq=7,hg-,tn=1,nlttf=3,jrvc-,nxr=1,qhdn-,mldh-,lqptdz=1,jzbx-,tkj=8,lcs=4,pg-,xdp=8,czf-,zlr=5,rfk-,nb-,rk-,sc-,mr=7,kvr=2,dq-,ph=6,hh=2,qgh=7,vcqxm-,hjn=7,mhd=7,bldd-,xdvm-,kjp-,vnnpcp=5,kbvgv=7,sz=9,btxb-,zhjlhc=9,bx-,xbz=3,blknq-,qk-,nhh-,rcv-,zgg-,xvz-,zxxf-,txcvg=7,kqqcsn-,zzvx-,fsbtv=3,nbvb=6,hst=5,qz-,dkpn=3,gz=8,mng=7,pl-,nbdt=3,brdh-,gk=8,tgr-,hf-,pr-,mpx-,vb=4,ftf-,rs-,dxh-,ssd=4,zl=9,hg=3,ztbmk=6,mn-,npj=6,qkcjt=4,zv=3,xjxx-,mpx=9,kh-,dcsn-,xh-,xs=3,kknx-,qfq-,mhm=8,dcg=1,rnx-,gsq=3,xjsxmj=5,nvf-,hmvnp-,ksq-,ksg-,ph=9,st=2,xz-,dg-,sb-,znl=6,bzh=2,dc-,bb-,tz-,zh=4,rxs-,rnv=5,vrjr=5,rqgb=1,kh=4,nqdb=6,qhdn=1,jbt=3,bj-,fzg=6,znl=5,bqpn=8,qtqhll-,dlk=2,qbb-,mpc=2,qsc=5,ljzpb=7,mr=4,hv-,jfr-,jqt-,fktrxp-,qd-,blz-,xpvr=7,psn=9,jzgh=2,xbhx=2,ttjs-,mt-,cbq-,jgs=3,tv-,frnx-,zbbb-,kknx-,rvm=5,ltdl=6,kh=9,mbp-,ssm-,mvl=8,ss-,fblp=6,rth-,qb=1,tz-,mc=3,bln-,fpllc=9,rth=4,skq-,rc-,vlq=5,pdz-,nzs-,kl-,bzc=1,bldd-,jq=8,qmh-,frnx-,vzj=2,dcg=6,dthkz=1,dxh-,rnq=2,rlm=8,clgs=4,rnx-,xs-,lp=3,sf-,fx-,dvrg=8,mlb=1,rfz=9,mm=1,xr=2,fx=6,cpn-,pjx-,xpz=6,xjxx-,jx=4,btp=6,qfq-,kkt-,jplf-,ltsl=3,tcx-,fktrxp-,kp-,jx-,jspg-,bgt-,dxd-,cl-,czf-,cbq=3,xxb-,jzgh=2,zvlc=6,cnp=3,bv=7,gfx-,rd-,zgt=5,xz-,bnfgrx-,pj=9,ck-,zbbb-,jmk=1,kvr-,trc-,vnnpcp=3,kd-,bxn-,pmqcz=1,nmsc-,svd-,kr=9,jxqr-,qz=4,dcg=1,nb-,xnrqz-,fblp-,qd-,rq=4,gz=4,hb=7,skq-,qb=5,dthkz=5,cmn=2,kt-,xktvp-,npj=1,kv=3,mhnjv-,rvjg-,jgs-,jfr-,sk=3,gzgqz=6,cl=2,kqb-,dm-,jzgh-,ntt-,qzz=6,kd=9,xjsxmj-,jkds-,cssn-,rth=7,jx=4,gslf=4,frh=4,xxmdx-,zlt=1,pdz-,zrf-,mvl=7,frg-,kp=9,ftcs=6,zdt-,qs-,cxbjsc=5,hqdgdx-,jpx=3,xdvm=7,trjxl-,nf=3,ftf-,xdz=4,mpc=3,zm-,zzvx=4,pvcq=3,rr=4,mxd=8,fr-,xxmdx-,sc=6,fj-,rtc=3,tpdq-,fb=9,lls=2,czf=9,vnnpcp=6,mvl=9,rsjt-,xqb-,dsssjs=3,kx=3,gvxmb-,gf-,xjxx=9,km-,btxb-,mh=6,vjzjnn=1,czz-,fktrxp-,fxz-,vfvj=2,nmsc=2,dthkz=1,nf-,rq-,gslf=1,nlptg=3,pjx-,bt=5,zgt-,pr-,xjqkf-,jnth-,bq=9,lk-,pvx=5,js=4,zlt-,vcz-,tcx-,pqxlsr-,ht=1,pj=9,dff=7,txcvg-,cp-,xczxrm-,mpx=8,lqptdz=2,pgc=9,cc-,ffv-,xllc-,mh-,pjx=3,ltdl-,gvxmb-,nbdt=4,qf=6,hddp-,khx-,rcv=6,hb-,jzbx-,sclb=2,mrx-,nd=3,njj=8,hg=4,fr-,ksq-,thf-,drj-,nzk-,bdld=1,jn-,gtbfk=5,jpx-,nj=4,mccv-,pps=4,zdt-,ntt-,kl-,mhm-,jkds=2,cb-,dxh-,nqdb=3,jmrx-,lbmz-,splpbg=2,kqb=3,ght-,nzs=5,ffv-,zdt-,tsj=2,gx-,fx=2,mvl=1,rtb=2,sr-,vrtgm-,jbt-,plx-,lls=1,cssn-,mnkkl=8,jt-,nsnx-,bch=9,lqptdz=1,fk=6,zp=3,dq-,jplf=1,mj-,zhjlhc-,frnx-,xqb-,fpllc-,gkj-,khx-,zmd=8,qhdn-,ksq=7,hz=2,nlttf-,gzgqz-,zgg-,jxqr-,mvxp-,xdz-,zd-,ps=2,lbd=2,jggftj=4,nq-,jvtfs=9,tjjbp=4,gz=1,rtc=9,xzs=5,nq=9,dsssjs=1,rmbn-,kptg=8,gfx-,pz-,gncb=6,pj-,jmk-,hf-,rnv-,gqp-,kt-,fr-,ttjs-,fxz=1,jqt=7,zp-,jkds-,mbp=6,vmz-,qzz-,nsr-,xz=9,zrf=4,dlk-,xff=8,jkqqkc-,npqjbg=7,mng-,hv-,bzz=2,mng=2,nq-,bnfgrx-,ssm=6,btp=5,sshzn-,sdv-,rp-,mgdmqf-,nbn-,vrjr-,mvl=1,mmqxv-,zd=7,cc-,cb-,dt-,pfk-,vrtgm=6,kknx=4,vhb-,frnx=7,rqnbh=2,cfczf=5,mc=7,jx-,nxr=9,jx=4,zzvx-,vjzjnn-,nb-,ttjs=4,kjndtt=6,xbl=9,rghth=4,nvf=2,rvq=3,xgzfv=7,mh=8,vbl=5,ngv-,qzlpc=3,pll=3,tkj-,kcgf=8,cp=8,hh-,jkqqkc-,rmbn-,ffv-,psn-,fr=3,btp=8,xdp-,bzc-,kbvgv-,pg=7,rh=7,nzs-,gqtb=1,tkj=3,tj-,lmj=7,kjp=3,xbl=7,ljnrz-,qknkv-,dcg-,xpvr=9,xltd=5,rh-,nmsc=9,xvz-,fx=9,rrq=9,ksg=6,zd-,tcx=1,khx-,dmdp-,mfs-,qfg=5,ght=1,ghdhl=6,qfg-,tvgf-,cnp-,pmqcz-,nsnx=2,qbb=2,rx-,rqgb=7,sf-,qk-,jggftj-,cl-,jmk=9,lk=5,zd-,sckkk=3,xjxx=8,qm=6,bdld-,jpx-,jrm=8,nhh-,zlr=3,rmkm-,jggftj-,gjx-,xxmdx-,xxmgh=2,nzk-,cn=3,jdfq-,vbl-,cssn=5,jrm=4,zgt=5,gvxmb-,ts-,pqxlsr-,jkqqkc=4,sr-,thq-,qgh=1,vjzjnn-,bfv-,hjn-,xllc=9,vn-,gt-,qsg=5,qmh=5,gq=2,bgt-,nbdt=2,kqb-,nb-,hlh=3,sbplc-,bdld=3,bzcq-,zd-,jtf-,st=6,mmqxv=1,dm-,dmz-,rq=9,fzg=2,tnbz=3,jgs-,bq=8,skq=8,vfvj=6,nhp=3,cbgx=8,mhm=7,sdv=4,vmz-,pg-,zbbb-,xllc=6,tnbz=2,qz-,rd-,kv-,zrf-,tnbz=4,gq-,nj=2,mh-,mfs-,trc-,xbl=4,ght=8,vlq=8,hp=8,cbgx=1,clg-,ksq-,bq=7,jrvc-,pqxlsr=3,rf-,skq=8,cpn=1,jqt-,kl=2,nfppt=6,kjp-,cp-,jzgh-,cn=9,xr=8,cbgx=1,kl-,vxzj-,cfczf-,rtb=6,qzz=2,gjz=1,tcx-,rr-,bxn-,sf-,qsg=6,vbl-,fr-,bqx=8,cp-,mhd-,rtb-,vk=2,nsr=9,xp=5,ltsl=6,fb=6,pgc-,zl=5,xdvm-,fz=4,gd=8,sckkk=7,pmqcz-,dvrg-,dq-,hmvnp-,trc-,xkmfp=8,mccv-,dxh-,thf-,cgplp-,xvz=3,dk-,sv=9,jqt=3,kd=2,xd-,pdz=9,bsp-,trjxl=3,ftf-,rp-,nzs-,ftcs=2,sckkk-,mrx=7,prb-,ccd=9,pn=8,fdh=7,gfx=7,jtf=7,cc=6,chlqr-,rfz-,gtbfk=7,bvvs=8,qgh=8,psn-,nlptg-,ts=6,jvtfs=1,dlk-,qf=4,qmh=6,thf-,pfk-,rxs-,jnth=1,zrf-,mm-,xm-,rth-,xzm=1,rx-,lrpgnl=4,cxbjsc-,xbl-,gtbfk=1,rs-,gz-,vzj-,fr-,dmz=3,pvx-,spm=2,xdp-,vbl-,xjqkf-,xnrqz=7,ttsz-,qz=8,gjx=9,fqg=7,tpdq=3,gg=2,lrpgnl=9,pvcq-,xbhx=3,gt=2,hq=8,mvl-,zmd=9,qzz=1,zl-,mc-,pvcq-,nff-,nhp-,blq-,lxcf=6,ck-,cbntnn-,zm-,xpz=1,jcvt-,plx=5,rth-,xllc=6,ph=7,cfczf=1,xl=6,mldh=3,rnv-,ssd=2,xnrqz-,npj-,nhh=4,lxcf-,qknkv=9,qm-,km=6,fx=2,sk=4,dvrg-,pptx-,bt=4,zgt-,mbpn=6,nff-,frg-,vgb=6,nlptg-,nj-,thq-,xdz-,ttsz-,xd-,gfx-,mhd-,ccd-,fx-,vrjr-,jfr=1,dm=8,xnrqz-,ksh-,gtbfk=8,gslt=3,zv=9,dvrg=1,rs=3,ccd-,plx=4,nsnx=8,prb-,rnq-,dthkz-,gsks=2,sg=7,ljnrz-,gtbfk-,tcx-,jq-,ngv-,rr-,sbplc-,dm=3,dlk-,zvlc-,pr-,rfk=8,xxmgh-,lrpgnl-,kjp-,hst=6,kl-,qsg-,htsz-,ss=5,bv-,rtsm-,gvl=4,jrm=5,bch=4,xff-,tsj-,jqt=3,czf-,hs=2,mccv=1,vd=6,tvgf=7,splpbg=5,rlfkx=7,xzm=5,gncb=8,hdg=8,pg=3,psn=3,hmvnp=6,xdp-,gqp-,lcs-,jrm=6,jmrx=7\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_15_questions.txt",
    "content": "--- Day 15: Lens Library ---\n\nThe newly-focused parabolic reflector dish is sending all of the collected light to a point on the side of yet another mountain - the largest mountain on Lava Island.\nAs you approach the mountain, you find that the light is being collected by the wall of a large facility embedded in the mountainside.\n\nYou find a door under a large sign that says \"Lava Production Facility\" and next to a smaller sign that says \"Danger - Personal Protective Equipment required beyond this point\".\n\nAs you step inside, you are immediately greeted by a somewhat panicked reindeer wearing goggles and a loose-fitting hard hat.\nThe reindeer leads you to a shelf of goggles and hard hats (you quickly find some that fit) and then further into the facility.\nAt one point, you pass a button with a faint snout mark and the label \"PUSH FOR HELP\".\nNo wonder you were loaded into that trebuchet so quickly!\n\nYou pass through a final set of doors surrounded with even more warning signs and into what must be the room that collects all of the light from outside.\nAs you admire the large assortment of lenses available to further focus the light, the reindeer brings you a book titled \"Initialization Manual\".\n\n\"Hello!\", the book cheerfully begins, apparently unaware of the concerned reindeer reading over your shoulder.\n\"This procedure will let you bring the Lava Production Facility online - all without burning or melting anything unintended!\"\n\n\"Before you begin, please be prepared to use the Holiday ASCII String Helper algorithm (appendix 1A).\"\nYou turn to appendix 1A.\nThe reindeer leans closer with interest.\n\nThe HASH algorithm is a way to turn any string of characters into a single number in the range 0 to 255.\nTo run the HASH algorithm on a string, start with a current value of 0.\nThen, for each character in the string starting from the beginning:\n\n    Determine the ASCII code for the current character of the string.\n    Increase the current value by the ASCII code you just determined.\n    Set the current value to itself multiplied by 17.\n    Set the current value to the remainder of dividing itself by 256.\n\nAfter following these steps for each character in the string in order, the current value is the output of the HASH algorithm.\n\nSo, to find the result of running the HASH algorithm on the string HASH:\n\n    The current value starts at 0.\n    The first character is H; its ASCII code is 72.\n    The current value increases to 72.\n    The current value is multiplied by 17 to become 1224.\n    The current value becomes 200 (the remainder of 1224 divided by 256).\n    The next character is A; its ASCII code is 65.\n    The current value increases to 265.\n    The current value is multiplied by 17 to become 4505.\n    The current value becomes 153 (the remainder of 4505 divided by 256).\n    The next character is S; its ASCII code is 83.\n    The current value increases to 236.\n    The current value is multiplied by 17 to become 4012.\n    The current value becomes 172 (the remainder of 4012 divided by 256).\n    The next character is H; its ASCII code is 72.\n    The current value increases to 244.\n    The current value is multiplied by 17 to become 4148.\n    The current value becomes 52 (the remainder of 4148 divided by 256).\n\nSo, the result of running the HASH algorithm on the string HASH is 52.\n\nThe initialization sequence (your puzzle input) is a comma-separated list of steps to start the Lava Production Facility.\nIgnore newline characters when parsing the initialization sequence.\nTo verify that your HASH algorithm is working, the book offers the sum of the result of running the HASH algorithm on each step in the initialization sequence.\n\nFor example:\n\nrn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7\n\nThis initialization sequence specifies 11 individual steps; the result of running the HASH algorithm on each of the steps is as follows:\n\n    rn=1 becomes 30.\n    cm- becomes 253.\n    qp=3 becomes 97.\n    cm=2 becomes 47.\n    qp- becomes 14.\n    pc=4 becomes 180.\n    ot=9 becomes 9.\n    ab=5 becomes 197.\n    pc- becomes 48.\n    pc=6 becomes 214.\n    ot=7 becomes 231.\n\nIn this example, the sum of these results is 1320.\nUnfortunately, the reindeer has stolen the page containing the expected verification number and is currently running around the facility with it excitedly.\n\nRun the HASH algorithm on each step in the initialization sequence.\nWhat is the sum of the results?\n(The initialization sequence is one long line; be careful when copy-pasting it.)\n\n--- Part Two ---\n\nYou convince the reindeer to bring you the page; the page confirms that your HASH algorithm is working.\n\nThe book goes on to describe a series of 256 boxes numbered 0 through 255.\nThe boxes are arranged in a line starting from the point where light enters the facility.\nThe boxes have holes that allow light to pass from one box to the next all the way down the line.\n\n      +-----+  +-----+         +-----+\nLight | Box |  | Box |   ...   | Box |\n----------------------------------------->\n      |  0  |  |  1  |   ...   | 255 |\n      +-----+  +-----+         +-----+\n\nInside each box, there are several lens slots that will keep a lens correctly positioned to focus light passing through the box.\nThe side of each box has a panel that opens to allow you to insert or remove lenses as necessary.\n\nAlong the wall running parallel to the boxes is a large library containing lenses organized by focal length ranging from 1 through 9.\nThe reindeer also brings you a small handheld label printer.\n\nThe book goes on to explain how to perform each step in the initialization sequence, a process it calls the Holiday ASCII String Helper Manual Arrangement Procedure, or HASHMAP for short.\n\nEach step begins with a sequence of letters that indicate the label of the lens on which the step operates.\nThe result of running the HASH algorithm on the label indicates the correct box for that step.\n\nThe label will be immediately followed by a character that indicates the operation to perform: either an equals sign (=) or a dash (-).\n\nIf the operation character is a dash (-), go to the relevant box and remove the lens with the given label if it is present in the box.\nThen, move any remaining lenses as far forward in the box as they can go without changing their order, filling any space made by removing the indicated lens.\n(If no lens in that box has the given label, nothing happens.)\n\nIf the operation character is an equals sign (=), it will be followed by a number indicating the focal length of the lens that needs to go into the relevant box;\nbe sure to use the label maker to mark the lens with the label given in the beginning of the step so you can find it later.\nThere are two possible situations:\n\n    If there is already a lens in the box with the same label, replace the old lens with the new lens:\n      remove the old lens and put the new lens in its place, not moving any other lenses in the box.\n    If there is not already a lens in the box with the same label, add the lens to the box immediately behind any lenses already in the box.\n      Don't move any of the other lenses when you do this.\n      If there aren't any lenses in the box, the new lens goes all the way to the front of the box.\n\nHere is the contents of every box after each step in the example initialization sequence above:\n\nAfter \"rn=1\":\nBox 0: [rn 1]\n\nAfter \"cm-\":\nBox 0: [rn 1]\n\nAfter \"qp=3\":\nBox 0: [rn 1]\nBox 1: [qp 3]\n\nAfter \"cm=2\":\nBox 0: [rn 1] [cm 2]\nBox 1: [qp 3]\n\nAfter \"qp-\":\nBox 0: [rn 1] [cm 2]\n\nAfter \"pc=4\":\nBox 0: [rn 1] [cm 2]\nBox 3: [pc 4]\n\nAfter \"ot=9\":\nBox 0: [rn 1] [cm 2]\nBox 3: [pc 4] [ot 9]\n\nAfter \"ab=5\":\nBox 0: [rn 1] [cm 2]\nBox 3: [pc 4] [ot 9] [ab 5]\n\nAfter \"pc-\":\nBox 0: [rn 1] [cm 2]\nBox 3: [ot 9] [ab 5]\n\nAfter \"pc=6\":\nBox 0: [rn 1] [cm 2]\nBox 3: [ot 9] [ab 5] [pc 6]\n\nAfter \"ot=7\":\nBox 0: [rn 1] [cm 2]\nBox 3: [ot 7] [ab 5] [pc 6]\n\nAll 256 boxes are always present; only the boxes that contain any lenses are shown here.\nWithin each box, lenses are listed from front to back; each lens is shown as its label and focal length in square brackets.\n\nTo confirm that all of the lenses are installed correctly, add up the focusing power of all of the lenses.\nThe focusing power of a single lens is the result of multiplying together:\n\n    One plus the box number of the lens in question.\n    The slot number of the lens within the box: 1 for the first lens, 2 for the second lens, and so on.\n    The focal length of the lens.\n\nAt the end of the above example, the focusing power of each lens is as follows:\n\n    rn: 1 (box 0) * 1 (first slot) * 1 (focal length) = 1\n    cm: 1 (box 0) * 2 (second slot) * 2 (focal length) = 4\n    ot: 4 (box 3) * 1 (first slot) * 7 (focal length) = 28\n    ab: 4 (box 3) * 2 (second slot) * 5 (focal length) = 40\n    pc: 4 (box 3) * 3 (third slot) * 6 (focal length) = 72\n\nSo, the above example ends up with a total focusing power of 145.\n\nWith the help of an over-enthusiastic reindeer in a hard hat, follow the initialization sequence.\nWhat is the focusing power of the resulting lens configuration?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_16.adb",
    "content": "--  Solution to Advent of Code 2023, Day 16\n-------------------------------------------\n--  The Floor Will Be Lava\n--\n--  https://adventofcode.com/2023/day/16\n--  Copy of questions in: aoc_2023_16_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_16 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 10;\n  input_name : constant VString := +\"aoc_2023_16\"; n : constant := 110;\n\n  map : array (1 .. n, 1 .. n) of Character;\n\n  type Tile_Beam is array (Direction) of Boolean;\n\n  clean_tile : Tile_Beam;\n\n  type Beam_Map_Type is array (1 .. n, 1 .. n) of Tile_Beam;\n\n  beam_map, clean_beam_map : Beam_Map_Type;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    for d in Direction loop\n      clean_tile (d) := False;\n    end loop;\n    Open (f, input_name & \".txt\");\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        Get (f, map (i, j));\n        clean_beam_map (i, j) := clean_tile;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show_Beams is\n    ct : Natural;\n  begin\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        ct := 0;\n        for d in Direction loop\n          if beam_map (i, j)(d) then\n            ct := ct + 1;\n          end if;\n        end loop;\n        case ct is\n          when 0 =>\n            Put ('.');  --  No beam\n          when 1 =>\n            for d in Direction loop\n              if beam_map (i, j)(d) then\n                case d is\n                  when north => Put ('^');\n                  when east  => Put ('>');\n                  when south => Put ('v');\n                  when west  => Put ('<');\n                end case;\n              end if;\n            end loop;\n          when 2 =>\n            Put ('2');  --  Beams in two directions\n          when 3 =>\n            Put ('3');  --  Beams in three directions\n          when 4 =>\n            Put ('4');  --  Beams in four directions\n          when others =>\n            null;\n        end case;\n      end loop;\n      New_Line;\n    end loop;\n  end Show_Beams;\n\n  procedure Progress (partial_state_beam_count : out Natural) is\n\n    procedure Offspring (i, j : Positive; d : Direction) is\n    begin\n      case d is\n        when north =>\n          if i > 1 then\n            beam_map (i - 1, j)(d) := True;\n          end if;\n        when east =>\n          if j < n then\n            beam_map (i, j + 1)(d) := True;\n          end if;\n        when south =>\n          if i < n then\n            beam_map (i + 1, j)(d) := True;\n          end if;\n        when west =>\n          if j > 1 then\n            beam_map (i, j - 1)(d) := True;\n          end if;\n      end case;\n    end Offspring;\n\n  begin\n    partial_state_beam_count := 0;\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        for d in Direction loop\n          --  There can be up to four different\n          --  beams through cell (i, j).\n          if beam_map (i, j)(d) then\n            partial_state_beam_count := partial_state_beam_count + 1;\n            --  ^ This count will miss propagation of beams onto cells\n            --    on a row < i or a column < j.\n            --    But on next call to `Progress`, they will be in.\n            case d is\n              when north =>\n                case map (i, j) is\n                  when '/' =>\n                    Offspring (i, j, east);\n                  when '\\' =>\n                    Offspring (i, j, west);\n                  when '-' =>  --  Flat side of a splitter\n                    Offspring (i, j, east);\n                    Offspring (i, j, west);\n                  when others =>\n                    Offspring (i, j, north);\n                end case;\n              when east =>\n                case map (i, j) is\n                  when '/' =>\n                    Offspring (i, j, north);\n                  when '\\' =>\n                    Offspring (i, j, south);\n                  when '|' =>  --  Flat side of a splitter\n                    Offspring (i, j, north);\n                    Offspring (i, j, south);\n                  when others =>\n                    Offspring (i, j, east);\n                end case;\n              when south =>\n                case map (i, j) is\n                  when '/' =>\n                    Offspring (i, j, west);\n                  when '\\' =>\n                    Offspring (i, j, east);\n                  when '-' =>  --  Flat side of a splitter\n                    Offspring (i, j, east);\n                    Offspring (i, j, west);\n                  when others =>\n                    Offspring (i, j, south);\n                end case;\n              when west =>\n                case map (i, j) is\n                  when '/' =>\n                    Offspring (i, j, south);\n                  when '\\' =>\n                    Offspring (i, j, north);\n                  when '|' =>  --  Flat side of a splitter\n                    Offspring (i, j, north);\n                    Offspring (i, j, south);\n                  when others =>\n                    Offspring (i, j, west);\n                end case;\n            end case;\n          end if;\n        end loop;\n      end loop;\n    end loop;\n  end Progress;\n\n  function Energized_Count return Natural is\n    c : Natural := 0;\n    ct : Natural;\n  begin\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n        ct := 0;\n        for d in Direction loop\n          if beam_map (i, j)(d) then\n            ct := 1;\n            exit;\n          end if;\n        end loop;\n        c := c + ct;\n      end loop;\n    end loop;\n    return c;\n  end Energized_Count;\n\n  r : array (Part_Type) of Integer;\n\n  verbose : constant Boolean := False;\n\n  procedure Spread_Beams is\n    bc, old_bc : Natural;\n  begin\n    old_bc := 0;\n    loop\n      Progress (bc);\n      exit when old_bc = bc;\n      old_bc := bc;\n    end loop;\n    if verbose then\n      Show_Beams;\n    end if;\n  end Spread_Beams;\n\n  procedure Do_Part_1 is\n  begin\n    beam_map := clean_beam_map;\n    beam_map (1, 1)(east) := True;\n    Spread_Beams;\n    r (part_1) := Energized_Count;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n  begin\n    r (part_2) := 0;\n    for x in 1 .. n loop\n      for d in Direction loop\n        beam_map := clean_beam_map;\n        case d is\n          when north => beam_map (n, x)(d) := True;\n          when east  => beam_map (x, 1)(d) := True;\n          when south => beam_map (1, x)(d) := True;\n          when west  => beam_map (x, n)(d) := True;\n        end case;\n        Spread_Beams;\n        r (part_2) := Max (r (part_2), Energized_Count);\n      end loop;\n    end loop;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  if not compiler_test_mode then\n    --  HAC is too slow on Part 2, which is basically 440x Part 1,\n    --  with different entrance points and directions.\n    --\n    --  GNAT (fast mode) takes 7 seconds.\n    --  HAC (VM) takes an estimated 7920 seconds, or 2.2 hours\n    --  that is, a factor 1131 !\n    Do_Part_2;\n  end if;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 7996\n    --  Part 2: validated by AoC: 8239\n  end if;\nend AoC_2023_16;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_16.txt",
    "content": "\\........-.........\\................................|..................-.............\\../......-..............\n........|....\\.../...-...............\\.........\\...........-......-.......\\...../.....................-.../...\n.......--.......|.-..-..........................\\....../..../........-............/.........|........|........\n.................................../.........................|....|.....\\............./..........|...../..\\\\..\n.........\\................|..../.........................................-......|........................|....\n.|............-....|.....-.....|...............-.............-....................................\\...........\n...|.....-.|........\\....|....................|....|......-.../..............|.....\\.../......................\n..../.-......|................/.....\\......................................./.........-.....-..............-..\n............|.\\.............|...\\...................|............-|.................|...............\\.........\n..-...............\\............./.......\\......\\....-..........\\.|.....|.........-........\\...................\n...|.................\\./.....\\.......-.........-................\\-.....................\\.............../......\n..................................-.../.........../...|...........................-\\............\\|.\\......../.\n..../.....................|..\\.|............./....|......................\\.........../.\\......................\n......-/.............|-.../.....|...........././..\\...........................\\.......\\..................|...|\n-.........................|.....\\...................|.\\.......|.....//..........|..........|........./.......-\n.......-........../.......\\.........|..../........-.-|....../....../....-......../..-.........................\n..-/.....-..//......./.....|.............-....|............/.........\\....|........|.............\\.....-.....-\n.....-........|.-.|........-.....................-/...\\..................................-.|.-.|.\\.../-.\\.....\n.......................\\....|.|....\\....................-../........................../|-.....................\n..........|.......-.../..\\........................./.....................|\\..................\\......./.-...../\n...............-................................\\............-...../.............\\........-.......\\...........\n.....................\\.......\\......\\..\\......-................................./...../.../...................\n...|......................-.......................|.............-.....-.-...-...|........-.........\\........|.\n.................../-.........../............-.......-\\........|....................|......./..-......|.......\n.../........|...../...................|/.......................|.........../..|........./../.../..........|...\n..|......-.......|./..|../....................-...............|......................../................|.....\n..|.........-............|/..\\....................//.......-.../.....................................-..../...\n............\\............|..\\../................./......\\\\...............|...../-./..........\\................\n...................././/../.|.|......\\................................|..|......|........../.........|./......\n...........|..................-............-.\\................./.................................|...-....\\...\n........-........|................../.................................../........|...........-.|......./......\n..\\..|\\./....\\.-......./........\\..-.....-.|..\\.............|........|.......|...................\\..........\\.\n.|\\\\.......\\......../.......................|...\\...\\......../.............|./....|...........-......\\........\n...\\........\\...../.....||...../.......\\............-.........................\\./..........\\.............-..-.\n......|.|.../....................-..././......|.\\......|../.......|.....|......|................./.-.......\\..\n...........................................-....|............................|..............-.-/....\\.........\n.....|/.../.....\\.......-.........|........................-......\\.......................-....-..............\n..\\..........-............\\..........|.......................-...|....\\.......|............/.......\\.-........\n.......|............................................-...-|........||..\\................./......\\..............\n......-....|................................-...../......\\.........................\\.\\/.....................\\/\n...................\\.................|..|.........|...|................-..\\...................................\n..|........-...../........|....\\|........./.......|-............/.-.........../......../...../.....\\.../......\n../.../...\\..............|..-..............\\./.................-...\\.|.................................../....\n/...-................................................\\............|......|............................|.......\n..................\\\\/\\.......-.............../................./.......|.....\\.-......-\\..-...................\n./......\\-......./...|.....................................|...........................|..........-../.....\\.-\n.................-...-............|................/.......-...............-...|........-........|..|......./.\n......../....-......\\.................\\/..\\..|...........\\\\-.../............/.\\..............|\\..|............\n................|.....|-...../..|....-..........|............................./......./.../.........\\.|....|..\n..-.......-./......................................\\........./..........................................-.....\n........\\....|.........--....-...................................................|..\\|...............\\./../...\n-...\\...........-........................\\.............\\.|.../......|..-...............\\..|...................\n...........\\....-.\\......../...../\\...\\.....|...................................\\..../|......-........-.......\n................|...........\\............../..................\\\\........|-..............|..../....|...........\n/.......|........................|...-......-.....-....|..\\......-....\\-../......\\............................\n.-....../....../.........................../...................................../........-...................\n.....................-..\\.//...............\\/..|.|.../.................../..../.....................|........\\\n.\\........-....................|............................./.........-.-................\\.-.-/.......\\......\n....|.......-....................|.....|.........................../................/.....................-...\n..................-.....-.|....................../../.-...../...\\..........\\...\\-......-...|.......\\...\\......\n......\\...../................./..........\\............................-....|||.../....................../..-..\n\\......\\.\\..............................|...........|...........-..../......../....-..........................\n........||......\\.......\\.\\/....|.../................|....../...........\\...............................\\.....\n.......-\\....|.--......./../.\\............-/\\....../.../.....-...........-\\................|..................\n...............|.......\\...-..//......\\/......................................./................./..../....\\/.\n.............|......../.........../.........\\......|..../.......-................|.....././...................\n..|......./.............................\\....../.........-..../............|...\\.\\..........................\\.\n....-....\\.....................-...........................\\.......\\\\............|.................-...\\..../.\n............./............-........./.........../..\\.............|............................../......-......\n...../...|.../.|......./|.............../\\.....|.............................-...........\\.-.-......\\./.......\n.........|..........................\\...................\\...............|\\......|/...../........../.....-.....\n..-.....\\....-..|........-............\\...-.............../..........|.........|.........\\/.....\\/....-...\\...\n....|.........\\............../..........|..............-|.........-...........|/..-......................\\....\n....|.....-.|..........|..|......../..............|...........|/.....|.............\\.......|...............|..\n.............\\.......\\.................../...................||..........//........................../....././\n............................|.....\\..-|........-..........\\..-......................../......................\\\n.................................\\.....................-..|.......\\/...........................--.............\n....\\........|||...........||..........\\\\./||.........../\\.-./-....\\......./.../............\\.................\n...........................-.....|.............\\.-.........../................\\....../...........\\.......-....\n...-.\\....//.\\....|..............|\\.|..............|.........-.....................................\\..........\n............-..../...............\\...|......|..-...................../.........-........\\.//............\\...|.\n....../..............-..................../..........-..........................|...........\\......../........\n.....|....................|.|...\\.....|........-..............-..-....\\/............../.......................\n............|......-........-............................-|-../.-..............-...../..........\\.........../.\n..|...../.......|....\\.\\.........-./..................\\.......|.......-.|.|...................../.-..|...\\....\n\\.|..................-..|................./....\\.............-...........|...........|/....................../\n..\\............/....../.|.../............./........./..................|.-\\.||.|....|..................-..-...\n.....|....................|..../............/....\\\\\\..../-...\\......./......-.............||..................\n\\......-..-........-..|...............|......../..-............\\........................-.....\\...............\n.............-................\\...........\\..-........-....-....\\...................................|....|.\\..\n/..................................../....\\.-...\\....\\..../.........--.....................|...../............\n...|........./........../....................................................................../..............\n.|-...|........\\..........-/..........-.........-.-..\\.|........./........|........-..........................\n.\\................|../................-...\\.............|.............../.......\\............\\......|.........\n.......|...\\.......\\.............../|.....|.....\\............/.....|..|............................/.....\\....\n..../....../..................\\-...../........|.....\\............................................../..........\n................|.\\..........................-........../..........\\.................|................/.......\n...............\\......-.-....\\.|..\\................................................|-|..-\\..../.../...........\n/.........|..|...........|.........\\......................\\........|............................\\...-..|./....\n......../..../...........|........\\..../.......|............-|...........................|../......|./.......-\n.....................................|./...../.........../.-..../................./..../......................\n/................................./......../.-../-.....\\............../....|......\\..|.......\\.....-..........\n.......-........................................./......|..../.............................-./..|.-...........\n............../..................|....|............-.......-..|./.|.../......-..................|.........../.\n..\\.\\..........................-...............-......../..........\\.......|...../..................|\\.\\......\n.......................|.....\\..-.............\\......|.......-.............................\\.../.............-\n............|........./.............|..........|\\................../..\\....-..\\...\\...........................\n......|.......................\\................./......................-.............|.................../|..-\n........-..\\..-/|-..-......./.............-.............../.......-.....-..-.|./............................/.\n.........|............/....................../..|..-...\\.........../......|........................|....\\..|.\\\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_16_questions.txt",
    "content": "--- Day 16: The Floor Will Be Lava ---\n\nWith the beam of light completely focused somewhere, the reindeer leads you deeper still into the Lava Production Facility.\nAt some point, you realize that the steel facility walls have been replaced with cave, and the doorways are just cave, and the floor is cave, and you're pretty sure this is actually just a giant cave.\n\nFinally, as you approach what must be the heart of the mountain, you see a bright light in a cavern up ahead.\nThere, you discover that the beam of light you so carefully focused is emerging from the cavern wall closest to the facility and pouring all of its energy into a contraption on the opposite side.\n\nUpon closer inspection, the contraption appears to be a flat, two-dimensional square grid containing empty space (.), mirrors (/ and \\), and splitters (| and -).\n\nThe contraption is aligned so that most of the beam bounces around the grid, but each tile on the grid converts some of the beam's light into heat to melt the rock in the cavern.\n\nYou note the layout of the contraption (your puzzle input). For example:\n\n.|...\\....\n|.-.\\.....\n.....|-...\n........|.\n..........\n.........\\\n..../.\\\\..\n.-.-/..|..\n.|....-|.\\\n..//.|....\n\nThe beam enters in the top-left corner from the left and heading to the right. Then, its behavior depends on what it encounters as it moves:\n\n    If the beam encounters empty space (.), it continues in the same direction.\n    If the beam encounters a mirror (/ or \\), the beam is reflected 90 degrees depending on the angle of the mirror.\n      For instance, a rightward-moving beam that encounters a / mirror would continue upward in the mirror's column, while a rightward-moving beam that encounters a \\ mirror would continue downward from the mirror's column.\n    If the beam encounters the pointy end of a splitter (| or -), the beam passes through the splitter as if the splitter were empty space.\n      For instance, a rightward-moving beam that encounters a - splitter would continue in the same direction.\n    If the beam encounters the flat side of a splitter (| or -), the beam is split into two beams going in each of the two directions the splitter's pointy ends are pointing.\n      For instance, a rightward-moving beam that encounters a | splitter would split into two beams: one that continues upward from the splitter's column and one that continues downward from the splitter's column.\n\nBeams do not interact with other beams; a tile can have many beams passing through it at the same time.\nA tile is energized if that tile has at least one beam pass through it, reflect in it, or split in it.\n\nIn the above example, here is how the beam of light bounces around the contraption:\n\n>|<<<\\....\n|v-.\\^....\n.v...|->>>\n.v...v^.|.\n.v...v^...\n.v...v^..\\\n.v../2\\\\..\n<->-/vv|..\n.|<<<2-|.\\\n.v//.|.v..\n\nBeams are only shown on empty tiles; arrows indicate the direction of the beams.\nIf a tile contains beams moving in multiple directions, the number of distinct directions is shown instead.\nHere is the same diagram but instead only showing whether a tile is energized (#) or not (.):\n\n######....\n.#...#....\n.#...#####\n.#...##...\n.#...##...\n.#...##...\n.#..####..\n########..\n.#######..\n.#...#.#..\n\nUltimately, in this example, 46 tiles become energized.\n\nThe light isn't energizing enough tiles to produce lava; to debug the contraption, you need to start by analyzing the current situation.\nWith the beam starting in the top-left heading right, how many tiles end up being energized?\n\n--- Part Two ---\n\nAs you try to work out what might be wrong, the reindeer tugs on your shirt and leads you to a nearby control panel.\nThere, a collection of buttons lets you align the contraption so that the beam enters from any edge tile and heading away from that edge.\n(You can choose either of two directions for the beam if it starts on a corner; for instance, if the beam starts in the bottom-right corner, it can start heading either left or upward.)\n\nSo, the beam could start on any tile in the top row (heading downward), any tile in the bottom row (heading upward), any tile in the leftmost column (heading right), or any tile in the rightmost column (heading left).\nTo produce lava, you need to find the configuration that energizes as many tiles as possible.\n\nIn the above example, this can be achieved by starting the beam in the fourth tile from the left in the top row:\n\n.|<2<\\....\n|v-v\\^....\n.v.v.|->>>\n.v.v.v^.|.\n.v.v.v^...\n.v.v.v^..\\\n.v.v/2\\\\..\n<-2-/vv|..\n.|<<<2-|.\\\n.v//.|.v..\n\nUsing this configuration, 51 tiles are energized:\n\n.#####....\n.#.#.#....\n.#.#.#####\n.#.#.##...\n.#.#.##...\n.#.#.##...\n.#.#####..\n########..\n.#######..\n.#...#.#..\n\nFind the initial beam configuration that energizes the largest number of tiles; how many tiles are energized in that configuration?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_17.adb",
    "content": "--  Solution to Advent of Code 2023, Day 17\n-------------------------------------------\n--  Clumsy Crucible\n--\n--  https://adventofcode.com/2023/day/17\n--  Copy of questions in: aoc_2023_17_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_17 is\n\n  use AoC_Toolbox, HAT;\n\n  input_name : constant VString := +\"aoc_2023_17_questions\";\n  n : constant := 13; skip_header : constant := 20;\n\n  --  GNAT runs this program on the actual problem data in 1.55 seconds,\n  --  while HAC takes forever.\n  --\n  --  input_name : constant VString := +\"aoc_2023_17\";\n  --  n : constant := 141; skip_header : constant := 0;\n\n  inf : constant Natural := Integer'Last / 4;\n\n  map : array (1 .. n, 1 .. n) of Natural;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    if skip_header > 0 then\n      Skip_Line (f, skip_header);\n    end if;\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        map (x, y) := Ord (c) - Ord ('0');\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  --  Dijkstra shortest path algorithm.\n  --  Code adapted from AoC_2022_12.\n  --\n  --  The following definitions belong to the Dijkstra algorithm, but\n  --  we keep them less local because of the visualization.\n\n  list_length_max : constant := 500_000;\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  steps_max : constant := 10;\n\n  type State_Type is record\n    pt    : Point;\n    dir   : Direction_or_Nil;\n    steps : Natural;\n  end record;\n\n  type Node is record\n    len   : Natural;\n    state : State_Type;\n    pred  : Natural;  --  This is just for displaying the path.\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  best : array (1 .. n, 1 .. n, Direction, 1 .. steps_max) of Natural;\n\n  verbose : constant Boolean := False;\n\n  function Dijkstra_Algorithm\n    (start, finish : Point;\n     part          : Part_Type)\n  return Natural\n  is\n\n    cur_len : Natural;\n    cur_s   : State_Type;\n    s       : State_Type;  --  Test state derived from current state.\n\n    procedure Visit (dir : Direction) is\n      len_to, ins : Integer;\n      new_node : Node;\n      vec : Point;\n      --  Jump over x, y positions that represent invalid states:\n      jump : Positive;\n    begin\n      if cur_s.dir /= nil and then dir = Opposite (cur_s.dir) then\n        --  Avoid gaming the rules by going back and forth (U-turns).\n        --  Turns must be 90 degrees.\n        return;\n      elsif dir = cur_s.dir then\n        --  Same direction\n        s.steps := cur_s.steps + 1;\n        jump := 1;\n      else\n        --  New direction: turn.\n        case part is\n          when part_1 =>\n            s.steps := 1;\n            jump := 1;\n          when part_2 =>\n            s.steps := 4;\n            jump := 4;\n        end case;\n      end if;\n      --  The number of steps in a single direction is limited:\n      case part is\n        when part_1 =>\n          if s.steps > 3 then return; end if;\n        when part_2 =>\n          if s.steps > 10 then return; end if;\n      end case;\n      s.dir := dir;\n      case dir is\n        when north => vec.x :=  0; vec.y := -1;\n        when east  => vec.x := +1; vec.y :=  0;\n        when south => vec.x :=  0; vec.y := +1;\n        when west  => vec.x := -1; vec.y :=  0;\n      end case;\n      s.pt.x := cur_s.pt.x + jump * vec.x;\n      if s.pt.x in 1 .. n then\n        s.pt.y := cur_s.pt.y + jump * vec.y;\n        if s.pt.y in 1 .. n then\n          len_to := cur_len;\n          for count in 1 .. jump loop\n            len_to := len_to + map (cur_s.pt.x + count * vec.x, cur_s.pt.y + count * vec.y);\n          end loop;\n          if len_to < best (s.pt.x, s.pt.y, dir, s.steps) then\n            --  Found a better path to target state s.\n            best (s.pt.x, s.pt.y, dir, s.steps) := len_to;\n            --\n            --  Insert in a sorted way.\n            --\n            ins := explored + 1;\n            for i in current + 1 .. explored loop\n              if len_to < list (i).len then\n                ins := i;  --  Insert here.\n                --  Optional: remove another node\n                --  with the same state and a larger length.\n                exit;\n              end if;\n            end loop;\n            for i in reverse ins .. explored loop\n              list (i + 1) := list (i);\n            end loop;\n            new_node.len   := len_to;\n            new_node.state := s;\n            new_node.pred  := current;\n            list (ins) := new_node;\n            explored := explored + 1;\n          end if;\n        end if;\n      end if;\n    end Visit;\n\n  begin\n    current  := 0;\n    explored := 0;\n\n    for x in 1 .. n loop\n      for y in 1 .. n loop\n        for d in Direction loop\n          for s in 1 .. steps_max loop\n            best (x, y, d, s) := inf;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n\n    --  Startup state (without a direction) is not visited again.\n    --  best (start.x, start.y, nil, 1) := 0;\n\n    cur_s.pt    := start;\n    cur_s.dir   := nil;\n    cur_s.steps := 1;\n    cur_len     := 0;\n\n    loop\n      for d in Direction loop\n        Visit (d);\n      end loop;\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_s := list (current).state;\n      exit when cur_s.pt.x = finish.x and then cur_s.pt.y = finish.y;\n      cur_len := best (cur_s.pt.x, cur_s.pt.y, cur_s.dir, cur_s.steps);\n    end loop;\n    if verbose then\n      Put_Line\n        (\"Final. Dir = \" & cur_s.dir'Image & \"; steps =\" & cur_s.steps'Image);\n    end if;\n    return best (cur_s.pt.x, cur_s.pt.y, cur_s.dir, cur_s.steps);\n  end Dijkstra_Algorithm;\n\n  procedure Show_Path is\n    char_map : array (1 .. n, 1 .. n) of Character;\n    i, j, len : Natural;\n    pt : Point;\n  begin\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        char_map (x, y) := Chr (map (x, y) + Ord ('0'));\n      end loop;\n    end loop;\n    --  Display optimal path, back from the end (E).\n    i := current;\n    len := list (i).len;\n    while i /= 0 loop\n      j := list (i).pred;\n      pt := list (i).state.pt;\n      Put_Line\n        (+\"Node \" & i &\n          \": \" & pt.x & \", \" & pt.y &\n          \";  steps: \" & list (i).state.steps &\n          \", towards \" & list (i).state.dir'Image &\n          \", cumulated heat loss: \" & len);\n      len := len - map (pt.x, pt.y);\n      if i = current then\n        char_map (pt.x, pt.y) := 'E';\n      else\n        for k in 0 .. list (i).state.steps - 1 loop  --  Backtrack the steps.\n          case list (i).state.dir is\n            when nil   => char_map (pt.x, pt.y) := '*';\n            when north => char_map (pt.x, pt.y + k) := '^';\n            when south => char_map (pt.x, pt.y - k) := 'v';\n            when east  => char_map (pt.x - k, pt.y) := '>';\n            when west  => char_map (pt.x + k, pt.y) := '<';\n          end case;\n        end loop;\n      end if;\n      i := j;\n    end loop;\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        Put (char_map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n  end Show_Path;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Do_Part (part : Part_Type) is\n    start, finish : Point;\n  begin\n    start.x := 1;\n    start.y := 1;\n    finish.x := n;\n    finish.y := n;\n    r (part) := Dijkstra_Algorithm (start, finish, part);\n    if verbose then\n      Show_Path;\n    end if;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  Read_Data;\n  for p in Part_Type loop\n    Do_Part (p);\n  end loop;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 638  (example: 102)\n    --  Part 2: validated by AoC: 748  (example: 94)\n  end if;\nend AoC_2023_17;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_17.txt",
    "content": "122122122221111223212131233223113223121333442231421433142332434134225233545342212211333112344344134442142433223412123123222112313121212221212\n222211221221231312321313313211342343411142324132123121134452332445155511344312331454432211221131443421221311311132313213121113133212212121121\n122122222123123112133333323222434211131132342432414314214452412531552132441122435121513351133144143322231342334223133211113332223112112212121\n121121122123221323133133124121313314444133314314111435332133355334444335454224312242224554224323414441121443212123222111111321321211121211212\n221122211323221232131333113424242413333242343434255431431524222114514555335533141355541521354112112323124134232112232412122113112231321212221\n122112113332111112211312241113114222334131115345325525553252224253442114313554141223521124145541224124314212142143231424133222231131333222211\n212212213321332113123242342411311111433442125134332211522512512135134454413433131555542522225543342113244321143124141111333313212212211321211\n111222113233231131222412143432342332212424325445154122325221333315223121441513551143423434221424535543443413414433343312211133122213311321111\n121122211212132122314144412132113122134521143321315442521141334521433553332314111441535455212441221412133441223422412413323113211321312211211\n121123313221131212422134134333321412515231255135114131115445421335451435423235211523233534133251531525332444243321231442133141331131331111311\n111321111323223132223324141431314353242311313155433331232415512425453645632225443423445133351122555413323232212313234221111112322131222113221\n213213233232223221144222214333434454513214544423255231433153443662543666342462636543433334445414545114133442433314231223211422211322312332323\n111221112223232243122122321421212241245125114454522522365543465656546642224263635556542642232214554245131431244342333332222233433111112222223\n233312212113123412143231124323422244335132153244522426656525464342366364422443356424233464621455534322155241541431411413441431421111131232332\n233211113333131421333443321151351344444113423244242646332566664266222556455466524354242644245335555232234433443223513323443142441123222111133\n312111233113311341414414431232342323214531455545553566654635256333552425266345422365656324526326425541151541544212511221434432244122222322313\n131332122131314111114323133241451244423521311354233425236524622465555445536565342435565336563325432514153221123314214123332331434141311113222\n231231311222331412324132154121355133321532234534343363466266542355662434334363442553244224224352564632515513424333425211241232312424422121332\n223313133214123314124342111353115332512446333635346644355425364423236256333435432425526444236666362464331343231251553453142224341133421111313\n332113123232234221124212545411551211254546423543323364625245243255345523262644624325265253334354625244354135354511121431232413344232242213122\n233323232121141443421251534243342514544532562336364566523455335463363576553654232523234463556234455234422132255555211315532434442233422312122\n212132232144234422134245243255112345524352552542455453443225565345577474547767565755345256433554633653546641242421312111522223434442124231223\n123321413434131222234421344553411334245226356625435233656577566553337746744743635774375326542552543223464223514114435131312133323313214422112\n331311433212424412324553455113141542523236246546552444375543467447566434346775647346346635636355362654525644235533342342445333422114144332112\n122313422432333243535141412111226566244363245465533665553657737566555564475644565467446545343254254632336563243412543535354334143232242421231\n222334443144224321514322454123462643226424362235574733446377737444643675636375653456655733776543463333422646536453112544535215124231432144411\n113442144242323332354154544325335642225352265663373764434446653675433547735435365476647645647754432256565226223651115542155254311121212212243\n113313124143434211345425154435326642625564656457346447377547765676634654653357374643773357345446635533456564663622454441423212422234234322433\n313222242331414514413444255555253253234656227456433775577557745353634344377335436455677376744456367564626234525346523413234531444111124123231\n234124424214211524123352224626233325345524664473373535773347657456436565357553375563677455675434564622453556536223343312211135132434143343241\n314223324221211151133432356545644332443347777536754354374665345545747757547557536636455566356777634676343653623666253552425151125111313124133\n411432414444422443515413332323655623663677673645546774756743445545884584744568887546563435746377776743354365536655346324314234524212431312341\n112244323223411445151512662434565532454734755653547347767358748877755884777648584548653743775573637777554466525633426251432231415131122244131\n331212134433452323233434542562336565263344644744333575576784744686467788544678847876764347776556673434767726536235644342145154533443223141311\n144223143322414541141526263242263466435443573476757354555687486788744755578445677587574655755664654345446634545543225643112344243425544243214\n211211133311315353455524632446523366777546655477466388688487754875444878458554748868687674647735745546477555655535423234422322223422214122332\n233323332451434545112243556662225233665445763747333558657577647644677878675688446866665464776546644334363437442454266655343334213213321233324\n231312413341215423223635646634566355537566476444388687576655766687788565766688684447666678646537343553547554455643546642542312435344351423122\n313223325341552155426532255526425546547737657655545485445645644747875684466476788564646675675847676434367747353455636325554111223444524434421\n313123233242152334525566532545665344375473366755655487584557568465585847744686484446444487557857766336674354743262456225534442324142434414413\n431431124241141212263254643262673746433375466588677858465664875557485554584766657847458665474787474354537364577626364443552224431324243433213\n221321314531554134523344446564537455733736634687688755447577544887569678585677447464647885478768547636453463633633542243445235152222312232431\n131134115135241554536422256224464564746667668658758478867875658586995598966779877578558658875764747577336564337734346462264545123321353322413\n123421114152115123452565655566657355443454564546865774587649578598978599655999858585447488774785576553346375767545452523653445151135523321234\n224422431425553423622462325637343634776737677744464464467598696979997867696898756585984566476466885674336435355455753322323433232411545155312\n414311352435124263223444455635745467476664887464785748566656865567786877787658858859777744487568656867536377353476452346262556224511521225443\n223114153345343246554656663354535563567585655685876555979689788777855688765667896889786657586464687878477477365356743325236635311242532412242\n123122325432225325522362544773453743736464578484748658666665985899785775886888579795689885885854847748647737737467434332235334651541341553334\n443352143214532263453554427657664436735458865786676655579768896689789986987959875959755569877767477557544556336777576453644354561324451251512\n121452413251312242546332336633337373756788687555766968565968979666787997968597868556877586876656485877786653354633564442463442362541244125224\n424124541535452643445252476377676354374875445574885857878987987657655556889585555975795677966654647686757575436656633742254463335251221312344\n442231145454245523353645554743563557867448558568969796957867599569966898697686599585997577896864466476674577455436764545262645522432355145213\n233354114345336444533456437343457777658566566456877668559598895867796987768986685767756566857885755778745887467765644633562255433431234351143\n324253342114343544244534675743375535768786586887668888886795977869879878866769698876985686759796678654768474747557563442633532665644452515454\n114221444443244223644424366376364386648564655896586789898968767796786977779787696888599798697978788567677757666633534565646253566451334212454\n231324515512325242535245455467675768588854567989787886666878776967999767878879879979996998665685875667865886455364335677254455642324552234125\n123335241124524366456344746675645476445445564767797955968577686666686667788996777698895868778677795767786486845454354747562263264622152553142\n231312152241525364542236367736373868458667666779885897585667886777666696769996697899878976676998677778578677886463537647626326654663511112343\n331331513311444364256353367734745744545664856969878699566968868997779887978889766677897775886779767476578544443633553536436626625345313454421\n311541535146254465342645333566578678568468487678685879887799978886979689787667788999676767566578997656474678758355474646655262523522152524231\n451251515414632223243357445374375787644478567996798579778668797886877698979789768899788686758566669664576746684677667734554226323432313522344\n312435235356534526643344674354564688886666767659955698886877689967676778876696679986799865887856759577778867444534473534334252443642442551112\n315222511556322242562347537534678876487554978596598969689897699688888889888986769669666697798777697575588744547554556557366454224542353433353\n425515431314443324446456745644487668777765897686895879799686896697779989879978988786779898678757569666776745678873556477463454524525151442254\n131431325313553226425634656745565844664566576586556979796877886679989997978989987667666976655865988864865656775744335663443624652436424325531\n331152143452533542664477374777485676554479868958665977868688897897877887987997896899887967697857559567767655574573444337555653226566254113133\n255253351164333322455334454735364887645786757955765868767899867977879879977989877699786799988987876687644786656753774437344362634226212342223\n341325252336244465354535753473368785645846688777855996896698888778787787899797988879866967688798779898487758847847636774576563352656341411335\n412155212433254555566676547343356768875455868866568967667697889887999797977897778886989999666596889665865858768577775545342446542456534425541\n511435114262464254434567436757745848466689665575568686766977899878799887898799787898779988976858986899585846555764436555672646532255213214135\n235135235456433443255643733544444586687565798557565898666868877777977789899899879876896676779975778859887665874733467535353655622336411132154\n355221152564242253526675554634758687685569665798667968999689998977799898988999979779689668679588596899447685845873474455345566623253441453525\n144515535232354443223644466635648545558655587768758978796698887978797979888787877966889799779769775868488586668456563746574453352624611541545\n551231142423244223353464335537757654777546558756665779688789797788977778887898799779869666789859799879888488746454467775676436542263235131445\n522543525436556635654735466736586558485855979659958799699677767777888978797789788897897666867797599969877576665645734356433246526233343135513\n151215345452433662463573567646376747544748576798589888998677769787877978877777789996788667685586578587576868646874634436646454265322235432555\n433212251254262522364635745743388864886455758886698968977779666988789797997788796966768678966878888568484854776463757346645435553465313553322\n544132151312562323225767567633447447857689758975596889667789979987779877897889989898776888859758688957655588855443657477473565664543214423442\n132533522454443664563553646546584784544867596878765666877698877999897889777999778796867869999695998698466685875766733646335435456534133231411\n431142312344522524452477637567588555474688958959868596969676998879978987898797688989986866685975656554558746687865453566353535655653123241131\n115455114346263343465744776567338855564648579889569857869987778876889788878798697766868979689999857858778884466774336433572662363526312322114\n124423142232246442653755647363365877767867897756668575996866767687886889987789797967798969958756997668547678466746454443532323233226355235342\n232532223216264564333443766675555444844655458885595987989996679699766776878888988667899876985589999645778885546437665576535456356642433242555\n112435522536545326463444747756576778855777776896885578668967866998798767676789699776896967799668777756457777786345647437625425325262514152431\n141255321434436364434567776573475764878488487879687685758897897779699968677997799868976688657969896464844867884637443556366336564243454535311\n111534441325652665664446566674344848447887547897677867968687879976698878888786777988968776987886586777846485554346366733556533552624123255542\n331325221254333336643467375367454374854656644655685976999896866669778968799896969778656688787659777756487844455477337464434225235431353141243\n341524514145465442443636437655366665675574545698896886987596668976999767966898986968989897676696584865466667744656347443222636656523455235322\n341525245521446332553646463474543665645656476868786995857565776787899669777798866678799789599766976878545456745456454434636642446454544134545\n431212551454443563543546343347764754885487858649897676956988866779787687876869767655985559587576884558657678673546353755553635464253522311355\n442223245413436353365545777475454566548786775558887889575775659867997769898976857796586996998585458867454784433544534336365626436443542114324\n412521114534256333553563253657345445578574748884966896579999556586986787688875965656899886565886687664654576346373446346533345342425144253542\n141134244215513433356245255736645756358576765676879558578887759589655659999659597659886999786666675568584467535654753662245545242244331433321\n241124212314412324422333464566774476578555555746885867968668765795577777868559659587655575959755765465874737343774753562366426635525432324422\n344321454522543342555342656764553677656744757674764785995877578857988666675575567558595899998445857848587745663745377424322622225412211551113\n142321545532451526325642547477757566378565868764557568666866966798869875698666797598566858655664457575664364367637463545662436345233543455244\n121325132533225424534264663333575675777477784764655885796558579879565689959755565968888854567464467584664756436763454322643335345134533322241\n411132145535425426545646566554747547667358468876885854897898696965559797959659888786656978844765445685537747477534546535554653641345413535442\n443224242533213122545543223635733774363436887564777678764996786677557569568788669698974787688878444488767765436347462324543446414522545514322\n213112524141422325632222556463336333457753845647454658644865977989779789559688975897475844844766754565777344463664552224425654444353122512221\n123443432412252524564255362252736643346755588866445576656678748669985758875867768544564467884874488756735576653545464556263343231123111522321\n211323341425143324532535522334757677737474375667554654845878448789676575559565755844675457876474846747646757737465642253334234224155335533414\n111432111251144512226623533254237535754663575485675544765887485484567486767488478777444576487475875457644745443735442644555544454253133512231\n333132344143445411444242323553364644365464444367778676886556648654665466444744454655845865464564536636477763643554632323522555531534144331442\n244323122552131443225544335344342767763474577436866475644768574755456444465858447688468646585854777676374647546452622455344222113421143212122\n342231141215552514353236463563632665374337734364468865868546455888557547486866488867574884486876376443635754362234234533421223244453342434434\n123124122115243354253633543434444367464463677335536567748475445854678657857686778754875678554764764344744356753232324645543552134132232311413\n412322222335233534224524645543263436773564533357454384844565855787755756655857656556775447657356465376444574535325643655232224413244242422241\n442124331351453453124232352455644554433457574575654367447547444644484764557787767678565583555446344647463335334565544545134555514343421111212\n222431312412133313414544343363225345263337357477543357466876456578557875877564574776863577563645546533577734644235445653433223115555413123221\n131142311424325131231415626545565522454765756454433633355654786445568748857677555746773554366765445745554525326622254363353251441122313112432\n332332333141444153453342266254436226562646347634565634766375744666754755757747473453555467576445474576726532225334562353311455111253244421433\n224444231141243443114221246563325466323637576764337656757766755435564377745535757444554644733745543766455355553252536334133443232223133343211\n133433133133432512223141551334545556423623267367767544777346476677533345447344753644364546563644456424436232554434623334555321531422132144432\n113233124412224451124113215455646254646222225767467475745657746436546455745637665743555573675466735433654535623522543143541252412133344213133\n113313113211312333511154552344363326562554546537466665744576457647554346656734756374654377776545545235644646664262515124413312421141213121323\n322222421342222214252232215221435422626363454264634545634676663446357773673747573356657377576367455445624632655425434255223522324111123233143\n111322131331343245153453232455262354632243324442567445464764374563466356563433437566763536645436456656653443332235534125521522233144343121221\n133324123332312444331234225442144255265352646244532253575445466747744556753756534345533443534236655362622225363354323122255134344334341431222\n313314123434442124331334115143441553656224434463336433763645464656564773553454765757377755433623554654556242621253142342224422433444142414222\n113232423231443231215512312555324225222535255224542442362635577345446476355436667773376632652343234523454234432555442151434342333334234331133\n111221111223233443443513121412314425366244523343343363346542377465367435774664773666342342464454634465656364152515332142331234424343341113332\n123123131422312322244134515214441154254626336325442536544262626326425654545246352322256622345565455425654132445343443221334443442344332131132\n321223131221322223424321343535452552544643563425665663523652322466242442625366465252244445533355526523361235252141251151443433442124111112311\n311312213323313332331111342422441335255544255533622536525426325635454556233265652646556652264344664363441313232433113353213111311112332132131\n212322231122222112122432215115412133452444143534343236642464362242254462346523633246526625322335356435211312122232452444222133334414213221113\n121221313222313433332143242344531312422454351362665223243633332665344332342636353543543423256355435554115254431122425211324233313242312232111\n223221132233331323111144312125545255234555545132336362242365466543245433652666455322542425323335251452515243245532544124442343122333331333321\n123222322233243112214113133123524333145353344253232643624253565332666444256556343643323223636624214313113234353353412132443232224331221321323\n112223231132232214112441124433412223131511441332144236555624533625326635255544253436325565225422351433334314423411343224222323242312111312133\n211131221333311111213411432341224154123123133213515431566564646662444222522324253444522622244144454154425142324341144331421244443223213213232\n222111122132232224442324344124122123145224125132335155435126345534565663625452325465323554352221224252232244354223233123243143132312331212232\n222133212113123231111224134212122153524554333333545213311153115535525423242642442243225422214244542445413325424323323121312422322132222332312\n222123213213213232321331324114422443445312325135244243412455434334354311235235431455431554343125142511555353431333143213323143311121132322311\n211213333322113111322243441224441224331423432342354253312145451242413254113552255541333211122424333322523224332234331241223323323322333212221\n211112231331213122221322142211314421423152552133251424314431245455332235144212425512331213434225534511323334233142443124423132222322322222121\n212122111211312312131311212444422113421122214351134125323221441453341253521324413552232513235135452552141234211333233413213333331112111112211\n111211211233232221231332234241143232142124231314152232241153452525451125324423425353544334544233125321313124222331431212222231121213322221221\n121211112132133312113121214332221431322243421112211153533111512234544332113252332432432345454334113213213231341443334233123121231132132122112\n111222121232211113231212313332413312441232221142313113334242353313211241554252255321445435111412223321342124431124242322212121111113121121121\n222121122221132313332132311231324312421333341214231343251244511153233344424212224145455513442444314313441334222211132131211221133322212122212\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_17_questions.txt",
    "content": "--- Day 17: Clumsy Crucible ---\n\nThe lava starts flowing rapidly once the Lava Production Facility is operational.\nAs you leave, the reindeer offers you a parachute, allowing you to quickly reach Gear Island.\n\nAs you descend, your bird's-eye view of Gear Island reveals why you had trouble finding anyone on your way up: half of Gear Island is empty, but the half below you is a giant factory city!\n\nYou land near the gradually-filling pool of lava at the base of your new lavafall.\nLavaducts will eventually carry the lava throughout the city, but to make use of it immediately, Elves are loading it into large crucibles on wheels.\n\nThe crucibles are top-heavy and pushed by hand.\nUnfortunately, the crucibles become very difficult to steer at high speeds, and so it can be hard to go in a straight line for very long.\n\nTo get Desert Island the machine parts it needs as soon as possible, you'll need to find the best way to get the crucible from the lava pool to the machine parts factory.\nTo do this, you need to minimize heat loss while choosing a route that doesn't require the crucible to go in a straight line for too long.\n\nFortunately, the Elves here have a map (your puzzle input) that uses traffic patterns, ambient temperature, and hundreds of other parameters to calculate exactly how much heat loss can be expected for a crucible entering any particular city block.\n\nFor example:\n\n2413432311323\n3215453535623\n3255245654254\n3446585845452\n4546657867536\n1438598798454\n4457876987766\n3637877979653\n4654967986887\n4564679986453\n1224686865563\n2546548887735\n4322674655533\n\nEach city block is marked by a single digit that represents the amount of heat loss if the crucible enters that block.\nThe starting point, the lava pool, is the top-left city block; the destination, the machine parts factory, is the bottom-right city block.\n(Because you already start in the top-left block, you don't incur that block's heat loss unless you leave that block and then return to it.)\n\nBecause it is difficult to keep the top-heavy crucible going in a straight line for very long, it can move at most three blocks in a single direction before it must turn 90 degrees left or right. The crucible also can't reverse direction; after entering each city block, it may only turn left, continue straight, or turn right.\n\nOne way to minimize heat loss is this path:\n\n2>>34^>>>1323\n32v>>>35v5623\n32552456v>>54\n3446585845v52\n4546657867v>6\n14385987984v4\n44578769877v6\n36378779796v>\n465496798688v\n456467998645v\n12246868655<v\n25465488877v5\n43226746555v>\n\nThis path never moves more than three consecutive blocks in the same direction and incurs a heat loss of only 102.\n\nDirecting the crucible from the lava pool to the machine parts factory, but not moving more than three consecutive blocks in the same direction, what is the least heat loss it can incur?\n\n--- Part Two ---\n\nThe crucibles of lava simply aren't large enough to provide an adequate supply of lava to the machine parts factory.\nInstead, the Elves are going to upgrade to ultra crucibles.\n\nUltra crucibles are even more difficult to steer than normal crucibles.\nNot only do they have trouble going in a straight line, but they also have trouble turning!\n\nOnce an ultra crucible starts moving in a direction, it needs to move a minimum of four blocks in that direction before it can turn (or even before it can stop at the end).\nHowever, it will eventually start to get wobbly: an ultra crucible can move a maximum of ten consecutive blocks without turning.\n\nIn the above example, an ultra crucible could follow this path to minimize heat loss:\n\n2>>>>>>>>1323\n32154535v5623\n32552456v4254\n34465858v5452\n45466578v>>>>\n143859879845v\n445787698776v\n363787797965v\n465496798688v\n456467998645v\n122468686556v\n254654888773v\n432267465553v\n\nIn the above example, an ultra crucible would incur the minimum possible heat loss of 94.\n\nHere's another example:\n\n111111111111\n999999999991\n999999999991\n999999999991\n999999999991\n\nSadly, an ultra crucible would need to take an unfortunate path like this one:\n\n1>>>>>>>1111\n9999999v9991\n9999999v9991\n9999999v9991\n9999999v>>>>\n\nThis route causes the ultra crucible to incur the minimum possible heat loss of 71.\n\nDirecting the ultra crucible from the lava pool to the machine parts factory, what is the least heat loss it can incur?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_18.adb",
    "content": "--  Solution to Advent of Code 2023, Day 18\n-------------------------------------------\n--  Lavaduct Lagoon\n--\n--  https://adventofcode.com/2023/day/18\n--  Copy of questions in: aoc_2023_18_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_18 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  verbose : constant Boolean := False;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 22; start_1 : constant := 2;\n  input_name : constant VString := +\"aoc_2023_18\"; n : constant := 822; start_1 : constant := 250;\n  --\n\n  type State is (clean, path, inside, outside);\n\n  map : array (1 .. n, 1 .. n) of State;\n\n  procedure Clean_Map is\n  begin\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        map (x, y) := clean;\n      end loop;\n    end loop;\n  end Clean_Map;\n\n  procedure Read_Data_Part_1 is\n    c : Character;\n    i : Integer;\n    f : File_Type;\n    pt : Point;\n  begin\n    Clean_Map;\n    pt.x := start_1;\n    pt.y := start_1;\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get (f, c);\n      Get (f, i);\n      for count in 1 .. i loop\n        map (pt.x, pt.y) := path;\n        case c is\n          when 'U' => pt.y := pt.y - 1;\n          when 'D' => pt.y := pt.y + 1;\n          when 'L' => pt.x := pt.x - 1;\n          when 'R' => pt.x := pt.x + 1;\n          when others => null;\n        end case;\n      end loop;\n      Skip_Line (f);\n    end loop;\n    Close (f);\n  end Read_Data_Part_1;\n\n  type Vector_Values is array (1 .. n) of Integer;\n\n  type Ordered_Vector is record\n    top : Natural;\n    val : Vector_Values;\n  end record;\n\n  procedure Insert (v : in out Ordered_Vector; value : Integer) is\n    ins : Positive;\n    found : Boolean := False;\n  begin\n    for i in 1 .. v.top loop\n      if v.val (i) = value then\n        found := True;\n        exit;\n      end if;\n    end loop;\n    if not found then\n      ins := v.top + 1;\n      for i in 1 .. v.top loop\n        if v.val (i) > value then\n          ins := i;\n          exit;\n        end if;\n      end loop;\n      for i in reverse ins .. v.top loop\n        v.val (i + 1) := v.val (i);\n      end loop;\n      v.val (ins) := value;\n      v.top := v.top + 1;\n    end if;\n  end Insert;\n\n  procedure Find\n    (v     : in out Ordered_Vector;\n             --  ^ \"out\" is not needed, we just force\n             --    a by-reference parameter passing on HAC.\n     value :        Integer;\n     index :    out Positive)\n  is\n  begin\n    for i in 1 .. v.top loop\n      if v.val (i) = value then\n        index := i;\n        return;\n      end if;\n    end loop;\n    index := Integer'Last;\n  end Find;\n\n  trx, try : Ordered_Vector;\n\n  procedure Read_Data_Part_2 is\n    c : Character;\n    sep : String (1 .. 2);\n    dummy, i, j, x1, x2, y1, y2 : Integer;\n    f : File_Type;\n    s : VString;\n    old_pt, new_pt : Point;\n  begin\n    Clean_Map;\n    new_pt.x := 0;\n    new_pt.y := 0;\n    old_pt := new_pt;\n    trx.top := 0;\n    try.top := 0;\n    --  Register start point (coordinates: 0,0).\n    --  We need some detailed pixellisation around each point.\n    for dxy in -1 .. +1 loop\n      Insert (trx, dxy);\n      Insert (try, dxy);\n    end loop;\n  Passes :\n    for pass in 1 .. 2 loop\n      Open (f, input_name & \".txt\");\n      while not End_Of_File (f) loop\n        Get (f, c);\n        Get (f, dummy);\n        Get (f, sep);\n        Get_Line (f, s);\n        Delete (s, 8, 8);\n        i := Integer_Value (+\"16\" & s & '#');  --  Read hexadecimal part.\n        j := i / 16;\n        case i rem 16 is\n          when 0 => new_pt.x := new_pt.x + j;  --  Right\n          when 1 => new_pt.y := new_pt.y + j;  --  Down\n          when 2 => new_pt.x := new_pt.x - j;  --  Left\n          when 3 => new_pt.y := new_pt.y - j;  --  Up\n          when others => null;\n        end case;\n        if pass = 1 then\n          --  Register a point (if it is a new point).\n          for dxy in -1 .. +1 loop\n            Insert (trx, new_pt.x + dxy);\n            Insert (try, new_pt.y + dxy);\n          end loop;\n        else\n          --  Draw a line in the index map\n          if new_pt.y = old_pt.y then\n            --  Horizontal\n            Find (trx, old_pt.x, x1);\n            Find (trx, new_pt.x, x2);\n            Find (try, new_pt.y, y1);\n            for x12 in Min (x1, x2) .. Max (x1, x2) loop\n              map (x12, y1) := path;\n            end loop;\n          else\n            --  Vertical\n            Find (trx, new_pt.x, x1);\n            Find (try, old_pt.y, y1);\n            Find (try, new_pt.y, y2);\n            for y12 in Min (y1, y2) .. Max (y1, y2) loop\n              map (x1, y12) := path;\n            end loop;\n          end if;\n          --\n          old_pt := new_pt;\n        end if;\n      end loop;\n      Close (f);\n    end loop Passes;\n\n    if verbose then\n      Put_Line (+\"TRX \" & trx.top);\n      for tx in 1 .. trx.top loop\n        Put_Line (trx.val (tx));\n      end loop;\n      Put_Line (+\"TRY \" & try.top);\n      for ty in 1 .. try.top loop\n        Put_Line (try.val (ty));\n      end loop;\n    end if;\n  end Read_Data_Part_2;\n\n  procedure Show is\n    trunc_n : constant Integer := Min (70, n);\n  begin\n\n    Put_Line (\"Map: -------------------\");\n    for y in 1 .. trunc_n loop\n      for x in 1 .. trunc_n loop\n        case map (x, y) is\n          when clean   => Put ('.');\n          when path    => Put ('#');\n          when outside => Put ('o');\n          when inside  => Put ('i');\n        end case;\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Do_Part (p : Part_Type) is\n    c : Integer_64 := 0;\n\n    procedure Flood_Fill (x, y : Integer) is  --  Taken from aoc_2023_10.\n    begin\n      if x in 1 .. n\n        and then y in 1 .. n\n        and then map (x, y) = clean\n      then\n        map (x, y) := outside;\n        c := c + 1;\n        Flood_Fill (x - 1, y);\n        Flood_Fill (x + 1, y);\n        Flood_Fill (x, y - 1);\n        Flood_Fill (x, y + 1);\n      end if;\n    end Flood_Fill;\n\n    width, height : array (1 .. n) of Positive;\n  begin\n    if verbose then\n      Put_Line (\"Part \" & p'Image);\n      Show;\n    end if;\n    Flood_Fill (1, 1);\n    if verbose then\n      Show;\n    end if;\n    case p is\n      when part_1 =>\n        r (p) := Integer_64 (n * n - c);\n      when part_2 =>\n        --  We need to compute the \"real\" surfaces\n        c := 0;\n        for ix in 1 .. trx.top loop\n          if ix = trx.top then\n            --  Last \"big pixel\" has width 1 (a decision)\n            width (ix) := 1;\n          else\n            width (ix) := trx.val (ix + 1) - trx.val (ix);\n          end if;\n        end loop;\n        for iy in 1 .. try.top loop\n          if iy = try.top then\n            --  Last \"big pixel\" has height 1 (a decision)\n            height (iy) := 1;\n          else\n            height (iy) := try.val (iy + 1) - try.val (iy);\n          end if;\n        end loop;\n        for iy in 1 .. try.top loop\n          for ix in 1 .. trx.top loop\n            if map (ix, iy) = outside then\n              c := c + Integer_64 (width (ix) * height (iy));\n            end if;\n          end loop;\n        end loop;\n        r (p) := Integer_64 (trx.val (trx.top) - trx.val (1) + 1) *\n                 Integer_64 (try.val (try.top) - try.val (1) + 1)\n                 -\n                 c;\n    end case;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data_Part_1;\n  Do_Part (part_1);\n\n  Read_Data_Part_2;\n  Do_Part (part_2);\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 53300\n    --  Part 2: validated by AoC: 64294334780659\n  end if;\nend AoC_2023_18;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_18.txt",
    "content": "L 6 (#53eec0)\nU 8 (#02fce3)\nL 3 (#23fe80)\nU 5 (#114c73)\nL 9 (#2d94d2)\nU 8 (#522163)\nL 7 (#2d94d0)\nD 9 (#3170e3)\nL 10 (#461852)\nD 4 (#1b4773)\nL 4 (#31d4f2)\nU 5 (#126143)\nL 7 (#810822)\nU 8 (#1a3e33)\nL 10 (#7437d2)\nU 8 (#3cc1c3)\nL 2 (#19f202)\nU 7 (#179353)\nR 6 (#6f6c02)\nU 9 (#52b813)\nR 2 (#2dd912)\nU 5 (#1f3a91)\nL 8 (#759782)\nU 6 (#1f3a93)\nL 3 (#46f342)\nU 7 (#4af7c3)\nR 4 (#481352)\nU 6 (#2fe7c1)\nR 8 (#5f5c12)\nU 7 (#2fe7c3)\nR 9 (#6f6dc2)\nU 4 (#438993)\nR 2 (#53c320)\nU 7 (#3ef223)\nR 3 (#534410)\nD 9 (#3ef221)\nR 7 (#10f8e0)\nD 9 (#1a8023)\nR 4 (#202f00)\nU 8 (#25bc33)\nR 5 (#7974b0)\nU 10 (#3c49e3)\nL 8 (#7974b2)\nU 4 (#28ee03)\nL 3 (#1f1182)\nU 5 (#258013)\nL 10 (#628bf2)\nU 2 (#65d2d3)\nL 4 (#16d082)\nU 5 (#248833)\nL 3 (#3fc122)\nD 5 (#072e53)\nL 11 (#114cd2)\nU 2 (#125843)\nL 3 (#095f22)\nU 5 (#627533)\nL 3 (#095f20)\nU 11 (#3148b3)\nL 7 (#317ca0)\nD 11 (#462e83)\nL 7 (#1e5990)\nU 6 (#2b0333)\nL 7 (#41b1e0)\nD 10 (#615cb3)\nR 5 (#08d330)\nD 10 (#79b2a1)\nR 6 (#3eaff0)\nD 10 (#105bd1)\nR 6 (#1daf70)\nD 7 (#487ff1)\nL 3 (#4de290)\nD 3 (#7db061)\nL 8 (#050970)\nD 5 (#494181)\nL 3 (#04ba50)\nD 3 (#2bbcc1)\nL 3 (#0ddc20)\nD 7 (#706f21)\nL 12 (#48c5d0)\nU 5 (#78abe3)\nL 8 (#3915a0)\nU 5 (#238003)\nL 3 (#2e0660)\nU 6 (#357a61)\nL 5 (#261990)\nU 7 (#7328a1)\nL 4 (#05ef52)\nU 4 (#08ab51)\nR 9 (#3d0ab2)\nU 4 (#3fb2d1)\nR 3 (#4a3642)\nU 6 (#135301)\nL 12 (#471722)\nU 6 (#3f4bd1)\nL 2 (#471720)\nU 5 (#460601)\nL 3 (#4d5e42)\nU 6 (#128f11)\nL 10 (#6b4bf0)\nU 3 (#0f2641)\nR 6 (#156a00)\nU 7 (#0f2643)\nR 6 (#59d890)\nU 9 (#4a4c61)\nR 5 (#250590)\nU 3 (#2f7f33)\nR 10 (#1506b0)\nU 9 (#27e5b3)\nR 6 (#23e040)\nU 5 (#338fa3)\nR 5 (#376040)\nU 6 (#3bb513)\nR 4 (#55b290)\nD 6 (#5e2183)\nR 7 (#3700d0)\nD 4 (#5d6c13)\nR 4 (#06baa2)\nU 10 (#497451)\nR 6 (#34a832)\nU 6 (#548e43)\nR 6 (#1d0420)\nU 7 (#1d0f63)\nR 9 (#1d0422)\nU 3 (#3f0db3)\nR 3 (#4e46c2)\nU 9 (#409131)\nR 7 (#0d0472)\nU 4 (#1ea4b1)\nR 5 (#0d0470)\nU 7 (#517571)\nR 7 (#37e962)\nD 6 (#497453)\nL 2 (#0280b2)\nD 7 (#0696b3)\nL 6 (#23e042)\nD 11 (#2e38c3)\nR 6 (#1506b2)\nD 4 (#2f7ad3)\nR 2 (#138810)\nD 9 (#0ef623)\nR 5 (#3f85f0)\nD 9 (#025be3)\nR 5 (#5f7582)\nU 4 (#3ec8c3)\nR 6 (#1d0ed2)\nU 7 (#18cf03)\nR 3 (#7c8450)\nD 7 (#4270a3)\nR 6 (#4c3d70)\nU 3 (#096283)\nR 10 (#3eb860)\nU 9 (#123503)\nR 9 (#36bf60)\nU 5 (#3a02f3)\nL 6 (#252a80)\nU 3 (#09b603)\nL 7 (#490872)\nU 4 (#4d1863)\nL 6 (#4494b2)\nU 5 (#2c7f23)\nR 7 (#1995b0)\nU 7 (#112853)\nR 4 (#17e290)\nU 4 (#749f03)\nR 4 (#3d7b60)\nU 4 (#85c751)\nL 12 (#1ea980)\nU 3 (#291c63)\nL 2 (#2460f0)\nU 4 (#6d7e81)\nR 6 (#052f30)\nU 12 (#2ed441)\nR 4 (#8608d0)\nD 12 (#3821c1)\nR 4 (#64d260)\nU 6 (#0ee041)\nR 2 (#60c110)\nU 2 (#22b951)\nR 9 (#118860)\nD 9 (#4efe01)\nR 3 (#118862)\nD 10 (#42fb01)\nR 7 (#1aacb0)\nD 8 (#57cb53)\nL 7 (#666d50)\nD 10 (#4f10f3)\nR 5 (#1fd020)\nD 5 (#1ba6f3)\nR 5 (#863d72)\nU 4 (#393123)\nR 7 (#206020)\nU 4 (#39ac13)\nL 7 (#642fe2)\nU 7 (#1cfa03)\nR 7 (#642fe0)\nU 9 (#45acb3)\nL 7 (#344b20)\nU 5 (#3fd1e3)\nR 4 (#475320)\nU 2 (#85a693)\nR 3 (#11fee2)\nU 5 (#830cd3)\nR 5 (#4d89b2)\nU 8 (#14bc13)\nR 7 (#4d89b0)\nD 4 (#76f4b3)\nR 12 (#11fee0)\nD 5 (#664543)\nL 12 (#1229d2)\nD 4 (#296263)\nR 4 (#502192)\nD 8 (#3b65d1)\nR 5 (#11aa02)\nD 7 (#37b981)\nL 7 (#5c8cc2)\nD 12 (#1cf031)\nR 7 (#1a4692)\nD 4 (#640eb1)\nR 3 (#105a10)\nD 8 (#260951)\nR 2 (#6493b0)\nD 4 (#03a4b1)\nL 9 (#5edd52)\nD 10 (#1b89d1)\nL 7 (#0b2252)\nU 7 (#7decf1)\nL 8 (#0aee22)\nD 7 (#709b41)\nL 7 (#5bf6d2)\nU 5 (#2e8673)\nL 4 (#340202)\nD 5 (#8a9631)\nL 8 (#1ea852)\nD 7 (#8a9633)\nR 7 (#38f1e2)\nD 9 (#076423)\nR 4 (#06dd12)\nD 5 (#2c2803)\nR 3 (#1069f0)\nD 7 (#676e03)\nR 12 (#1069f2)\nD 4 (#419313)\nR 5 (#5d0a32)\nD 3 (#1ee113)\nR 7 (#3a1ce0)\nD 5 (#7e1e83)\nR 3 (#19f960)\nD 6 (#2e97f3)\nR 6 (#209d20)\nD 10 (#13dc73)\nR 3 (#7ad010)\nD 8 (#3d56a3)\nR 5 (#0011d2)\nD 4 (#38a891)\nR 5 (#356642)\nD 5 (#065e33)\nR 7 (#36cea2)\nD 8 (#065e31)\nR 7 (#403c22)\nD 9 (#38a893)\nL 11 (#389522)\nU 7 (#506df3)\nL 9 (#042020)\nD 7 (#3a1463)\nL 4 (#841670)\nD 6 (#1ec383)\nR 8 (#027ec0)\nD 10 (#364483)\nR 4 (#2c21b0)\nD 4 (#1f7111)\nL 5 (#44d720)\nD 6 (#5e4e61)\nR 5 (#44d722)\nD 3 (#2a5381)\nR 4 (#039440)\nU 9 (#067b53)\nR 4 (#449850)\nU 4 (#4314d3)\nL 4 (#2692f0)\nU 4 (#4314d1)\nR 4 (#659580)\nU 6 (#067b51)\nR 4 (#3240d0)\nD 9 (#547a73)\nR 4 (#598c10)\nD 7 (#3a8603)\nR 7 (#5d2660)\nD 4 (#4c8ea3)\nL 7 (#4c4f50)\nD 9 (#08ed81)\nR 5 (#6ad850)\nU 4 (#535cc1)\nR 6 (#1e0c02)\nU 3 (#6db991)\nR 3 (#1e0c00)\nU 3 (#118b41)\nL 4 (#1f5db0)\nU 6 (#0f0c11)\nR 4 (#1015c2)\nU 6 (#829e11)\nR 4 (#1015c0)\nU 3 (#051531)\nR 7 (#4c4da0)\nU 9 (#1b2601)\nR 4 (#129bb0)\nU 4 (#049701)\nR 9 (#894f30)\nU 5 (#46be91)\nR 6 (#021aa0)\nU 6 (#1f1831)\nR 4 (#170ec0)\nU 9 (#38cfd1)\nR 5 (#267550)\nU 3 (#7a31d1)\nR 6 (#155f60)\nU 7 (#80dc51)\nR 7 (#1c20f0)\nU 5 (#0e9461)\nR 4 (#498740)\nD 6 (#01add1)\nR 4 (#0b8ca0)\nU 6 (#7e7a41)\nR 7 (#4ce290)\nU 4 (#2086e1)\nL 5 (#4559c0)\nU 3 (#6bd593)\nL 10 (#1c0000)\nU 3 (#6bd591)\nR 10 (#540970)\nU 2 (#383a23)\nL 10 (#185b40)\nU 5 (#4240b3)\nL 9 (#520e40)\nU 4 (#29b043)\nR 9 (#47f830)\nU 7 (#43dc53)\nR 7 (#1f44b2)\nU 9 (#0ae9f1)\nR 3 (#602012)\nU 11 (#0ae9f3)\nR 5 (#32fcf2)\nU 6 (#481843)\nL 3 (#3ae230)\nU 9 (#283893)\nL 5 (#21ff10)\nD 9 (#283891)\nL 5 (#55b440)\nU 6 (#480913)\nL 5 (#383a90)\nU 8 (#0b1143)\nL 5 (#3a2930)\nU 3 (#5ad163)\nR 11 (#3d20a2)\nU 2 (#16b3b3)\nR 12 (#2b20e2)\nU 4 (#5808a3)\nL 8 (#0f5990)\nU 5 (#12c943)\nR 4 (#58e7f0)\nU 5 (#1eedf3)\nR 10 (#7a5930)\nU 3 (#2ef693)\nR 10 (#02f430)\nU 7 (#35b991)\nR 7 (#4b0e40)\nD 6 (#35b993)\nR 10 (#463450)\nD 8 (#296b13)\nL 10 (#440580)\nD 3 (#440183)\nR 8 (#1b38d0)\nD 10 (#43e2d3)\nL 8 (#2e4850)\nD 5 (#48c283)\nL 9 (#50a6a0)\nD 5 (#6adf71)\nL 8 (#047f02)\nD 4 (#2db381)\nR 7 (#6b0ac2)\nD 6 (#585c51)\nR 10 (#674822)\nD 4 (#2ee9d1)\nR 5 (#25db62)\nU 11 (#7e8e71)\nR 5 (#23ae62)\nD 11 (#3aed01)\nR 3 (#53ae72)\nU 4 (#0d2571)\nR 3 (#476c40)\nD 7 (#2143e1)\nL 6 (#7cbb22)\nD 2 (#311da1)\nL 7 (#7cbb20)\nD 6 (#38fed1)\nL 5 (#476c42)\nU 6 (#1a2e71)\nL 5 (#583fb2)\nD 2 (#2eff51)\nL 3 (#48a100)\nD 11 (#1426e1)\nL 6 (#2b2c40)\nD 2 (#535e31)\nL 8 (#1bcf60)\nD 12 (#5d2851)\nR 4 (#4f14c0)\nD 11 (#062bf1)\nR 7 (#047222)\nD 7 (#449c11)\nR 3 (#52dd12)\nD 6 (#538d13)\nL 7 (#490b82)\nD 8 (#538d11)\nR 3 (#0b68e2)\nD 8 (#449c13)\nL 4 (#32edd2)\nU 2 (#067f81)\nL 5 (#12ce72)\nU 13 (#259801)\nL 4 (#2650f2)\nD 5 (#29bdd3)\nL 3 (#7cee92)\nD 10 (#29bdd1)\nL 3 (#2f78c2)\nD 8 (#7b1753)\nR 6 (#46fad2)\nD 11 (#7b1751)\nR 6 (#170562)\nU 11 (#2119f1)\nR 5 (#11ae82)\nD 6 (#814a91)\nR 2 (#0fc390)\nD 3 (#5e3f21)\nR 10 (#043cc0)\nD 7 (#2ae8a1)\nR 4 (#3eabd0)\nD 7 (#33eb71)\nL 13 (#67bbb0)\nD 6 (#5345d1)\nR 13 (#06ba30)\nD 3 (#762c81)\nL 5 (#25ef60)\nD 6 (#170e13)\nL 10 (#58aaf0)\nD 6 (#170e11)\nL 3 (#5a3550)\nD 7 (#695e01)\nL 4 (#138370)\nU 8 (#0eab11)\nL 5 (#359090)\nD 8 (#3e2791)\nL 7 (#359092)\nD 8 (#4526c1)\nR 6 (#335fb0)\nD 3 (#259813)\nR 7 (#7123d0)\nU 5 (#0efb81)\nR 5 (#6245d2)\nD 5 (#56cc91)\nR 4 (#384f62)\nD 5 (#1bf021)\nR 6 (#145fe0)\nU 8 (#01c6b1)\nR 6 (#1617c0)\nD 10 (#4832e1)\nL 3 (#701d90)\nD 6 (#0cf2a1)\nL 3 (#2bcf40)\nD 3 (#19b033)\nL 7 (#1302b2)\nD 12 (#6761e3)\nL 7 (#1302b0)\nU 12 (#579253)\nL 3 (#482030)\nD 8 (#259811)\nL 8 (#5b9720)\nD 9 (#495741)\nL 6 (#443092)\nD 6 (#53ea41)\nL 5 (#1d2d22)\nU 6 (#28fe21)\nL 5 (#079352)\nD 5 (#3e1a71)\nL 3 (#8ab872)\nD 4 (#169531)\nL 10 (#093742)\nD 5 (#53cfc1)\nL 6 (#394902)\nD 5 (#031c71)\nR 9 (#042602)\nD 10 (#386101)\nR 4 (#095682)\nD 6 (#272ac1)\nR 10 (#56c552)\nD 4 (#4b7e91)\nR 12 (#4f5732)\nD 9 (#19ec31)\nL 3 (#371552)\nU 6 (#361081)\nL 6 (#22fc02)\nD 6 (#57bc91)\nL 7 (#3d2182)\nD 7 (#094ef3)\nL 6 (#018e22)\nD 8 (#529c93)\nL 7 (#018e20)\nD 9 (#31e193)\nL 2 (#0f3a52)\nD 12 (#32ff41)\nL 5 (#5b0fb2)\nD 3 (#5d51c1)\nL 6 (#13b1a2)\nD 5 (#374ec1)\nL 13 (#3b9e72)\nD 4 (#174083)\nL 12 (#1dd322)\nD 5 (#7d6003)\nL 9 (#1acb22)\nD 4 (#4aade3)\nL 10 (#4de282)\nD 5 (#23a8e3)\nR 4 (#676a62)\nD 3 (#4b56c1)\nR 5 (#83d302)\nD 7 (#230001)\nR 6 (#017252)\nD 6 (#32ff43)\nL 2 (#08e202)\nD 4 (#09c633)\nL 13 (#206970)\nD 7 (#7c3473)\nL 8 (#206972)\nD 7 (#057673)\nL 11 (#1b1d72)\nU 10 (#61afe1)\nL 2 (#5608c2)\nU 2 (#616c21)\nL 4 (#3c0562)\nU 7 (#616c23)\nL 6 (#530aa2)\nD 6 (#3cc191)\nL 3 (#086e42)\nU 6 (#3f6001)\nL 5 (#115072)\nU 3 (#689eb1)\nL 7 (#444cf0)\nU 11 (#32b1e1)\nL 7 (#444cf2)\nU 7 (#38d3d1)\nL 4 (#22f312)\nU 5 (#623d73)\nR 4 (#38b942)\nU 4 (#4333a3)\nL 5 (#0ca750)\nU 2 (#32b8a3)\nL 8 (#151332)\nU 10 (#3dd1e1)\nL 4 (#4de562)\nU 2 (#574101)\nL 5 (#26c592)\nU 2 (#116471)\nL 7 (#0bb092)\nU 13 (#07dff3)\nR 3 (#45c262)\nU 4 (#5a4843)\nR 7 (#45c260)\nU 10 (#444f23)\nR 6 (#12fd52)\nU 4 (#36d293)\nL 8 (#528cf0)\nU 9 (#1e3a43)\nR 5 (#55df10)\nU 3 (#3c4b53)\nR 2 (#0ca752)\nU 10 (#23b003)\nR 7 (#38b940)\nD 2 (#24c403)\nR 6 (#41b532)\nD 7 (#0d07a3)\nR 7 (#4893c2)\nD 8 (#7ded93)\nR 9 (#288282)\nD 5 (#1d4c71)\nR 2 (#441c82)\nD 3 (#6da8c1)\nL 6 (#209002)\nD 5 (#1bdfe1)\nL 8 (#42a410)\nD 4 (#48f551)\nR 4 (#42a412)\nD 9 (#269be1)\nR 7 (#4572f2)\nU 9 (#8452c3)\nR 3 (#077832)\nD 6 (#3b4b83)\nR 2 (#5137e2)\nD 4 (#4bca13)\nR 10 (#46aee2)\nU 7 (#1c3673)\nR 4 (#1f3030)\nU 7 (#0196f3)\nL 4 (#5d0f30)\nU 2 (#5fe723)\nL 9 (#17aa10)\nU 7 (#0fcb63)\nR 13 (#03fd50)\nU 3 (#0138a3)\nL 4 (#064d42)\nU 4 (#008751)\nR 5 (#37ea32)\nU 3 (#4ff661)\nR 13 (#51faf2)\nU 6 (#0ef911)\nL 3 (#14c232)\nU 6 (#4c22b1)\nL 7 (#099d22)\nD 6 (#5625d1)\nL 8 (#42ee42)\nU 5 (#1c4a71)\nR 5 (#40d180)\nU 5 (#041b51)\nL 5 (#386ed0)\nU 8 (#041b53)\nL 5 (#15c0f0)\nU 8 (#436731)\nL 9 (#0b8222)\nU 4 (#31f073)\nL 13 (#7b1c72)\nU 8 (#31f071)\nL 7 (#0862b2)\nU 5 (#34f5d1)\nL 8 (#2c0f82)\nU 2 (#03ba21)\nL 6 (#493052)\nU 12 (#319093)\nL 7 (#240372)\nU 8 (#7053e3)\nL 4 (#2a5bf2)\nU 6 (#296e63)\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_18_questions.txt",
    "content": "--- Day 18: Lavaduct Lagoon ---\n\nThanks to your efforts, the machine parts factory is one of the first factories up and running since the lavafall came back.\nHowever, to catch up with the large backlog of parts requests, the factory will also need a large supply of lava for a while; the Elves have already started creating a large lagoon nearby for this purpose.\n\nHowever, they aren't sure the lagoon will be big enough; they've asked you to take a look at the dig plan (your puzzle input).\nFor example:\n\nR 6 (#70c710)\nD 5 (#0dc571)\nL 2 (#5713f0)\nD 2 (#d2c081)\nR 2 (#59c680)\nD 2 (#411b91)\nL 5 (#8ceee2)\nU 2 (#caa173)\nL 1 (#1b58a2)\nU 2 (#caa171)\nR 2 (#7807d2)\nU 3 (#a77fa3)\nL 2 (#015232)\nU 2 (#7a21e3)\n\nThe digger starts in a 1 meter cube hole in the ground.\nThey then dig the specified number of meters up (U), down (D), left (L), or right (R), clearing full 1 meter cubes as they go.\nThe directions are given as seen from above, so if \"up\" were north, then \"right\" would be east, and so on.\nEach trench is also listed with the color that the edge of the trench should be painted as an RGB hexadecimal color code.\n\nWhen viewed from above, the above example dig plan would result in the following loop of trench (#) having been dug out from otherwise ground-level terrain (.):\n\n#######\n#.....#\n###...#\n..#...#\n..#...#\n###.###\n#...#..\n##..###\n.#....#\n.######\n\nAt this point, the trench could contain 38 cubic meters of lava.\nHowever, this is just the edge of the lagoon; the next step is to dig out the interior so that it is one meter deep as well:\n\n#######\n#######\n#######\n..#####\n..#####\n#######\n#####..\n#######\n.######\n.######\n\nNow, the lagoon can contain a much more respectable 62 cubic meters of lava.\nWhile the interior is dug out, the edges are also painted according to the color codes in the dig plan.\n\nThe Elves are concerned the lagoon won't be large enough; if they follow their dig plan, how many cubic meters of lava could it hold?\n\n--- Part Two ---\n\nThe Elves were right to be concerned; the planned lagoon would be much too small.\n\nAfter a few minutes, someone realizes what happened; someone swapped the color and instruction parameters when producing the dig plan. They don't have time to fix the bug; one of them asks if you can extract the correct instructions from the hexadecimal codes.\n\nEach hexadecimal code is six hexadecimal digits long.\nThe first five hexadecimal digits encode the distance in meters as a five-digit hexadecimal number.\nThe last hexadecimal digit encodes the direction to dig: 0 means R, 1 means D, 2 means L, and 3 means U.\n\nSo, in the above example, the hexadecimal codes can be converted into the true instructions:\n\n    #70c710 = R 461937\n    #0dc571 = D 56407\n    #5713f0 = R 356671\n    #d2c081 = D 863240\n    #59c680 = R 367720\n    #411b91 = D 266681\n    #8ceee2 = L 577262\n    #caa173 = U 829975\n    #1b58a2 = L 112010\n    #caa171 = D 829975\n    #7807d2 = L 491645\n    #a77fa3 = U 686074\n    #015232 = L 5411\n    #7a21e3 = U 500254\n\nDigging out this loop and its interior produces a lagoon that can hold an impressive 952408144115 cubic meters of lava.\n\nConvert the hexadecimal color codes into the correct instructions; if the Elves follow this new dig plan, how many cubic meters of lava could the lagoon hold?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_19.adb",
    "content": "--  Solution to Advent of Code 2023, Day 19\n-------------------------------------------\n--  Aplenty\n--\n--  https://adventofcode.com/2023/day/19\n--  Copy of questions in: aoc_2023_19_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_19 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  x, m, a, s : Integer;\n  ok : Boolean;\n\n  procedure AA is begin ok := True; end AA;\n  procedure RR is begin ok := False; end RR;\n\n  --  pragma Style_Checks (Off);\n\n  --  In this day's puzzle, the data is actually a program of\n  --  a Binary Space Partition.\n  --  We have turned XMAS programs into Ada programs using\n  --  Regexp replacements.\n  --  Note the possible simplifications (could be done several times):\n  --    if [cond] then AA; else AA; -> AA\n  --    if [cond] then RR; else RR; -> RR\n\n  --\n  --  The \"Mini\" program (the example shown with the questions):\n  --\n\n  procedure m_qkq;\n  procedure m_rfg;\n  procedure m_gd;\n  procedure m_crn;\n  procedure m_qqz;\n  procedure m_hdj;\n\n  procedure m_px  is begin if a < 2006 then m_qkq; elsif m > 2090 then AA; else m_rfg; end if; end;\n  procedure m_pv  is begin if a > 1716 then RR; else AA; end if; end;\n  procedure m_lnx is begin if m > 1548 then AA; else AA; end if; end;     --  m_lnx = AA\n  procedure m_rfg is begin if s < 537  then m_gd; elsif x > 2440 then RR; else AA; end if; end;\n  procedure m_qs  is begin if s > 3448 then AA; else m_lnx; end if; end;  --  m_qs = AA\n  procedure m_qkq is begin if x < 1416 then AA; else m_crn; end if; end;\n  procedure m_crn is begin if x > 2662 then AA; else RR; end if; end;\n  procedure m_in  is begin if s < 1351 then m_px; else m_qqz; end if; end;\n  procedure m_qqz is begin if s > 2770 then m_qs; elsif m < 1801 then m_hdj; else RR; end if; end;\n  procedure m_gd  is begin if a > 3333 then RR; else RR; end if; end;     --  m_gd = RR\n  procedure m_hdj is begin if m > 838  then AA; else m_pv; end if; end;\n\n  --\n  --  The \"Input\" program:\n  --\n\n  procedure px;\n  procedure sv;\n  procedure lhx;\n  procedure jg;\n  procedure jhd;\n  procedure mhd;\n  procedure bn;\n  procedure bz;\n  procedure dmc;\n  procedure tgt;\n  procedure vb;\n  procedure vtt;\n  procedure fs;\n  procedure rct;\n  procedure sgr;\n  procedure tc;\n  procedure dh;\n  procedure ncl;\n  procedure pbx;\n  procedure xzk;\n  procedure mls;\n  procedure mcm;\n  procedure gqc;\n  procedure tfs;\n  procedure zg;\n  procedure vqn;\n  procedure pkf;\n  procedure hx;\n  procedure mk;\n  procedure xvn;\n  procedure nsd;\n  procedure ft;\n  procedure cng;\n  procedure tkj;\n  procedure mlj;\n  procedure rmb;\n  procedure qkz;\n  procedure mt;\n  procedure gkl;\n  procedure khv;\n  procedure gx;\n  procedure kkc;\n  procedure qcb;\n  procedure zmn;\n  procedure cbv;\n  procedure qnj;\n  procedure lsz;\n  procedure hcp;\n  procedure ntl;\n  procedure crk;\n  procedure rlz;\n  procedure lj;\n  procedure bnz;\n  procedure tv;\n  procedure qrp;\n  procedure blf;\n  procedure xrc;\n  procedure nr;\n  procedure jld;\n  procedure nk;\n  procedure rgl;\n  procedure rl;\n  procedure bjq;\n  procedure bxb;\n  procedure ksl;\n  procedure qzz;\n  procedure xmx;\n  procedure bqt;\n  procedure nx;\n  procedure kfr;\n  procedure rzc;\n  procedure zbv;\n  procedure qds;\n  procedure zz;\n  procedure ctn;\n  procedure mv;\n  procedure pm;\n  procedure vcd;\n  procedure dn;\n  procedure cjf;\n  procedure fcr;\n  procedure kf;\n  procedure zf;\n  procedure npl;\n  procedure hxj;\n  procedure bk;\n  procedure cgf;\n  procedure fj;\n  procedure tvz;\n  procedure ptj;\n  procedure jcf;\n  procedure jf;\n  procedure frc;\n  procedure gkt;\n  procedure lk;\n  procedure cpv;\n  procedure hr;\n  procedure fm;\n  procedure rh;\n  procedure bj;\n  procedure qqj;\n  procedure vs;\n  procedure clk;\n  procedure qrq;\n  procedure blm;\n  procedure bh;\n  procedure qq;\n  procedure pqb;\n  procedure ktn;\n  procedure bxg;\n  procedure ksd;\n  procedure pt;\n  procedure rtk;\n  procedure tck;\n  procedure jzc;\n  procedure csz;\n  procedure qps;\n  procedure lp;\n  procedure blx;\n  procedure ctt;\n  procedure xrp;\n  procedure sm;\n  procedure plc;\n  procedure bnx;\n  procedure dz;\n  procedure fpz;\n  procedure vgq;\n  procedure hrl;\n  procedure kbm;\n  procedure jx;\n  procedure xbr;\n  procedure cz;\n  procedure zh;\n  procedure mx;\n  procedure pz;\n  procedure rt;\n  procedure lbk;\n  procedure cpm;\n  procedure km;\n  procedure qzx;\n  procedure hp;\n  procedure sj;\n  procedure rs;\n  procedure xp;\n  procedure cbr;\n  procedure gcm;\n  procedure kj;\n  procedure lxb;\n  procedure rsn;\n  procedure jbk;\n  procedure zv;\n  procedure jps;\n  procedure mth;\n  procedure mgd;\n  procedure rnh;\n  procedure psj;\n  procedure shf;\n  procedure bgd;\n  procedure mlt;\n  procedure vnq;\n  procedure spg;\n  procedure kqk;\n  procedure zrf;\n  procedure ltl;\n  procedure pk;\n  procedure jct;\n  procedure pbh;\n  procedure bkc;\n  procedure lmm;\n  procedure jjm;\n  procedure td;\n  procedure mdn;\n  procedure st;\n  procedure sts;\n  procedure pr;\n  procedure ds;\n  procedure dmp;\n  procedure nst;\n  procedure szs;\n  procedure zs;\n  procedure vp;\n  procedure dl;\n  procedure lb;\n  procedure kl;\n  procedure hlx;\n  procedure hz;\n  procedure lv;\n  procedure qs;\n  procedure mpf;\n  procedure dm;\n  procedure vq;\n  procedure rrx;\n  procedure hxg;\n  procedure pj;\n  procedure gjs;\n  procedure rk;\n  procedure gr;\n  procedure zlr;\n  procedure qzq;\n  procedure qb;\n  procedure jkl;\n  procedure kd;\n  procedure ztq;\n  procedure vtl;\n  procedure tj;\n  procedure dhp;\n  procedure jv;\n  procedure pjd;\n  procedure fh;\n  procedure gf;\n  procedure cnb;\n  procedure rjs;\n  procedure sl;\n  procedure dd;\n  procedure hl;\n  procedure zc;\n  procedure jhv;\n  procedure rjx;\n  procedure bp;\n  procedure rj;\n  procedure mmc;\n  procedure jzr;\n  procedure hj;\n  procedure lpx;\n  procedure hxs;\n  procedure xv;\n  procedure pfl;\n  procedure vjn;\n  procedure gdk;\n  procedure ljv;\n  procedure rf;\n  procedure zpb;\n  procedure xgr;\n  procedure ln;\n  procedure fg;\n  procedure kq;\n  procedure mln;\n  procedure sjq;\n  procedure rpm;\n  procedure jc;\n  procedure lvq;\n  procedure cc;\n  procedure kxk;\n  procedure lzl;\n  procedure sh;\n  procedure pzx;\n  procedure mrc;\n  procedure sx;\n  procedure jmf;\n  procedure hs;\n  procedure ljn;\n  procedure mq;\n  procedure gc;\n  procedure zjx;\n  procedure kqb;\n  procedure xr;\n  procedure kct;\n  procedure vn;\n  procedure bvg;\n  procedure tzr;\n  procedure ghp;\n  procedure ljh;\n  procedure ttc;\n  procedure hmd;\n  procedure tb;\n  procedure skm;\n  procedure bmk;\n  procedure frf;\n  procedure qzr;\n  procedure xxd;\n  procedure nvs;\n  procedure sbd;\n  procedure sbh;\n  procedure kmc;\n  procedure ks;\n  procedure dxl;\n  procedure lbl;\n  procedure mbj;\n  procedure jsn;\n  procedure qjg;\n  procedure tq;\n  procedure qnp;\n  procedure gnb;\n  procedure xq;\n  procedure ddr;\n  procedure nl;\n  procedure bgz;\n  procedure gj;\n  procedure nzb;\n  procedure gg;\n  procedure lcg;\n  procedure gq;\n  procedure zx;\n  procedure jcs;\n  procedure sdm;\n  procedure btg;\n  procedure rq;\n  procedure fpj;\n  procedure vd;\n  procedure nxf;\n  procedure rhb;\n  procedure qv;\n  procedure hv;\n  procedure ttv;\n  procedure nv;\n  procedure cgx;\n  procedure mz;\n  procedure jnn;\n  procedure vf;\n  procedure gfk;\n  procedure dcg;\n  procedure mp;\n  procedure mg;\n  procedure hzc;\n  procedure nc;\n  procedure vlr;\n  procedure xkx;\n  procedure bb;\n  procedure nh;\n  procedure gmg;\n  procedure cl;\n  procedure xkb;\n  procedure cbb;\n  procedure fr;\n  procedure mh;\n  procedure cv;\n  procedure dcz;\n  procedure vcn;\n  procedure kqs;\n  procedure mcq;\n  procedure hxt;\n  procedure ld;\n  procedure xs;\n  procedure mfn;\n  procedure qfs;\n  procedure nd;\n  procedure jjc;\n  procedure gtq;\n  procedure xf;\n  procedure zgv;\n  procedure dgf;\n  procedure xg;\n  procedure tzv;\n  procedure nt;\n  procedure gbv;\n  procedure qmm;\n  procedure cr;\n  procedure gxs;\n  procedure ctq;\n  procedure mfh;\n  procedure ff;\n  procedure ggb;\n  procedure jkf;\n  procedure bls;\n  procedure czg;\n  procedure sxz;\n  procedure vdv;\n  procedure nsx;\n  procedure gd;\n  procedure vnp;\n  procedure dtc;\n  procedure glj;\n  procedure qt;\n  procedure qvc;\n  procedure ctb;\n  procedure xz;\n  procedure lg;\n  procedure lpq;\n  procedure jhh;\n  procedure mqj;\n  procedure fnv;\n  procedure zfm;\n  procedure vsx;\n  procedure csr;\n  procedure mhf;\n  procedure vc;\n  procedure qnv;\n  procedure cm;\n  procedure jhl;\n  procedure sq;\n  procedure hvz;\n  procedure tr;\n  procedure cgv;\n  procedure ps;\n  procedure rm;\n  procedure qp;\n  procedure qj;\n  procedure qr;\n  procedure cql;\n  procedure fvp;\n  procedure tn;\n  procedure fl;\n  procedure vv;\n  procedure lr;\n  procedure xhx;\n  procedure jzm;\n  procedure tlj;\n  procedure xk;\n  procedure zk;\n  procedure zn;\n  procedure ggh;\n  procedure ht;\n  procedure jbl;\n  procedure vfk;\n  procedure qdz;\n  procedure ll;\n  procedure vbp;\n  procedure rhg;\n  procedure inn;\n  procedure bv;\n  procedure zgx;\n  procedure cfj;\n  procedure mr;\n  procedure bf;\n  procedure rtg;\n  procedure qcr;\n  procedure xnv;\n  procedure nlp;\n  procedure tg;\n  procedure tnp;\n  procedure slq;\n  procedure fz;\n  procedure rgz;\n  procedure rg;\n  procedure nm;\n  procedure mdc;\n  procedure pbt;\n  procedure dbl;\n  procedure cn;\n  procedure hb;\n  procedure nls;\n  procedure tl;\n  procedure mml;\n  procedure dtm;\n  procedure pf;\n  procedure jh;\n  procedure sg;\n  procedure sp;\n  procedure cj;\n  procedure dfh;\n  procedure lm;\n  procedure pp;\n  procedure ddf;\n  procedure mn;\n  procedure hc;\n  procedure lgt;\n  procedure pmb;\n  procedure bq;\n  procedure dj;\n  procedure lz;\n  procedure hml;\n  procedure ckz;\n  procedure vh;\n  procedure rc;\n  procedure zm;\n  procedure jhs;\n  procedure hhd;\n  procedure zds;\n  procedure zd;\n\n  procedure fzf is begin if m<1642 then AA; else px; end if; end;\n  procedure qqp is begin if s>3732 then RR; elsif m>946 then RR; elsif a<1401 then AA; else AA; end if; end;\n  procedure mqh is begin if x>1081 then AA; elsif m<3344 then RR; elsif m>3632 then RR; else AA; end if; end;\n  procedure bnk is begin if a>2841 then RR; elsif s<3562 then RR; elsif x>3483 then AA; else AA; end if; end;\n  procedure jt  is begin if a>3076 then AA; elsif s<2748 then AA; elsif s>2805 then RR; else AA; end if; end;\n  procedure vl  is begin if x>2613 then sv; elsif a>2454 then lhx; else jg; end if; end;\n  procedure bhj is begin if x>2768 then jhd; else mhd; end if; end;\n  procedure ggs is begin if x>3053 then RR; elsif x>2848 then RR; else RR; end if; end;\n  procedure lx  is begin if a>3685 then AA; else bn; end if; end;\n  procedure hcz is begin if x>763 then RR; elsif s<2753 then AA; else RR; end if; end;\n  procedure mnr is begin if x>1157 then RR; else RR; end if; end;\n  procedure cpd is begin if a<320 then AA; elsif m>1387 then bz; else AA; end if; end;\n  procedure lbm is begin if s<3387 then RR; elsif s>3672 then RR; elsif a<3818 then RR; else AA; end if; end;\n  procedure npb is begin if a<1149 then dmc; else tgt; end if; end;\n  procedure bsh is begin if x<1228 then RR; else RR; end if; end;\n  procedure px  is begin if x>1003 then AA; elsif a>3750 then AA; else AA; end if; end;\n  procedure jl  is begin if a<1881 then RR; elsif m>1146 then RR; elsif s<400 then AA; else RR; end if; end;\n  procedure cs  is begin if s<3185 then AA; else AA; end if; end;\n  procedure krx is begin if x<3153 then AA; elsif a<2570 then RR; else AA; end if; end;\n  procedure dp  is begin if a>3221 then AA; else AA; end if; end;\n  procedure zxh is begin if s<2883 then RR; else vb; end if; end;\n  procedure dtj is begin if x<1574 then AA; elsif m<961 then AA; elsif m>1183 then RR; else RR; end if; end;\n  procedure mhd is begin if a<2806 then vtt; else RR; end if; end;\n  procedure mll is begin if s<2589 then fs; else rct; end if; end;\n  procedure nbf is begin if x<2665 then sgr; else AA; end if; end;\n  procedure jr  is begin if a>3301 then tc; elsif x>996 then dh; elsif a>2980 then ncl; else AA; end if; end;\n  procedure lxc is begin if x<1450 then RR; elsif m>899 then AA; elsif x>1653 then AA; else RR; end if; end;\n  procedure xfp is begin if a>586 then pbx; else xzk; end if; end;\n  procedure crf is begin if s>3081 then RR; elsif a>1253 then AA; elsif s<2740 then RR; else AA; end if; end;\n  procedure mc  is begin if a<330 then AA; elsif a>440 then AA; elsif x>2613 then RR; else AA; end if; end;\n  procedure lcl is begin if m>1452 then mls; else RR; end if; end;\n  procedure scv is begin if a>653 then RR; elsif a<385 then AA; elsif s>2291 then mcm; else AA; end if; end;\n  procedure jg  is begin if m>2877 then gqc; elsif a>2247 then RR; else AA; end if; end;\n  procedure kbt is begin if a<75 then AA; elsif x>3256 then RR; elsif a>137 then AA; else RR; end if; end;\n  procedure cmf is begin if m<795 then RR; else AA; end if; end;\n  procedure zxc is begin if a<1971 then AA; elsif a>2270 then RR; else AA; end if; end;\n  procedure lms is begin if s>323 then tfs; else AA; end if; end;\n  procedure mgs is begin if x<2480 then AA; elsif a<1050 then AA; else RR; end if; end;\n  procedure kz  is begin if s<3266 then zg; elsif a<2977 then AA; else vqn; end if; end;\n  procedure lh  is begin if x>1958 then pkf; elsif m>3511 then hx; else mk; end if; end;\n  procedure db  is begin if m<1657 then xvn; else nsd; end if; end;\n  procedure gbg is begin if m<1371 then AA; elsif x>3428 then AA; elsif s<3077 then AA; else RR; end if; end;\n  procedure gz  is begin if s<3104 then AA; elsif m<2828 then AA; elsif m>3281 then RR; else RR; end if; end;\n  procedure hpl is begin if a>3117 then AA; else ft; end if; end;\n  procedure zg  is begin if x<1698 then RR; else RR; end if; end;\n  procedure vqv is begin if a>1031 then AA; elsif x>2460 then AA; elsif x<1912 then AA; else RR; end if; end;\n  procedure vb  is begin if m<1499 then AA; elsif x>1894 then RR; else RR; end if; end;\n  procedure xkq is begin if s<1553 then cng; elsif s<3162 then tkj; else mlj; end if; end;\n  procedure ngz is begin if a<3373 then AA; elsif s>402 then AA; elsif s>204 then AA; else AA; end if; end;\n  procedure dq  is begin if m<801 then rmb; elsif a<2127 then AA; else RR; end if; end;\n  procedure kh  is begin if x>1408 then AA; else AA; end if; end;\n  procedure jfk is begin if a>1219 then qkz; elsif s<1492 then mt; elsif m<2952 then gkl; else khv; end if; end;\n  procedure pl  is begin if s>3123 then RR; else AA; end if; end;\n  procedure tdg is begin if a>1983 then AA; elsif a<1853 then gx; elsif x>1678 then kkc; else qcb; end if; end;\n  procedure nlk is begin if a<2055 then RR; else zmn; end if; end;\n  procedure sxc is begin if s<1553 then RR; else RR; end if; end;\n  procedure nzx is begin if a<2569 then AA; elsif x<1812 then cbv; else AA; end if; end;\n  procedure cph is begin if m<2856 then AA; else AA; end if; end;\n  procedure pxx is begin if x<3670 then qnj; elsif m<3015 then RR; elsif a<3243 then RR; else AA; end if; end;\n  procedure bnz is begin if a<949 then lsz; elsif s>1899 then hcp; elsif s>1631 then AA; else ntl; end if; end;\n  procedure tv  is begin if m<1352 then RR; elsif m<1812 then AA; else RR; end if; end;\n  procedure qkz is begin if a<2141 then crk; elsif x<1866 then rlz; else vl; end if; end;\n  procedure qrp is begin if a>3607 then RR; elsif m<2423 then lj; else qqj; end if; end;\n  procedure blf is begin if s<1970 then RR; else RR; end if; end;\n  procedure xrc is begin if x<2476 then rjx; elsif a>1724 then tj; else pbt; end if; end;\n  procedure nr  is begin if m>2092 then hzc; else AA; end if; end;\n  procedure jld is begin if s<1570 then AA; else ps; end if; end;\n  procedure nk  is begin if a<3132 then RR; else RR; end if; end;\n  procedure rgl is begin if a<2558 then AA; else RR; end if; end;\n  procedure rl  is begin if a<1021 then AA; else RR; end if; end;\n  procedure bjq is begin if s<2821 then RR; elsif s<2872 then AA; else RR; end if; end;\n  procedure qnj is begin if s>1202 then RR; elsif s>488 then RR; else RR; end if; end;\n  procedure bxb is begin if m<911 then AA; elsif x>468 then bnx; elsif s>3663 then RR; else RR; end if; end;\n  procedure ksl is begin if x<688 then AA; elsif x>1068 then AA; else RR; end if; end;\n  procedure qzz is begin if a>1963 then sdm; elsif s<1753 then RR; else cgx; end if; end;\n  procedure xmx is begin if m<1231 then qnv; elsif m>1789 then nsx; elsif s>1698 then xrp; else AA; end if; end;\n  procedure bqt is begin if x>392 then RR; else AA; end if; end;\n  procedure nx  is begin if m<3603 then RR; elsif s<2999 then mg; elsif m>3830 then RR; else AA; end if; end;\n  procedure kfr is begin if a<2455 then jf; elsif m>1009 then nzx; elsif x<2605 then cgv; else sm; end if; end;\n  procedure rzc is begin if m<3116 then RR; elsif x>1302 then RR; elsif s<2205 then RR; else shf; end if; end;\n  procedure zbv is begin if m<3299 then RR; elsif x<740 then AA; else RR; end if; end;\n  procedure qds is begin if a<3031 then tg; elsif a<3095 then pp; elsif x>2192 then bf; else cgf; end if; end;\n  procedure zz  is begin if m<602 then RR; elsif m>616 then AA; else AA; end if; end;\n  procedure ctn is begin if s<1118 then qvc; else jzc; end if; end;\n  procedure mv  is begin if m>3603 then RR; elsif s<1044 then RR; else AA; end if; end;\n  procedure pm  is begin if m>2113 then kd; elsif a>278 then AA; else RR; end if; end;\n  procedure vcd is begin if m<1762 then AA; else RR; end if; end;\n  procedure dn  is begin if m>2924 then RR; else AA; end if; end;\n  procedure cjf is begin if a<886 then jsn; elsif s>538 then hp; else RR; end if; end;\n  procedure fcr is begin if s>738 then vnp; elsif s>647 then cz; else AA; end if; end;\n  procedure kf  is begin if a<2869 then RR; elsif m<1983 then RR; else AA; end if; end;\n  procedure zf  is begin if m>1116 then vh; elsif m<741 then ljn; else xz; end if; end;\n  procedure npl is begin if m<604 then RR; elsif x<2557 then AA; elsif s>3273 then AA; else lzl; end if; end;\n  procedure hxj is begin if x>1696 then lgt; else hxt; end if; end;\n  procedure bk  is begin if m>2024 then kqk; elsif m>1977 then AA; else AA; end if; end;\n  procedure cgf is begin if m>1839 then mdc; else nk; end if; end;\n  procedure fj  is begin if s<3773 then RR; else AA; end if; end;\n  procedure tvz is begin if m<725 then AA; else RR; end if; end;\n  procedure nsd is begin if a>549 then AA; else rm; end if; end;\n  procedure ptj is begin if a>2544 then RR; elsif s<474 then RR; else RR; end if; end;\n  procedure jcf is begin if a>3207 then RR; else RR; end if; end;\n  procedure jf  is begin if x>1679 then RR; else hmd; end if; end;\n  procedure frc is begin if a>3423 then RR; elsif s<3574 then RR; else RR; end if; end;\n  procedure fs  is begin if s<2535 then RR; elsif s>2554 then RR; elsif s>2547 then RR; else RR; end if; end;\n  procedure gkt is begin if x<3699 then AA; elsif s<1808 then RR; else RR; end if; end;\n  procedure lk  is begin if x>1920 then vgq; elsif x<915 then vc; elsif s>911 then dcg; else pjd; end if; end;\n  procedure cpv is begin if s<84 then RR; else AA; end if; end;\n  procedure hr  is begin if m>3382 then mdn; elsif x<1457 then cph; else vp; end if; end;\n  procedure fm  is begin if x<1347 then kxk; else dl; end if; end;\n  procedure rh  is begin if m>1468 then AA; elsif a<3525 then ngz; else RR; end if; end;\n  procedure bj  is begin if x>574 then RR; elsif a<2312 then AA; else RR; end if; end;\n  procedure qqj is begin if x>1087 then RR; else AA; end if; end;\n  procedure vs  is begin if x>1075 then vcd; elsif m<1978 then jv; else jr; end if; end;\n  procedure clk is begin if x<444 then RR; elsif m<2947 then AA; elsif s<3126 then AA; else AA; end if; end;\n  procedure qrq is begin if s>2012 then RR; elsif a<1950 then AA; else AA; end if; end;\n  procedure blm is begin if m<1460 then rj; elsif m>2331 then pxx; elsif s<1091 then bmk; else kq; end if; end;\n  procedure bh  is begin if x>1415 then hj; elsif a>1216 then tr; else cj; end if; end;\n  procedure qq  is begin if a<3194 then qdz; else rg; end if; end;\n  procedure pqb is begin if s<3296 then AA; else RR; end if; end;\n  procedure lj  is begin if s<3684 then RR; elsif s<3855 then RR; elsif a<3556 then RR; else AA; end if; end;\n  procedure ktn is begin if a>3308 then RR; elsif x>2669 then AA; else AA; end if; end;\n  procedure bxg is begin if a>1442 then AA; elsif a>1347 then AA; else AA; end if; end;\n  procedure ksd is begin if s<3546 then mr; else rhb; end if; end;\n  procedure pt  is begin if x<1007 then AA; elsif s<3086 then RR; elsif a<2912 then RR; else RR; end if; end;\n  procedure rtk is begin if a<2468 then AA; elsif s>1601 then AA; else RR; end if; end;\n  procedure tck is begin if a>1635 then tlj; elsif m<329 then xhx; else hc; end if; end;\n  procedure jzc is begin if a<1524 then zrf; elsif m>1067 then pr; elsif x>1870 then bls; else rrx; end if; end;\n  procedure csz is begin if a>762 then bnz; elsif x<3126 then qv; elsif s>1898 then csr; else skm; end if; end;\n  procedure qps is begin if a>615 then cjf; elsif s>671 then pm; elsif s>240 then dbl; else nl; end if; end;\n  procedure lp  is begin if x<3084 then AA; elsif s<3733 then AA; else RR; end if; end;\n  procedure blx is begin if m>131 then RR; else RR; end if; end;\n  procedure ctt is begin if a<3522 then nxf; elsif x>1395 then cnb; else jzr; end if; end;\n  procedure xrp is begin if x<574 then RR; elsif m<1446 then RR; else AA; end if; end;\n  procedure sm  is begin if m<795 then ptj; elsif m>883 then RR; elsif x<3307 then AA; else sbd; end if; end;\n  procedure plc is begin if x>559 then RR; elsif a>3782 then RR; elsif s>3878 then RR; else AA; end if; end;\n  procedure bnx is begin if m<1013 then AA; else AA; end if; end;\n  procedure dz  is begin if s<3377 then RR; elsif m>2092 then RR; else AA; end if; end;\n  procedure fpz is begin if m>695 then tvz; elsif s<3213 then qnp; elsif a<1023 then RR; else RR; end if; end;\n  procedure mcm is begin if a<540 then AA; else RR; end if; end;\n  procedure vgq is begin if x<3260 then xp; else blm; end if; end;\n  procedure hrl is begin if s>571 then fcr; elsif a>3310 then lms; elsif a>3059 then dn; else cc; end if; end;\n  procedure sgr is begin if a<2253 then RR; elsif a>2477 then RR; elsif x>1631 then AA; else RR; end if; end;\n  procedure kbm is begin if a<773 then RR; elsif x<500 then xs; else AA; end if; end;\n  procedure dmc is begin if x>811 then ddf; elsif m>1293 then ckz; else RR; end if; end;\n  procedure jx  is begin if x<147 then AA; elsif s<3246 then RR; else AA; end if; end;\n  procedure xbr is begin if s<3780 then AA; else AA; end if; end;\n  procedure cz  is begin if m>3005 then AA; elsif x<1279 then AA; else RR; end if; end;\n  procedure zh  is begin if m>2724 then RR; else AA; end if; end;\n  procedure mx  is begin if a>2368 then RR; elsif s<2360 then RR; elsif x<3285 then AA; else RR; end if; end;\n  procedure pz  is begin if x>1619 then AA; elsif a>965 then RR; elsif x<1449 then AA; else RR; end if; end;\n  procedure rt  is begin if a>1181 then RR; elsif x>2446 then RR; else AA; end if; end;\n  procedure lbk is begin if a>2730 then fz; else hs; end if; end;\n  procedure cpm is begin if a<3279 then rsn; elsif m<1164 then dcz; elsif x>1415 then mcq; else rh; end if; end;\n  procedure km  is begin if m>3737 then AA; elsif a>3725 then RR; else RR; end if; end;\n  procedure qzx is begin if s>1504 then RR; elsif s>1454 then RR; elsif x<415 then AA; else AA; end if; end;\n  procedure hp  is begin if x<2493 then RR; elsif s<1127 then AA; else RR; end if; end;\n  procedure sj  is begin if m>683 then RR; elsif x<1742 then AA; elsif s<2208 then RR; else AA; end if; end;\n  procedure rs  is begin if m<1908 then tnp; elsif x<1393 then RR; else AA; end if; end;\n  procedure xp  is begin if m>1774 then ktn; elsif a<3517 then bq; else gj; end if; end;\n  procedure cbr is begin if a>2266 then RR; elsif m<819 then AA; else AA; end if; end;\n  procedure gcm is begin if a<3170 then AA; elsif a<3297 then RR; else RR; end if; end;\n  procedure kj  is begin if s>3251 then bnk; elsif x<3524 then AA; else AA; end if; end;\n  procedure lxb is begin if a<536 then AA; elsif a>630 then RR; elsif s<1570 then AA; else RR; end if; end;\n  procedure rsn is begin if m<1293 then RR; else RR; end if; end;\n  procedure jbk is begin if x>3170 then AA; elsif a>1074 then RR; else AA; end if; end;\n  procedure zv  is begin if x>2404 then AA; elsif s>457 then jmf; else AA; end if; end;\n  procedure jps is begin if a<593 then RR; else ggb; end if; end;\n  procedure mth is begin if x>3569 then gbv; else ds; end if; end;\n  procedure mgd is begin if s>2772 then RR; elsif x<173 then AA; else AA; end if; end;\n  procedure rnh is begin if x>460 then vn; elsif x>266 then pl; elsif a<2800 then hvz; else RR; end if; end;\n  procedure psj is begin if s<3000 then RR; elsif s<3141 then AA; else RR; end if; end;\n  procedure qcb is begin if x<798 then AA; elsif x>1338 then AA; else AA; end if; end;\n  procedure shf is begin if s<2342 then RR; else AA; end if; end;\n  procedure bgd is begin if m>2415 then nzb; elsif s>3123 then ld; else lcl; end if; end;\n  procedure mlt is begin if s<3301 then AA; elsif m>2092 then RR; else AA; end if; end;\n  procedure vtt is begin if a<2787 then RR; elsif m<1501 then AA; else RR; end if; end;\n  procedure gk  is begin if a<815 then AA; elsif s>2886 then RR; else RR; end if; end;\n  procedure vnq is begin if x<655 then AA; elsif s<3763 then RR; else AA; end if; end;\n  procedure spg is begin if a<1477 then RR; else RR; end if; end;\n  procedure kqk is begin if a>986 then RR; else AA; end if; end;\n  procedure zrf is begin if a>904 then gg; elsif m<1153 then ljh; elsif s<1804 then jld; else cpd; end if; end;\n  procedure ltl is begin if x>1025 then mh; elsif a<2706 then mlt; else mq; end if; end;\n  procedure kkc is begin if a<1939 then RR; elsif a>1966 then RR; else AA; end if; end;\n  procedure pk  is begin if s<3412 then fzf; elsif a>3726 then hxs; else qrp; end if; end;\n  procedure jct is begin if x>2955 then AA; else czg; end if; end;\n  procedure pbh is begin if a>1099 then AA; else RR; end if; end;\n  procedure bkc is begin if x<994 then RR; else RR; end if; end;\n  procedure lmm is begin if m>3383 then RR; elsif a>2887 then AA; else AA; end if; end;\n  procedure jjm is begin if a>2703 then lbk; else fpj; end if; end;\n  procedure td  is begin if x<247 then mpf; elsif s>3739 then tzv; else gf; end if; end;\n  procedure mdn is begin if a<3498 then RR; else RR; end if; end;\n  procedure st  is begin if s<3009 then AA; elsif a>1143 then rt; elsif a<1107 then rgz; else qzr; end if; end;\n  procedure sts is begin if a<1200 then RR; elsif m<87 then AA; elsif m>132 then AA; else AA; end if; end;\n  procedure pr  is begin if x>2249 then dtm; else qzz; end if; end;\n  procedure ds  is begin if s<3752 then AA; else RR; end if; end;\n  procedure dmp is begin if m<3305 then RR; elsif a<463 then AA; elsif m<3681 then cm; else RR; end if; end;\n  procedure sdr is begin if a>3376 then vdv; else zbv; end if; end;\n  procedure nst is begin if s>2046 then cbr; else mfn; end if; end;\n  procedure mk  is begin if a<388 then RR; else pmb; end if; end;\n  procedure pkf is begin if s>499 then mv; else AA; end if; end;\n  procedure szs is begin if m<3349 then sq; elsif a>718 then AA; else gc; end if; end;\n  procedure zs  is begin if m<2661 then RR; else AA; end if; end;\n  procedure vp  is begin if x>1477 then RR; elsif s>2269 then RR; else AA; end if; end;\n  procedure dl  is begin if s<1214 then RR; else qp; end if; end;\n  procedure lb  is begin if x<3138 then AA; elsif a>2670 then RR; else RR; end if; end;\n  procedure kl  is begin if m>3862 then AA; elsif x>1259 then mqj; elsif x<1033 then zn; else blf; end if; end;\n  procedure hlx is begin if a<2205 then RR; elsif x>3579 then AA; elsif s<1636 then AA; else RR; end if; end;\n  procedure hz  is begin if x>1358 then AA; elsif x<1311 then RR; else AA; end if; end;\n  procedure lv  is begin if s>424 then RR; elsif a>3455 then RR; elsif m>513 then AA; else AA; end if; end;\n  procedure qs  is begin if a<3308 then AA; elsif x>723 then RR; else RR; end if; end;\n  procedure gqc is begin if x<2158 then RR; elsif s<1851 then RR; else RR; end if; end;\n  procedure mpf is begin if a>3792 then AA; elsif a>3662 then mml; elsif a>3577 then RR; else xk; end if; end;\n  procedure dm  is begin if m>3103 then AA; elsif x<1276 then RR; else AA; end if; end;\n  procedure vq  is begin if s>2244 then hz; elsif x>1360 then AA; else AA; end if; end;\n  procedure rrx is begin if s>1629 then nst; elsif s>1413 then xnv; else dq; end if; end;\n  procedure hxg is begin if x<324 then mgd; elsif x<469 then dj; else gr; end if; end;\n  procedure pj  is begin if a<3150 then AA; elsif a<3454 then AA; elsif x>1606 then AA; else RR; end if; end;\n  procedure gjs is begin if a<2848 then AA; elsif x<651 then AA; else RR; end if; end;\n  procedure nbz is begin if x<2579 then rtg; else bvg; end if; end;\n  procedure tkj is begin if x<2510 then zx; elsif x>3340 then blx; elsif a>1123 then ggs; else ctb; end if; end;\n  procedure rk  is begin if m<105 then AA; elsif s<2581 then RR; elsif s>3343 then AA; else RR; end if; end;\n  procedure gr  is begin if s>2781 then RR; elsif m>938 then AA; elsif a<3798 then AA; else AA; end if; end;\n  procedure zlr is begin if s>2444 then AA; else RR; end if; end;\n  procedure qzq is begin if x>260 then RR; elsif s>2233 then RR; else AA; end if; end;\n  procedure qb  is begin if a<3400 then tv; elsif x<1211 then lbl; elsif s<3532 then AA; else AA; end if; end;\n  procedure jkl is begin if a>569 then RR; elsif a>219 then AA; else AA; end if; end;\n  procedure kd  is begin if a<332 then AA; elsif s>1163 then AA; elsif a<441 then AA; else RR; end if; end;\n  procedure ztq is begin if s<1701 then xg; elsif s>1889 then dmp; elsif x>944 then szs; else kbm; end if; end;\n  procedure vtl is begin if s<1362 then RR; elsif m>1164 then RR; elsif s>1500 then AA; else AA; end if; end;\n  procedure tj  is begin if x>3274 then AA; elsif s<708 then AA; elsif a<1760 then RR; else AA; end if; end;\n  procedure dhp is begin if a>3146 then qzq; else RR; end if; end;\n  procedure bn  is begin if x<466 then RR; else AA; end if; end;\n  procedure jv  is begin if a<3111 then RR; else bkc; end if; end;\n  procedure pjd is begin if m<2011 then cpm; else hrl; end if; end;\n  procedure fh  is begin if a<3064 then RR; elsif s<2885 then jt; elsif x>920 then RR; else clk; end if; end;\n  procedure gf  is begin if s>3568 then AA; else jcs; end if; end;\n  procedure cnb is begin if x>2602 then bgd; else lpq; end if; end;\n  procedure rjs is begin if x<3342 then AA; elsif x>3570 then RR; elsif a<1033 then AA; else RR; end if; end;\n  procedure sl  is begin if m>1009 then fvp; else spg; end if; end;\n  procedure dd  is begin if a<3115 then AA; else RR; end if; end;\n  procedure hl  is begin if a<3182 then RR; elsif x<2541 then AA; elsif s>1661 then RR; else AA; end if; end;\n  procedure zc  is begin if m>3224 then RR; elsif x<1402 then AA; else RR; end if; end;\n  procedure jhv is begin if a>2713 then AA; else nh; end if; end;\n  procedure rjx is begin if s>715 then RR; elsif s<450 then RR; else RR; end if; end;\n  procedure bp  is begin if a>3418 then RR; elsif a>2981 then AA; else RR; end if; end;\n  procedure rj  is begin if m>817 then bp; else AA; end if; end;\n  procedure mmc is begin if a>2356 then bsh; else AA; end if; end;\n  procedure jzr is begin if x>627 then pk; elsif s<3294 then jjc; else td; end if; end;\n  procedure hj  is begin if a<1124 then RR; else AA; end if; end;\n  procedure lpx is begin if x>1886 then RR; elsif s<521 then RR; elsif a<379 then AA; else RR; end if; end;\n  procedure vxl is begin if x>1956 then AA; else RR; end if; end;\n  procedure ncl is begin if m>2887 then AA; else AA; end if; end;\n  procedure hxs is begin if a>3893 then zgx; elsif a>3783 then AA; else RR; end if; end;\n  procedure xv  is begin if a>245 then AA; else lg; end if; end;\n  procedure pfl is begin if a<440 then RR; else AA; end if; end;\n  procedure jhd is begin if a<2796 then AA; elsif a<2813 then RR; else AA; end if; end;\n  procedure vjn is begin if x<2270 then RR; elsif s<1166 then AA; else AA; end if; end;\n  procedure gdk is begin if a>2886 then qds; elsif x>1553 then jkf; else gmg; end if; end;\n  procedure ljv is begin if m>954 then AA; else bqt; end if; end;\n  procedure rf  is begin if m<2314 then AA; else RR; end if; end;\n  procedure zpb is begin if s>1717 then AA; elsif a>434 then RR; else AA; end if; end;\n  procedure xgr is begin if s<2801 then gd; elsif x>2319 then tb; else nv; end if; end;\n  procedure ln  is begin if a<3324 then AA; elsif a<3448 then AA; elsif x>1756 then RR; else AA; end if; end;\n  procedure ntl is begin if s<1540 then RR; elsif x<2910 then AA; elsif x>3423 then AA; else RR; end if; end;\n  procedure fg  is begin if m<3195 then RR; else AA; end if; end;\n  procedure kq  is begin if m<1917 then RR; else AA; end if; end;\n  procedure mln is begin if m>674 then dtc; elsif x<3229 then tl; elsif s<3218 then AA; else AA; end if; end;\n  procedure sjq is begin if x<2421 then RR; elsif s<3380 then zz; else lp; end if; end;\n  procedure rpm is begin if s>67 then RR; elsif x<2573 then AA; else AA; end if; end;\n  procedure jc  is begin if s<799 then AA; elsif m>3802 then AA; else RR; end if; end;\n  procedure lvq is begin if x>3719 then AA; elsif s<3613 then ghp; elsif a<1156 then RR; else AA; end if; end;\n  procedure cc  is begin if m>3325 then AA; elsif m<2610 then RR; elsif m>3049 then zc; else xxd; end if; end;\n  procedure kxk is begin if m<1500 then AA; elsif a>3205 then RR; elsif m<2576 then RR; else lmm; end if; end;\n  procedure qqs is begin if s>3227 then AA; elsif s>2736 then RR; elsif x<2614 then kqb; else kbt; end if; end;\n  procedure lzl is begin if a>399 then RR; else AA; end if; end;\n  procedure sh  is begin if x<2261 then RR; else RR; end if; end;\n  procedure pzx is begin if a<1051 then RR; else RR; end if; end;\n  procedure mrc is begin if x<2382 then RR; elsif a<693 then AA; else RR; end if; end;\n  procedure sx  is begin if x>3458 then AA; else AA; end if; end;\n  procedure sv  is begin if a>2471 then krx; elsif a<2306 then AA; elsif a<2413 then mx; else AA; end if; end;\n  procedure jmf is begin if a<292 then RR; elsif m>1008 then AA; else AA; end if; end;\n  procedure hs  is begin if m<2526 then RR; elsif x>2622 then RR; else RR; end if; end;\n  procedure ljn is begin if m>627 then pf; elsif m>586 then cfj; else bh; end if; end;\n  procedure mq  is begin if x>903 then AA; elsif s>3293 then AA; else RR; end if; end;\n  procedure gc  is begin if a<365 then AA; elsif a<570 then RR; else RR; end if; end;\n  procedure zjx is begin if m>2207 then RR; else RR; end if; end;\n  procedure kqb is begin if m<602 then RR; else AA; end if; end;\n  procedure xr  is begin if s<3802 then RR; else RR; end if; end;\n  procedure lhx is begin if m>3170 then AA; else rgl; end if; end;\n  procedure kct is begin if a<1891 then ttc; else zm; end if; end;\n  procedure vn  is begin if a>2795 then AA; elsif s<3343 then AA; else AA; end if; end;\n  procedure bvg is begin if a>1980 then AA; else RR; end if; end;\n  procedure tzr is begin if a>2885 then AA; elsif s<3105 then RR; else AA; end if; end;\n  procedure ghp is begin if s>3260 then AA; else AA; end if; end;\n  procedure ljh is begin if m>884 then zpb; else AA; end if; end;\n  procedure crk is begin if s<1819 then zgv; elsif m<3162 then lz; elsif a<1774 then kh; else nx; end if; end;\n  procedure ttc is begin if x<2046 then RR; else AA; end if; end;\n  procedure hmd is begin if a<2368 then RR; elsif m>1132 then RR; elsif x<1075 then AA; else AA; end if; end;\n  procedure tb  is begin if s>3294 then RR; elsif s>2982 then AA; elsif x<3285 then AA; else RR; end if; end;\n  procedure skm is begin if s>1721 then gkt; elsif a>382 then lxb; elsif s>1637 then AA; else AA; end if; end;\n  procedure bmk is begin if x<3657 then fl; elsif a<3341 then RR; else RR; end if; end;\n  procedure frf is begin if m<2252 then xmx; elsif s<1800 then bb; elsif x>515 then sdr; else dhp; end if; end;\n  procedure grp is begin if a>1183 then RR; elsif x>2651 then RR; else RR; end if; end;\n  procedure qzr is begin if a>1128 then RR; elsif a>1121 then AA; else AA; end if; end;\n  procedure xxd is begin if x>1538 then AA; elsif a>2807 then RR; elsif s<361 then RR; else AA; end if; end;\n  procedure nvs is begin if s<2686 then RR; elsif a>148 then RR; else AA; end if; end;\n  procedure sbd is begin if a>2540 then RR; elsif a>2502 then AA; elsif x<3553 then RR; else RR; end if; end;\n  procedure rmb is begin if x<949 then AA; elsif x<1340 then RR; else RR; end if; end;\n  procedure sbh is begin if x>3465 then zxc; elsif m>810 then AA; else qrq; end if; end;\n  procedure kmc is begin if m>2641 then mqh; else RR; end if; end;\n  procedure ks  is begin if m<1434 then vq; elsif m<2308 then rs; elsif x>1362 then hr; else rzc; end if; end;\n  procedure dxl is begin if x>2295 then RR; elsif a>2873 then AA; elsif s<3812 then AA; else RR; end if; end;\n  procedure czp is begin if m<90 then AA; elsif x>3608 then AA; elsif s<1450 then AA; else RR; end if; end;\n  procedure lbl is begin if x>571 then AA; else RR; end if; end;\n  procedure mbj is begin if x>2946 then AA; elsif s<1470 then cmf; elsif x<2327 then RR; else AA; end if; end;\n  procedure jsn is begin if s>871 then AA; elsif x>2587 then AA; else AA; end if; end;\n  procedure qjg is begin if s>3258 then RR; elsif m>2447 then AA; elsif x>549 then AA; else AA; end if; end;\n  procedure tq  is begin if s<2590 then lk; elsif a<3153 then gdk; else ctt; end if; end;\n  procedure qnp is begin if s>2942 then RR; elsif s<2748 then RR; else RR; end if; end;\n  procedure gnb is begin if s>1449 then RR; elsif a<3469 then AA; else RR; end if; end;\n  procedure xq  is begin if x<740 then RR; elsif x>822 then AA; elsif s>1796 then AA; else RR; end if; end;\n  procedure ddr is begin if x>825 then kmc; elsif a<2829 then rnh; else hb; end if; end;\n  procedure nl  is begin if s<112 then rpm; else RR; end if; end;\n  procedure bgz is begin if s<3472 then AA; elsif s<3715 then frc; elsif s>3840 then RR; else fj; end if; end;\n  procedure xd  is begin if s<3101 then bv; elsif a<3302 then jcf; elsif s<3572 then jh; else xr; end if; end;\n  procedure rxc is begin if m>891 then AA; else AA; end if; end;\n  procedure gj  is begin if m<673 then RR; else zds; end if; end;\n  procedure nzb is begin if m<3405 then RR; else lbm; end if; end;\n  procedure gg  is begin if a<1286 then mgs; elsif m>935 then bxg; elsif x<2090 then AA; else RR; end if; end;\n  procedure lcg is begin if m<1248 then AA; elsif s>3297 then AA; elsif s>2766 then AA; else RR; end if; end;\n  procedure gq  is begin if x<3301 then mz; else lvq; end if; end;\n  procedure cng is begin if x>2558 then rjs; elsif x>992 then sts; else vfk; end if; end;\n  procedure gkl is begin if m>2141 then dfh; elsif m<1900 then db; elsif x>1897 then vd; else sp; end if; end;\n  procedure zx  is begin if m>98 then RR; else RR; end if; end;\n  procedure jcs is begin if m<1494 then AA; elsif x<389 then AA; elsif a>3699 then AA; else RR; end if; end;\n  procedure sdm is begin if a>2317 then AA; else RR; end if; end;\n  procedure btg is begin if s>1891 then AA; elsif x<2144 then AA; elsif s>906 then AA; else RR; end if; end;\n  procedure rq  is begin if x<2267 then RR; elsif a<513 then RR; elsif x<3300 then AA; else AA; end if; end;\n  procedure fpj is begin if s>3216 then lb; elsif a>2662 then RR; elsif s<2815 then AA; else psj; end if; end;\n  procedure vd  is begin if a<417 then xv; elsif a>769 then bk; else jps; end if; end;\n  procedure qvd is begin if a>1423 then kct; elsif a<832 then cql; else xkq; end if; end;\n  procedure nxf is begin if m>2417 then xd; else rc; end if; end;\n  procedure rhb is begin if a<3055 then RR; else AA; end if; end;\n  procedure hq  is begin if s>949 then zd; else vcn; end if; end;\n  procedure qv  is begin if a<270 then nls; elsif x<2596 then AA; else RR; end if; end;\n  procedure hv  is begin if a>116 then AA; elsif a<67 then RR; elsif s<2371 then RR; else AA; end if; end;\n  procedure ttv is begin if a<3583 then RR; elsif a<3757 then RR; elsif s>500 then RR; else AA; end if; end;\n  procedure nv  is begin if a>1042 then AA; elsif x<1348 then AA; else RR; end if; end;\n  procedure cgx is begin if a>1726 then AA; else AA; end if; end;\n  procedure mz  is begin if s>3365 then qqp; else RR; end if; end;\n  procedure jnn is begin if x>2684 then AA; elsif m<1408 then RR; else AA; end if; end;\n  procedure vf  is begin if x<715 then AA; else AA; end if; end;\n  procedure gfk is begin if a<633 then zv; elsif a>1261 then vxl; else cr; end if; end;\n  procedure dcg is begin if x<1256 then vs; elsif x>1509 then hxj; elsif s>1703 then ks; else fm; end if; end;\n  procedure mp  is begin if m>1507 then jfk; elsif m<526 then cv; elsif s>2468 then zf; else ctn; end if; end;\n  procedure mg  is begin if x<1958 then AA; elsif a>1912 then AA; else AA; end if; end;\n  procedure hzc is begin if s>3226 then AA; elsif x>2499 then AA; elsif a<2843 then AA; else RR; end if; end;\n  procedure nc  is begin if m<494 then RR; else RR; end if; end;\n  procedure vlr is begin if a<1639 then RR; elsif m>965 then AA; else RR; end if; end;\n  procedure xkx is begin if s<2878 then RR; elsif s<3070 then RR; else AA; end if; end;\n  procedure bb  is begin if a>3530 then RR; elsif s<1510 then AA; else RR; end if; end;\n  procedure nh  is begin if x>1430 then RR; elsif a>2684 then AA; elsif m<2349 then AA; else RR; end if; end;\n  procedure dh  is begin if x<1024 then RR; else AA; end if; end;\n  procedure gmg is begin if a>2772 then ddr; else cl; end if; end;\n  procedure cl  is begin if x<745 then qmm; elsif x<1185 then ltl; else jhv; end if; end;\n  procedure xkb is begin if s<1903 then RR; elsif x>2528 then RR; else RR; end if; end;\n  procedure cbb is begin if m<1781 then AA; else qr; end if; end;\n  procedure fr  is begin if s<3106 then slq; else RR; end if; end;\n  procedure mh  is begin if m>2269 then AA; elsif x<1093 then AA; elsif a<2684 then AA; else RR; end if; end;\n  procedure cv  is begin if m<197 then qvd; else tck; end if; end;\n  procedure mlj is begin if s<3617 then pzx; else sh; end if; end;\n  procedure dcz is begin if a<3605 then lv; elsif a<3752 then AA; elsif s<468 then RR; else RR; end if; end;\n  procedure vcn is begin if s<524 then RR; elsif x<1378 then RR; else vqv; end if; end;\n  procedure kqs is begin if x<1335 then RR; else lr; end if; end;\n  procedure mcq is begin if x>1676 then ttv; else AA; end if; end;\n  procedure hxt is begin if s<2024 then gnb; elsif m>1410 then pj; elsif m<736 then RR; else dtj; end if; end;\n  procedure ld  is begin if s<3688 then ggh; elsif s<3793 then AA; elsif m>1290 then AA; else AA; end if; end;\n  procedure xs  is begin if x>258 then AA; elsif s<1774 then RR; else RR; end if; end;\n  procedure mfn is begin if s<1906 then RR; else AA; end if; end;\n  procedure qfs is begin if m>1437 then RR; else RR; end if; end;\n  procedure tx  is begin if a<3403 then jzm; else tn; end if; end;\n  procedure rct is begin if m<1016 then AA; elsif s<2621 then RR; else RR; end if; end;\n  procedure nd  is begin if s>3135 then AA; else RR; end if; end;\n  procedure jjc is begin if s>2911 then mhf; elsif m<1665 then hxg; elsif x<348 then qcr; else lx; end if; end;\n  procedure gtq is begin if m>961 then xbr; elsif m<830 then AA; elsif x<507 then AA; else vnq; end if; end;\n  procedure cx  is begin if m>268 then AA; else AA; end if; end;\n  procedure xf  is begin if x<345 then AA; elsif s>3174 then RR; elsif m<1739 then AA; else AA; end if; end;\n  procedure cbv is begin if m>1242 then AA; elsif m>1121 then RR; elsif x>897 then RR; else AA; end if; end;\n  procedure zgv is begin if x>2074 then AA; elsif s>733 then AA; elsif s<478 then RR; else RR; end if; end;\n  procedure dgf is begin if x<494 then rtk; elsif x<648 then bj; else xq; end if; end;\n  procedure xg  is begin if x<795 then AA; elsif s>1607 then AA; elsif m>3324 then RR; else dm; end if; end;\n  procedure tzv is begin if m<1869 then jhs; elsif m>3270 then km; elsif x>493 then plc; else zs; end if; end;\n  procedure nt  is begin if a>3068 then AA; elsif a<3045 then AA; else RR; end if; end;\n  procedure gbv is begin if s<3584 then RR; elsif s<3728 then RR; else RR; end if; end;\n  procedure qmm is begin if m>2061 then zh; else RR; end if; end;\n  procedure cr  is begin if x>1870 then RR; elsif x>982 then AA; elsif s<463 then RR; else rl; end if; end;\n  procedure gxs is begin if s>3087 then AA; elsif m>385 then AA; elsif a<280 then RR; else rq; end if; end;\n  procedure ctq is begin if a>987 then RR; else RR; end if; end;\n  procedure mfh is begin if a>1105 then ll; else lm; end if; end;\n  procedure ff  is begin if x<1886 then pt; elsif m<1867 then AA; else RR; end if; end;\n  procedure ggb is begin if a<657 then RR; elsif a>714 then RR; else RR; end if; end;\n  procedure jkf is begin if a<2776 then jjm; elsif a<2825 then bhj; elsif a<2860 then hhd; else jhl; end if; end;\n  procedure fdx is begin if s>3342 then RR; else RR; end if; end;\n  procedure bls is begin if s<1648 then mbj; elsif x>3066 then sbh; else nlk; end if; end;\n  procedure czg is begin if s<3077 then RR; elsif x<2514 then AA; else RR; end if; end;\n  procedure sxz is begin if m<937 then grp; elsif s<2655 then mll; elsif m>1045 then vsx; else sl; end if; end;\n  procedure vqn is begin if m<1679 then RR; elsif a>2998 then AA; else RR; end if; end;\n  procedure vdv is begin if s>2257 then RR; elsif a<3750 then AA; elsif s<2080 then AA; else RR; end if; end;\n  procedure nsx is begin if s>1907 then AA; elsif a>3246 then AA; else AA; end if; end;\n  procedure gd  is begin if x<2557 then AA; elsif a>1050 then RR; elsif s>2360 then RR; else RR; end if; end;\n  procedure vnp is begin if x<1424 then AA; elsif x>1732 then AA; else AA; end if; end;\n  procedure dtc is begin if m>702 then RR; else AA; end if; end;\n  procedure glj is begin if s>2917 then AA; else AA; end if; end;\n  procedure qt  is begin if s>3494 then dxl; elsif x<2302 then kf; else RR; end if; end;\n  procedure xzk is begin if a>296 then RR; elsif x>2358 then RR; else hv; end if; end;\n  procedure mls is begin if s<2885 then AA; elsif m>1811 then AA; else AA; end if; end;\n  procedure qvc is begin if a<1613 then gfk; elsif a>2225 then kfr; elsif a<1820 then xrc; else nbz; end if; end;\n  procedure ctb is begin if s>2109 then RR; else AA; end if; end;\n  procedure xz  is begin if s<3018 then sxz; elsif x>2273 then gq; else fnv; end if; end;\n  procedure lg  is begin if m<2007 then AA; elsif m<2082 then RR; else AA; end if; end;\n  procedure lpq is begin if s>3341 then zjx; else zxh; end if; end;\n  procedure jhh is begin if m<3882 then AA; elsif s<3163 then mrc; elsif s<3625 then nm; else RR; end if; end;\n  procedure tc  is begin if a<3635 then AA; else AA; end if; end;\n  procedure gx  is begin if a<1752 then AA; elsif x<2622 then AA; else AA; end if; end;\n  procedure mqj is begin if a>2450 then RR; else RR; end if; end;\n  procedure bz  is begin if a>676 then AA; elsif s>2182 then AA; else RR; end if; end;\n  procedure fnv is begin if x>879 then mfh; elsif s<3449 then ljv; elsif a>1353 then gtq; else bxb; end if; end;\n  procedure zfm is begin if x>3316 then czp; else RR; end if; end;\n  procedure vsx is begin if x>1654 then jbk; elsif s>2805 then RR; elsif a>1136 then ksl; else hcz; end if; end;\n  procedure csr is begin if m<3505 then RR; else AA; end if; end;\n  procedure mhf is begin if s<3158 then RR; elsif s<3205 then xf; elsif x<414 then jx; else qjg; end if; end;\n  procedure vc  is begin if s<1158 then qq; else frf; end if; end;\n  procedure qnv is begin if m<696 then RR; else RR; end if; end;\n  procedure cm  is begin if m>3441 then RR; elsif x<1223 then RR; elsif x>1733 then AA; else AA; end if; end;\n  procedure jhl is begin if x<3102 then qt; elsif a<2877 then cs; elsif a>2880 then cn; else cbb; end if; end;\n  procedure sq  is begin if a>671 then AA; elsif s<1821 then AA; elsif x>1635 then RR; else RR; end if; end;\n  procedure hvz is begin if m>2461 then RR; else AA; end if; end;\n  procedure tr  is begin if m>563 then RR; else RR; end if; end;\n  procedure cgv is begin if a<2538 then RR; else AA; end if; end;\n  procedure ps  is begin if x<1895 then RR; elsif x>3216 then RR; else AA; end if; end;\n  procedure rm  is begin if s<3054 then RR; elsif s>3470 then AA; elsif m>1762 then RR; else AA; end if; end;\n  procedure qp  is begin if m<2013 then AA; elsif s<1385 then RR; elsif s>1514 then RR; else AA; end if; end;\n  procedure qj  is begin if m<3381 then fg; elsif m<3694 then pqb; else jhh; end if; end;\n  procedure qr  is begin if x<3568 then AA; elsif m<2760 then AA; else RR; end if; end;\n  procedure tfs is begin if s>433 then AA; elsif x<1324 then RR; else AA; end if; end;\n  procedure cql is begin if x<2048 then rk; else zfm; end if; end;\n  procedure fvp is begin if m>1027 then AA; elsif x<2630 then RR; elsif x<3279 then RR; else AA; end if; end;\n  procedure tgt is begin if a>1670 then RR; else mnr; end if; end;\n  procedure tn  is begin if m>824 then RR; else AA; end if; end;\n  procedure fl  is begin if x<3396 then AA; else AA; end if; end;\n  procedure vv  is begin if s>3244 then RR; elsif a<3126 then dd; elsif s<2826 then rf; else RR; end if; end;\n  procedure lr  is begin if s<2004 then AA; else RR; end if; end;\n  procedure xhx is begin if x<1756 then scv; else cx; end if; end;\n  procedure jzm is begin if x>1343 then AA; elsif x>703 then RR; elsif a>3373 then AA; else AA; end if; end;\n  procedure tlj is begin if s>1605 then nbf; else tdg; end if; end;\n  procedure xk  is begin if x>152 then RR; else AA; end if; end;\n  procedure mt  is begin if m<2968 then qps; elsif a>701 then hq; else lh; end if; end;\n  procedure zk  is begin if m>416 then RR; elsif x>3052 then AA; elsif x<2638 then AA; else AA; end if; end;\n  procedure zn  is begin if a<2399 then AA; else AA; end if; end;\n  procedure ggh is begin if m<894 then AA; elsif a>3830 then AA; elsif a>3691 then RR; else AA; end if; end;\n  procedure ht  is begin if x<1797 then AA; elsif s>2872 then AA; else AA; end if; end;\n  procedure jbl is begin if m>1401 then RR; else dp; end if; end;\n  procedure vfk is begin if x<479 then RR; elsif m>117 then AA; else AA; end if; end;\n  procedure qdz is begin if s>554 then RR; elsif s<239 then cpv; else RR; end if; end;\n  procedure ll  is begin if s>3366 then AA; elsif s<3226 then AA; else RR; end if; end;\n  procedure vbp is begin if a<527 then RR; elsif m>2007 then gk; else pz; end if; end;\n  procedure rhg is begin if m<1474 then AA; elsif a>1417 then AA; elsif a<862 then AA; else AA; end if; end;\n  procedure inn is begin if a>2639 then tq; else mp; end if; end;\n  procedure bv  is begin if m<3468 then ln; else ht; end if; end;\n  procedure zgx is begin if a>3932 then RR; elsif a>3907 then RR; elsif x>1109 then RR; else RR; end if; end;\n  procedure hx  is begin if a<449 then jc; else RR; end if; end;\n  procedure cfj is begin if a>1414 then fr; elsif a>556 then sjq; elsif a>190 then npl; else qqs; end if; end;\n  procedure mr  is begin if m<2693 then AA; else AA; end if; end;\n  procedure hcp is begin if a>1108 then RR; else RR; end if; end;\n  procedure bf  is begin if x>3211 then vv; else hpl; end if; end;\n  procedure rtg is begin if a>1997 then rxc; else jl; end if; end;\n  procedure qcr is begin if x>162 then AA; elsif x>74 then AA; elsif s>2711 then bjq; else AA; end if; end;\n  procedure xnv is begin if m<724 then sxc; elsif x<921 then qzx; elsif a<2263 then mn; else lxc; end if; end;\n  procedure pbx is begin if a>826 then ctq; elsif m<3306 then AA; else zlr; end if; end;\n  procedure nlp is begin if s>1893 then AA; else RR; end if; end;\n  procedure mfr is begin if x<2238 then RR; else RR; end if; end;\n  procedure tg  is begin if a<2948 then ff; else kz; end if; end;\n  procedure tnp is begin if a<3177 then RR; elsif s>2055 then AA; else AA; end if; end;\n  procedure slq is begin if m>611 then RR; else AA; end if; end;\n  procedure fz  is begin if m>2476 then RR; elsif s>3368 then RR; elsif s<2963 then RR; else AA; end if; end;\n  procedure rgz is begin if a<1096 then AA; elsif x<2237 then RR; else RR; end if; end;\n  procedure rg  is begin if x<396 then RR; elsif a<3472 then qs; else RR; end if; end;\n  procedure nm  is begin if x>2253 then AA; else RR; end if; end;\n  procedure mdc is begin if x>1209 then gz; elsif s<3278 then vf; else AA; end if; end;\n  procedure pbt is begin if a>1678 then AA; elsif x>3246 then vlr; elsif m<1092 then RR; else RR; end if; end;\n  procedure dbl is begin if m<2274 then RR; elsif m<2607 then mc; else lpx; end if; end;\n  procedure cn  is begin if a<2884 then dz; elsif x>3410 then sg; elsif s>3454 then RR; else tzr; end if; end;\n  procedure hb  is begin if s>3486 then RR; elsif a>2860 then glj; elsif x<378 then AA; else gjs; end if; end;\n  procedure nls is begin if a<134 then AA; elsif s>1825 then RR; elsif m<3471 then AA; else AA; end if; end;\n  procedure tl  is begin if s>3434 then AA; else AA; end if; end;\n  procedure bl  is begin if a<555 then RR; elsif a>1174 then AA; else RR; end if; end;\n  procedure mml is begin if a<3707 then AA; else RR; end if; end;\n  procedure dtm is begin if x>2903 then hlx; elsif a>1934 then xkb; else nlp; end if; end;\n  procedure rb  is begin if a>379 then AA; elsif x<2450 then nvs; elsif a>224 then AA; else sx; end if; end;\n  procedure pf  is begin if x<1899 then fpz; else mln; end if; end;\n  procedure zmn is begin if m>882 then AA; elsif a>2320 then RR; elsif a>2208 then RR; else AA; end if; end;\n  procedure jh  is begin if x<2603 then fdx; else RR; end if; end;\n  procedure crh is begin if a>1398 then xkx; elsif s>2903 then gbg; else RR; end if; end;\n  procedure fmp is begin if a>709 then RR; elsif x<507 then AA; elsif s>2752 then RR; else AA; end if; end;\n  procedure sg  is begin if m>1527 then RR; else RR; end if; end;\n  procedure sp  is begin if x>1242 then vbp; else fmp; end if; end;\n  procedure cj  is begin if m<564 then AA; elsif x<900 then AA; else RR; end if; end;\n  procedure khv is begin if s>2714 then qj; elsif s>2119 then xfp; elsif x>2174 then csz; else ztq; end if; end;\n  procedure lsz is begin if m<3503 then AA; else AA; end if; end;\n  procedure dfh is begin if a<612 then rb; elsif a<1008 then mfr; elsif a>1087 then st; else xgr; end if; end;\n  procedure lm  is begin if x>1566 then RR; elsif s>3634 then AA; elsif m<917 then AA; else AA; end if; end;\n  procedure hn  is begin if x>1169 then RR; else nt; end if; end;\n  procedure pp  is begin if x>2075 then jct; elsif m<1540 then hn; elsif s>3287 then ksd; else fh; end if; end;\n  procedure ddf is begin if s>3058 then AA; else AA; end if; end;\n  procedure mn  is begin if x>1509 then RR; else RR; end if; end;\n  procedure hc  is begin if m>452 then nc; elsif s<2479 then hml; elsif a>714 then crf; else gxs; end if; end;\n  procedure lgt is begin if x>1822 then AA; elsif m>1939 then RR; elsif s>1685 then sj; else vtl; end if; end;\n  procedure pmb is begin if x<1257 then RR; else RR; end if; end;\n  procedure bq  is begin if m>749 then hl; elsif a<2978 then RR; elsif m>283 then AA; else gcm; end if; end;\n  procedure dj  is begin if x>419 then RR; elsif m>890 then AA; elsif m<591 then RR; else RR; end if; end;\n  procedure lz  is begin if m>2383 then RR; elsif a<1605 then AA; else nd; end if; end;\n  procedure rlz is begin if x<908 then dgf; elsif m<2926 then mmc; elsif m>3586 then kl; else kqs; end if; end;\n  procedure lbs is begin if m<1371 then lcg; elsif m>1435 then rhg; else jnn; end if; end;\n  procedure hml is begin if m<403 then jkl; elsif x<2272 then RR; elsif m<428 then zk; else bl; end if; end;\n  procedure ckz is begin if s<3014 then RR; elsif m>1426 then AA; elsif a>431 then AA; else AA; end if; end;\n  procedure ft  is begin if x<2599 then RR; else AA; end if; end;\n  procedure mxb is begin if x<3119 then lbs; elsif s>3317 then mth; else crh; end if; end;\n  procedure vh  is begin if x>2169 then mxb; else npb; end if; end;\n  procedure rc  is begin if a<3327 then jbl; elsif x>2380 then bgz; elsif s<3109 then tx; else qb; end if; end;\n  procedure zm  is begin if m<76 then btg; else RR; end if; end;\n  procedure jhs is begin if a<3796 then AA; elsif a<3916 then RR; elsif a>3966 then RR; else AA; end if; end;\n  procedure hhd is begin if x>2759 then kj; elsif x<2163 then qfs; else nr; end if; end;\n  procedure zds is begin if m<1380 then RR; else RR; end if; end;\n  procedure zd  is begin if a>899 then pbh; else vjn; end if; end;\n  procedure xvn is begin if s>2657 then pfl; else RR; end if; end;\n\n  --  pragma Style_Checks (On);\n\n  r : array (Part_Type) of Integer_64;\n\n  choice : Data_Type;\n\n  procedure Do_Part_1 is\n    sum : Integer_64 := 0;\n\n    procedure Mini_Test (x0, m0, a0, s0 : Natural) is\n    begin\n      x := x0;\n      m := m0;\n      a := a0;\n      s := s0;\n      m_in;\n      if ok then\n        sum := sum + Integer_64 (x + m + a + s);\n      end if;\n    end Mini_Test;\n\n    procedure Input_Test (x0, m0, a0, s0 : Natural) is\n    begin\n      x := x0;\n      m := m0;\n      a := a0;\n      s := s0;\n      inn;\n      if ok then\n        sum := sum + Integer_64 (x + m + a + s);\n      end if;\n    end Input_Test;\n  begin\n    ok := False;\n    case choice is\n      when mini =>\n        Mini_Test (787,  2655, 1222, 2876);\n        Mini_Test (1679, 44,   2067, 496);\n        Mini_Test (2036, 264,  79,   2244);\n        Mini_Test (2461, 1339, 466,  291);\n        Mini_Test (2127, 1623, 2188, 1013);\n      when input =>\n        Input_Test (6, 309, 1182, 757);\n        Input_Test (531, 106, 1009, 142);\n        Input_Test (3264, 506, 301, 807);\n        Input_Test (1197, 394, 351, 1266);\n        Input_Test (3009, 1048, 143, 1549);\n        Input_Test (617, 1696, 778, 28);\n        Input_Test (172, 2243, 1135, 2330);\n        Input_Test (309, 457, 1943, 8);\n        Input_Test (424, 100, 288, 1745);\n        Input_Test (282, 138, 2134, 272);\n        Input_Test (2982, 2488, 1452, 3065);\n        Input_Test (1760, 2317, 3608, 119);\n        Input_Test (682, 303, 1113, 34);\n        Input_Test (806, 3417, 720, 1219);\n        Input_Test (908, 2564, 1065, 766);\n        Input_Test (1044, 70, 511, 1410);\n        Input_Test (848, 262, 1100, 778);\n        Input_Test (1042, 1887, 2083, 847);\n        Input_Test (1051, 1636, 187, 892);\n        Input_Test (782, 489, 1940, 18);\n        Input_Test (33, 1970, 838, 1123);\n        Input_Test (20, 2180, 2036, 1720);\n        Input_Test (468, 788, 170, 983);\n        Input_Test (1893, 1399, 1661, 1493);\n        Input_Test (42, 604, 2889, 219);\n        Input_Test (109, 56, 1004, 2498);\n        Input_Test (1249, 213, 329, 117);\n        Input_Test (544, 380, 124, 1479);\n        Input_Test (1222, 996, 498, 2270);\n        Input_Test (38, 228, 59, 1060);\n        Input_Test (17, 613, 2060, 1358);\n        Input_Test (188, 976, 100, 1415);\n        Input_Test (965, 641, 1563, 2718);\n        Input_Test (867, 386, 1798, 682);\n        Input_Test (1596, 350, 143, 167);\n        Input_Test (390, 2438, 225, 171);\n        Input_Test (1014, 1030, 718, 2678);\n        Input_Test (473, 2034, 1270, 449);\n        Input_Test (2092, 268, 653, 691);\n        Input_Test (951, 16, 1869, 2764);\n        Input_Test (494, 154, 178, 1323);\n        Input_Test (2653, 1230, 238, 787);\n        Input_Test (922, 1420, 1390, 2030);\n        Input_Test (2958, 2763, 1486, 2822);\n        Input_Test (615, 373, 31, 1548);\n        Input_Test (1275, 1486, 2205, 171);\n        Input_Test (1, 2571, 234, 1346);\n        Input_Test (945, 107, 99, 754);\n        Input_Test (1398, 1428, 556, 1724);\n        Input_Test (693, 3354, 3, 218);\n        Input_Test (1706, 39, 1620, 1403);\n        Input_Test (465, 408, 2153, 651);\n        Input_Test (1026, 794, 340, 920);\n        Input_Test (1275, 1806, 120, 599);\n        Input_Test (78, 1030, 1601, 1019);\n        Input_Test (2442, 1645, 331, 69);\n        Input_Test (1797, 480, 479, 1634);\n        Input_Test (135, 1838, 216, 1293);\n        Input_Test (1914, 1031, 53, 23);\n        Input_Test (2862, 303, 883, 537);\n        Input_Test (60, 192, 109, 1577);\n        Input_Test (527, 629, 103, 136);\n        Input_Test (66, 1861, 135, 1026);\n        Input_Test (105, 678, 2551, 495);\n        Input_Test (2558, 33, 322, 1359);\n        Input_Test (2032, 376, 39, 857);\n        Input_Test (929, 1035, 174, 2372);\n        Input_Test (731, 156, 26, 2512);\n        Input_Test (1120, 880, 500, 1070);\n        Input_Test (845, 108, 1492, 1340);\n        Input_Test (2460, 2527, 1057, 1382);\n        Input_Test (390, 942, 953, 402);\n        Input_Test (557, 440, 335, 426);\n        Input_Test (1850, 3068, 1956, 258);\n        Input_Test (351, 296, 222, 181);\n        Input_Test (27, 389, 650, 999);\n        Input_Test (1941, 3377, 1600, 1377);\n        Input_Test (62, 2099, 9, 25);\n        Input_Test (34, 658, 215, 32);\n        Input_Test (1408, 989, 54, 560);\n        Input_Test (969, 431, 634, 856);\n        Input_Test (75, 678, 1523, 157);\n        Input_Test (1087, 837, 763, 118);\n        Input_Test (112, 904, 3317, 313);\n        Input_Test (2163, 1100, 271, 882);\n        Input_Test (474, 289, 305, 197);\n        Input_Test (1307, 2741, 279, 1550);\n        Input_Test (1109, 629, 1600, 298);\n        Input_Test (868, 815, 2970, 21);\n        Input_Test (1850, 285, 1158, 373);\n        Input_Test (1430, 1078, 226, 2374);\n        Input_Test (296, 413, 1609, 1099);\n        Input_Test (11, 3105, 505, 2170);\n        Input_Test (2126, 1961, 389, 1087);\n        Input_Test (592, 1842, 1991, 1083);\n        Input_Test (93, 1662, 1840, 2377);\n        Input_Test (433, 30, 1269, 857);\n        Input_Test (1898, 662, 861, 1131);\n        Input_Test (2484, 278, 1782, 134);\n        Input_Test (102, 1146, 3527, 2090);\n        Input_Test (2530, 727, 1577, 211);\n        Input_Test (316, 2957, 18, 730);\n        Input_Test (492, 183, 624, 1454);\n        Input_Test (3325, 30, 1660, 938);\n        Input_Test (407, 1854, 99, 326);\n        Input_Test (1336, 1276, 473, 24);\n        Input_Test (1718, 438, 956, 384);\n        Input_Test (353, 1534, 2180, 2974);\n        Input_Test (2705, 211, 94, 837);\n        Input_Test (104, 123, 413, 1789);\n        Input_Test (176, 395, 2652, 50);\n        Input_Test (738, 1018, 103, 200);\n        Input_Test (750, 31, 916, 121);\n        Input_Test (2967, 1253, 1593, 1357);\n        Input_Test (262, 112, 131, 63);\n        Input_Test (145, 807, 291, 959);\n        Input_Test (1476, 239, 1054, 3491);\n        Input_Test (428, 351, 2465, 65);\n        Input_Test (35, 236, 863, 1089);\n        Input_Test (1233, 2010, 177, 764);\n        Input_Test (1083, 1863, 25, 1974);\n        Input_Test (957, 1180, 837, 679);\n        Input_Test (66, 1204, 285, 2075);\n        Input_Test (444, 560, 172, 1447);\n        Input_Test (812, 350, 876, 661);\n        Input_Test (200, 366, 752, 851);\n        Input_Test (749, 377, 815, 648);\n        Input_Test (60, 285, 517, 39);\n        Input_Test (2921, 381, 119, 249);\n        Input_Test (466, 1290, 801, 2159);\n        Input_Test (62, 201, 881, 95);\n        Input_Test (3598, 126, 1688, 979);\n        Input_Test (2963, 1112, 2733, 520);\n        Input_Test (62, 1067, 920, 451);\n        Input_Test (2501, 475, 1074, 1150);\n        Input_Test (50, 1111, 12, 44);\n        Input_Test (617, 1106, 1489, 1333);\n        Input_Test (90, 208, 219, 2352);\n        Input_Test (1179, 2166, 1693, 2055);\n        Input_Test (61, 595, 1382, 1140);\n        Input_Test (62, 354, 123, 793);\n        Input_Test (436, 865, 2408, 2578);\n        Input_Test (515, 398, 303, 312);\n        Input_Test (637, 2236, 474, 148);\n        Input_Test (2488, 35, 75, 924);\n        Input_Test (461, 1196, 7, 1092);\n        Input_Test (923, 3184, 1161, 308);\n        Input_Test (191, 1399, 1324, 2784);\n        Input_Test (170, 421, 51, 625);\n        Input_Test (170, 362, 471, 2100);\n        Input_Test (289, 66, 143, 284);\n        Input_Test (542, 339, 455, 54);\n        Input_Test (155, 124, 732, 2057);\n        Input_Test (8, 420, 784, 1455);\n        Input_Test (479, 251, 1883, 136);\n        Input_Test (104, 146, 97, 249);\n        Input_Test (2766, 833, 386, 585);\n        Input_Test (373, 514, 466, 2192);\n        Input_Test (296, 1190, 249, 963);\n        Input_Test (518, 1840, 860, 306);\n        Input_Test (1003, 1955, 756, 1098);\n        Input_Test (1545, 242, 1479, 576);\n        Input_Test (77, 1717, 475, 1692);\n        Input_Test (417, 1517, 2199, 374);\n        Input_Test (3247, 348, 1065, 1154);\n        Input_Test (456, 868, 182, 1077);\n        Input_Test (464, 425, 15, 781);\n        Input_Test (640, 294, 303, 261);\n        Input_Test (1018, 327, 18, 1830);\n        Input_Test (262, 988, 1974, 1665);\n        Input_Test (123, 525, 3062, 460);\n        Input_Test (228, 2020, 29, 701);\n        Input_Test (129, 1163, 1561, 958);\n        Input_Test (29, 1576, 74, 348);\n        Input_Test (64, 2153, 63, 1771);\n        Input_Test (71, 66, 1642, 1749);\n        Input_Test (1373, 3063, 1958, 561);\n        Input_Test (2277, 3766, 384, 363);\n        Input_Test (2956, 127, 865, 1862);\n        Input_Test (599, 115, 2360, 526);\n        Input_Test (651, 644, 580, 514);\n        Input_Test (880, 173, 613, 3270);\n        Input_Test (1228, 951, 1515, 333);\n        Input_Test (1621, 2392, 2665, 1515);\n        Input_Test (933, 1805, 228, 1720);\n        Input_Test (25, 1553, 54, 3177);\n        Input_Test (85, 550, 273, 142);\n        Input_Test (489, 624, 126, 557);\n        Input_Test (256, 2513, 509, 186);\n        Input_Test (2616, 377, 2497, 707);\n        Input_Test (688, 509, 410, 557);\n        Input_Test (1306, 105, 1605, 3217);\n        Input_Test (1405, 31, 824, 543);\n        Input_Test (600, 559, 1299, 110);\n        Input_Test (2683, 1112, 458, 27);\n        Input_Test (1240, 882, 417, 1066);\n        Input_Test (651, 667, 178, 3045);\n        Input_Test (2089, 19, 879, 90);\n        Input_Test (263, 423, 41, 734);\n        Input_Test (630, 44, 135, 98);\n    end case;\n    r (part_1) := sum;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n  \n    subtype XMAS_Rating_Range is Integer_64 range 1 .. 4000;\n    \n    sum : Integer_64 := 0;\n    width_x, width_m, width_a, width_s : XMAS_Rating_Range;\n    \n    procedure Part_2_Mini is\n      d_x : array (1 .. 5) of Positive;\n      d_m : array (1 .. 6) of Positive;\n      d_a : array (1 .. 5) of Positive;\n      d_s : array (1 .. 6) of Positive;\n    begin\n      d_x (1) := 1;\n      d_x (2) := 1416;\n      d_x (3) := 2441;\n      d_x (4) := 2663;\n      d_x (5) := 4001;\n      --\n      d_m (1) := 1;\n      d_m (2) := 839;\n      d_m (3) := 1549;\n      d_m (4) := 1801;\n      d_m (5) := 2091;\n      d_m (6) := 4001;\n      --\n      d_a (1) := 1;\n      d_a (2) := 1717;\n      d_a (3) := 2006;\n      d_a (4) := 3334;\n      d_a (5) := 4001;\n      --\n      d_s (1) := 1;\n      d_s (2) := 537;\n      d_s (3) := 1351;\n      d_s (4) := 2771;\n      d_s (5) := 3449;\n      d_s (6) := 4001;\n      --\n      for i_x in 1 .. d_x'Last - 1 loop\n        width_x := XMAS_Rating_Range (d_x (i_x + 1) - d_x (i_x));\n        x := d_x (i_x);\n        for i_m in 1 .. d_m'Last - 1 loop\n          width_m := XMAS_Rating_Range (d_m (i_m + 1) - d_m (i_m));\n          m := d_m (i_m);\n          for i_a in 1 .. d_a'Last - 1 loop\n            width_a := XMAS_Rating_Range (d_a (i_a + 1) - d_a (i_a));\n            a := d_a (i_a);\n            for i_s in 1 .. d_s'Last - 1 loop\n              width_s := XMAS_Rating_Range (d_s (i_s + 1) - d_s (i_s));\n              s := d_s (i_s);\n              --  Test a point in the 4D rectangle\n              m_in;\n              if ok then\n                sum := sum + width_x * width_m * width_a * width_s;\n              end if;\n            end loop;\n          end loop;\n        end loop;\n      end loop;\n    end Part_2_Mini;\n\n    procedure Part_2_Input is\n      d_x : array (1 .. 257) of Positive;\n      d_m : array (1 .. 211) of Positive;\n      d_a : array (1 .. 288) of Positive;\n      d_s : array (1 .. 249) of Positive;\n    begin\n      --  The partitioning data was retrieved from the\n      --  puzzle's program using Regexp, and Excel.\n      --  In Excel, \"> n\" was replaced implicitly by \">= n + 1\",\n      --  which is the converse of \"< n + 1\".\n      --  The boundaries (the n's) were then sorted and duplicates removed\n      --  The presence of duplicates were spotted thanks to the\n      --  XMAS_Rating_Range subtype used for the width_* variables.\n      --   \n      d_x (1) := 1;\n      d_x (2) := 75;\n      d_x (3) := 147;\n      d_x (4) := 153;\n      d_x (5) := 163;\n      d_x (6) := 173;\n      d_x (7) := 247;\n      d_x (8) := 259;\n      d_x (9) := 261;\n      d_x (10) := 267;\n      d_x (11) := 324;\n      d_x (12) := 345;\n      d_x (13) := 348;\n      d_x (14) := 378;\n      d_x (15) := 389;\n      d_x (16) := 393;\n      d_x (17) := 396;\n      d_x (18) := 414;\n      d_x (19) := 415;\n      d_x (20) := 420;\n      d_x (21) := 444;\n      d_x (22) := 461;\n      d_x (23) := 466;\n      d_x (24) := 469;\n      d_x (25) := 479;\n      d_x (26) := 494;\n      d_x (27) := 500;\n      d_x (28) := 507;\n      d_x (29) := 516;\n      d_x (30) := 550;\n      d_x (31) := 560;\n      d_x (32) := 572;\n      d_x (33) := 574;\n      d_x (34) := 575;\n      d_x (35) := 628;\n      d_x (36) := 648;\n      d_x (37) := 651;\n      d_x (38) := 655;\n      d_x (39) := 688;\n      d_x (40) := 704;\n      d_x (41) := 715;\n      d_x (42) := 724;\n      d_x (43) := 740;\n      d_x (44) := 745;\n      d_x (45) := 764;\n      d_x (46) := 795;\n      d_x (47) := 798;\n      d_x (48) := 812;\n      d_x (49) := 823;\n      d_x (50) := 826;\n      d_x (51) := 880;\n      d_x (52) := 898;\n      d_x (53) := 900;\n      d_x (54) := 904;\n      d_x (55) := 908;\n      d_x (56) := 915;\n      d_x (57) := 921;\n      d_x (58) := 945;\n      d_x (59) := 949;\n      d_x (60) := 983;\n      d_x (61) := 993;\n      d_x (62) := 994;\n      d_x (63) := 997;\n      d_x (64) := 1004;\n      d_x (65) := 1007;\n      d_x (66) := 1024;\n      d_x (67) := 1026;\n      d_x (68) := 1033;\n      d_x (69) := 1069;\n      d_x (70) := 1075;\n      d_x (71) := 1076;\n      d_x (72) := 1082;\n      d_x (73) := 1088;\n      d_x (74) := 1093;\n      d_x (75) := 1110;\n      d_x (76) := 1158;\n      d_x (77) := 1170;\n      d_x (78) := 1185;\n      d_x (79) := 1210;\n      d_x (80) := 1211;\n      d_x (81) := 1223;\n      d_x (82) := 1228;\n      d_x (83) := 1243;\n      d_x (84) := 1256;\n      d_x (85) := 1257;\n      d_x (86) := 1260;\n      d_x (87) := 1276;\n      d_x (88) := 1279;\n      d_x (89) := 1303;\n      d_x (90) := 1311;\n      d_x (91) := 1324;\n      d_x (92) := 1335;\n      d_x (93) := 1339;\n      d_x (94) := 1340;\n      d_x (95) := 1344;\n      d_x (96) := 1347;\n      d_x (97) := 1348;\n      d_x (98) := 1359;\n      d_x (99) := 1361;\n      d_x (100) := 1363;\n      d_x (101) := 1378;\n      d_x (102) := 1393;\n      d_x (103) := 1396;\n      d_x (104) := 1402;\n      d_x (105) := 1409;\n      d_x (106) := 1416;\n      d_x (107) := 1424;\n      d_x (108) := 1431;\n      d_x (109) := 1449;\n      d_x (110) := 1450;\n      d_x (111) := 1457;\n      d_x (112) := 1478;\n      d_x (113) := 1510;\n      d_x (114) := 1539;\n      d_x (115) := 1554;\n      d_x (116) := 1567;\n      d_x (117) := 1574;\n      d_x (118) := 1607;\n      d_x (119) := 1620;\n      d_x (120) := 1632;\n      d_x (121) := 1636;\n      d_x (122) := 1654;\n      d_x (123) := 1655;\n      d_x (124) := 1677;\n      d_x (125) := 1679;\n      d_x (126) := 1680;\n      d_x (127) := 1697;\n      d_x (128) := 1698;\n      d_x (129) := 1733;\n      d_x (130) := 1734;\n      d_x (131) := 1742;\n      d_x (132) := 1756;\n      d_x (133) := 1757;\n      d_x (134) := 1797;\n      d_x (135) := 1812;\n      d_x (136) := 1823;\n      d_x (137) := 1866;\n      d_x (138) := 1871;\n      d_x (139) := 1886;\n      d_x (140) := 1887;\n      d_x (141) := 1895;\n      d_x (142) := 1898;\n      d_x (143) := 1899;\n      d_x (144) := 1912;\n      d_x (145) := 1921;\n      d_x (146) := 1957;\n      d_x (147) := 1958;\n      d_x (148) := 1959;\n      d_x (149) := 2046;\n      d_x (150) := 2048;\n      d_x (151) := 2075;\n      d_x (152) := 2076;\n      d_x (153) := 2090;\n      d_x (154) := 2144;\n      d_x (155) := 2158;\n      d_x (156) := 2163;\n      d_x (157) := 2170;\n      d_x (158) := 2175;\n      d_x (159) := 2193;\n      d_x (160) := 2237;\n      d_x (161) := 2238;\n      d_x (162) := 2250;\n      d_x (163) := 2254;\n      d_x (164) := 2261;\n      d_x (165) := 2267;\n      d_x (166) := 2270;\n      d_x (167) := 2272;\n      d_x (168) := 2274;\n      d_x (169) := 2296;\n      d_x (170) := 2302;\n      d_x (171) := 2320;\n      d_x (172) := 2327;\n      d_x (173) := 2359;\n      d_x (174) := 2381;\n      d_x (175) := 2382;\n      d_x (176) := 2405;\n      d_x (177) := 2421;\n      d_x (178) := 2447;\n      d_x (179) := 2450;\n      d_x (180) := 2461;\n      d_x (181) := 2476;\n      d_x (182) := 2480;\n      d_x (183) := 2493;\n      d_x (184) := 2500;\n      d_x (185) := 2510;\n      d_x (186) := 2514;\n      d_x (187) := 2529;\n      d_x (188) := 2541;\n      d_x (189) := 2557;\n      d_x (190) := 2559;\n      d_x (191) := 2573;\n      d_x (192) := 2579;\n      d_x (193) := 2588;\n      d_x (194) := 2596;\n      d_x (195) := 2599;\n      d_x (196) := 2603;\n      d_x (197) := 2605;\n      d_x (198) := 2614;\n      d_x (199) := 2622;\n      d_x (200) := 2623;\n      d_x (201) := 2630;\n      d_x (202) := 2638;\n      d_x (203) := 2652;\n      d_x (204) := 2665;\n      d_x (205) := 2670;\n      d_x (206) := 2685;\n      d_x (207) := 2760;\n      d_x (208) := 2769;\n      d_x (209) := 2849;\n      d_x (210) := 2904;\n      d_x (211) := 2910;\n      d_x (212) := 2947;\n      d_x (213) := 2956;\n      d_x (214) := 3053;\n      d_x (215) := 3054;\n      d_x (216) := 3067;\n      d_x (217) := 3084;\n      d_x (218) := 3102;\n      d_x (219) := 3119;\n      d_x (220) := 3126;\n      d_x (221) := 3138;\n      d_x (222) := 3153;\n      d_x (223) := 3171;\n      d_x (224) := 3212;\n      d_x (225) := 3217;\n      d_x (226) := 3229;\n      d_x (227) := 3247;\n      d_x (228) := 3257;\n      d_x (229) := 3260;\n      d_x (230) := 3275;\n      d_x (231) := 3279;\n      d_x (232) := 3285;\n      d_x (233) := 3300;\n      d_x (234) := 3301;\n      d_x (235) := 3307;\n      d_x (236) := 3317;\n      d_x (237) := 3341;\n      d_x (238) := 3342;\n      d_x (239) := 3396;\n      d_x (240) := 3411;\n      d_x (241) := 3424;\n      d_x (242) := 3429;\n      d_x (243) := 3459;\n      d_x (244) := 3466;\n      d_x (245) := 3484;\n      d_x (246) := 3524;\n      d_x (247) := 3553;\n      d_x (248) := 3568;\n      d_x (249) := 3570;\n      d_x (250) := 3571;\n      d_x (251) := 3580;\n      d_x (252) := 3609;\n      d_x (253) := 3657;\n      d_x (254) := 3670;\n      d_x (255) := 3699;\n      d_x (256) := 3720;\n      d_x (257) := 4001;\n      --\n      d_m (1) := 1;\n      d_m (2) := 76;\n      d_m (3) := 87;\n      d_m (4) := 90;\n      d_m (5) := 99;\n      d_m (6) := 105;\n      d_m (7) := 118;\n      d_m (8) := 132;\n      d_m (9) := 133;\n      d_m (10) := 197;\n      d_m (11) := 269;\n      d_m (12) := 284;\n      d_m (13) := 329;\n      d_m (14) := 386;\n      d_m (15) := 403;\n      d_m (16) := 417;\n      d_m (17) := 428;\n      d_m (18) := 453;\n      d_m (19) := 494;\n      d_m (20) := 514;\n      d_m (21) := 526;\n      d_m (22) := 564;\n      d_m (23) := 587;\n      d_m (24) := 591;\n      d_m (25) := 602;\n      d_m (26) := 604;\n      d_m (27) := 612;\n      d_m (28) := 617;\n      d_m (29) := 628;\n      d_m (30) := 673;\n      d_m (31) := 675;\n      d_m (32) := 684;\n      d_m (33) := 696;\n      d_m (34) := 703;\n      d_m (35) := 724;\n      d_m (36) := 725;\n      d_m (37) := 736;\n      d_m (38) := 741;\n      d_m (39) := 750;\n      d_m (40) := 795;\n      d_m (41) := 801;\n      d_m (42) := 811;\n      d_m (43) := 818;\n      d_m (44) := 819;\n      d_m (45) := 825;\n      d_m (46) := 830;\n      d_m (47) := 883;\n      d_m (48) := 884;\n      d_m (49) := 885;\n      d_m (50) := 891;\n      d_m (51) := 892;\n      d_m (52) := 894;\n      d_m (53) := 900;\n      d_m (54) := 911;\n      d_m (55) := 917;\n      d_m (56) := 936;\n      d_m (57) := 937;\n      d_m (58) := 939;\n      d_m (59) := 947;\n      d_m (60) := 955;\n      d_m (61) := 961;\n      d_m (62) := 962;\n      d_m (63) := 966;\n      d_m (64) := 1009;\n      d_m (65) := 1010;\n      d_m (66) := 1013;\n      d_m (67) := 1016;\n      d_m (68) := 1028;\n      d_m (69) := 1046;\n      d_m (70) := 1068;\n      d_m (71) := 1092;\n      d_m (72) := 1117;\n      d_m (73) := 1122;\n      d_m (74) := 1133;\n      d_m (75) := 1147;\n      d_m (76) := 1153;\n      d_m (77) := 1164;\n      d_m (78) := 1165;\n      d_m (79) := 1184;\n      d_m (80) := 1231;\n      d_m (81) := 1243;\n      d_m (82) := 1248;\n      d_m (83) := 1291;\n      d_m (84) := 1293;\n      d_m (85) := 1294;\n      d_m (86) := 1352;\n      d_m (87) := 1371;\n      d_m (88) := 1380;\n      d_m (89) := 1388;\n      d_m (90) := 1402;\n      d_m (91) := 1408;\n      d_m (92) := 1411;\n      d_m (93) := 1427;\n      d_m (94) := 1434;\n      d_m (95) := 1436;\n      d_m (96) := 1438;\n      d_m (97) := 1446;\n      d_m (98) := 1453;\n      d_m (99) := 1460;\n      d_m (100) := 1469;\n      d_m (101) := 1474;\n      d_m (102) := 1494;\n      d_m (103) := 1499;\n      d_m (104) := 1500;\n      d_m (105) := 1501;\n      d_m (106) := 1508;\n      d_m (107) := 1528;\n      d_m (108) := 1540;\n      d_m (109) := 1642;\n      d_m (110) := 1657;\n      d_m (111) := 1665;\n      d_m (112) := 1679;\n      d_m (113) := 1739;\n      d_m (114) := 1762;\n      d_m (115) := 1763;\n      d_m (116) := 1775;\n      d_m (117) := 1781;\n      d_m (118) := 1790;\n      d_m (119) := 1812;\n      d_m (120) := 1840;\n      d_m (121) := 1867;\n      d_m (122) := 1869;\n      d_m (123) := 1900;\n      d_m (124) := 1908;\n      d_m (125) := 1917;\n      d_m (126) := 1940;\n      d_m (127) := 1978;\n      d_m (128) := 1983;\n      d_m (129) := 2007;\n      d_m (130) := 2008;\n      d_m (131) := 2011;\n      d_m (132) := 2013;\n      d_m (133) := 2025;\n      d_m (134) := 2062;\n      d_m (135) := 2082;\n      d_m (136) := 2093;\n      d_m (137) := 2114;\n      d_m (138) := 2142;\n      d_m (139) := 2208;\n      d_m (140) := 2252;\n      d_m (141) := 2270;\n      d_m (142) := 2274;\n      d_m (143) := 2308;\n      d_m (144) := 2314;\n      d_m (145) := 2332;\n      d_m (146) := 2349;\n      d_m (147) := 2384;\n      d_m (148) := 2416;\n      d_m (149) := 2418;\n      d_m (150) := 2423;\n      d_m (151) := 2448;\n      d_m (152) := 2462;\n      d_m (153) := 2477;\n      d_m (154) := 2526;\n      d_m (155) := 2576;\n      d_m (156) := 2607;\n      d_m (157) := 2610;\n      d_m (158) := 2642;\n      d_m (159) := 2661;\n      d_m (160) := 2693;\n      d_m (161) := 2725;\n      d_m (162) := 2760;\n      d_m (163) := 2828;\n      d_m (164) := 2856;\n      d_m (165) := 2878;\n      d_m (166) := 2888;\n      d_m (167) := 2925;\n      d_m (168) := 2926;\n      d_m (169) := 2947;\n      d_m (170) := 2952;\n      d_m (171) := 2968;\n      d_m (172) := 3006;\n      d_m (173) := 3015;\n      d_m (174) := 3050;\n      d_m (175) := 3104;\n      d_m (176) := 3116;\n      d_m (177) := 3162;\n      d_m (178) := 3171;\n      d_m (179) := 3195;\n      d_m (180) := 3225;\n      d_m (181) := 3271;\n      d_m (182) := 3282;\n      d_m (183) := 3299;\n      d_m (184) := 3305;\n      d_m (185) := 3306;\n      d_m (186) := 3325;\n      d_m (187) := 3326;\n      d_m (188) := 3344;\n      d_m (189) := 3349;\n      d_m (190) := 3381;\n      d_m (191) := 3383;\n      d_m (192) := 3384;\n      d_m (193) := 3405;\n      d_m (194) := 3442;\n      d_m (195) := 3468;\n      d_m (196) := 3471;\n      d_m (197) := 3503;\n      d_m (198) := 3505;\n      d_m (199) := 3512;\n      d_m (200) := 3587;\n      d_m (201) := 3603;\n      d_m (202) := 3604;\n      d_m (203) := 3633;\n      d_m (204) := 3681;\n      d_m (205) := 3694;\n      d_m (206) := 3738;\n      d_m (207) := 3803;\n      d_m (208) := 3831;\n      d_m (209) := 3863;\n      d_m (210) := 3882;\n      d_m (211) := 4001;\n      --\n      d_a (1) := 1;\n      d_a (2) := 67;\n      d_a (3) := 75;\n      d_a (4) := 117;\n      d_a (5) := 134;\n      d_a (6) := 138;\n      d_a (7) := 149;\n      d_a (8) := 191;\n      d_a (9) := 220;\n      d_a (10) := 225;\n      d_a (11) := 246;\n      d_a (12) := 270;\n      d_a (13) := 279;\n      d_a (14) := 280;\n      d_a (15) := 292;\n      d_a (16) := 297;\n      d_a (17) := 320;\n      d_a (18) := 330;\n      d_a (19) := 332;\n      d_a (20) := 365;\n      d_a (21) := 379;\n      d_a (22) := 380;\n      d_a (23) := 383;\n      d_a (24) := 385;\n      d_a (25) := 388;\n      d_a (26) := 400;\n      d_a (27) := 417;\n      d_a (28) := 432;\n      d_a (29) := 435;\n      d_a (30) := 440;\n      d_a (31) := 441;\n      d_a (32) := 449;\n      d_a (33) := 463;\n      d_a (34) := 513;\n      d_a (35) := 527;\n      d_a (36) := 536;\n      d_a (37) := 540;\n      d_a (38) := 550;\n      d_a (39) := 555;\n      d_a (40) := 557;\n      d_a (41) := 570;\n      d_a (42) := 587;\n      d_a (43) := 593;\n      d_a (44) := 612;\n      d_a (45) := 616;\n      d_a (46) := 631;\n      d_a (47) := 633;\n      d_a (48) := 654;\n      d_a (49) := 657;\n      d_a (50) := 672;\n      d_a (51) := 677;\n      d_a (52) := 693;\n      d_a (53) := 702;\n      d_a (54) := 710;\n      d_a (55) := 715;\n      d_a (56) := 719;\n      d_a (57) := 763;\n      d_a (58) := 770;\n      d_a (59) := 773;\n      d_a (60) := 815;\n      d_a (61) := 827;\n      d_a (62) := 832;\n      d_a (63) := 862;\n      d_a (64) := 886;\n      d_a (65) := 900;\n      d_a (66) := 905;\n      d_a (67) := 949;\n      d_a (68) := 966;\n      d_a (69) := 987;\n      d_a (70) := 988;\n      d_a (71) := 1008;\n      d_a (72) := 1021;\n      d_a (73) := 1023;\n      d_a (74) := 1032;\n      d_a (75) := 1033;\n      d_a (76) := 1043;\n      d_a (77) := 1050;\n      d_a (78) := 1051;\n      d_a (79) := 1075;\n      d_a (80) := 1088;\n      d_a (81) := 1096;\n      d_a (82) := 1100;\n      d_a (83) := 1106;\n      d_a (84) := 1107;\n      d_a (85) := 1109;\n      d_a (86) := 1122;\n      d_a (87) := 1124;\n      d_a (88) := 1129;\n      d_a (89) := 1137;\n      d_a (90) := 1144;\n      d_a (91) := 1149;\n      d_a (92) := 1156;\n      d_a (93) := 1175;\n      d_a (94) := 1182;\n      d_a (95) := 1184;\n      d_a (96) := 1200;\n      d_a (97) := 1217;\n      d_a (98) := 1220;\n      d_a (99) := 1254;\n      d_a (100) := 1262;\n      d_a (101) := 1286;\n      d_a (102) := 1348;\n      d_a (103) := 1354;\n      d_a (104) := 1399;\n      d_a (105) := 1401;\n      d_a (106) := 1415;\n      d_a (107) := 1418;\n      d_a (108) := 1424;\n      d_a (109) := 1443;\n      d_a (110) := 1477;\n      d_a (111) := 1524;\n      d_a (112) := 1605;\n      d_a (113) := 1613;\n      d_a (114) := 1636;\n      d_a (115) := 1639;\n      d_a (116) := 1671;\n      d_a (117) := 1679;\n      d_a (118) := 1725;\n      d_a (119) := 1727;\n      d_a (120) := 1752;\n      d_a (121) := 1760;\n      d_a (122) := 1774;\n      d_a (123) := 1820;\n      d_a (124) := 1853;\n      d_a (125) := 1881;\n      d_a (126) := 1891;\n      d_a (127) := 1913;\n      d_a (128) := 1935;\n      d_a (129) := 1939;\n      d_a (130) := 1950;\n      d_a (131) := 1964;\n      d_a (132) := 1967;\n      d_a (133) := 1971;\n      d_a (134) := 1981;\n      d_a (135) := 1984;\n      d_a (136) := 1998;\n      d_a (137) := 2055;\n      d_a (138) := 2127;\n      d_a (139) := 2141;\n      d_a (140) := 2205;\n      d_a (141) := 2209;\n      d_a (142) := 2226;\n      d_a (143) := 2248;\n      d_a (144) := 2253;\n      d_a (145) := 2263;\n      d_a (146) := 2267;\n      d_a (147) := 2271;\n      d_a (148) := 2306;\n      d_a (149) := 2312;\n      d_a (150) := 2318;\n      d_a (151) := 2321;\n      d_a (152) := 2357;\n      d_a (153) := 2368;\n      d_a (154) := 2369;\n      d_a (155) := 2399;\n      d_a (156) := 2413;\n      d_a (157) := 2451;\n      d_a (158) := 2455;\n      d_a (159) := 2468;\n      d_a (160) := 2472;\n      d_a (161) := 2478;\n      d_a (162) := 2503;\n      d_a (163) := 2538;\n      d_a (164) := 2541;\n      d_a (165) := 2545;\n      d_a (166) := 2558;\n      d_a (167) := 2569;\n      d_a (168) := 2570;\n      d_a (169) := 2640;\n      d_a (170) := 2663;\n      d_a (171) := 2671;\n      d_a (172) := 2684;\n      d_a (173) := 2685;\n      d_a (174) := 2704;\n      d_a (175) := 2706;\n      d_a (176) := 2714;\n      d_a (177) := 2731;\n      d_a (178) := 2773;\n      d_a (179) := 2776;\n      d_a (180) := 2787;\n      d_a (181) := 2796;\n      d_a (182) := 2800;\n      d_a (183) := 2806;\n      d_a (184) := 2808;\n      d_a (185) := 2813;\n      d_a (186) := 2825;\n      d_a (187) := 2829;\n      d_a (188) := 2842;\n      d_a (189) := 2843;\n      d_a (190) := 2848;\n      d_a (191) := 2860;\n      d_a (192) := 2861;\n      d_a (193) := 2869;\n      d_a (194) := 2874;\n      d_a (195) := 2877;\n      d_a (196) := 2881;\n      d_a (197) := 2884;\n      d_a (198) := 2886;\n      d_a (199) := 2887;\n      d_a (200) := 2888;\n      d_a (201) := 2912;\n      d_a (202) := 2948;\n      d_a (203) := 2977;\n      d_a (204) := 2978;\n      d_a (205) := 2981;\n      d_a (206) := 2982;\n      d_a (207) := 2999;\n      d_a (208) := 3031;\n      d_a (209) := 3045;\n      d_a (210) := 3055;\n      d_a (211) := 3060;\n      d_a (212) := 3064;\n      d_a (213) := 3069;\n      d_a (214) := 3077;\n      d_a (215) := 3095;\n      d_a (216) := 3111;\n      d_a (217) := 3115;\n      d_a (218) := 3118;\n      d_a (219) := 3126;\n      d_a (220) := 3132;\n      d_a (221) := 3147;\n      d_a (222) := 3150;\n      d_a (223) := 3153;\n      d_a (224) := 3170;\n      d_a (225) := 3177;\n      d_a (226) := 3182;\n      d_a (227) := 3194;\n      d_a (228) := 3206;\n      d_a (229) := 3208;\n      d_a (230) := 3222;\n      d_a (231) := 3243;\n      d_a (232) := 3247;\n      d_a (233) := 3279;\n      d_a (234) := 3297;\n      d_a (235) := 3302;\n      d_a (236) := 3308;\n      d_a (237) := 3309;\n      d_a (238) := 3311;\n      d_a (239) := 3324;\n      d_a (240) := 3327;\n      d_a (241) := 3341;\n      d_a (242) := 3373;\n      d_a (243) := 3374;\n      d_a (244) := 3377;\n      d_a (245) := 3400;\n      d_a (246) := 3403;\n      d_a (247) := 3419;\n      d_a (248) := 3424;\n      d_a (249) := 3448;\n      d_a (250) := 3454;\n      d_a (251) := 3456;\n      d_a (252) := 3469;\n      d_a (253) := 3472;\n      d_a (254) := 3498;\n      d_a (255) := 3517;\n      d_a (256) := 3522;\n      d_a (257) := 3525;\n      d_a (258) := 3531;\n      d_a (259) := 3556;\n      d_a (260) := 3578;\n      d_a (261) := 3583;\n      d_a (262) := 3605;\n      d_a (263) := 3608;\n      d_a (264) := 3635;\n      d_a (265) := 3663;\n      d_a (266) := 3686;\n      d_a (267) := 3692;\n      d_a (268) := 3700;\n      d_a (269) := 3707;\n      d_a (270) := 3726;\n      d_a (271) := 3727;\n      d_a (272) := 3750;\n      d_a (273) := 3751;\n      d_a (274) := 3752;\n      d_a (275) := 3757;\n      d_a (276) := 3783;\n      d_a (277) := 3784;\n      d_a (278) := 3793;\n      d_a (279) := 3796;\n      d_a (280) := 3798;\n      d_a (281) := 3818;\n      d_a (282) := 3831;\n      d_a (283) := 3894;\n      d_a (284) := 3908;\n      d_a (285) := 3916;\n      d_a (286) := 3933;\n      d_a (287) := 3967;\n      d_a (288) := 4001;\n      --\n      d_s (1) := 1;\n      d_s (2) := 68;\n      d_s (3) := 84;\n      d_s (4) := 112;\n      d_s (5) := 205;\n      d_s (6) := 239;\n      d_s (7) := 241;\n      d_s (8) := 324;\n      d_s (9) := 361;\n      d_s (10) := 400;\n      d_s (11) := 403;\n      d_s (12) := 425;\n      d_s (13) := 434;\n      d_s (14) := 450;\n      d_s (15) := 458;\n      d_s (16) := 463;\n      d_s (17) := 468;\n      d_s (18) := 474;\n      d_s (19) := 478;\n      d_s (20) := 489;\n      d_s (21) := 500;\n      d_s (22) := 501;\n      d_s (23) := 521;\n      d_s (24) := 524;\n      d_s (25) := 539;\n      d_s (26) := 555;\n      d_s (27) := 572;\n      d_s (28) := 648;\n      d_s (29) := 672;\n      d_s (30) := 708;\n      d_s (31) := 716;\n      d_s (32) := 734;\n      d_s (33) := 739;\n      d_s (34) := 799;\n      d_s (35) := 872;\n      d_s (36) := 907;\n      d_s (37) := 912;\n      d_s (38) := 950;\n      d_s (39) := 1044;\n      d_s (40) := 1091;\n      d_s (41) := 1118;\n      d_s (42) := 1127;\n      d_s (43) := 1158;\n      d_s (44) := 1164;\n      d_s (45) := 1166;\n      d_s (46) := 1203;\n      d_s (47) := 1214;\n      d_s (48) := 1362;\n      d_s (49) := 1385;\n      d_s (50) := 1414;\n      d_s (51) := 1450;\n      d_s (52) := 1455;\n      d_s (53) := 1470;\n      d_s (54) := 1492;\n      d_s (55) := 1501;\n      d_s (56) := 1505;\n      d_s (57) := 1510;\n      d_s (58) := 1515;\n      d_s (59) := 1540;\n      d_s (60) := 1553;\n      d_s (61) := 1570;\n      d_s (62) := 1602;\n      d_s (63) := 1606;\n      d_s (64) := 1608;\n      d_s (65) := 1630;\n      d_s (66) := 1632;\n      d_s (67) := 1636;\n      d_s (68) := 1638;\n      d_s (69) := 1648;\n      d_s (70) := 1662;\n      d_s (71) := 1686;\n      d_s (72) := 1699;\n      d_s (73) := 1701;\n      d_s (74) := 1704;\n      d_s (75) := 1718;\n      d_s (76) := 1722;\n      d_s (77) := 1753;\n      d_s (78) := 1774;\n      d_s (79) := 1797;\n      d_s (80) := 1800;\n      d_s (81) := 1804;\n      d_s (82) := 1808;\n      d_s (83) := 1819;\n      d_s (84) := 1821;\n      d_s (85) := 1826;\n      d_s (86) := 1851;\n      d_s (87) := 1890;\n      d_s (88) := 1892;\n      d_s (89) := 1894;\n      d_s (90) := 1899;\n      d_s (91) := 1900;\n      d_s (92) := 1903;\n      d_s (93) := 1906;\n      d_s (94) := 1908;\n      d_s (95) := 1970;\n      d_s (96) := 2004;\n      d_s (97) := 2013;\n      d_s (98) := 2024;\n      d_s (99) := 2047;\n      d_s (100) := 2056;\n      d_s (101) := 2080;\n      d_s (102) := 2110;\n      d_s (103) := 2120;\n      d_s (104) := 2183;\n      d_s (105) := 2205;\n      d_s (106) := 2208;\n      d_s (107) := 2234;\n      d_s (108) := 2245;\n      d_s (109) := 2258;\n      d_s (110) := 2270;\n      d_s (111) := 2292;\n      d_s (112) := 2342;\n      d_s (113) := 2360;\n      d_s (114) := 2361;\n      d_s (115) := 2371;\n      d_s (116) := 2445;\n      d_s (117) := 2469;\n      d_s (118) := 2479;\n      d_s (119) := 2535;\n      d_s (120) := 2548;\n      d_s (121) := 2555;\n      d_s (122) := 2581;\n      d_s (123) := 2589;\n      d_s (124) := 2590;\n      d_s (125) := 2621;\n      d_s (126) := 2655;\n      d_s (127) := 2658;\n      d_s (128) := 2686;\n      d_s (129) := 2712;\n      d_s (130) := 2715;\n      d_s (131) := 2737;\n      d_s (132) := 2740;\n      d_s (133) := 2748;\n      d_s (134) := 2753;\n      d_s (135) := 2767;\n      d_s (136) := 2773;\n      d_s (137) := 2782;\n      d_s (138) := 2801;\n      d_s (139) := 2806;\n      d_s (140) := 2815;\n      d_s (141) := 2821;\n      d_s (142) := 2826;\n      d_s (143) := 2872;\n      d_s (144) := 2873;\n      d_s (145) := 2878;\n      d_s (146) := 2883;\n      d_s (147) := 2885;\n      d_s (148) := 2887;\n      d_s (149) := 2904;\n      d_s (150) := 2912;\n      d_s (151) := 2918;\n      d_s (152) := 2943;\n      d_s (153) := 2963;\n      d_s (154) := 2983;\n      d_s (155) := 2999;\n      d_s (156) := 3000;\n      d_s (157) := 3009;\n      d_s (158) := 3014;\n      d_s (159) := 3018;\n      d_s (160) := 3054;\n      d_s (161) := 3059;\n      d_s (162) := 3070;\n      d_s (163) := 3077;\n      d_s (164) := 3082;\n      d_s (165) := 3086;\n      d_s (166) := 3088;\n      d_s (167) := 3101;\n      d_s (168) := 3104;\n      d_s (169) := 3105;\n      d_s (170) := 3106;\n      d_s (171) := 3109;\n      d_s (172) := 3124;\n      d_s (173) := 3126;\n      d_s (174) := 3136;\n      d_s (175) := 3141;\n      d_s (176) := 3158;\n      d_s (177) := 3162;\n      d_s (178) := 3163;\n      d_s (179) := 3175;\n      d_s (180) := 3185;\n      d_s (181) := 3205;\n      d_s (182) := 3213;\n      d_s (183) := 3217;\n      d_s (184) := 3218;\n      d_s (185) := 3226;\n      d_s (186) := 3227;\n      d_s (187) := 3228;\n      d_s (188) := 3245;\n      d_s (189) := 3246;\n      d_s (190) := 3252;\n      d_s (191) := 3259;\n      d_s (192) := 3261;\n      d_s (193) := 3266;\n      d_s (194) := 3274;\n      d_s (195) := 3278;\n      d_s (196) := 3288;\n      d_s (197) := 3294;\n      d_s (198) := 3295;\n      d_s (199) := 3296;\n      d_s (200) := 3298;\n      d_s (201) := 3301;\n      d_s (202) := 3318;\n      d_s (203) := 3342;\n      d_s (204) := 3343;\n      d_s (205) := 3344;\n      d_s (206) := 3366;\n      d_s (207) := 3367;\n      d_s (208) := 3369;\n      d_s (209) := 3377;\n      d_s (210) := 3380;\n      d_s (211) := 3387;\n      d_s (212) := 3412;\n      d_s (213) := 3435;\n      d_s (214) := 3449;\n      d_s (215) := 3455;\n      d_s (216) := 3471;\n      d_s (217) := 3472;\n      d_s (218) := 3487;\n      d_s (219) := 3495;\n      d_s (220) := 3532;\n      d_s (221) := 3546;\n      d_s (222) := 3562;\n      d_s (223) := 3569;\n      d_s (224) := 3572;\n      d_s (225) := 3574;\n      d_s (226) := 3584;\n      d_s (227) := 3613;\n      d_s (228) := 3617;\n      d_s (229) := 3625;\n      d_s (230) := 3635;\n      d_s (231) := 3664;\n      d_s (232) := 3673;\n      d_s (233) := 3684;\n      d_s (234) := 3688;\n      d_s (235) := 3715;\n      d_s (236) := 3728;\n      d_s (237) := 3733;\n      d_s (238) := 3740;\n      d_s (239) := 3752;\n      d_s (240) := 3763;\n      d_s (241) := 3773;\n      d_s (242) := 3780;\n      d_s (243) := 3793;\n      d_s (244) := 3802;\n      d_s (245) := 3812;\n      d_s (246) := 3841;\n      d_s (247) := 3855;\n      d_s (248) := 3879;\n      d_s (249) := 4001;\n      --\n      for i_x in 1 .. d_x'Last - 1 loop\n        width_x := XMAS_Rating_Range (d_x (i_x + 1) - d_x (i_x));\n        x := d_x (i_x);\n        for i_m in 1 .. d_m'Last - 1 loop\n          width_m := XMAS_Rating_Range (d_m (i_m + 1) - d_m (i_m));\n          m := d_m (i_m);\n          for i_a in 1 .. d_a'Last - 1 loop\n            width_a := XMAS_Rating_Range (d_a (i_a + 1) - d_a (i_a));\n            a := d_a (i_a);\n            for i_s in 1 .. d_s'Last - 1 loop\n              width_s := XMAS_Rating_Range (d_s (i_s + 1) - d_s (i_s));\n              s := d_s (i_s);\n              --  Test a point in the 4D rectangle\n              inn;\n              if ok then\n                sum := sum + width_x * width_m * width_a * width_s;\n              end if;\n            end loop;\n          end loop;\n        end loop;\n      end loop;\n    end Part_2_Input;\n\n  begin\n    case choice is\n      when mini =>\n        Part_2_Mini;\n      when input =>\n        Part_2_Input;\n    end case;\n    r (part_2) := sum;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n  \nbegin\n  if compiler_test_mode then\n    choice := mini;\n  else\n    choice := input;\n  end if;\n  \n  Do_Part_1;\n  Do_Part_2;\n  \n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 330820           (example: 19114)\n    --  Part 2: validated by AoC: 123972546935551  (example: 167409079868000)\n  end if;\nend AoC_2023_19;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_19.txt",
    "content": "fzf{m<1642:A,px}\nqqp{s>3732:R,m>946:R,a<1401:A,A}\nmqh{x>1081:A,m<3344:R,m>3632:R,A}\nbnk{a>2841:R,s<3562:R,x>3483:A,A}\njt{a>3076:A,s<2748:A,s>2805:R,A}\nvl{x>2613:sv,a>2454:lhx,jg}\nbhj{x>2768:jhd,mhd}\nggs{x>3053:R,x>2848:R,R}\nlx{a>3685:A,bn}\nhcz{x>763:R,s<2753:A,R}\nmnr{x>1157:R,R}\ncpd{a<320:A,m>1387:bz,A}\nlbm{s<3387:R,s>3672:R,a<3818:R,A}\nnpb{a<1149:dmc,tgt}\nbsh{x<1228:R,R}\npx{x>1003:A,a>3750:A,A}\njl{a<1881:R,m>1146:R,s<400:A,R}\ncs{s<3185:A,A}\nkrx{x<3153:A,a<2570:R,A}\ndp{a>3221:A,A}\nzxh{s<2883:R,vb}\ndtj{x<1574:A,m<961:A,m>1183:R,R}\nmhd{a<2806:vtt,R}\nmll{s<2589:fs,rct}\nnbf{x<2665:sgr,A}\njr{a>3301:tc,x>996:dh,a>2980:ncl,A}\nlxc{x<1450:R,m>899:A,x>1653:A,R}\nxfp{a>586:pbx,xzk}\ncrf{s>3081:R,a>1253:A,s<2740:R,A}\nmc{a<330:A,a>440:A,x>2613:R,A}\nlcl{m>1452:mls,R}\nscv{a>653:R,a<385:A,s>2291:mcm,A}\njg{m>2877:gqc,a>2247:R,A}\nkbt{a<75:A,x>3256:R,a>137:A,R}\ncmf{m<795:R,A}\nzxc{a<1971:A,a>2270:R,A}\nlms{s>323:tfs,A}\nmgs{x<2480:A,a<1050:A,R}\nkz{s<3266:zg,a<2977:A,vqn}\nlh{x>1958:pkf,m>3511:hx,mk}\ndb{m<1657:xvn,nsd}\ngbg{m<1371:A,x>3428:A,s<3077:A,R}\ngz{s<3104:A,m<2828:A,m>3281:R,R}\nhpl{a>3117:A,ft}\nzg{x<1698:R,R}\nvqv{a>1031:A,x>2460:A,x<1912:A,R}\nvb{m<1499:A,x>1894:R,R}\nxkq{s<1553:cng,s<3162:tkj,mlj}\nngz{a<3373:A,s>402:A,s>204:A,A}\ndq{m<801:rmb,a<2127:A,R}\nkh{x>1408:A,A}\njfk{a>1219:qkz,s<1492:mt,m<2952:gkl,khv}\npl{s>3123:R,A}\ntdg{a>1983:A,a<1853:gx,x>1678:kkc,qcb}\nnlk{a<2055:R,zmn}\nsxc{s<1553:R,R}\nnzx{a<2569:A,x<1812:cbv,A}\ncph{m<2856:A,A}\npxx{x<3670:qnj,m<3015:R,a<3243:R,A}\nbnz{a<949:lsz,s>1899:hcp,s>1631:A,ntl}\ntv{m<1352:R,m<1812:A,R}\nqkz{a<2141:crk,x<1866:rlz,vl}\nqrp{a>3607:R,m<2423:lj,qqj}\nblf{s<1970:R,R}\nxrc{x<2476:rjx,a>1724:tj,pbt}\nnr{m>2092:hzc,A}\njld{s<1570:A,ps}\nnk{a<3132:R,R}\nrgl{a<2558:A,R}\nrl{a<1021:A,R}\nbjq{s<2821:R,s<2872:A,R}\nqnj{s>1202:R,s>488:R,R}\nbxb{m<911:A,x>468:bnx,s>3663:R,R}\nksl{x<688:A,x>1068:A,R}\nqzz{a>1963:sdm,s<1753:R,cgx}\nxmx{m<1231:qnv,m>1789:nsx,s>1698:xrp,A}\nbqt{x>392:R,A}\nnx{m<3603:R,s<2999:mg,m>3830:R,A}\nkfr{a<2455:jf,m>1009:nzx,x<2605:cgv,sm}\nrzc{m<3116:R,x>1302:R,s<2205:R,shf}\nzbv{m<3299:R,x<740:A,R}\nqds{a<3031:tg,a<3095:pp,x>2192:bf,cgf}\nzz{m<602:R,m>616:A,A}\nctn{s<1118:qvc,jzc}\nmv{m>3603:R,s<1044:R,A}\npm{m>2113:kd,a>278:A,R}\nvcd{m<1762:A,R}\ndn{m>2924:R,A}\ncjf{a<886:jsn,s>538:hp,R}\nfcr{s>738:vnp,s>647:cz,A}\nkf{a<2869:R,m<1983:R,A}\nzf{m>1116:vh,m<741:ljn,xz}\nnpl{m<604:R,x<2557:A,s>3273:A,lzl}\nhxj{x>1696:lgt,hxt}\nbk{m>2024:kqk,m>1977:A,A}\ncgf{m>1839:mdc,nk}\nfj{s<3773:R,A}\ntvz{m<725:A,R}\nnsd{a>549:A,rm}\nptj{a>2544:R,s<474:R,R}\njcf{a>3207:R,R}\njf{x>1679:R,hmd}\nfrc{a>3423:R,s<3574:R,R}\nfs{s<2535:R,s>2554:R,s>2547:R,R}\ngkt{x<3699:A,s<1808:R,R}\nlk{x>1920:vgq,x<915:vc,s>911:dcg,pjd}\ncpv{s<84:R,A}\nhr{m>3382:mdn,x<1457:cph,vp}\nfm{x<1347:kxk,dl}\nrh{m>1468:A,a<3525:ngz,R}\nbj{x>574:R,a<2312:A,R}\nqqj{x>1087:R,A}\nvs{x>1075:vcd,m<1978:jv,jr}\nclk{x<444:R,m<2947:A,s<3126:A,A}\nqrq{s>2012:R,a<1950:A,A}\nblm{m<1460:rj,m>2331:pxx,s<1091:bmk,kq}\nbh{x>1415:hj,a>1216:tr,cj}\nqq{a<3194:qdz,rg}\npqb{s<3296:A,R}\nlj{s<3684:R,s<3855:R,a<3556:R,A}\nktn{a>3308:R,x>2669:A,A}\nbxg{a>1442:A,a>1347:A,A}\nksd{s<3546:mr,rhb}\npt{x<1007:A,s<3086:R,a<2912:R,R}\nrtk{a<2468:A,s>1601:A,R}\ntck{a>1635:tlj,m<329:xhx,hc}\njzc{a<1524:zrf,m>1067:pr,x>1870:bls,rrx}\ncsz{a>762:bnz,x<3126:qv,s>1898:csr,skm}\nqps{a>615:cjf,s>671:pm,s>240:dbl,nl}\nlp{x<3084:A,s<3733:A,R}\nblx{m>131:R,R}\nctt{a<3522:nxf,x>1395:cnb,jzr}\nxrp{x<574:R,m<1446:R,A}\nsm{m<795:ptj,m>883:R,x<3307:A,sbd}\nplc{x>559:R,a>3782:R,s>3878:R,A}\nbnx{m<1013:A,A}\ndz{s<3377:R,m>2092:R,A}\nfpz{m>695:tvz,s<3213:qnp,a<1023:R,R}\nmcm{a<540:A,R}\nvgq{x<3260:xp,blm}\nhrl{s>571:fcr,a>3310:lms,a>3059:dn,cc}\nsgr{a<2253:R,a>2477:R,x>1631:A,R}\nkbm{a<773:R,x<500:xs,A}\ndmc{x>811:ddf,m>1293:ckz,R}\njx{x<147:A,s<3246:R,A}\nxbr{s<3780:A,A}\ncz{m>3005:A,x<1279:A,R}\nzh{m>2724:R,A}\nmx{a>2368:R,s<2360:R,x<3285:A,R}\npz{x>1619:A,a>965:R,x<1449:A,R}\nrt{a>1181:R,x>2446:R,A}\nlbk{a>2730:fz,hs}\ncpm{a<3279:rsn,m<1164:dcz,x>1415:mcq,rh}\nkm{m>3737:A,a>3725:R,R}\nqzx{s>1504:R,s>1454:R,x<415:A,A}\nhp{x<2493:R,s<1127:A,R}\nsj{m>683:R,x<1742:A,s<2208:R,A}\nrs{m<1908:tnp,x<1393:R,A}\nxp{m>1774:ktn,a<3517:bq,gj}\ncbr{a>2266:R,m<819:A,A}\ngcm{a<3170:A,a<3297:R,R}\nkj{s>3251:bnk,x<3524:A,A}\nlxb{a<536:A,a>630:R,s<1570:A,R}\nrsn{m<1293:R,R}\njbk{x>3170:A,a>1074:R,A}\nzv{x>2404:A,s>457:jmf,A}\njps{a<593:R,ggb}\nmth{x>3569:gbv,ds}\nmgd{s>2772:R,x<173:A,A}\nrnh{x>460:vn,x>266:pl,a<2800:hvz,R}\npsj{s<3000:R,s<3141:A,R}\nqcb{x<798:A,x>1338:A,A}\nshf{s<2342:R,A}\nbgd{m>2415:nzb,s>3123:ld,lcl}\nmlt{s<3301:A,m>2092:R,A}\nvtt{a<2787:R,m<1501:A,R}\ngk{a<815:A,s>2886:R,R}\nvnq{x<655:A,s<3763:R,A}\nspg{a<1477:R,R}\nkqk{a>986:R,A}\nzrf{a>904:gg,m<1153:ljh,s<1804:jld,cpd}\nltl{x>1025:mh,a<2706:mlt,mq}\nkkc{a<1939:R,a>1966:R,A}\npk{s<3412:fzf,a>3726:hxs,qrp}\njct{x>2955:A,czg}\npbh{a>1099:A,R}\nbkc{x<994:R,R}\nlmm{m>3383:R,a>2887:A,A}\njjm{a>2703:lbk,fpj}\ntd{x<247:mpf,s>3739:tzv,gf}\nmdn{a<3498:R,R}\nst{s<3009:A,a>1143:rt,a<1107:rgz,qzr}\nsts{a<1200:R,m<87:A,m>132:A,A}\npr{x>2249:dtm,qzz}\nds{s<3752:A,R}\ndmp{m<3305:R,a<463:A,m<3681:cm,R}\nsdr{a>3376:vdv,zbv}\nnst{s>2046:cbr,mfn}\nmk{a<388:R,pmb}\npkf{s>499:mv,A}\nszs{m<3349:sq,a>718:A,gc}\nzs{m<2661:R,A}\nvp{x>1477:R,s>2269:R,A}\ndl{s<1214:R,qp}\nlb{x<3138:A,a>2670:R,R}\nkl{m>3862:A,x>1259:mqj,x<1033:zn,blf}\nhlx{a<2205:R,x>3579:A,s<1636:A,R}\nhz{x>1358:A,x<1311:R,A}\nlv{s>424:R,a>3455:R,m>513:A,A}\nqs{a<3308:A,x>723:R,R}\ngqc{x<2158:R,s<1851:R,R}\nmpf{a>3792:A,a>3662:mml,a>3577:R,xk}\ndm{m>3103:A,x<1276:R,A}\nvq{s>2244:hz,x>1360:A,A}\nrrx{s>1629:nst,s>1413:xnv,dq}\nhxg{x<324:mgd,x<469:dj,gr}\npj{a<3150:A,a<3454:A,x>1606:A,R}\ngjs{a<2848:A,x<651:A,R}\nnbz{x<2579:rtg,bvg}\ntkj{x<2510:zx,x>3340:blx,a>1123:ggs,ctb}\nrk{m<105:A,s<2581:R,s>3343:A,R}\ngr{s>2781:R,m>938:A,a<3798:A,A}\nzlr{s>2444:A,R}\nqzq{x>260:R,s>2233:R,A}\nqb{a<3400:tv,x<1211:lbl,s<3532:A,A}\njkl{a>569:R,a>219:A,A}\nkd{a<332:A,s>1163:A,a<441:A,R}\nztq{s<1701:xg,s>1889:dmp,x>944:szs,kbm}\nvtl{s<1362:R,m>1164:R,s>1500:A,A}\ntj{x>3274:A,s<708:A,a<1760:R,A}\ndhp{a>3146:qzq,R}\nbn{x<466:R,A}\njv{a<3111:R,bkc}\npjd{m<2011:cpm,hrl}\nfh{a<3064:R,s<2885:jt,x>920:R,clk}\ngf{s>3568:A,jcs}\ncnb{x>2602:bgd,lpq}\nrjs{x<3342:A,x>3570:R,a<1033:A,R}\nsl{m>1009:fvp,spg}\ndd{a<3115:A,R}\nhl{a<3182:R,x<2541:A,s>1661:R,A}\nzc{m>3224:R,x<1402:A,R}\njhv{a>2713:A,nh}\nrjx{s>715:R,s<450:R,R}\nbp{a>3418:R,a>2981:A,R}\nrj{m>817:bp,A}\nmmc{a>2356:bsh,A}\njzr{x>627:pk,s<3294:jjc,td}\nhj{a<1124:R,A}\nlpx{x>1886:R,s<521:R,a<379:A,R}\nvxl{x>1956:A,R}\nncl{m>2887:A,A}\nhxs{a>3893:zgx,a>3783:A,R}\nxv{a>245:A,lg}\npfl{a<440:R,A}\njhd{a<2796:A,a<2813:R,A}\nvjn{x<2270:R,s<1166:A,A}\ngdk{a>2886:qds,x>1553:jkf,gmg}\nljv{m>954:A,bqt}\nrf{m<2314:A,R}\nzpb{s>1717:A,a>434:R,A}\nxgr{s<2801:gd,x>2319:tb,nv}\nln{a<3324:A,a<3448:A,x>1756:R,A}\nntl{s<1540:R,x<2910:A,x>3423:A,R}\nfg{m<3195:R,A}\nkq{m<1917:R,A}\nmln{m>674:dtc,x<3229:tl,s<3218:A,A}\nsjq{x<2421:R,s<3380:zz,lp}\nrpm{s>67:R,x<2573:A,A}\njc{s<799:A,m>3802:A,R}\nlvq{x>3719:A,s<3613:ghp,a<1156:R,A}\ncc{m>3325:A,m<2610:R,m>3049:zc,xxd}\nkxk{m<1500:A,a>3205:R,m<2576:R,lmm}\nqqs{s>3227:A,s>2736:R,x<2614:kqb,kbt}\nlzl{a>399:R,A}\nsh{x<2261:R,R}\npzx{a<1051:R,R}\nmrc{x<2382:R,a<693:A,R}\nsx{x>3458:A,A}\nsv{a>2471:krx,a<2306:A,a<2413:mx,A}\njmf{a<292:R,m>1008:A,A}\nhs{m<2526:R,x>2622:R,R}\nljn{m>627:pf,m>586:cfj,bh}\nmq{x>903:A,s>3293:A,R}\ngc{a<365:A,a<570:R,R}\nzjx{m>2207:R,R}\nkqb{m<602:R,A}\nxr{s<3802:R,R}\nlhx{m>3170:A,rgl}\nkct{a<1891:ttc,zm}\nvn{a>2795:A,s<3343:A,A}\nbvg{a>1980:A,R}\ntzr{a>2885:A,s<3105:R,A}\nghp{s>3260:A,A}\nljh{m>884:zpb,A}\ncrk{s<1819:zgv,m<3162:lz,a<1774:kh,nx}\nttc{x<2046:R,A}\nhmd{a<2368:R,m>1132:R,x<1075:A,A}\ntb{s>3294:R,s>2982:A,x<3285:A,R}\nskm{s>1721:gkt,a>382:lxb,s>1637:A,A}\nbmk{x<3657:fl,a<3341:R,R}\nfrf{m<2252:xmx,s<1800:bb,x>515:sdr,dhp}\ngrp{a>1183:R,x>2651:R,R}\nqzr{a>1128:R,a>1121:A,A}\nxxd{x>1538:A,a>2807:R,s<361:R,A}\nnvs{s<2686:R,a>148:R,A}\nsbd{a>2540:R,a>2502:A,x<3553:R,R}\nrmb{x<949:A,x<1340:R,R}\nsbh{x>3465:zxc,m>810:A,qrq}\nkmc{m>2641:mqh,R}\nks{m<1434:vq,m<2308:rs,x>1362:hr,rzc}\ndxl{x>2295:R,a>2873:A,s<3812:A,R}\nczp{m<90:A,x>3608:A,s<1450:A,R}\nlbl{x>571:A,R}\nmbj{x>2946:A,s<1470:cmf,x<2327:R,A}\njsn{s>871:A,x>2587:A,A}\nqjg{s>3258:R,m>2447:A,x>549:A,A}\ntq{s<2590:lk,a<3153:gdk,ctt}\nqnp{s>2942:R,s<2748:R,R}\ngnb{s>1449:R,a<3469:A,R}\nxq{x<740:R,x>822:A,s>1796:A,R}\nddr{x>825:kmc,a<2829:rnh,hb}\nnl{s<112:rpm,R}\nbgz{s<3472:A,s<3715:frc,s>3840:R,fj}\nxd{s<3101:bv,a<3302:jcf,s<3572:jh,xr}\nrxc{m>891:A,A}\ngj{m<673:R,zds}\nnzb{m<3405:R,lbm}\ngg{a<1286:mgs,m>935:bxg,x<2090:A,R}\nlcg{m<1248:A,s>3297:A,s>2766:A,R}\ngq{x<3301:mz,lvq}\ncng{x>2558:rjs,x>992:sts,vfk}\ngkl{m>2141:dfh,m<1900:db,x>1897:vd,sp}\nzx{m>98:R,R}\njcs{m<1494:A,x<389:A,a>3699:A,R}\nsdm{a>2317:A,R}\nbtg{s>1891:A,x<2144:A,s>906:A,R}\nrq{x<2267:R,a<513:R,x<3300:A,A}\nfpj{s>3216:lb,a>2662:R,s<2815:A,psj}\nvd{a<417:xv,a>769:bk,jps}\nqvd{a>1423:kct,a<832:cql,xkq}\nnxf{m>2417:xd,rc}\nrhb{a<3055:R,A}\nhq{s>949:zd,vcn}\nqv{a<270:nls,x<2596:A,R}\nhv{a>116:A,a<67:R,s<2371:R,A}\nttv{a<3583:R,a<3757:R,s>500:R,A}\nnv{a>1042:A,x<1348:A,R}\ncgx{a>1726:A,A}\nmz{s>3365:qqp,R}\njnn{x>2684:A,m<1408:R,A}\nvf{x<715:A,A}\ngfk{a<633:zv,a>1261:vxl,cr}\ndcg{x<1256:vs,x>1509:hxj,s>1703:ks,fm}\nmp{m>1507:jfk,m<526:cv,s>2468:zf,ctn}\nmg{x<1958:A,a>1912:A,A}\nhzc{s>3226:A,x>2499:A,a<2843:A,R}\nnc{m<494:R,R}\nvlr{a<1639:R,m>965:A,R}\nxkx{s<2878:R,s<3070:R,A}\nbb{a>3530:R,s<1510:A,R}\nnh{x>1430:R,a>2684:A,m<2349:A,R}\ndh{x<1024:R,A}\ngmg{a>2772:ddr,cl}\ncl{x<745:qmm,x<1185:ltl,jhv}\nxkb{s<1903:R,x>2528:R,R}\ncbb{m<1781:A,qr}\nfr{s<3106:slq,R}\nmh{m>2269:A,x<1093:A,a<2684:A,R}\ncv{m<197:qvd,tck}\nmlj{s<3617:pzx,sh}\ndcz{a<3605:lv,a<3752:A,s<468:R,R}\nvcn{s<524:R,x<1378:R,vqv}\nkqs{x<1335:R,lr}\nmcq{x>1676:ttv,A}\nhxt{s<2024:gnb,m>1410:pj,m<736:R,dtj}\nld{s<3688:ggh,s<3793:A,m>1290:A,A}\nxs{x>258:A,s<1774:R,R}\nmfn{s<1906:R,A}\nqfs{m>1437:R,R}\ntx{a<3403:jzm,tn}\nrct{m<1016:A,s<2621:R,R}\nnd{s>3135:A,R}\njjc{s>2911:mhf,m<1665:hxg,x<348:qcr,lx}\ngtq{m>961:xbr,m<830:A,x<507:A,vnq}\ncx{m>268:A,A}\nxf{x<345:A,s>3174:R,m<1739:A,A}\ncbv{m>1242:A,m>1121:R,x>897:R,A}\nzgv{x>2074:A,s>733:A,s<478:R,R}\ndgf{x<494:rtk,x<648:bj,xq}\nxg{x<795:A,s>1607:A,m>3324:R,dm}\ntzv{m<1869:jhs,m>3270:km,x>493:plc,zs}\nnt{a>3068:A,a<3045:A,R}\ngbv{s<3584:R,s<3728:R,R}\nqmm{m>2061:zh,R}\ncr{x>1870:R,x>982:A,s<463:R,rl}\ngxs{s>3087:A,m>385:A,a<280:R,rq}\nctq{a>987:R,R}\nmfh{a>1105:ll,lm}\nff{x<1886:pt,m<1867:A,R}\nggb{a<657:R,a>714:R,R}\njkf{a<2776:jjm,a<2825:bhj,a<2860:hhd,jhl}\nfdx{s>3342:R,R}\nbls{s<1648:mbj,x>3066:sbh,nlk}\nczg{s<3077:R,x<2514:A,R}\nsxz{m<937:grp,s<2655:mll,m>1045:vsx,sl}\nvqn{m<1679:R,a>2998:A,R}\nvdv{s>2257:R,a<3750:A,s<2080:A,R}\nnsx{s>1907:A,a>3246:A,A}\ngd{x<2557:A,a>1050:R,s>2360:R,R}\nvnp{x<1424:A,x>1732:A,A}\ndtc{m>702:R,A}\nglj{s>2917:A,A}\nqt{s>3494:dxl,x<2302:kf,R}\nxzk{a>296:R,x>2358:R,hv}\nmls{s<2885:A,m>1811:A,A}\nqvc{a<1613:gfk,a>2225:kfr,a<1820:xrc,nbz}\nctb{s>2109:R,A}\nxz{s<3018:sxz,x>2273:gq,fnv}\nlg{m<2007:A,m<2082:R,A}\nlpq{s>3341:zjx,zxh}\njhh{m<3882:A,s<3163:mrc,s<3625:nm,R}\ntc{a<3635:A,A}\ngx{a<1752:A,x<2622:A,A}\nmqj{a>2450:R,R}\nbz{a>676:A,s>2182:A,R}\nfnv{x>879:mfh,s<3449:ljv,a>1353:gtq,bxb}\nzfm{x>3316:czp,R}\nvsx{x>1654:jbk,s>2805:R,a>1136:ksl,hcz}\ncsr{m<3505:R,A}\nmhf{s<3158:R,s<3205:xf,x<414:jx,qjg}\nvc{s<1158:qq,frf}\nqnv{m<696:R,R}\ncm{m>3441:R,x<1223:R,x>1733:A,A}\njhl{x<3102:qt,a<2877:cs,a>2880:cn,cbb}\nsq{a>671:A,s<1821:A,x>1635:R,R}\nhvz{m>2461:R,A}\ntr{m>563:R,R}\ncgv{a<2538:R,A}\nps{x<1895:R,x>3216:R,A}\nrm{s<3054:R,s>3470:A,m>1762:R,A}\nqp{m<2013:A,s<1385:R,s>1514:R,A}\nqj{m<3381:fg,m<3694:pqb,jhh}\nqr{x<3568:A,m<2760:A,R}\ntfs{s>433:A,x<1324:R,A}\ncql{x<2048:rk,zfm}\nfvp{m>1027:A,x<2630:R,x<3279:R,A}\ntgt{a>1670:R,mnr}\ntn{m>824:R,A}\nfl{x<3396:A,A}\nvv{s>3244:R,a<3126:dd,s<2826:rf,R}\nlr{s<2004:A,R}\nxhx{x<1756:scv,cx}\njzm{x>1343:A,x>703:R,a>3373:A,A}\ntlj{s>1605:nbf,tdg}\nxk{x>152:R,A}\nmt{m<2968:qps,a>701:hq,lh}\nzk{m>416:R,x>3052:A,x<2638:A,A}\nzn{a<2399:A,A}\nggh{m<894:A,a>3830:A,a>3691:R,A}\nht{x<1797:A,s>2872:A,A}\njbl{m>1401:R,dp}\nvfk{x<479:R,m>117:A,A}\nqdz{s>554:R,s<239:cpv,R}\nll{s>3366:A,s<3226:A,R}\nvbp{a<527:R,m>2007:gk,pz}\nrhg{m<1474:A,a>1417:A,a<862:A,A}\nin{a>2639:tq,mp}\nbv{m<3468:ln,ht}\nzgx{a>3932:R,a>3907:R,x>1109:R,R}\nhx{a<449:jc,R}\ncfj{a>1414:fr,a>556:sjq,a>190:npl,qqs}\nmr{m<2693:A,A}\nhcp{a>1108:R,R}\nbf{x>3211:vv,hpl}\nrtg{a>1997:rxc,jl}\nqcr{x>162:A,x>74:A,s>2711:bjq,A}\nxnv{m<724:sxc,x<921:qzx,a<2263:mn,lxc}\npbx{a>826:ctq,m<3306:A,zlr}\nnlp{s>1893:A,R}\nmfr{x<2238:R,R}\ntg{a<2948:ff,kz}\ntnp{a<3177:R,s>2055:A,A}\nslq{m>611:R,A}\nfz{m>2476:R,s>3368:R,s<2963:R,A}\nrgz{a<1096:A,x<2237:R,R}\nrg{x<396:R,a<3472:qs,R}\nnm{x>2253:A,R}\nmdc{x>1209:gz,s<3278:vf,A}\npbt{a>1678:A,x>3246:vlr,m<1092:R,R}\ndbl{m<2274:R,m<2607:mc,lpx}\ncn{a<2884:dz,x>3410:sg,s>3454:R,tzr}\nhb{s>3486:R,a>2860:glj,x<378:A,gjs}\nnls{a<134:A,s>1825:R,m<3471:A,A}\ntl{s>3434:A,A}\nbl{a<555:R,a>1174:A,R}\nmml{a<3707:A,R}\ndtm{x>2903:hlx,a>1934:xkb,nlp}\nrb{a>379:A,x<2450:nvs,a>224:A,sx}\npf{x<1899:fpz,mln}\nzmn{m>882:A,a>2320:R,a>2208:R,A}\njh{x<2603:fdx,R}\ncrh{a>1398:xkx,s>2903:gbg,R}\nfmp{a>709:R,x<507:A,s>2752:R,A}\nsg{m>1527:R,R}\nsp{x>1242:vbp,fmp}\ncj{m<564:A,x<900:A,R}\nkhv{s>2714:qj,s>2119:xfp,x>2174:csz,ztq}\nlsz{m<3503:A,A}\ndfh{a<612:rb,a<1008:mfr,a>1087:st,xgr}\nlm{x>1566:R,s>3634:A,m<917:A,A}\nhn{x>1169:R,nt}\npp{x>2075:jct,m<1540:hn,s>3287:ksd,fh}\nddf{s>3058:A,A}\nmn{x>1509:R,R}\nhc{m>452:nc,s<2479:hml,a>714:crf,gxs}\nlgt{x>1822:A,m>1939:R,s>1685:sj,vtl}\npmb{x<1257:R,R}\nbq{m>749:hl,a<2978:R,m>283:A,gcm}\ndj{x>419:R,m>890:A,m<591:R,R}\nlz{m>2383:R,a<1605:A,nd}\nrlz{x<908:dgf,m<2926:mmc,m>3586:kl,kqs}\nlbs{m<1371:lcg,m>1435:rhg,jnn}\nhml{m<403:jkl,x<2272:R,m<428:zk,bl}\nckz{s<3014:R,m>1426:A,a>431:A,A}\nft{x<2599:R,A}\nmxb{x<3119:lbs,s>3317:mth,crh}\nvh{x>2169:mxb,npb}\nrc{a<3327:jbl,x>2380:bgz,s<3109:tx,qb}\nzm{m<76:btg,R}\njhs{a<3796:A,a<3916:R,a>3966:R,A}\nhhd{x>2759:kj,x<2163:qfs,nr}\nzds{m<1380:R,R}\nzd{a>899:pbh,vjn}\nxvn{s>2657:pfl,R}\n\n{x=6,m=309,a=1182,s=757}\n{x=531,m=106,a=1009,s=142}\n{x=3264,m=506,a=301,s=807}\n{x=1197,m=394,a=351,s=1266}\n{x=3009,m=1048,a=143,s=1549}\n{x=617,m=1696,a=778,s=28}\n{x=172,m=2243,a=1135,s=2330}\n{x=309,m=457,a=1943,s=8}\n{x=424,m=100,a=288,s=1745}\n{x=282,m=138,a=2134,s=272}\n{x=2982,m=2488,a=1452,s=3065}\n{x=1760,m=2317,a=3608,s=119}\n{x=682,m=303,a=1113,s=34}\n{x=806,m=3417,a=720,s=1219}\n{x=908,m=2564,a=1065,s=766}\n{x=1044,m=70,a=511,s=1410}\n{x=848,m=262,a=1100,s=778}\n{x=1042,m=1887,a=2083,s=847}\n{x=1051,m=1636,a=187,s=892}\n{x=782,m=489,a=1940,s=18}\n{x=33,m=1970,a=838,s=1123}\n{x=20,m=2180,a=2036,s=1720}\n{x=468,m=788,a=170,s=983}\n{x=1893,m=1399,a=1661,s=1493}\n{x=42,m=604,a=2889,s=219}\n{x=109,m=56,a=1004,s=2498}\n{x=1249,m=213,a=329,s=117}\n{x=544,m=380,a=124,s=1479}\n{x=1222,m=996,a=498,s=2270}\n{x=38,m=228,a=59,s=1060}\n{x=17,m=613,a=2060,s=1358}\n{x=188,m=976,a=100,s=1415}\n{x=965,m=641,a=1563,s=2718}\n{x=867,m=386,a=1798,s=682}\n{x=1596,m=350,a=143,s=167}\n{x=390,m=2438,a=225,s=171}\n{x=1014,m=1030,a=718,s=2678}\n{x=473,m=2034,a=1270,s=449}\n{x=2092,m=268,a=653,s=691}\n{x=951,m=16,a=1869,s=2764}\n{x=494,m=154,a=178,s=1323}\n{x=2653,m=1230,a=238,s=787}\n{x=922,m=1420,a=1390,s=2030}\n{x=2958,m=2763,a=1486,s=2822}\n{x=615,m=373,a=31,s=1548}\n{x=1275,m=1486,a=2205,s=171}\n{x=1,m=2571,a=234,s=1346}\n{x=945,m=107,a=99,s=754}\n{x=1398,m=1428,a=556,s=1724}\n{x=693,m=3354,a=3,s=218}\n{x=1706,m=39,a=1620,s=1403}\n{x=465,m=408,a=2153,s=651}\n{x=1026,m=794,a=340,s=920}\n{x=1275,m=1806,a=120,s=599}\n{x=78,m=1030,a=1601,s=1019}\n{x=2442,m=1645,a=331,s=69}\n{x=1797,m=480,a=479,s=1634}\n{x=135,m=1838,a=216,s=1293}\n{x=1914,m=1031,a=53,s=23}\n{x=2862,m=303,a=883,s=537}\n{x=60,m=192,a=109,s=1577}\n{x=527,m=629,a=103,s=136}\n{x=66,m=1861,a=135,s=1026}\n{x=105,m=678,a=2551,s=495}\n{x=2558,m=33,a=322,s=1359}\n{x=2032,m=376,a=39,s=857}\n{x=929,m=1035,a=174,s=2372}\n{x=731,m=156,a=26,s=2512}\n{x=1120,m=880,a=500,s=1070}\n{x=845,m=108,a=1492,s=1340}\n{x=2460,m=2527,a=1057,s=1382}\n{x=390,m=942,a=953,s=402}\n{x=557,m=440,a=335,s=426}\n{x=1850,m=3068,a=1956,s=258}\n{x=351,m=296,a=222,s=181}\n{x=27,m=389,a=650,s=999}\n{x=1941,m=3377,a=1600,s=1377}\n{x=62,m=2099,a=9,s=25}\n{x=34,m=658,a=215,s=32}\n{x=1408,m=989,a=54,s=560}\n{x=969,m=431,a=634,s=856}\n{x=75,m=678,a=1523,s=157}\n{x=1087,m=837,a=763,s=118}\n{x=112,m=904,a=3317,s=313}\n{x=2163,m=1100,a=271,s=882}\n{x=474,m=289,a=305,s=197}\n{x=1307,m=2741,a=279,s=1550}\n{x=1109,m=629,a=1600,s=298}\n{x=868,m=815,a=2970,s=21}\n{x=1850,m=285,a=1158,s=373}\n{x=1430,m=1078,a=226,s=2374}\n{x=296,m=413,a=1609,s=1099}\n{x=11,m=3105,a=505,s=2170}\n{x=2126,m=1961,a=389,s=1087}\n{x=592,m=1842,a=1991,s=1083}\n{x=93,m=1662,a=1840,s=2377}\n{x=433,m=30,a=1269,s=857}\n{x=1898,m=662,a=861,s=1131}\n{x=2484,m=278,a=1782,s=134}\n{x=102,m=1146,a=3527,s=2090}\n{x=2530,m=727,a=1577,s=211}\n{x=316,m=2957,a=18,s=730}\n{x=492,m=183,a=624,s=1454}\n{x=3325,m=30,a=1660,s=938}\n{x=407,m=1854,a=99,s=326}\n{x=1336,m=1276,a=473,s=24}\n{x=1718,m=438,a=956,s=384}\n{x=353,m=1534,a=2180,s=2974}\n{x=2705,m=211,a=94,s=837}\n{x=104,m=123,a=413,s=1789}\n{x=176,m=395,a=2652,s=50}\n{x=738,m=1018,a=103,s=200}\n{x=750,m=31,a=916,s=121}\n{x=2967,m=1253,a=1593,s=1357}\n{x=262,m=112,a=131,s=63}\n{x=145,m=807,a=291,s=959}\n{x=1476,m=239,a=1054,s=3491}\n{x=428,m=351,a=2465,s=65}\n{x=35,m=236,a=863,s=1089}\n{x=1233,m=2010,a=177,s=764}\n{x=1083,m=1863,a=25,s=1974}\n{x=957,m=1180,a=837,s=679}\n{x=66,m=1204,a=285,s=2075}\n{x=444,m=560,a=172,s=1447}\n{x=812,m=350,a=876,s=661}\n{x=200,m=366,a=752,s=851}\n{x=749,m=377,a=815,s=648}\n{x=60,m=285,a=517,s=39}\n{x=2921,m=381,a=119,s=249}\n{x=466,m=1290,a=801,s=2159}\n{x=62,m=201,a=881,s=95}\n{x=3598,m=126,a=1688,s=979}\n{x=2963,m=1112,a=2733,s=520}\n{x=62,m=1067,a=920,s=451}\n{x=2501,m=475,a=1074,s=1150}\n{x=50,m=1111,a=12,s=44}\n{x=617,m=1106,a=1489,s=1333}\n{x=90,m=208,a=219,s=2352}\n{x=1179,m=2166,a=1693,s=2055}\n{x=61,m=595,a=1382,s=1140}\n{x=62,m=354,a=123,s=793}\n{x=436,m=865,a=2408,s=2578}\n{x=515,m=398,a=303,s=312}\n{x=637,m=2236,a=474,s=148}\n{x=2488,m=35,a=75,s=924}\n{x=461,m=1196,a=7,s=1092}\n{x=923,m=3184,a=1161,s=308}\n{x=191,m=1399,a=1324,s=2784}\n{x=170,m=421,a=51,s=625}\n{x=170,m=362,a=471,s=2100}\n{x=289,m=66,a=143,s=284}\n{x=542,m=339,a=455,s=54}\n{x=155,m=124,a=732,s=2057}\n{x=8,m=420,a=784,s=1455}\n{x=479,m=251,a=1883,s=136}\n{x=104,m=146,a=97,s=249}\n{x=2766,m=833,a=386,s=585}\n{x=373,m=514,a=466,s=2192}\n{x=296,m=1190,a=249,s=963}\n{x=518,m=1840,a=860,s=306}\n{x=1003,m=1955,a=756,s=1098}\n{x=1545,m=242,a=1479,s=576}\n{x=77,m=1717,a=475,s=1692}\n{x=417,m=1517,a=2199,s=374}\n{x=3247,m=348,a=1065,s=1154}\n{x=456,m=868,a=182,s=1077}\n{x=464,m=425,a=15,s=781}\n{x=640,m=294,a=303,s=261}\n{x=1018,m=327,a=18,s=1830}\n{x=262,m=988,a=1974,s=1665}\n{x=123,m=525,a=3062,s=460}\n{x=228,m=2020,a=29,s=701}\n{x=129,m=1163,a=1561,s=958}\n{x=29,m=1576,a=74,s=348}\n{x=64,m=2153,a=63,s=1771}\n{x=71,m=66,a=1642,s=1749}\n{x=1373,m=3063,a=1958,s=561}\n{x=2277,m=3766,a=384,s=363}\n{x=2956,m=127,a=865,s=1862}\n{x=599,m=115,a=2360,s=526}\n{x=651,m=644,a=580,s=514}\n{x=880,m=173,a=613,s=3270}\n{x=1228,m=951,a=1515,s=333}\n{x=1621,m=2392,a=2665,s=1515}\n{x=933,m=1805,a=228,s=1720}\n{x=25,m=1553,a=54,s=3177}\n{x=85,m=550,a=273,s=142}\n{x=489,m=624,a=126,s=557}\n{x=256,m=2513,a=509,s=186}\n{x=2616,m=377,a=2497,s=707}\n{x=688,m=509,a=410,s=557}\n{x=1306,m=105,a=1605,s=3217}\n{x=1405,m=31,a=824,s=543}\n{x=600,m=559,a=1299,s=110}\n{x=2683,m=1112,a=458,s=27}\n{x=1240,m=882,a=417,s=1066}\n{x=651,m=667,a=178,s=3045}\n{x=2089,m=19,a=879,s=90}\n{x=263,m=423,a=41,s=734}\n{x=630,m=44,a=135,s=98}\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_19_questions.txt",
    "content": "--- Day 19: Aplenty ---\n\nThe Elves of Gear Island are thankful for your help and send you on your way.\nThey even have a hang glider that someone stole from Desert Island; since you're already going that direction, it would help them a lot if you would use it to get down there and return it to them.\n\nAs you reach the bottom of the relentless avalanche of machine parts, you discover that they're already forming a formidable heap.\nDon't worry, though - a group of Elves is already here organizing the parts, and they have a system.\n\nTo start, each part is rated in each of four categories:\n\n    x: Extremely cool looking\n    m: Musical (it makes a noise when you hit it)\n    a: Aerodynamic\n    s: Shiny\n\nThen, each part is sent through a series of workflows that will ultimately accept or reject the part.\nEach workflow has a name and contains a list of rules; each rule specifies a condition and where to send the part if the condition is true.\nThe first rule that matches the part being considered is applied immediately, and the part moves on to the destination described by the rule.\n(The last rule in each workflow has no condition and always applies if reached.)\n\nConsider the workflow ex{x>10:one,m<20:two,a>30:R,A}. This workflow is named ex and contains four rules.\nIf workflow ex were considering a specific part, it would perform the following steps in order:\n\n    Rule \"x>10:one\": If the part's x is more than 10, send the part to the workflow named one.\n    Rule \"m<20:two\": Otherwise, if the part's m is less than 20, send the part to the workflow named two.\n    Rule \"a>30:R\": Otherwise, if the part's a is more than 30, the part is immediately rejected (R).\n    Rule \"A\": Otherwise, because no other rules matched the part, the part is immediately accepted (A).\n\nIf a part is sent to another workflow, it immediately switches to the start of that workflow instead and never returns.\nIf a part is accepted (sent to A) or rejected (sent to R), the part immediately stops any further processing.\n\nThe system works, but it's not keeping up with the torrent of weird metal shapes.\nThe Elves ask if you can help sort a few parts and give you the list of workflows and some part ratings (your puzzle input).\nFor example:\n\npx{a<2006:qkq,m>2090:A,rfg}\npv{a>1716:R,A}\nlnx{m>1548:A,A}\nrfg{s<537:gd,x>2440:R,A}\nqs{s>3448:A,lnx}\nqkq{x<1416:A,crn}\ncrn{x>2662:A,R}\nin{s<1351:px,qqz}\nqqz{s>2770:qs,m<1801:hdj,R}\ngd{a>3333:R,R}\nhdj{m>838:A,pv}\n\n{x=787,m=2655,a=1222,s=2876}\n{x=1679,m=44,a=2067,s=496}\n{x=2036,m=264,a=79,s=2244}\n{x=2461,m=1339,a=466,s=291}\n{x=2127,m=1623,a=2188,s=1013}\n\nThe workflows are listed first, followed by a blank line, then the ratings of the parts the Elves would like you to sort.\nAll parts begin in the workflow named in.\nIn this example, the five listed parts go through the following workflows:\n\n    {x=787,m=2655,a=1222,s=2876}: in -> qqz -> qs -> lnx -> A\n    {x=1679,m=44,a=2067,s=496}: in -> px -> rfg -> gd -> R\n    {x=2036,m=264,a=79,s=2244}: in -> qqz -> hdj -> pv -> A\n    {x=2461,m=1339,a=466,s=291}: in -> px -> qkq -> crn -> R\n    {x=2127,m=1623,a=2188,s=1013}: in -> px -> rfg -> A\n\nUltimately, three parts are accepted. Adding up the x, m, a, and s rating for each of the accepted parts gives 7540 for the part with x=787, 4623 for the part with x=2036, and 6951 for the part with x=2127.\nAdding all of the ratings for all of the accepted parts gives the sum total of 19114.\n\nSort through all of the parts you've been given; what do you get if you add together all of the rating numbers for all of the parts that ultimately get accepted?\n\n--- Part Two ---\n\nEven with your help, the sorting process still isn't fast enough.\n\nOne of the Elves comes up with a new plan: rather than sort parts individually through all of these workflows, maybe you can figure out in advance which combinations of ratings will be accepted or rejected.\n\nEach of the four ratings (x, m, a, s) can have an integer value ranging from a minimum of 1 to a maximum of 4000.\nOf all possible distinct combinations of ratings, your job is to figure out which ones will be accepted.\n\nIn the above example, there are 167409079868000 distinct combinations of ratings that will be accepted.\n\nConsider only your list of workflows; the list of part ratings that the Elves wanted you to sort is no longer relevant.\nHow many distinct combinations of ratings will be accepted by the Elves' workflows?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_20.adb",
    "content": "--  Solution to Advent of Code 2023, Day 20\n-------------------------------------------\n--  Pulse Propagation\n--\n--  https://adventofcode.com/2023/day/20\n--  Copy of questions in: aoc_2023_20_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_20 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  subtype Link_Range is Integer range 1 .. 10;\n\n  type Destination_Array is array (Link_Range) of Integer;\n\n  type Pulse is (low, high);\n\n  type Input_Info is record\n    source : Natural;\n    mem    : Pulse;\n    cycle  : Natural;  --  Concerns only the pre_final node's inputs.\n  end record;\n\n  type Input_Array is array (Link_Range) of Input_Info;\n\n  type Module_Kind is (broadcaster, flip_flop, conjunction, final);\n\n  type Flip_Flop_State is (off, on);\n\n  type Module_Type is record\n    kind  : Module_Kind;\n    dest  : Destination_Array;  --  0-terminated (a bad idea...)\n    name  : VString;            --  Only for display.\n    state : Flip_Flop_State;    --  Concerns only flip-flop\n    input : Input_Array;        --  Concerns only conjunction; 0-terminated.\n  end record;\n\n  map : array (1 .. 60) of Module_Type;\n  top : Natural := 0;\n\n  function Name (i : Integer) return VString is\n  begin\n    if i = 0 then\n      return +\"Button\";\n    elsif i < 0 then\n      return +\"Unknown \" & i'Image;  --  Notably, the mysterious \"rx\" node...\n    else\n      return map (i).name;\n    end if;\n  end Name;\n\n  procedure Clear_Machine is\n  begin\n    for i in map'Range loop\n      --  Set the 0-terminators.\n      map (i).dest (1) := 0;\n      map (i).input (1).source := 0;\n    end loop;\n  end Clear_Machine;\n\n  procedure Reset_Inputs is\n    dest : Integer;\n  begin\n    for src in 1 .. top loop\n      map (src).state := off;\n      for d_lnk in Link_Range loop\n        dest := map (src).dest (d_lnk);\n        exit when dest = 0;\n        if dest > 0 and then map (dest).kind = conjunction then\n          --  For conjunctions, we need to know the pulse state\n          --  of each source, because some sources may have not been\n          --  yet activated and have an assumed \"low\" state.\n          for s_lnk in Link_Range loop\n            if map (dest).input (s_lnk).source = 0 then\n              map (dest).input (s_lnk).source := src;\n              map (dest).input (s_lnk).mem    := low;\n              map (dest).input (s_lnk).cycle  := 0;  --  Only useful for pre_final.\n              --  0-terminate:\n              map (dest).input (s_lnk + 1).source := 0;\n              exit;\n            end if;\n          end loop;\n          --\n        end if;\n      end loop;\n    end loop;\n  end Reset_Inputs;\n\n  broadcaster_idx : Positive;\n\n  --  input_name : constant VString := +\"mini_1\";\n  input_name : constant VString := +\"aoc_2023_20\";\n  --\n  procedure Read_Data is\n    use Hash_Maps;\n    hm : Hash_Map_Type;\n    prefix, c : Character;\n    key : VString;\n    arrow : String (1 .. 3);\n    row, i, dest : Integer;\n    f : File_Type;\n\n    procedure Get_Key is\n    begin\n      key := Null_VString;\n      while not End_Of_Line (f) loop\n        Get (f, c);\n        exit when c not in Alpha;\n        key := key & c;\n      end loop;\n    end Get_Key;\n\n    dummy, i64 : Integer_64;\n    ignore : constant := -1;\n\n  begin\n    Clear_Machine;\n    Clear (hm);\n    top := top + 1;\n    key := +\"rx\";\n    map (top).name := key;\n    map (top).kind := final;\n    Insert (hm, key, Integer_64 (top), False, dummy);\n  Passes :\n    for pass in 1 .. 2 loop\n      Open (f, input_name & \".txt\");\n      while not End_Of_File (f) loop\n        Get (f, prefix);\n        Get_Key;\n        case pass is\n          when 1 =>\n            --  In pass #1 we just fill the vector `map` with names\n            --  and feed the hash map. All but one nodes are listed\n            --  on the lines' headers.\n            top := top + 1;\n            map (top).name := key;\n            Insert (hm, key, Integer_64 (top), False, dummy);\n            Skip_Line (f);\n          when 2 =>\n            Find (hm, key, ignore, i64);\n            row := Integer (i64);\n            case prefix is\n              when 'b' =>\n                map (row).kind := broadcaster;\n                broadcaster_idx := row;\n                map (row).name := 'b' & map (row).name;\n              when '%' =>\n                map (row).kind := flip_flop;\n              when '&' =>\n                map (row).kind := conjunction;\n              when others =>\n                Put_Line (\"Bad data!\");\n            end case;\n            Get (f, arrow);\n            i := 0;\n            loop\n              Get_Key;\n              Find (hm, key, ignore, i64);\n              dest := Integer (i64);\n              i := i + 1;\n              map (row).dest (i) := dest;\n              exit when End_Of_Line (f);\n              Get (f, c);  --  Space after ','\n            end loop;\n            --  0-terminate:\n            map (row).dest (i + 1) := 0;\n        end case;\n      end loop;\n      Close (f);\n    end loop Passes;\n  end Read_Data;\n\n  verbosity : constant := 0;\n\n  --  We make a FIFO buffer\n\n  type To_Do_Type is record\n    sent     : Pulse;\n    from, to : Integer;\n  end record;\n\n  buffer : array (0 .. 49) of To_Do_Type;\n\n  read_idx  : Natural;\n  write_idx : Natural;\n\n  procedure FIFO_Reset is\n  begin\n    read_idx  := 0;\n    write_idx := 0;\n  end FIFO_Reset;\n\n  function FIFO_Is_Full return Boolean is\n  begin\n    return (write_idx + 1) mod buffer'Length = read_idx;\n  end FIFO_Is_Full;\n\n  function FIFO_Is_Empty return Boolean is\n  begin\n    return write_idx = read_idx;\n  end FIFO_Is_Empty;\n\n  procedure Put_To_Do (e : in To_Do_Type) is\n  begin\n    if FIFO_Is_Full then\n      Put_Line (+\"FIFO is full! w:\" & write_idx & \" r:\" & read_idx);\n      Skip_Line;\n    else\n      if verbosity >= 2 then\n        Put_Line (Name (e.from) & \" -\" & e.sent'Image & \" -> \" & Name (e.to));\n      end if;\n      buffer (write_idx) := e;\n      write_idx          := (write_idx + 1) mod buffer'Length;\n    end if;\n  end Put_To_Do;\n\n  procedure Get_To_Do (e : out To_Do_Type) is\n  begin\n    if FIFO_Is_Empty then\n      Put_Line (\"FIFO is empty!\");\n    else\n      e        := buffer (read_idx);\n      read_idx := (read_idx + 1) mod buffer'Length;\n    end if;\n  end Get_To_Do;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Simulate is\n    e_cur, e : To_Do_Type;\n    row : Integer;\n    dest : Integer;\n    all_cycles : Boolean;\n    out_pulse : Pulse;\n    ignore : Boolean;\n    high_pulses_for_all_inputs : Boolean;\n    counter : array (Pulse) of Natural;\n    pre_final_idx : Natural := 0;\n\n    procedure Put_Job is\n    begin\n      counter (e.sent) := counter (e.sent) + 1;\n      Put_To_Do (e);\n    end Put_Job;\n\n    button_press_count : Natural := 0;\n\n  begin\n    Reset_Inputs;\n    counter (low)  := 0;\n    counter (high) := 0;\n  Button_Presses :\n    loop\n      button_press_count := button_press_count + 1;\n      if verbosity >= 2 then\n        Put_Line (+\"===================  Round number \" & button_press_count);\n      end if;\n      FIFO_Reset;\n      e.sent := low;\n      e.from := 0;\n      e.to   := broadcaster_idx;\n      Put_Job;\n      while not FIFO_Is_Empty loop\n        Get_To_Do (e_cur);\n        row := e_cur.to;\n\n        if row > 0 then\n          out_pulse := e_cur.sent;\n          ignore := False;\n\n          case map (row).kind is\n\n            when broadcaster =>\n              null;\n\n            when flip_flop =>\n              case e_cur.sent is\n                when high =>\n                  ignore := True;\n                when low =>\n                  if map (row).state = off then\n                    map (row).state := on;\n                    out_pulse := high;\n                  else\n                    map (row).state := off;\n                    out_pulse := low;\n                  end if;\n              end case;\n\n            when conjunction =>\n              if verbosity >= 3 then\n                Put_Line (\"  For \" & Name (row) & \", checking inputs\");\n              end if;\n              high_pulses_for_all_inputs := True;\n              for s_lnk in Link_Range loop\n                exit when map (row).input (s_lnk).source = 0;\n                if verbosity >= 3 then\n                  Put_Line\n                    (\"    \" &\n                     Name (map (row).input (s_lnk).source) & \": \" &\n                     map (row).input (s_lnk).mem'Image);\n                end if;\n                high_pulses_for_all_inputs :=\n                  high_pulses_for_all_inputs and\n                    map (row).input (s_lnk).mem = high;\n              end loop;\n              if high_pulses_for_all_inputs then\n                out_pulse := low;\n              else\n                out_pulse := high;\n              end if;\n\n            when final =>\n              null;\n\n          end case;\n\n          if not ignore then\n            --  Broadcasting\n            if verbosity >= 2 then\n              Put_Line (\"  Broadcasting from \" & Name (row));\n            end if;\n            for id in map (row).dest'Range loop\n              dest := map (row).dest (id);\n              exit when dest = 0;\n              e.sent := out_pulse;\n              e.from := row;\n              e.to   := dest;\n              Put_Job;\n              if dest > 0 then\n                case map (dest).kind is\n                  when conjunction =>\n                    if verbosity >= 2 then\n                      Put_Line (\"  Destination is a conjunction: \" & Name (dest));\n                    end if;\n                    for s_lnk in Link_Range loop\n                      exit when map (dest).input (s_lnk).source = 0;\n                      if map (dest).input (s_lnk).source = row then\n                        map (dest).input (s_lnk).mem := out_pulse;\n                        if verbosity >= 2 then\n                          Put_Line (\"  Updated pulse from input \" & Name (row));\n                        end if;\n                        if dest = pre_final_idx\n                          and then out_pulse = high\n                          and then map (dest).input (s_lnk).cycle = 0\n                        then\n                          if verbosity >= 1 then\n                            Put_Line\n                              (\"New cycle on the \" & Name (row) & \" -> \" & Name (dest) &\n                               \" broadcast; button press so far: \" & button_press_count);\n                          end if;\n                          map (dest).input (s_lnk).cycle := button_press_count;\n                        end if;\n                        exit;\n                      end if;\n                    end loop;\n                    if dest = pre_final_idx then\n                      all_cycles := True;\n                      for s_lnk in Link_Range loop\n                        exit when map (dest).input (s_lnk).source = 0;\n                        all_cycles := all_cycles and map (dest).input (s_lnk).cycle > 0;\n                      end loop;\n                      exit Button_Presses when all_cycles;\n                    end if;\n\n                  when final =>\n                    --  Put_Line\n                    --    (+\"FINAL \" & count & \", pulse: \" &\n                    --     out_pulse'Image & \", from \" & Name (row));\n                    pre_final_idx := row;\n                    --  In our data (and seemingly other data as well)\n                    --  The final node (rx) has a single predecessor\n                    --  (in our case, called \"xn\"), which is a conjunction\n                    --  node. Let's call that node \"pre_final\".\n                    --  The pre_final node will emit a low pulse only\n                    --  after all its inputs are high.\n                  when others =>\n                    null;\n                end case;\n              end if;\n            end loop;\n          end if;\n        end if;\n      end loop;\n      if button_press_count = 1000 then\n        r (part_1) := Integer_64 (counter (low) * counter (high));\n      end if;\n    end loop Button_Presses;\n    r (part_2) := 1;\n    for s_lnk in Link_Range loop\n      exit when map (pre_final_idx).input (s_lnk).source = 0;\n      r (part_2) :=\n        LCM_64\n          (r (part_2),\n           Integer_64 (map (pre_final_idx).input (s_lnk).cycle));\n    end loop;\n  end Simulate;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n\n  Read_Data;\n  Simulate;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1)'Image);\n    Put_Line (+\"Part 2: \" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 806332748\n    --  Part 2: validated by AoC: 228060006554227\n  end if;\nend AoC_2023_20;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_20.txt",
    "content": "%jv -> rn, jn\n&fb -> hb, vk, fz, kl, cg\n%rr -> vm, gp\n&gp -> vm, cb, bd, qm, xf, pk\n%hm -> ql\n%cf -> dx, fb\n%cg -> kl\n%hv -> kg, fb\n%hs -> jv\n%bd -> dt\n%xv -> mv, gp\n%js -> zb, jl\n%rn -> bk, jn\n%lp -> hm\n%dx -> fb, jm\n%ss -> lp\n&hn -> xn\n%bh -> jl, ms\n%km -> jl, lm\n%mv -> gp, qm\n&jl -> km, lm, ms, mp, lr, zb, bg\n%pt -> jt, jl\n%cb -> bd\n%xt -> jn, jf\n%kg -> fb\n%dg -> jn\n%rt -> fb, hb\nbroadcaster -> km, xt, pk, vk\n%lr -> pt\n%vm -> bf\n%hx -> qd, jl\n&mp -> xn\n%hb -> pd\n%vk -> cg, fb\n%kl -> rs\n%pk -> gp, cb\n%jt -> hx, jl\n&jn -> hs, lp, hm, hn, ql, xt, ss\n%bg -> js\n%kz -> ss, jn\n%bf -> fx, gp\n%bk -> dg, jn\n%qm -> rr\n%fx -> gp, dp\n%dp -> gp\n%jf -> jn, kz\n%jm -> hv, fb\n%ql -> hs\n%ms -> bg\n%zb -> lr\n%rs -> fb, rt\n%dt -> xv, gp\n%lm -> bh\n&xf -> xn\n%pd -> cf, fb\n%qd -> jl\n&xn -> rx\n&fz -> xn\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_20_questions.txt",
    "content": "--- Day 20: Pulse Propagation ---\n\nWith your help, the Elves manage to find the right parts and fix all of the machines.\nNow, they just need to send the command to boot up the machines and get the sand flowing again.\n\nThe machines are far apart and wired together with long cables.\nThe cables don't connect to the machines directly, but rather to communication modules attached to the machines that perform various initialization tasks and also act as communication relays.\n\nModules communicate using pulses.\nEach pulse is either a high pulse or a low pulse.\nWhen a module sends a pulse, it sends that type of pulse to each module in its list of destination modules.\n\nThere are several different types of modules:\n\nFlip-flop modules (prefix %) are either on or off; they are initially off.\nIf a flip-flop module receives a high pulse, it is ignored and nothing happens.\nHowever, if a flip-flop module receives a low pulse, it flips between on and off.\nIf it was off, it turns on and sends a high pulse.\nIf it was on, it turns off and sends a low pulse.\n\nConjunction modules (prefix &) remember the type of the most recent pulse received from each of their connected input modules; they initially default to remembering a low pulse for each input.\nWhen a pulse is received, the conjunction module first updates its memory for that input.\nThen, if it remembers high pulses for all inputs, it sends a low pulse; otherwise, it sends a high pulse.\n\nThere is a single broadcast module (named broadcaster).\nWhen it receives a pulse, it sends the same pulse to all of its destination modules.\n\nHere at Desert Machine Headquarters, there is a module with a single button on it called, aptly, the button module.\nWhen you push the button, a single low pulse is sent directly to the broadcaster module.\n\nAfter pushing the button, you must wait until all pulses have been delivered and fully handled before pushing it again.\nNever push the button if modules are still processing pulses.\n\nPulses are always processed in the order they are sent.\nSo, if a pulse is sent to modules a, b, and c, and then module a processes its pulse and sends more pulses, the pulses sent to modules b and c would have to be handled first.\n\nThe module configuration (your puzzle input) lists each module.\nThe name of the module is preceded by a symbol identifying its type, if any.\nThe name is then followed by an arrow and a list of its destination modules.\nFor example:\n\nbroadcaster -> a, b, c\n%a -> b\n%b -> c\n%c -> inv\n&inv -> a\n\nIn this module configuration, the broadcaster has three destination modules named a, b, and c.\nEach of these modules is a flip-flop module (as indicated by the % prefix).\na outputs to b which outputs to c which outputs to another module named inv.\ninv is a conjunction module (as indicated by the & prefix) which, because it has only one input, acts like an inverter (it sends the opposite of the pulse type it receives); it outputs to a.\n\nBy pushing the button once, the following pulses are sent:\n\nbutton -low-> broadcaster\nbroadcaster -low-> a\nbroadcaster -low-> b\nbroadcaster -low-> c\na -high-> b\nb -high-> c\nc -high-> inv\ninv -low-> a\na -low-> b\nb -low-> c\nc -low-> inv\ninv -high-> a\n\nAfter this sequence, the flip-flop modules all end up off, so pushing the button again repeats the same sequence.\n\nHere's a more interesting example:\n\nbroadcaster -> a\n%a -> inv, con\n&inv -> b\n%b -> con\n&con -> output\n\nThis module configuration includes the broadcaster, two flip-flops (named a and b), a single-input conjunction module (inv), a multi-input conjunction module (con), and an untyped module named output (for testing purposes).\nThe multi-input conjunction module con watches the two flip-flop modules and, if they're both on, sends a low pulse to the output module.\n\nHere's what happens if you push the button once:\n\nbutton -low-> broadcaster\nbroadcaster -low-> a\na -high-> inv\na -high-> con\ninv -low-> b\ncon -high-> output\nb -high-> con\ncon -low-> output\n\nBoth flip-flops turn on and a low pulse is sent to output!\nHowever, now that both flip-flops are on and con remembers a high pulse from each of its two inputs, pushing the button a second time does something different:\n\nbutton -low-> broadcaster\nbroadcaster -low-> a\na -low-> inv\na -low-> con\ninv -high-> b\ncon -high-> output\n\nFlip-flop a turns off!\nNow, con remembers a low pulse from module a, and so it sends only a high pulse to output.\n\nPush the button a third time:\n\nbutton -low-> broadcaster\nbroadcaster -low-> a\na -high-> inv\na -high-> con\ninv -low-> b\ncon -low-> output\nb -low-> con\ncon -high-> output\n\nThis time, flip-flop a turns on, then flip-flop b turns off.\nHowever, before b can turn off, the pulse sent to con is handled first, so it briefly remembers all high pulses for its inputs and sends a low pulse to output.\nAfter that, flip-flop b turns off, which causes con to update its state and send a high pulse to output.\n\nFinally, with a on and b off, push the button a fourth time:\n\nbutton -low-> broadcaster\nbroadcaster -low-> a\na -low-> inv\na -low-> con\ninv -high-> b\ncon -high-> output\n\nThis completes the cycle: a turns off, causing con to remember only low pulses and restoring all modules to their original states.\n\nTo get the cables warmed up, the Elves have pushed the button 1000 times.\nHow many pulses got sent as a result (including the pulses sent by the button itself)?\n\nIn the first example, the same thing happens every time the button is pushed: 8 low pulses and 4 high pulses are sent.\nSo, after pushing the button 1000 times, 8000 low pulses and 4000 high pulses are sent.\nMultiplying these together gives 32000000.\n\nIn the second example, after pushing the button 1000 times, 4250 low pulses and 2750 high pulses are sent.\nMultiplying these together gives 11687500.\n\nConsult your module configuration; determine the number of low pulses and high pulses that would be sent after pushing the button 1000 times, waiting for all pulses to be fully handled after each push of the button.\nWhat do you get if you multiply the total number of low pulses sent by the total number of high pulses sent?\n\n--- Part Two ---\n\nThe final machine responsible for moving the sand down to Island Island has a module attached named rx.\nThe machine turns on when a single low pulse is sent to rx.\n\nReset all modules to their default states.\nWaiting for all pulses to be fully handled after each button press, what is the fewest number of button presses required to deliver a single low pulse to the module named rx?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_21.adb",
    "content": "--  Solution to Advent of Code 2023, Day 21\n-------------------------------------------\n--  Step Counter\n--\n--  https://adventofcode.com/2023/day/21\n--  Copy of questions in: aoc_2023_21_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_21 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 11; n7 : constant := 77; steps_part_1 : constant := 6;\n  input_name : constant VString := +\"aoc_2023_21\"; n : constant := 131; n7 : constant := 917; steps_part_1 : constant := 64;\n\n  steps_part_2 : constant := 26501365;\n\n  type Map_Type is array (1 .. n7, 1 .. n7) of Character;\n\n  map : array (Binary) of Map_Type;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n    S : Point;\n  begin\n    Open (f, input_name & \".txt\");\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        if c = 'S' then\n          c := '.';\n          S.x := x;\n          S.y := y;\n        end if;\n        --  Copy the data on a n*7 x n*7 map.\n        --  The 7-fold map is used for extrapolating\n        --  further to the infinity...\n        for kx in 0 .. 6 loop\n          for ky in 0 .. 6 loop\n            map (0)(x + n * kx, y + n * ky) := c;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    Close (f);\n    map (1) := map (0);\n    map (0) (S.x + 3 * n, S.y + 3 * n) := 'O';\n  end Read_Data;\n\n  verbosity : constant := 0;\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Solve is\n    cur : Binary := 0;  --  Oscillate between two maps (game-of-life-style).\n\n    procedure Step_Aside (x, y : Integer) is\n    begin\n      if map (1 - cur) (x, y) = '.' then\n        map (1 - cur) (x, y) := 'O';\n      end if;\n    end Step_Aside;\n\n    b_min, b_max : Positive;\n\n    function Count_Garden_Plots return Natural is\n      total : Natural := 0;\n    begin\n      for y in b_min .. b_max loop\n        for x in b_min .. b_max loop\n          if map (cur) (x, y) = 'O' then\n            total := total + 1;\n          end if;\n        end loop;\n      end loop;\n      return total;\n    end Count_Garden_Plots;\n\n    degree : constant := 2;\n    t : Integer_64;\n    --  Observations of Count_Garden_Plots every n steps:\n    obs : array (0 .. degree) of Integer_64;\n\n  begin\n  Macro :\n    for macro_step in 0 .. degree loop\n      b_min := 1 + n * (2 - macro_step);\n      b_max := n * (5 + macro_step);\n    Micro :\n      for micro_step in 1 .. n loop\n        if verbosity >= 2 then\n          Put_Line (\"------------\");\n          for y in 1 .. n7 loop\n            for x in 1 .. n7 loop\n              Put (map (cur) (x, y));\n            end loop;\n            New_Line;\n          end loop;\n        end if;\n        for y in b_min .. b_max loop\n          for x in b_min .. b_max loop\n            if map (cur) (x, y) = 'O' then\n              Step_Aside (x, y - 1);\n              Step_Aside (x, y + 1);\n              Step_Aside (x + 1, y);\n              Step_Aside (x - 1, y);\n              map (1 - cur) (x, y) := '.';\n            end if;\n          end loop;\n        end loop;\n        cur := 1 - cur;\n        if macro_step = 0 and then micro_step = steps_part_1 then\n          r (part_1) := Integer_64 (Count_Garden_Plots);\n          if compiler_test_mode then\n            return;\n          end if;\n        end if;\n        if (micro_step mod n) = (steps_part_2 mod n) then\n          --  We measure the result every n steps for a while.\n          obs (macro_step) := Integer_64 (Count_Garden_Plots);\n          exit Macro when macro_step = degree;\n        end if;\n      end loop Micro;\n    end loop Macro;\n    --\n    --  Someone somewhere seems to claim that due to favourable\n    --  settings (n being odd, S being at the centre, borders and\n    --  the crosss through S being free, moves being only horizontal\n    --  or vertical,...), the result is exactly predicted by a\n    --  polynomial of degree 2.\n    --\n    --  We determine p such as:   p (t) = obs (t)  for t = 0, 1, 2\n    --\n    if verbosity >= 1 then\n      for d in 0 .. degree loop\n        Put_Line (+\"d = \" & d & \", observation \" & obs (d)'Image);\n      end loop;\n    end if;\n    t := steps_part_2 / n;\n    r (part_2) :=\n       obs (0) +\n      (obs (1) - obs (0)) * t +\n      (obs (2) - 2 * obs (1) + obs (0)) * t * (t - 1) / 2;\n  end Solve;\n\n  T0 : constant Time := Clock;\n\nbegin\n\n  Read_Data;\n  Solve;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1)'Image);\n    Put_Line (+\"Part 2: \" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 3677.\n    --  Part 2: validated by AoC: 609585229256084.\n  end if;\nend AoC_2023_21;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_21.txt",
    "content": "...................................................................................................................................\n.#....................#..#......##.#..#.#..#.#..#.#.........#....................##......##...#....#.....#..#.....#........#.......\n.........#......#.#.........#...#.#...##..#.......#..#...................#........#..........#.#..##...#...#.......................\n..#...#...#..#..#.#..#......#.....#...#....##..............................#......#.....#........#.......#.#.......#..#......#.....\n............#................#...#.............#.........................#..................#....#..............#......##..#.......\n.##....#...#....#............#.#..................#.#...#.................#......#.....#..........#.....#.#.#...........#..........\n..###....#.#.#....#....##............##.#...#...............................#.#..#.#.........#....................#.#....###.#.....\n..#....##.......#...##..#......#.....................#..........#...#............#.........#.........##......#......#..#......#....\n....................#......##.............#.#.................................#.....#..#.#..#....#...##........#....#..............\n................#...........#.#.....#.#....#.................#.....#...................#..............#....#..#......#......#......\n.....#.....#...........#.............#.##......#.#..............#................#........#..#..#....#....#....#.#..........#.#....\n..#......#..........#.............#..........#...#.................#.##..................#.##.....#......##.......#...#.........##.\n.......#..#..#.......#.......#...##.#....#.....#...........#...#....#..#..............#.............#......#..#....................\n..#..#.........#.......#...#..............#.............#......#....#...................#..........##.....##.##.....#.....#.#......\n.....#....###....#......#..#..#..#........#..#............#.....#.....#.#.#..................#.......#...........##................\n.........#....#.....#...........#..##..##.......................#..#.......#.............#....##...##...#...#...##........#...#....\n.#...#..#.....#.......#.#......#.......#.#.............#..#.#.....#.#.#......#.........#.........#...........#..#.....##....#......\n.....#.#.#...............#...........###.#..............#.#..#......#...................#...#....##.........#..#..#.#...#.#........\n......#..........#....##.....#.......#.....#..........#......###....#.......#...........#......#..............#.........#..#.#.....\n...#......#............#............#.#..#........#.....#.......#..............#.............#.........#...........#...............\n..............##........#.##..#....................#.......#...............#...#.............#...#..##.........#.......#.........#.\n..........##....#..#.........#...#..............#.....##..#.....................#...........##.......................#...........#.\n......#..........##..............#...................#...#..#.....#.....#.......#...............#.........#..#......#........#.....\n....#.#.............#.....#...#.....#.#........#.#...#...###..#........#..#...#.............#.........#.....................##.....\n....#...#.........#..............#..............#.......####.........#..............##...........###.......#.....#........##..#..#.\n..#...#...........#.#...#...#...............................#............#....................#...#....#..#...#.#...........#..#...\n..#.....##..#.#.........................................#.........#....#......#....#..#....................#.#........#..........#.\n..#...#..#...#......#.#.......#...............#.#......##..#..#.........#.............#......................#....##...##.#........\n...#.#.#..............#...##..............#...#............#...............#...........#.#.........#..#.......#.#.#...........#....\n............#.....#....#.....##...............#......#..........#.....#........#........#..............#...#.#.....#.#.............\n............#........##.................#......#...............................#.#.#................#...#.................#..#.....\n......#...#....#............#.........#.......#....#...................#........#..........#...............#...........#...........\n........#............#......##.......#...........#.......#.............#.....................................#...........#.........\n..........#.....#.........#.#.......................#..........##.........#....#........#.....#..........##..................##....\n..........#........................#.............#.......##..#......#..........#...........#.............#....#..#..#....#......#..\n......#........#........#.........#.......#....#..................#.........##.....#......#....................#...#.........#.....\n...#..#....#....#.................#...#.....#.....##....................#.......##.....#...#...##.......................##.....#...\n...##........#.....................#.........#..##....#.................###........#.......#..............#...#...#.......#....##..\n.......#...........##.............#......##.............##.##........##...#..#..#.#.......#..#.#...........#...#...................\n.........#.......##.............#............##.....#........#...............#.#.....#.....#.#..............#.......##...#.........\n.......##...#....#...........#...........#..............#..#..#.........####..........#....##.................#..............#.....\n....#..........................#..........#.............#..........#...#...........#.......#............................##.........\n...#...#.....###.................................##...............................#....#...#..##.................................#.\n..#....#.#......#............#...#......##.....#.....#..##...#.........#.....#.............#......#...#............#...............\n......#.....#.##................#.......##.##........#.........................#..............................................#....\n.#....#..................#.#...............#..#......##.......##...............#....####..........#...#........................#...\n...#........#..........#.................#....#.........#....#.....#.........#.....#.#.......##.......#................#..##.......\n.#.......#.#..#............##...........#......#.#.......................#.........#.....#.....#.....###...............#.#..##.....\n.......................#...#...........#.........#....###.......................#.........###.#.#....#......#........##............\n..#....................#.................#.#.##.#........#..#......#....#......##......#............#..#..............#....#....#..\n.......................##.##.#..#.....###....#..#.#...#............#........#.....#....#.#.....#..#....#......................##...\n....#.....#.........##..#....#..#.........#...#...#..##........#......###.....#..................#......................#..........\n.#.#................#..#.#...#........................#....##..#.............#...#.#.......#........#.#.....##................#....\n.##..#..........#..#.#........##............#.......#..........#....#.#...#....##.#...#..##...........#.......................#....\n.#.#.##..................#............#.#......#.........#............#.#....#..#.........##..#..................##...........##.#.\n..............#..........#...#...##..........#.....................#..#..............#.....#.#...........#.....#....#.......#......\n..###.........#........###...#...........#..##.##..###....#...#................#.....#......#...##...................#...........#.\n..#...........#.................##........#.........#...#.....##......##...#.........#......#.............#...#..#.................\n..#.............#..........#.#.............#.....#............#....#.#......#....................#.#.......#.#.....#............##.\n..........#...........#...#...#...#................#......#................#..........................##.##.....#..#..#.#..........\n..............#....#......#............#.....#.......#..#..........................#..#...............................#............\n............#.............#...........##...#.##..#.........#....#.....#..#.....#...............##....#.................#...........\n...........#.....#.##..............#....#..........#......#.......#..##....##.......#.........#.......#....#...#..........#........\n......#...#...#..............#.#...##.#..#........#.....#.......#...#.........#.....#.....##.........#.#...........................\n..............#..#........#......##.......#......#...#.#........#.............#...##.............#.#.#...............##....#.......\n.................................................................S.................................................................\n.........#.....#.#.#..........#.#.............#..#.....................##......##.#.............#.#.......#.........#...#..........\n.........#......#......#......#..........#...........................#...#......#..........#..#.#..........#......#..#..#...#......\n........#.#...............##...............................#.#..............#.#....##..#...#...#....#..#.................#.........\n.............#..#....#............#........#.#......#........#.......#....#......#...#.#..........#....##......#.#.................\n............#..........#.............#.#..............#.....#.....#...#...#........#.#........#.#........#.#.......................\n.................#........#......#....#.#................#..............#.....#.#.....#.............#.#........#.#...#.............\n...........#....#.##...........#..#...................................#.#...#........#.......#.........#...#..##..##...............\n.....................#.#..#...#.#..........#....##...#.................#...............#.......................#...................\n..............#..#.............#.#...........#....#.......#.........#.......#.........#...#.#.........##............#..............\n....#.............##....#......#..........................##.........#.#.........#.....#...#..............#........................\n....#............#...........#.####....#...#.......#..#.........#...#.............#...........#...#...........#.##...........#.#...\n..##..............#...............#...#.#..#....##.....................#..#.....#.............#....#.......#..###.............##.#.\n.....#.##........#....#...##.#..###...#......#..##.#.....#..#.#.#........##......#............#.......#.....#....#...........##....\n.#......................#.#.......#........#.#.#.........##.....#.....#..#........#..#..#...#..##.......#...............#..........\n.....#...#.............................#.....#.....#......##......#...##........#.#.........................###.........#..........\n...#........#...................#....#...........#..#....#...#.........#...........##.#..#..#..#...........##............#.........\n......##..#..........##..#..#...........#......#...#........#.....#........#...........#........#............#........#.......#....\n.......#.......................#....#......###..#..#..#.........#.##..#................#.....#...............................#.....\n...#.........#............................................#...#....#...........#.#..................#.....##.......#...#........#..\n..##..###.......#........#................#.....#..................##.........#..#..#...........#..##...###.........###...#...#....\n..........#.....#.............#.#..#.#...........##.........#..............................#..#.......#.#................#.#.#.....\n.......#..................#............##.............#..............#.#........#.#..............#...#..........................#..\n...#.......#.....#..........................#...#...#...........#..#.............#.........#..........#.............#........#.....\n..............#................##......#.#......#........................####...#.....#....#....#..................#.#.#........#..\n........#.....#.#....#....................##......................................#...#..#.......#..........................##.....\n...#.#.........#.#..#.............#...#....##.......#......................##...#.#.........#.....#..........#.....................\n..#.#......#...#......##............#......#....#.#..#.#..........#....#......##..#................................#...............\n........###..##....##...........................#.#.#.##..###........#....#............#........##.........#...#...................\n....#............................#.#.........#.........#...#.......#.................#..#......#.........#..#.....#...#.#....#...#.\n..#.#..........#..........#.........#..#...#..........#.....#....................#.#..#.......#...........#............#...........\n.......#.....#...........##.........#.....#..........#....#..#......#...........#...##....#......................#....#.......#....\n..##......#...##.............................##..........#....#..............#..........#..............##..#....##.#........##.....\n....#......#....#.#..................#..........#....#.#..##.#.##........#.............................#...............#.......#.#.\n.............#..#......#.................#.#..#....####........#......#......#....#.#.....................#.#.#.#..#...............\n.##......#........##........#.............#.#.###.....#.............#.......#..##....#...#....................##..###.......#......\n....#.#......##.#.......#......#......................#.......#.........#..#...........#................#.........#..#...#....#....\n..........#....#..#...........#.................#...#..#.....................#.#........##.......#.#....#..#................##...#.\n......#....#.......#.......#..#...........#......#............#......#................#..........#...#.......##...#....#.#.........\n...#..##...##....#..#.......#....#.................#.#.....#....#........#..#.....####.#...........#..#............#...#..##.....#.\n..#......#...................#...............................#............#.....##.............#..#...#..##.#......#...............\n....#.........#.........#..............................#...#....#..#.#..............#...............#..##.........#.......#....#...\n.....#.........#....#.............#............................#.................##............#...#......#..........#.....#.....#.\n...#.#....#.......##...#....#............................##.#...#.......#...##...................#..........#.#....................\n...........#..#.###.....##...#.........#...........#..#.#.........#.#.#.......#.................#....#............###.........#..#.\n.##..........#..#......#.....##.##.#...##.........#.................#....#.#.....#.................#.....#...#....#.....###..#.#...\n......#.#..##.#.......#...#..#........................#..#..........#.#....#..##........#...#.#.............#.#....................\n.......#.#.............#..#.........................#.##..........##......................#...##.........#....#..........#..###....\n...............#..#...#.........#.........#.................#.#......#....................#.........#.......................#.#....\n.....#.................#.#...............##............................####...................##....#......#.#....##..#..#.......#.\n....#..#.......#.#...#.......................##.........#..#.......#.#.#............#...........#.###............#......#...##.....\n..#.#..........#..#.......#...#.........#....#.........#....#...#.......#.#..........##..##........................#..........##...\n....#...##......##......#.......#....###..............................#.##........................#......##.......#............#...\n...........#......#.#......#.............................#..........#...............#......##...............#.#........###.......#.\n..............#......#.....#.........#.....##....#..................#..##.......#.........##.#..##..................#....#.........\n....#...#...##.......###.......#....#...........#.#.............#...#.............#.#...#.#..................#..#.........#........\n................#.........#....#....#.##.....#...###..........#.......#...........#..#....#.............#....................##....\n.......................##..............#...#.#....##.#............#.#........#......##....#.......#........#.#.......#....#..#..#..\n..#....#..#............#.#...................#.....................................#.......##.#............##..#........#..........\n.....#............#.......##.........##...#........#........................................#................#.......#..........#..\n......#.#.....#.......#............##......#.#..#....#.........................#...............#..#.......##....###......###.......\n..#...................#.#...#.....#.......#..................................#..#....#......#.#...#..#..#......#.#.#....#....#.....\n...#....#....#.....#.....#.............................#.##..............#.....#..#.........#...#.....#........#.......#......##...\n.....#.......#.....#...#..#....#................#.......................#..#...#........#..........#....#..#....................#..\n......#.............#.#...#.##.......#...#.....#.....#.#.#...............#.....##.#....#...............................#.#.....#...\n...................................................................................................................................\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_21_questions.txt",
    "content": "--- Day 21: Step Counter ---\n\nYou manage to catch the airship right as it's dropping someone else off on their all-expenses-paid trip to Desert Island!\nIt even helpfully drops you off near the gardener and his massive farm.\n\n\"You got the sand flowing again! Great work! Now we just need to wait until we have enough sand to filter the water for Snow Island and we'll have snow again in no time.\"\n\nWhile you wait, one of the Elves that works with the gardener heard how good you are at solving problems and would like your help.\nHe needs to get his steps in for the day, and so he'd like to know which garden plots he can reach with exactly his remaining 64 steps.\n\nHe gives you an up-to-date map (your puzzle input) of his starting position (S), garden plots (.), and rocks (#).\nFor example:\n\n...........\n.....###.#.\n.###.##..#.\n..#.#...#..\n....#.#....\n.##..S####.\n.##..#...#.\n.......##..\n.##.#.####.\n.##..##.##.\n...........\n\nThe Elf starts at the starting position (S) which also counts as a garden plot.\nThen, he can take one step north, south, east, or west, but only onto tiles that are garden plots.\nThis would allow him to reach any of the tiles marked O:\n\n...........\n.....###.#.\n.###.##..#.\n..#.#...#..\n....#O#....\n.##.OS####.\n.##..#...#.\n.......##..\n.##.#.####.\n.##..##.##.\n...........\n\nThen, he takes a second step.\nSince at this point he could be at either tile marked O, his second step would allow him to reach any garden plot that is one step north, south, east, or west of any tile that he could have reached after the first step:\n\n...........\n.....###.#.\n.###.##..#.\n..#.#O..#..\n....#.#....\n.##O.O####.\n.##.O#...#.\n.......##..\n.##.#.####.\n.##..##.##.\n...........\n\nAfter two steps, he could be at any of the tiles marked O above, including the starting position (either by going north-then-south or by going west-then-east).\n\nA single third step leads to even more possibilities:\n\n...........\n.....###.#.\n.###.##..#.\n..#.#.O.#..\n...O#O#....\n.##.OS####.\n.##O.#...#.\n....O..##..\n.##.#.####.\n.##..##.##.\n...........\n\nHe will continue like this until his steps for the day have been exhausted.\nAfter a total of 6 steps, he could reach any of the garden plots marked O:\n\n...........\n.....###.#.\n.###.##.O#.\n.O#O#O.O#..\nO.O.#.#.O..\n.##O.O####.\n.##.O#O..#.\n.O.O.O.##..\n.##.#.####.\n.##O.##.##.\n...........\n\nIn this example, if the Elf's goal was to get exactly 6 more steps today, he could use them to reach any of 16 garden plots.\n\nHowever, the Elf actually needs to get 64 steps today, and the map he's handed you is much larger than the example map.\n\nStarting from the garden plot marked S on your map, how many garden plots could the Elf reach in exactly 64 steps?\n\n--- Part Two ---\n\nThe Elf seems confused by your answer until he realizes his mistake: he was reading from a list of his favorite numbers that are both perfect squares and perfect cubes, not his step counter.\n\nThe actual number of steps he needs to get today is exactly 26501365.\n\nHe also points out that the garden plots and rocks are set up so that the map repeats infinitely in every direction.\n\nSo, if you were to look one additional map-width or map-height out from the edge of the example map above, you would find that it keeps repeating:\n\n.................................\n.....###.#......###.#......###.#.\n.###.##..#..###.##..#..###.##..#.\n..#.#...#....#.#...#....#.#...#..\n....#.#........#.#........#.#....\n.##...####..##...####..##...####.\n.##..#...#..##..#...#..##..#...#.\n.......##.........##.........##..\n.##.#.####..##.#.####..##.#.####.\n.##..##.##..##..##.##..##..##.##.\n.................................\n.................................\n.....###.#......###.#......###.#.\n.###.##..#..###.##..#..###.##..#.\n..#.#...#....#.#...#....#.#...#..\n....#.#........#.#........#.#....\n.##...####..##..S####..##...####.\n.##..#...#..##..#...#..##..#...#.\n.......##.........##.........##..\n.##.#.####..##.#.####..##.#.####.\n.##..##.##..##..##.##..##..##.##.\n.................................\n.................................\n.....###.#......###.#......###.#.\n.###.##..#..###.##..#..###.##..#.\n..#.#...#....#.#...#....#.#...#..\n....#.#........#.#........#.#....\n.##...####..##...####..##...####.\n.##..#...#..##..#...#..##..#...#.\n.......##.........##.........##..\n.##.#.####..##.#.####..##.#.####.\n.##..##.##..##..##.##..##..##.##.\n.................................\n\nThis is just a tiny three-map-by-three-map slice of the inexplicably-infinite farm layout; garden plots and rocks repeat as far as you can see.\nThe Elf still starts on the one middle tile marked S, though - every other repeated S is replaced with a normal garden plot (.).\n\nHere are the number of reachable garden plots in this new infinite version of the example map for different numbers of steps:\n\n    In exactly 6    steps, he can still reach  16       garden plots.\n    In exactly 10   steps, he can reach any of 50       garden plots.\n    In exactly 50   steps, he can reach        1594     garden plots.\n    In exactly 100  steps, he can reach        6536     garden plots.\n    In exactly 500  steps, he can reach        167004   garden plots.\n    In exactly 1000 steps, he can reach        668697   garden plots.\n    In exactly 5000 steps, he can reach        16733044 garden plots.\n\nHowever, the step count the Elf needs is much larger!\nStarting from the garden plot marked S on your infinite map, how many garden plots could the Elf reach in exactly 26501365 steps?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_22.adb",
    "content": "--  Solution to Advent of Code 2023, Day 22\n------------------------------------------\n--  Sand Slabs\n--\n--  https://adventofcode.com/2023/day/22\n--  Copy of questions in: aoc_2023_22_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_22 is\n\n  use AoC_Toolbox, HAT;\n\n  capacity : constant := 1500;\n\n  --  Poor man's ordered map (inspired from Day 18).\n  --  On a \"full Ada\" system like GNAT we would use\n  --  efficient Ada.Container.* goodies...\n\n  type Vector_Values is array (1 .. capacity) of Integer;\n\n  type Ordered_Map is record\n    last : Natural;\n    key  : Vector_Values;  --  Ordered values\n    elt  : Vector_Values;  --  Elements\n  end record;\n\n  procedure Insert (v : in out Ordered_Map; key, element : Integer) is\n    ins : Positive;\n    found : Boolean := False;\n  begin\n    for i in 1 .. v.last loop\n      if v.key (i) = key then\n        ins := i;\n        found := True;\n        exit;\n      end if;\n    end loop;\n    if not found then\n      ins := v.last + 1;\n    end if;\n    for i in 1 .. v.last loop\n      if v.key (i) > key then\n        ins := i;\n        exit;\n      end if;\n    end loop;\n    --  Make room for the new element\n    for i in reverse ins .. v.last loop\n      v.key (i + 1) := v.key (i);\n      v.elt (i + 1) := v.elt (i);\n    end loop;\n    v.key (ins) := key;\n    v.elt (ins) := element;\n    v.last := v.last + 1;\n  end Insert;\n\n  procedure Find\n    (v     : in out Ordered_Map;\n             --  ^ \"out\" is not needed, we just force\n             --    a by-reference parameter passing on HAC.\n     key   : in     Integer;\n     index :    out Integer;\n     found :    out Boolean)\n  is\n  begin\n    for i in 1 .. v.last loop\n      if v.key (i) = key then\n        index := i;\n        found := True;\n        return;\n      end if;\n    end loop;\n    found := False;\n  end Find;\n\n  procedure Delete_Index\n    (v     : in out Ordered_Map;\n     index : in     Integer)\n  is\n  begin\n    for i in index + 1 ..  v.last loop\n      v.key (i - 1) := v.key (i);\n      v.elt (i - 1) := v.elt (i);\n    end loop;\n    v.last := v.last - 1;\n  end Delete_Index;\n\n  --  There may be multiple elements for the same key.\n\n  procedure Delete_Element (map : in out Ordered_Map; key, element : Integer) is\n    idx_ord_delete : Integer;\n    key_found : Boolean;\n    elt_found : Boolean;\n  begin\n    Find (map, key, idx_ord_delete, key_found);\n    if key_found then\n      elt_found := False;\n      for j in idx_ord_delete .. map.last loop\n        if map.elt (j) = element then\n          --  Found our element in the map.\n          Delete_Index (map, j);\n          elt_found := True;\n          exit;\n        end if;\n      end loop;\n      if not elt_found then\n        Put (\"Element not found\");\n      end if;\n    else\n      Put (\"Key not found\");\n    end if;\n  end Delete_Element;\n\n  type Brick is record\n    edge_min, edge_max : Point_3D;\n  end record;\n\n  type Brick_Array is array (1 .. capacity) of Brick;\n\n  type List_Type is record\n    brick           : Brick_Array;\n    last            : Natural;\n    z_top, z_bottom : Ordered_Map;  --  Ordered tops and bottoms of bricks\n  end record;\n\n  --  GNAT runs this program on the actual problem data in 2.24 seconds,\n  --  while HAC takes forever.\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n\n  function Input_Name return VString is\n  begin\n    if compiler_test_mode then\n      --  We grab the small data directly from the text!\n      return +\"aoc_2023_22_questions\";\n    else\n      return +\"aoc_2023_22\";\n    end if;\n  end Input_Name;\n\n  example_length : constant := 7;\n\n  procedure Read_Data (list : out List_Type) is\n    dummy : Character;\n    f : File_Type;\n    e_min, e_max : Point_3D;\n  begin\n    list.last := 0;\n    list.z_top.last    := 0;\n    list.z_bottom.last := 0;\n    Open (f, Input_Name & \".txt\");\n    if compiler_test_mode then\n      --  Skip x lines of bla-bla.\n      Skip_Line (f, 13);\n    end if;\n    while not End_Of_File (f) loop\n      Get (f, e_min.x); Get (f, dummy);\n      Get (f, e_min.y); Get (f, dummy);\n      Get (f, e_min.z);\n      Get (f, dummy);\n      Get (f, e_max.x); Get (f, dummy);\n      Get (f, e_max.y); Get (f, dummy);\n      Get (f, e_max.z);\n      --\n      list.last := list.last + 1;\n      list.brick (list.last).edge_min := e_min;\n      list.brick (list.last).edge_max := e_max;\n      Insert (list.z_bottom, e_min.z, list.last);\n      Insert (list.z_top,    e_max.z, list.last);\n      --\n      exit when compiler_test_mode and then list.last = example_length;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Fall\n    (list     : in out List_Type;\n     ignore   : in     Natural;\n     simulate : in     Boolean;\n     moves    :    out Natural)\n  is\n    own_z_bottom, own_z_top : Integer;\n    idx_own, idx_ord_other, idx_other : Integer;\n    found : Boolean;\n    x1, x2, y1, y2 : Integer;\n    xt1, xt2, yt1, yt2 : Integer;\n    brick_can_move : Boolean;\n  begin\n    moves := 0;\n  Check_Bottoms :\n    for i in 1 .. list.z_bottom.last loop\n      own_z_bottom := list.z_bottom.key (i);\n      idx_own      := list.z_bottom.elt (i);\n      own_z_top    := list.brick (idx_own).edge_max.z;\n      brick_can_move := False;\n    Iterate_Bottom :\n      while own_z_bottom > 1 loop\n        own_z_bottom := own_z_bottom - 1;\n        own_z_top    := own_z_top    - 1;\n        --  We let the bottom fall until it hits the top\n        --  of another brick.\n        Find (list.z_top, own_z_bottom, idx_ord_other, found);\n        if found then\n          x1 := list.brick (idx_own).edge_min.x;\n          x2 := list.brick (idx_own).edge_max.x;\n          y1 := list.brick (idx_own).edge_min.y;\n          y2 := list.brick (idx_own).edge_max.y;\n          while\n            idx_ord_other <= list.z_top.last\n            and then list.z_top.key (idx_ord_other) = own_z_bottom\n          loop\n            --  We have a series of \"other\" bricks whose top face\n            --  might collide with \"our\" falling brick's bottom face.\n            --  \"Our\" brick's bottom is at height `own_z_bottom`\n            --  The \"other\" brick's top face is at the same height.\n            --  If the rectangles intersect, the fall has clearly\n            --  gone too far...\n            idx_other := list.z_top.elt (idx_ord_other);\n            if idx_other /= idx_own and then idx_other /= ignore then\n              xt1 := list.brick (idx_other).edge_min.x;\n              xt2 := list.brick (idx_other).edge_max.x;\n              yt1 := list.brick (idx_other).edge_min.y;\n              yt2 := list.brick (idx_other).edge_max.y;\n              exit Iterate_Bottom when\n                not\n                  (xt2 < x1 or else  --  the \"other\" brick is left to our brick\n                   xt1 > x2 or else  --  the \"other\" brick is right to our brick\n                   yt2 < y1 or else  --  same for y axis\n                   yt1 > y2);        --  same for y axis\n            end if;\n            idx_ord_other := idx_ord_other + 1;\n          end loop;\n        end if;\n        brick_can_move := True;\n        if simulate then\n          moves := 1;  --  Just some non-zero value.\n          exit Check_Bottoms;\n          --  \"Don't actually disintegrate any bricks - just determine\n          --   what would happen if, for each brick, only that\n          --   brick were disintegrated.\"\n        end if;\n        --  All right, we can safely move the brick down by -1.\n        list.brick (idx_own).edge_min.z := own_z_bottom;\n        list.brick (idx_own).edge_max.z := own_z_top;\n        --  Keep top / bottom lists up-to-date.\n        Delete_Element (list.z_top,    own_z_top + 1,    idx_own);\n        Delete_Element (list.z_bottom, own_z_bottom + 1, idx_own);\n        Insert (list.z_top,    own_z_top,    idx_own);\n        Insert (list.z_bottom, own_z_bottom, idx_own);\n      end loop Iterate_Bottom;\n      if brick_can_move then\n        moves := moves + 1;\n      end if;\n    end loop Check_Bottoms;\n  end Fall;\n\n  data : List_Type;\n\n  procedure Do_Part_1 is\n    list : List_Type := data;\n    moves : Natural;\n  begin\n    --  \"You'll need to start by figuring out where [the falling bricks]\n    --   will end up.\"\n    Fall (list, 0, False, moves);\n\n    r (part_1) := 0;\n    for brick_index in 1 .. list.last loop\n      Fall (list, brick_index, True, moves);\n      if moves = 0 then\n        --  Brick #brick_index is safe to disintegrate.\n        r (part_1) := r (part_1) + 1;\n      end if;\n    end loop;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    list, work : List_Type := data;\n    moves : Natural;\n  begin\n    Fall (list, 0, False, moves);\n    r (part_2) := 0;\n    for brick_index in 1 .. list.last loop\n      work := list;\n      Fall (work, brick_index, False, moves);\n      --  Put_Line\n      --    (+\"Disintegrating brick #\" & brick_index &\n      --      \" would cause \" & moves & \" to fall\");\n      r (part_2) := r (part_2) + moves;\n    end loop;\n  end Do_Part_2;\n\n  T0 : constant Time := Clock;\n\nbegin\n\n  Read_Data (data);\n\n  Do_Part_1;\n\n  Do_Part_2;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 451    (example: 5)\n    --  Part 2: validated by AoC: 66530  (example: 7)\n  end if;\nend AoC_2023_22;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_22.txt",
    "content": "9,7,295~9,8,295\n7,1,214~7,1,217\n4,3,272~6,3,272\n6,2,55~6,4,55\n1,2,254~1,4,254\n4,5,291~7,5,291\n4,2,73~4,2,74\n8,3,224~9,3,224\n2,5,94~2,7,94\n9,9,15~9,9,17\n9,5,88~9,7,88\n6,9,253~7,9,253\n9,7,215~9,9,215\n1,2,295~1,5,295\n2,6,54~4,6,54\n8,0,7~8,0,9\n5,4,301~5,5,301\n2,1,172~4,1,172\n9,4,99~9,7,99\n2,6,59~2,8,59\n1,5,17~1,9,17\n5,9,100~7,9,100\n8,6,227~8,6,227\n0,2,177~0,5,177\n4,2,184~4,2,187\n3,4,147~3,6,147\n4,5,313~4,6,313\n4,6,99~5,6,99\n0,6,3~3,6,3\n1,4,265~2,4,265\n9,8,14~9,9,14\n5,4,317~5,5,317\n1,3,253~1,5,253\n5,1,85~5,1,86\n5,7,24~8,7,24\n1,1,84~3,1,84\n1,0,101~4,0,101\n5,1,58~8,1,58\n9,3,234~9,5,234\n9,4,203~9,5,203\n6,4,227~9,4,227\n9,0,261~9,2,261\n9,7,106~9,8,106\n9,1,262~9,2,262\n3,7,67~3,9,67\n4,7,301~4,9,301\n4,2,339~4,3,339\n8,0,262~8,0,264\n6,1,91~7,1,91\n0,2,102~0,6,102\n0,1,169~0,4,169\n4,4,332~7,4,332\n1,2,39~1,4,39\n0,8,45~2,8,45\n9,6,211~9,8,211\n3,8,137~3,8,139\n7,7,242~7,9,242\n2,4,128~2,6,128\n8,6,299~8,8,299\n3,3,42~5,3,42\n7,3,9~9,3,9\n1,8,92~2,8,92\n4,9,289~7,9,289\n3,2,280~5,2,280\n1,4,1~1,4,1\n0,1,39~0,1,42\n4,2,231~4,3,231\n7,2,86~7,2,88\n4,9,104~7,9,104\n8,2,234~8,4,234\n0,0,163~0,0,164\n8,2,22~8,4,22\n8,0,131~8,0,133\n5,1,196~7,1,196\n7,2,311~9,2,311\n1,9,188~4,9,188\n2,4,29~4,4,29\n6,6,342~6,8,342\n4,1,116~6,1,116\n9,6,213~9,8,213\n8,3,270~8,4,270\n5,4,312~5,5,312\n6,3,257~8,3,257\n8,6,81~8,8,81\n6,7,191~6,7,193\n5,2,6~7,2,6\n0,1,117~2,1,117\n1,3,338~1,3,339\n5,2,58~7,2,58\n3,4,140~5,4,140\n8,5,315~9,5,315\n0,2,259~0,2,261\n2,9,300~2,9,302\n4,0,263~7,0,263\n3,5,28~5,5,28\n9,6,234~9,6,235\n4,7,126~4,8,126\n4,2,286~4,2,286\n9,0,124~9,1,124\n1,7,137~1,9,137\n3,3,136~3,5,136\n9,0,104~9,1,104\n1,4,229~1,4,232\n9,1,200~9,2,200\n2,7,209~2,9,209\n3,1,33~3,4,33\n0,1,124~1,1,124\n1,2,242~3,2,242\n8,9,176~9,9,176\n2,1,46~4,1,46\n1,1,43~1,2,43\n5,6,243~5,7,243\n8,5,42~8,7,42\n7,1,84~7,3,84\n5,4,127~5,6,127\n0,2,117~1,2,117\n9,1,296~9,1,299\n2,6,44~2,9,44\n3,6,49~7,6,49\n0,8,188~0,9,188\n8,3,195~8,5,195\n4,3,140~8,3,140\n8,4,200~8,5,200\n4,2,31~4,4,31\n0,5,327~2,5,327\n0,0,109~0,3,109\n7,8,301~9,8,301\n5,4,112~6,4,112\n4,3,255~6,3,255\n5,0,177~5,0,177\n4,5,320~6,5,320\n0,5,58~2,5,58\n4,4,300~6,4,300\n1,6,39~3,6,39\n0,6,94~0,6,97\n0,8,182~1,8,182\n3,5,30~3,6,30\n6,2,71~6,5,71\n2,5,125~2,7,125\n8,5,168~8,7,168\n5,3,275~5,5,275\n6,2,153~6,2,154\n6,3,63~6,6,63\n1,5,42~2,5,42\n3,5,306~3,8,306\n2,1,296~5,1,296\n5,5,85~5,8,85\n3,0,260~3,2,260\n7,2,213~7,4,213\n0,0,16~0,3,16\n4,9,34~7,9,34\n2,8,163~2,8,163\n4,6,209~4,9,209\n5,4,297~5,6,297\n1,6,222~1,7,222\n0,4,227~3,4,227\n4,2,50~7,2,50\n9,5,61~9,7,61\n5,5,115~8,5,115\n6,3,85~9,3,85\n0,0,106~0,2,106\n8,2,219~9,2,219\n9,1,14~9,2,14\n9,2,306~9,5,306\n5,4,302~5,7,302\n2,6,97~5,6,97\n5,0,146~5,2,146\n4,9,125~4,9,127\n0,4,293~3,4,293\n6,7,295~6,9,295\n0,1,44~2,1,44\n4,8,158~7,8,158\n0,2,118~0,4,118\n7,2,191~7,3,191\n1,6,18~1,7,18\n5,7,33~5,9,33\n1,6,140~1,6,142\n1,8,321~3,8,321\n2,7,30~5,7,30\n8,2,174~8,4,174\n2,2,275~2,5,275\n6,8,247~9,8,247\n6,7,217~6,9,217\n3,3,65~3,5,65\n1,0,312~3,0,312\n0,5,141~2,5,141\n6,1,208~8,1,208\n3,6,99~3,7,99\n4,5,57~6,5,57\n7,6,121~9,6,121\n1,5,317~4,5,317\n6,2,56~8,2,56\n5,0,13~7,0,13\n6,5,157~8,5,157\n6,2,52~6,3,52\n7,3,239~7,3,242\n0,6,220~2,6,220\n4,2,91~6,2,91\n4,5,332~5,5,332\n8,0,65~9,0,65\n2,7,282~4,7,282\n2,4,100~2,6,100\n6,1,98~9,1,98\n5,4,119~7,4,119\n6,4,153~6,6,153\n5,1,62~8,1,62\n5,3,142~5,4,142\n3,2,326~3,5,326\n9,5,90~9,8,90\n5,4,145~5,6,145\n9,0,234~9,2,234\n1,7,21~1,9,21\n4,1,261~6,1,261\n2,7,336~4,7,336\n7,3,87~7,3,90\n2,7,154~4,7,154\n0,4,171~0,4,173\n3,6,309~3,6,311\n6,6,114~8,6,114\n8,5,60~8,7,60\n7,0,205~7,2,205\n5,3,339~7,3,339\n5,5,276~5,7,276\n3,2,241~3,4,241\n6,5,301~7,5,301\n7,5,40~7,6,40\n6,1,331~8,1,331\n2,0,96~5,0,96\n6,3,87~6,5,87\n4,9,228~6,9,228\n0,1,49~0,2,49\n1,1,248~1,3,248\n8,3,87~8,5,87\n1,4,149~2,4,149\n0,3,31~0,3,33\n6,7,122~6,7,124\n2,6,149~5,6,149\n3,9,7~6,9,7\n1,4,329~4,4,329\n4,2,259~4,2,262\n0,1,1~0,3,1\n6,3,12~6,4,12\n7,1,199~9,1,199\n5,3,166~5,6,166\n4,9,97~6,9,97\n4,5,292~4,7,292\n0,5,79~0,6,79\n0,3,258~2,3,258\n4,1,258~8,1,258\n0,4,72~3,4,72\n1,7,261~3,7,261\n8,5,313~8,7,313\n3,0,44~3,3,44\n4,6,307~7,6,307\n2,8,258~5,8,258\n2,6,45~3,6,45\n8,3,90~8,5,90\n4,7,213~4,8,213\n0,0,19~3,0,19\n3,1,306~3,3,306\n8,5,207~8,8,207\n0,7,210~1,7,210\n3,7,102~6,7,102\n2,8,249~4,8,249\n5,4,133~7,4,133\n9,3,237~9,3,240\n7,8,125~7,9,125\n0,0,272~0,0,274\n6,4,16~7,4,16\n1,2,47~1,2,49\n6,0,265~6,3,265\n7,3,148~9,3,148\n0,2,264~0,3,264\n4,6,124~5,6,124\n5,7,75~7,7,75\n5,0,75~5,2,75\n4,3,28~4,4,28\n3,1,92~3,2,92\n1,4,92~1,4,93\n4,5,49~5,5,49\n3,4,76~3,4,78\n0,4,252~2,4,252\n1,5,205~2,5,205\n1,2,263~1,6,263\n5,0,17~7,0,17\n7,1,59~7,1,60\n5,6,173~5,6,175\n7,4,81~9,4,81\n3,4,330~3,5,330\n5,3,216~5,5,216\n0,3,338~0,6,338\n6,8,292~8,8,292\n6,2,3~8,2,3\n7,3,259~8,3,259\n0,0,223~2,0,223\n1,2,118~3,2,118\n1,9,71~3,9,71\n6,0,121~9,0,121\n7,6,197~7,8,197\n2,0,81~5,0,81\n9,1,100~9,2,100\n6,3,3~6,6,3\n3,0,262~3,1,262\n6,1,144~6,4,144\n2,5,95~5,5,95\n7,3,198~7,5,198\n4,9,86~6,9,86\n7,7,84~8,7,84\n7,2,327~7,2,331\n4,6,69~4,8,69\n2,3,255~2,5,255\n0,8,319~2,8,319\n1,7,198~1,9,198\n3,0,263~3,0,264\n4,3,327~4,6,327\n9,1,126~9,1,128\n2,4,22~4,4,22\n4,2,207~6,2,207\n5,3,45~6,3,45\n1,0,232~1,2,232\n3,0,330~4,0,330\n4,5,101~6,5,101\n1,3,42~1,3,43\n5,5,239~5,7,239\n1,8,332~3,8,332\n2,8,6~2,9,6\n6,5,113~6,6,113\n3,6,249~3,7,249\n0,8,164~3,8,164\n1,2,179~1,2,181\n5,8,91~8,8,91\n4,0,54~7,0,54\n2,9,286~5,9,286\n8,5,260~8,7,260\n0,0,302~2,0,302\n7,3,195~7,6,195\n8,6,86~9,6,86\n5,3,171~7,3,171\n9,2,15~9,3,15\n6,8,225~7,8,225\n1,5,203~3,5,203\n3,2,301~3,3,301\n7,2,265~7,2,268\n1,4,81~3,4,81\n6,6,65~6,7,65\n6,0,22~7,0,22\n2,7,124~4,7,124\n0,5,145~0,5,146\n2,3,179~2,6,179\n8,5,308~8,7,308\n8,4,173~8,6,173\n5,4,284~7,4,284\n1,2,147~1,2,148\n8,0,64~8,3,64\n4,0,283~4,2,283\n2,3,253~2,4,253\n6,6,171~9,6,171\n2,6,290~2,8,290\n4,8,37~4,9,37\n5,8,252~6,8,252\n7,0,267~9,0,267\n7,6,317~7,7,317\n4,3,250~4,5,250\n6,8,21~6,8,23\n4,0,156~6,0,156\n9,5,96~9,5,98\n3,6,51~6,6,51\n4,0,167~5,0,167\n4,1,251~5,1,251\n1,1,13~1,4,13\n6,1,87~7,1,87\n4,4,135~6,4,135\n4,4,88~4,4,90\n6,1,287~6,4,287\n1,7,163~1,9,163\n1,2,90~5,2,90\n3,9,131~3,9,134\n7,3,11~9,3,11\n4,9,225~5,9,225\n5,6,37~8,6,37\n0,9,289~2,9,289\n0,5,88~2,5,88\n7,0,78~9,0,78\n9,3,5~9,6,5\n3,9,105~6,9,105\n1,5,147~1,7,147\n6,6,339~6,8,339\n1,5,57~2,5,57\n6,9,119~8,9,119\n4,1,11~4,3,11\n3,5,133~5,5,133\n7,4,217~7,6,217\n6,0,220~8,0,220\n5,7,70~5,7,73\n3,0,3~7,0,3\n6,1,24~6,3,24\n6,7,319~6,9,319\n3,1,256~5,1,256\n6,4,36~6,6,36\n2,5,151~2,8,151\n3,2,281~5,2,281\n3,5,144~3,7,144\n2,7,46~3,7,46\n6,7,336~8,7,336\n7,5,162~8,5,162\n4,1,241~8,1,241\n3,1,47~3,4,47\n6,0,266~6,0,269\n1,9,8~3,9,8\n6,7,220~6,8,220\n9,6,174~9,9,174\n9,5,92~9,6,92\n5,1,111~5,3,111\n8,6,83~8,9,83\n4,3,23~6,3,23\n2,5,324~2,8,324\n2,4,256~4,4,256\n5,9,292~6,9,292\n3,3,243~3,5,243\n3,3,163~6,3,163\n8,3,96~8,4,96\n3,6,142~5,6,142\n9,5,58~9,7,58\n4,4,172~7,4,172\n0,1,115~1,1,115\n2,6,8~3,6,8\n9,1,316~9,4,316\n1,5,256~1,8,256\n6,3,137~6,5,137\n2,9,316~5,9,316\n0,1,38~2,1,38\n4,6,328~7,6,328\n6,7,287~6,7,290\n4,9,84~6,9,84\n2,2,315~2,4,315\n3,3,197~5,3,197\n4,0,217~8,0,217\n0,9,297~3,9,297\n1,2,277~1,5,277\n3,4,202~4,4,202\n4,3,150~5,3,150\n1,5,207~1,7,207\n0,3,17~0,4,17\n3,6,256~3,8,256\n7,1,129~7,2,129\n1,1,272~1,5,272\n1,2,278~1,2,280\n1,0,267~3,0,267\n6,6,19~9,6,19\n3,0,140~3,2,140\n0,0,95~2,0,95\n0,1,159~0,3,159\n4,9,322~6,9,322\n2,7,173~2,9,173\n8,4,92~9,4,92\n7,0,19~7,1,19\n5,8,320~6,8,320\n1,1,251~3,1,251\n2,4,24~2,7,24\n5,4,303~5,6,303\n0,0,270~2,0,270\n2,2,70~2,2,73\n2,7,174~2,7,177\n6,2,11~6,4,11\n3,0,169~4,0,169\n9,3,93~9,5,93\n5,7,316~7,7,316\n5,1,3~8,1,3\n2,4,70~3,4,70\n2,2,61~2,5,61\n4,5,205~6,5,205\n1,1,2~1,1,5\n2,0,143~5,0,143\n0,0,166~0,1,166\n0,0,113~2,0,113\n5,4,23~5,5,23\n8,5,78~8,8,78\n0,0,224~0,2,224\n4,1,90~4,1,91\n6,9,91~6,9,93\n0,4,207~2,4,207\n5,2,39~5,5,39\n0,0,22~2,0,22\n1,7,95~1,7,95\n1,1,274~1,1,277\n0,0,25~0,0,27\n7,7,295~7,9,295\n7,1,52~7,2,52\n0,8,219~0,8,221\n0,6,136~2,6,136\n0,4,255~0,6,255\n6,6,294~6,8,294\n8,5,57~9,5,57\n0,8,175~4,8,175\n6,8,47~6,8,49\n4,1,342~4,2,342\n3,3,200~3,5,200\n0,1,337~0,4,337\n3,3,43~4,3,43\n1,8,179~3,8,179\n4,0,205~4,2,205\n1,1,130~1,1,131\n2,6,4~4,6,4\n2,0,211~5,0,211\n8,4,295~8,6,295\n4,9,211~4,9,214\n0,1,47~2,1,47\n5,5,160~7,5,160\n1,6,85~2,6,85\n2,1,170~5,1,170\n2,7,191~2,9,191\n3,8,68~5,8,68\n6,4,204~6,5,204\n6,8,194~9,8,194\n5,6,111~7,6,111\n0,2,256~2,2,256\n0,3,73~3,3,73\n1,5,177~2,5,177\n3,4,84~5,4,84\n1,2,229~1,2,231\n1,4,290~1,7,290\n3,0,108~5,0,108\n5,0,127~7,0,127\n6,7,196~6,9,196\n4,2,188~7,2,188\n9,5,316~9,7,316\n3,2,136~3,2,139\n5,3,2~5,6,2\n1,0,8~3,0,8\n4,2,252~6,2,252\n4,6,167~6,6,167\n5,6,188~5,7,188\n8,6,261~8,9,261\n2,2,332~2,4,332\n3,1,4~4,1,4\n6,0,292~6,1,292\n2,0,99~3,0,99\n0,4,147~1,4,147\n3,4,242~3,5,242\n5,5,245~8,5,245\n4,7,217~4,9,217\n6,7,85~6,9,85\n8,5,66~8,5,67\n6,0,190~6,2,190\n2,7,137~2,9,137\n0,4,87~0,6,87\n1,6,217~3,6,217\n1,4,14~1,4,14\n6,2,176~9,2,176\n5,8,139~8,8,139\n6,7,300~6,9,300\n3,0,180~3,2,180\n8,0,129~8,1,129\n7,8,175~9,8,175\n7,7,244~7,9,244\n6,4,38~8,4,38\n8,0,171~9,0,171\n4,0,285~4,2,285\n0,4,12~0,4,13\n0,1,75~0,3,75\n9,4,177~9,6,177\n4,1,324~4,3,324\n5,4,75~8,4,75\n4,6,118~6,6,118\n5,4,158~5,4,160\n7,2,152~7,4,152\n3,0,87~5,0,87\n3,1,78~3,1,78\n5,4,87~5,6,87\n4,7,67~4,9,67\n6,7,157~8,7,157\n7,4,184~7,5,184\n0,1,307~3,1,307\n4,6,299~5,6,299\n4,3,325~6,3,325\n5,2,196~5,4,196\n1,5,52~4,5,52\n7,8,99~8,8,99\n0,9,179~2,9,179\n5,5,58~5,7,58\n5,2,327~5,2,327\n3,8,17~5,8,17\n6,4,333~6,5,333\n1,1,245~1,4,245\n7,6,292~8,6,292\n3,9,223~5,9,223\n7,8,128~9,8,128\n2,0,338~2,3,338\n5,2,152~5,3,152\n2,1,304~4,1,304\n2,3,69~4,3,69\n4,1,71~4,3,71\n5,0,300~7,0,300\n4,0,328~4,2,328\n3,8,6~3,8,8\n5,8,219~6,8,219\n3,1,14~4,1,14\n5,5,54~7,5,54\n3,5,71~5,5,71\n3,7,159~3,8,159\n5,2,260~7,2,260\n1,3,204~4,3,204\n6,2,179~6,4,179\n5,5,81~5,7,81\n4,4,299~7,4,299\n7,8,47~8,8,47\n4,3,6~6,3,6\n2,5,3~4,5,3\n8,2,203~8,5,203\n8,8,86~9,8,86\n5,0,16~7,0,16\n3,6,218~3,8,218\n7,2,158~8,2,158\n6,3,162~6,6,162\n3,6,173~3,6,174\n8,6,224~9,6,224\n3,7,221~3,9,221\n4,1,247~4,4,247\n1,7,85~1,9,85\n0,4,93~0,7,93\n4,8,7~5,8,7\n7,5,305~8,5,305\n6,3,74~7,3,74\n5,8,245~7,8,245\n3,5,305~3,8,305\n8,9,127~9,9,127\n3,9,181~5,9,181\n8,8,197~8,8,198\n2,3,142~2,5,142\n0,1,157~0,3,157\n5,9,302~7,9,302\n2,9,128~5,9,128\n6,5,9~7,5,9\n2,1,320~2,4,320\n5,4,72~7,4,72\n3,5,201~3,8,201\n1,3,271~1,6,271\n9,2,19~9,3,19\n3,7,68~5,7,68\n2,1,302~3,1,302\n1,7,318~1,8,318\n2,0,164~2,1,164\n3,6,330~3,8,330\n6,5,250~6,8,250\n0,2,42~1,2,42\n4,5,168~4,7,168\n4,4,241~5,4,241\n3,7,281~5,7,281\n0,5,61~0,6,61\n6,4,13~6,4,15\n7,6,251~7,6,252\n5,2,173~5,3,173\n4,3,206~4,6,206\n6,2,54~6,3,54\n3,6,247~3,9,247\n1,1,77~4,1,77\n2,0,226~2,0,228\n0,4,335~3,4,335\n4,3,288~7,3,288\n0,3,72~2,3,72\n7,1,2~7,4,2\n7,0,4~9,0,4\n0,5,257~0,6,257\n4,2,12~7,2,12\n0,3,30~3,3,30\n7,4,309~7,7,309\n4,9,101~6,9,101\n0,8,75~1,8,75\n4,0,76~8,0,76\n7,9,11~9,9,11\n5,1,182~6,1,182\n5,5,170~5,7,170\n1,6,143~1,8,143\n2,7,61~2,7,62\n5,6,43~5,8,43\n5,6,65~5,7,65\n6,0,152~6,0,154\n6,7,175~8,7,175\n0,6,258~0,7,258\n2,3,65~2,5,65\n4,0,89~4,2,89\n2,6,130~2,8,130\n7,0,333~7,3,333\n6,3,269~6,5,269\n8,4,267~9,4,267\n2,1,184~3,1,184\n5,9,295~5,9,296\n5,7,215~6,7,215\n6,4,188~7,4,188\n2,2,43~2,5,43\n6,2,311~6,4,311\n2,5,105~2,6,105\n9,6,222~9,9,222\n6,3,334~6,5,334\n3,3,338~4,3,338\n6,4,155~6,7,155\n0,9,86~0,9,88\n5,8,159~5,9,159\n6,4,148~6,4,151\n9,2,291~9,5,291\n4,1,211~7,1,211\n1,7,78~1,9,78\n1,7,44~1,9,44\n0,5,8~0,8,8\n5,1,127~8,1,127\n7,4,78~7,5,78\n2,3,1~2,3,2\n7,8,43~9,8,43\n2,0,6~2,2,6\n1,7,134~3,7,134\n1,5,72~1,8,72\n7,3,337~7,6,337\n3,1,336~3,3,336\n1,6,1~1,6,2\n5,0,246~5,3,246\n5,1,328~7,1,328\n2,7,100~2,8,100\n9,5,205~9,7,205\n7,6,165~8,6,165\n1,6,139~2,6,139\n7,3,135~7,5,135\n9,2,207~9,2,210\n1,3,311~1,6,311\n2,4,152~2,5,152\n5,6,88~7,6,88\n3,6,33~3,6,37\n3,2,177~6,2,177\n7,6,38~7,8,38\n6,2,150~9,2,150\n7,5,250~7,6,250\n7,4,334~7,7,334\n5,1,180~5,4,180\n5,3,155~5,4,155\n3,7,310~3,9,310\n2,0,15~2,3,15\n0,1,227~0,1,229\n6,4,68~6,6,68\n7,8,215~7,8,217\n1,9,45~2,9,45\n7,6,21~7,6,23\n1,1,294~1,4,294\n3,6,283~3,8,283\n0,3,63~3,3,63\n5,5,315~5,7,315\n4,7,5~4,9,5\n9,3,6~9,5,6\n4,8,322~6,8,322\n9,0,308~9,2,308\n0,2,144~0,5,144\n2,7,28~5,7,28\n4,3,308~6,3,308\n4,4,330~4,5,330\n7,8,1~9,8,1\n4,1,1~4,2,1\n9,5,289~9,7,289\n2,9,192~4,9,192\n6,4,185~6,6,185\n0,8,90~2,8,90\n1,5,316~1,7,316\n6,6,189~6,8,189\n5,7,252~6,7,252\n4,0,141~4,3,141\n0,6,7~0,8,7\n7,0,65~7,1,65\n1,0,233~1,1,233\n1,8,154~4,8,154\n3,8,157~5,8,157\n9,6,216~9,8,216\n2,6,172~2,7,172\n0,3,130~0,3,132\n6,0,207~9,0,207\n6,6,298~6,9,298\n0,4,210~0,5,210\n1,9,185~4,9,185\n6,1,93~6,1,95\n0,5,328~2,5,328\n1,6,289~3,6,289\n5,3,46~5,5,46\n7,1,144~7,3,144\n7,4,247~7,6,247\n1,4,36~1,4,38\n0,9,139~2,9,139\n1,4,89~1,6,89\n8,5,196~8,5,198\n0,6,5~0,9,5\n5,4,266~8,4,266\n3,3,234~5,3,234\n4,2,301~4,4,301\n6,7,68~7,7,68\n8,4,311~8,6,311\n0,9,84~2,9,84\n5,6,82~7,6,82\n0,0,162~2,0,162\n4,8,200~4,8,202\n2,6,284~2,9,284\n3,2,131~3,5,131\n5,2,236~7,2,236\n0,3,312~2,3,312\n3,2,203~7,2,203\n5,3,108~5,6,108\n0,1,301~3,1,301\n1,6,82~1,8,82\n5,7,60~5,8,60\n0,8,218~2,8,218\n9,7,2~9,7,5\n2,7,178~2,7,181\n8,1,103~9,1,103\n8,7,235~9,7,235\n4,1,72~4,1,74\n5,5,284~5,6,284\n2,5,175~2,6,175\n6,5,12~6,7,12\n3,3,238~3,5,238\n2,5,222~2,7,222\n6,0,149~6,1,149\n8,2,225~8,5,225\n7,8,210~9,8,210\n5,6,278~6,6,278\n6,7,18~9,7,18\n4,6,295~4,9,295\n1,8,14~3,8,14\n2,3,83~2,3,84\n9,2,206~9,5,206\n4,9,184~5,9,184\n5,3,247~5,5,247\n0,2,155~0,3,155\n6,1,151~6,2,151\n3,2,134~4,2,134\n5,0,303~5,1,303\n2,2,326~2,2,328\n6,0,124~6,3,124\n6,9,315~6,9,318\n6,7,36~6,7,38\n7,0,311~9,0,311\n8,5,118~8,5,119\n0,0,168~2,0,168\n2,2,10~2,2,12\n6,1,42~6,1,45\n8,2,70~8,3,70\n8,7,88~8,8,88\n3,2,199~6,2,199\n8,0,107~9,0,107\n9,2,231~9,5,231\n1,6,322~1,9,322\n6,7,77~8,7,77\n7,5,161~9,5,161\n1,0,12~4,0,12\n3,5,35~4,5,35\n4,6,164~8,6,164\n4,1,270~4,2,270\n9,7,101~9,9,101\n4,1,113~6,1,113\n1,1,127~3,1,127\n7,4,53~8,4,53\n8,4,17~8,7,17\n1,2,319~1,2,319\n3,4,19~3,5,19\n3,5,246~3,6,246\n6,8,191~6,8,193\n3,5,164~5,5,164\n0,6,89~0,8,89\n8,6,4~8,9,4\n7,6,289~7,8,289\n1,2,144~4,2,144\n5,4,294~5,5,294\n8,3,95~8,6,95\n6,5,117~6,7,117\n7,1,53~9,1,53\n7,7,107~7,7,109\n1,1,336~1,3,336\n9,2,12~9,4,12\n0,4,10~2,4,10\n3,0,305~3,2,305\n8,2,1~8,4,1\n8,3,67~8,3,67\n4,4,137~4,7,137\n1,8,3~4,8,3\n7,1,220~9,1,220\n8,1,178~8,3,178\n0,3,314~1,3,314\n4,6,187~6,6,187\n9,4,229~9,6,229\n2,5,257~2,5,259\n6,6,41~9,6,41\n5,6,62~5,7,62\n1,3,105~1,5,105\n0,3,175~0,5,175\n2,4,268~2,4,268\n2,3,35~2,5,35\n0,7,195~2,7,195\n4,0,257~7,0,257\n2,6,87~2,6,90\n5,2,77~5,2,78\n5,0,63~5,2,63\n4,7,170~4,7,171\n5,5,214~9,5,214\n5,7,240~7,7,240\n1,2,317~4,2,317\n6,6,16~6,8,16\n2,3,167~2,5,167\n6,6,198~6,7,198\n2,1,167~3,1,167\n8,9,124~9,9,124\n4,0,168~6,0,168\n1,6,213~1,8,213\n4,8,286~7,8,286\n3,8,10~6,8,10\n7,8,41~9,8,41\n0,0,219~3,0,219\n2,0,4~4,0,4\n2,5,138~3,5,138\n6,4,182~7,4,182\n3,6,341~6,6,341\n6,0,159~6,0,161\n6,0,162~8,0,162\n7,5,69~7,7,69\n8,2,314~8,2,316\n4,4,113~4,6,113\n4,5,208~4,5,211\n4,9,305~6,9,305\n1,4,268~1,4,270\n1,9,1~3,9,1\n7,2,8~9,2,8\n2,1,130~2,1,132\n2,8,11~3,8,11\n0,0,112~0,2,112\n7,9,2~7,9,3\n1,2,177~1,3,177\n6,7,14~8,7,14\n5,7,279~7,7,279\n1,8,160~4,8,160\n7,7,171~8,7,171\n7,2,263~7,4,263\n1,0,45~1,2,45\n2,2,67~2,5,67\n4,6,77~4,8,77\n3,5,162~5,5,162\n0,5,211~1,5,211\n4,7,285~6,7,285\n1,2,276~2,2,276\n0,2,335~3,2,335\n8,1,271~8,4,271\n6,9,304~8,9,304\n4,4,111~6,4,111\n0,6,217~0,8,217\n1,6,74~2,6,74\n1,5,69~3,5,69\n0,4,336~0,6,336\n4,0,104~4,0,107\n6,5,2~9,5,2\n7,0,208~9,0,208\n1,7,156~2,7,156\n5,1,39~5,1,42\n5,1,289~7,1,289\n6,5,298~8,5,298\n7,1,145~7,1,147\n9,7,20~9,7,22\n1,5,6~1,6,6\n2,7,212~5,7,212\n0,2,34~3,2,34\n6,5,14~6,5,15\n6,1,7~6,3,7\n7,0,63~7,2,63\n3,2,164~3,4,164\n7,7,250~7,9,250\n0,7,292~2,7,292\n5,2,191~5,4,191\n7,2,145~7,5,145\n6,8,231~6,9,231\n4,0,158~7,0,158\n5,5,206~7,5,206\n3,5,18~7,5,18\n0,7,320~0,9,320\n3,6,178~3,9,178\n5,2,210~7,2,210\n6,8,93~8,8,93\n1,1,133~1,1,136\n2,0,210~2,1,210\n5,7,287~5,8,287\n5,9,94~7,9,94\n7,0,67~7,2,67\n0,6,313~2,6,313\n7,9,129~7,9,130\n4,5,181~6,5,181\n5,9,96~7,9,96\n3,3,290~3,6,290\n7,6,258~9,6,258\n1,8,200~2,8,200\n3,7,333~3,7,335\n1,0,81~1,3,81\n2,3,108~2,6,108\n3,7,145~3,7,148\n0,3,160~1,3,160\n3,4,91~6,4,91\n3,2,321~5,2,321\n5,1,215~5,4,215\n1,7,81~1,9,81\n8,2,175~8,3,175\n3,5,206~3,7,206\n0,1,125~0,1,127\n4,1,238~4,4,238\n1,2,33~1,5,33\n3,2,322~3,4,322\n3,5,36~5,5,36\n2,9,85~2,9,86\n0,5,1~0,5,3\n0,2,105~0,3,105\n6,8,222~6,9,222\n2,7,138~2,7,138\n7,0,90~7,1,90\n0,8,190~0,9,190\n6,3,142~7,3,142\n4,3,328~5,3,328\n5,9,313~7,9,313\n0,4,74~0,6,74\n1,7,295~1,9,295\n6,6,179~6,9,179\n1,2,84~1,4,84\n1,7,259~2,7,259\n1,4,61~1,6,61\n2,0,146~2,3,146\n5,4,86~7,4,86\n2,7,164~4,7,164\n1,3,29~4,3,29\n7,8,74~7,8,74\n2,8,79~4,8,79\n4,5,67~5,5,67\n5,7,26~9,7,26\n5,0,55~8,0,55\n6,0,214~6,1,214\n5,9,88~6,9,88\n0,1,122~0,3,122\n1,4,308~4,4,308\n8,0,223~8,3,223\n4,1,265~4,3,265\n5,9,308~5,9,311\n5,3,237~5,5,237\n6,5,33~6,8,33\n2,3,260~3,3,260\n6,0,78~6,0,80\n8,2,160~8,3,160\n1,6,41~1,7,41\n8,4,244~8,4,247\n2,3,203~3,3,203\n7,6,202~7,8,202\n4,6,301~4,6,303\n9,4,180~9,6,180\n0,0,115~1,0,115\n7,2,324~7,5,324\n8,0,80~8,1,80\n2,1,255~5,1,255\n2,6,56~2,6,58\n3,0,1~6,0,1\n9,2,179~9,2,182\n6,3,193~9,3,193\n1,8,220~1,8,221\n1,0,57~4,0,57\n0,5,109~2,5,109\n9,2,212~9,4,212\n1,5,258~1,5,260\n3,6,40~5,6,40\n4,2,83~6,2,83\n9,2,202~9,3,202\n0,4,314~0,6,314\n1,0,159~4,0,159\n2,5,262~2,5,264\n4,4,25~4,6,25\n9,6,60~9,8,60\n3,1,36~6,1,36\n3,2,237~3,5,237\n3,6,253~3,9,253\n7,5,213~7,8,213\n4,7,123~4,9,123\n4,3,305~4,6,305\n0,2,323~3,2,323\n4,6,26~6,6,26\n0,2,325~4,2,325\n8,4,61~8,6,61\n4,8,88~5,8,88\n0,7,293~0,7,295\n6,8,343~6,9,343\n6,3,88~6,3,90\n8,2,245~8,2,246\n9,6,29~9,7,29\n5,0,175~7,0,175\n4,3,343~5,3,343\n1,6,250~3,6,250\n9,7,250~9,9,250\n0,6,263~0,7,263\n9,0,223~9,1,223\n2,3,166~4,3,166\n2,7,97~2,7,97\n1,0,9~3,0,9\n2,3,273~4,3,273\n4,1,147~4,3,147\n2,6,194~2,7,194\n3,4,30~5,4,30\n5,8,71~8,8,71\n4,8,199~7,8,199\n7,6,72~8,6,72\n7,0,135~8,0,135\n1,2,124~2,2,124\n6,2,47~6,3,47\n5,5,88~5,5,88\n6,6,121~6,9,121\n2,3,341~4,3,341\n4,5,16~7,5,16\n8,4,210~8,5,210\n5,6,283~5,8,283\n7,2,89~9,2,89\n3,7,135~3,8,135\n6,7,203~6,8,203\n4,1,9~7,1,9\n6,7,118~6,9,118\n1,5,312~2,5,312\n3,3,286~3,6,286\n4,3,85~4,5,85\n6,3,60~6,5,60\n9,4,233~9,7,233\n8,4,19~8,4,20\n7,0,168~8,0,168\n8,4,250~8,5,250\n8,3,149~8,3,150\n6,9,308~9,9,308\n6,9,123~9,9,123\n6,9,12~8,9,12\n4,9,82~6,9,82\n5,3,243~5,5,243\n5,5,311~7,5,311\n3,9,313~3,9,314\n2,2,279~2,2,282\n2,3,80~2,6,80\n2,8,303~4,8,303\n2,6,285~2,7,285\n2,5,208~2,7,208\n5,5,183~5,5,186\n7,4,118~7,6,118\n8,3,142~8,6,142\n0,6,138~0,6,139\n7,3,267~7,4,267\n2,6,170~4,6,170\n2,7,213~2,9,213\n9,0,294~9,2,294\n6,1,175~6,4,175\n3,0,299~3,3,299\n5,2,74~7,2,74\n6,5,209~8,5,209\n5,8,3~5,8,5\n7,6,311~7,7,311\n3,4,101~3,6,101\n9,2,17~9,3,17\n0,0,1~2,0,1\n4,3,321~7,3,321\n0,6,86~1,6,86\n1,0,87~2,0,87\n9,2,314~9,4,314\n5,3,169~5,4,169\n5,0,174~5,2,174\n7,4,232~9,4,232\n7,6,46~7,9,46\n2,2,9~2,5,9\n7,2,238~7,3,238\n5,6,15~7,6,15\n6,3,178~6,6,178\n5,5,97~5,5,99\n8,5,201~9,5,201\n9,9,216~9,9,220\n1,7,225~1,8,225\n9,0,153~9,2,153\n1,1,79~1,3,79\n4,3,116~4,3,116\n6,7,177~6,8,177\n3,3,9~4,3,9\n4,8,297~4,9,297\n6,7,20~6,7,21\n2,0,89~2,0,92\n7,2,51~7,5,51\n0,3,149~2,3,149\n3,7,64~5,7,64\n7,9,128~9,9,128\n5,0,266~5,2,266\n9,7,103~9,8,103\n6,5,20~9,5,20\n4,1,212~6,1,212\n3,7,224~3,9,224\n1,1,182~4,1,182\n8,4,54~8,6,54\n1,3,151~2,3,151\n8,0,243~8,4,243\n6,1,70~8,1,70\n3,5,32~6,5,32\n7,1,82~8,1,82\n1,0,309~1,1,309\n2,2,228~5,2,228\n0,1,304~0,2,304\n6,1,254~6,4,254\n1,0,11~1,1,11\n5,5,66~6,5,66\n0,3,108~0,4,108\n6,0,216~6,3,216\n6,6,24~9,6,24\n9,8,61~9,9,61\n3,4,309~3,4,310\n2,5,293~3,5,293\n1,2,226~4,2,226\n2,0,84~4,0,84\n6,8,72~7,8,72\n9,0,3~9,1,3\n2,4,34~3,4,34\n7,9,307~8,9,307\n6,8,5~8,8,5\n2,1,35~4,1,35\n6,7,194~8,7,194\n8,2,63~8,4,63\n4,8,44~6,8,44\n1,1,121~3,1,121\n5,9,160~5,9,162\n8,7,21~8,7,22\n0,2,127~0,3,127\n4,0,254~4,2,254\n0,6,99~1,6,99\n0,8,298~1,8,298\n4,2,266~4,2,267\n2,2,103~2,4,103\n2,5,294~4,5,294\n4,0,51~4,3,51\n4,7,299~4,9,299\n4,1,305~6,1,305\n2,1,225~2,4,225\n0,6,212~0,9,212\n5,0,326~5,3,326\n8,7,296~8,8,296\n3,0,49~3,1,49\n7,0,119~7,3,119\n3,5,165~3,6,165\n1,7,144~1,9,144\n6,1,1~6,3,1\n5,2,310~5,3,310\n8,1,216~8,3,216\n6,0,297~6,2,297\n2,4,41~2,6,41\n6,1,39~6,1,41\n5,5,104~5,5,106\n5,4,59~5,7,59\n2,9,256~4,9,256\n3,3,172~3,5,172\n4,5,310~4,7,310\n5,3,21~5,6,21\n3,0,202~3,2,202\n1,6,165~1,6,167\n8,4,306~8,7,306\n5,5,6~7,5,6\n5,8,20~5,8,22\n6,9,223~6,9,226\n5,7,104~8,7,104\n0,8,185~2,8,185\n4,4,74~4,7,74\n6,5,288~9,5,288\n1,3,249~1,4,249\n6,6,181~8,6,181\n7,0,260~9,0,260\n6,5,286~6,7,286\n1,3,174~3,3,174\n4,7,163~4,8,163\n1,9,80~4,9,80\n3,5,257~3,8,257\n0,4,89~0,4,91\n8,0,108~8,2,108\n0,5,77~2,5,77\n4,1,249~4,3,249\n5,0,83~5,1,83\n5,0,279~5,2,279\n5,4,279~5,4,282\n6,6,200~6,8,200\n1,7,92~1,7,93\n1,4,315~1,6,315\n1,2,17~3,2,17\n0,4,294~0,5,294\n4,3,114~5,3,114\n6,8,19~8,8,19\n2,8,46~4,8,46\n2,2,166~4,2,166\n9,2,103~9,3,103\n3,7,312~4,7,312\n1,8,94~1,8,95\n5,3,256~5,3,256\n2,0,301~4,0,301\n0,5,317~0,7,317\n4,5,140~4,6,140\n1,2,120~1,2,121\n5,4,78~5,6,78\n7,5,255~9,5,255\n0,3,124~2,3,124\n0,5,62~0,7,62\n9,4,292~9,6,292\n7,3,12~7,3,15\n7,2,116~7,5,116\n0,3,78~0,3,80\n8,7,173~8,7,173\n3,2,181~5,2,181\n2,5,27~2,7,27\n8,6,170~8,8,170\n5,5,255~5,7,255\n1,4,74~3,4,74\n4,6,121~4,7,121\n3,9,68~3,9,69\n0,1,116~0,3,116\n2,4,337~2,6,337\n5,4,136~5,6,136\n0,1,15~0,4,15\n3,3,244~3,3,245\n3,4,130~5,4,130\n4,2,233~6,2,233\n4,4,244~4,6,244\n1,7,158~4,7,158\n8,5,253~8,7,253\n5,5,138~5,8,138\n1,1,236~4,1,236\n5,0,23~7,0,23\n0,1,77~0,3,77\n1,4,55~1,6,55\n0,5,103~2,5,103\n5,1,213~8,1,213\n1,6,191~1,9,191\n0,6,261~0,8,261\n2,3,148~2,4,148\n2,1,208~5,1,208\n0,7,91~2,7,91\n1,4,204~1,6,204\n8,0,313~8,3,313\n6,6,310~6,8,310\n6,9,9~8,9,9\n3,0,10~6,0,10\n0,6,216~3,6,216\n5,0,165~7,0,165\n0,1,119~2,1,119\n4,1,293~7,1,293\n5,1,194~5,3,194\n1,7,327~4,7,327\n6,3,5~6,4,5\n5,0,80~5,2,80\n7,5,303~9,5,303\n4,2,84~6,2,84\n3,6,41~5,6,41\n7,6,216~8,6,216\n0,3,152~1,3,152\n1,3,145~3,3,145\n0,6,105~0,6,108\n7,4,302~9,4,302\n8,8,294~9,8,294\n8,5,63~8,7,63\n3,7,309~5,7,309\n3,2,169~3,4,169\n5,1,276~5,4,276\n2,5,133~2,7,133\n5,1,56~7,1,56\n8,1,109~8,4,109\n3,2,257~5,2,257\n2,0,213~2,0,217\n6,1,147~6,4,147\n7,1,177~7,3,177\n8,5,205~8,7,205\n8,1,317~9,1,317\n0,9,7~0,9,7\n7,5,119~7,5,121\n0,5,196~0,7,196\n1,9,176~2,9,176\n8,6,255~8,8,255\n5,1,2~6,1,2\n3,4,7~3,6,7\n8,2,39~8,4,39\n9,7,319~9,7,321\n8,7,96~8,8,96\n5,0,295~7,0,295\n1,5,266~1,7,266\n3,8,19~4,8,19\n1,5,164~1,7,164\n3,3,104~3,5,104\n3,0,89~3,0,90\n5,2,65~5,4,65\n6,4,8~8,4,8\n2,0,222~2,2,222\n4,2,318~4,3,318\n7,1,155~7,3,155\n3,5,202~6,5,202\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_22_questions.txt",
    "content": "--- Day 22: Sand Slabs ---\n\nEnough sand has fallen; it can finally filter water for Snow Island.\n\nWell, almost.\n\nThe sand has been falling as large compacted bricks of sand, piling up to form an impressive stack here near the edge of Island Island. In order to make use of the sand to filter water, some of the bricks will need to be broken apart - nay, disintegrated - back into freely flowing sand.\n\nThe stack is tall enough that you'll have to be careful about choosing which bricks to disintegrate; if you disintegrate the wrong brick, large portions of the stack could topple, which sounds pretty dangerous.\n\nThe Elves responsible for water filtering operations took a snapshot of the bricks while they were still falling (your puzzle input) which should let you work out which bricks are safe to disintegrate.\nFor example:\n\n1,0,1~1,2,1\n0,0,2~2,0,2\n0,2,3~2,2,3\n0,0,4~0,2,4\n2,0,5~2,2,5\n0,1,6~2,1,6\n1,1,8~1,1,9\n\nEach line of text in the snapshot represents the position of a single brick at the time the snapshot was taken.\nThe position is given as two x,y,z coordinates - one for each end of the brick - separated by a tilde (~).\nEach brick is made up of a single straight line of cubes, and the Elves were even careful to choose a time for the snapshot that had all of the free-falling bricks at integer positions above the ground, so the whole snapshot is aligned to a three-dimensional cube grid.\n\nA line like 2,2,2~2,2,2 means that both ends of the brick are at the same coordinate - in other words, that the brick is a single cube.\n\nLines like 0,0,10~1,0,10 or 0,0,10~0,1,10 both represent bricks that are two cubes in volume, both oriented horizontally.\nThe first brick extends in the x direction, while the second brick extends in the y direction.\n\nA line like 0,0,1~0,0,10 represents a ten-cube brick which is oriented vertically.\nOne end of the brick is the cube located at 0,0,1, while the other end of the brick is located directly above it at 0,0,10.\n\nThe ground is at z=0 and is perfectly flat; the lowest z value a brick can have is therefore 1.\nSo, 5,5,1~5,6,1 and 0,2,1~0,2,5 are both resting on the ground, but 3,3,2~3,3,3 was above the ground at the time of the snapshot.\n\nBecause the snapshot was taken while the bricks were still falling, some bricks will still be in the air; you'll need to start by figuring out where they will end up.\nBricks are magically stabilized, so they never rotate, even in weird situations like where a long horizontal brick is only supported on one end.\nTwo bricks cannot occupy the same position, so a falling brick will come to rest upon the first other brick it encounters.\n\nHere is the same example again, this time with each brick given a letter so it can be marked in diagrams:\n\n1,0,1~1,2,1   <- A\n0,0,2~2,0,2   <- B\n0,2,3~2,2,3   <- C\n0,0,4~0,2,4   <- D\n2,0,5~2,2,5   <- E\n0,1,6~2,1,6   <- F\n1,1,8~1,1,9   <- G\n\nAt the time of the snapshot, from the side so the x axis goes left to right, these bricks are arranged like this:\n\n x\n012\n.G. 9\n.G. 8\n... 7\nFFF 6\n..E 5 z\nD.. 4\nCCC 3\nBBB 2\n.A. 1\n--- 0\n\nRotating the perspective 90 degrees so the y axis now goes left to right, the same bricks are arranged like this:\n\n y\n012\n.G. 9\n.G. 8\n... 7\n.F. 6\nEEE 5 z\nDDD 4\n..C 3\nB.. 2\nAAA 1\n--- 0\n\nOnce all of the bricks fall downward as far as they can go, the stack looks like this, where ? means bricks are hidden behind other bricks at that location:\n\n x\n012\n.G. 6\n.G. 5\nFFF 4\nD.E 3 z\n??? 2\n.A. 1\n--- 0\n\nAgain from the side:\n\n y\n012\n.G. 6\n.G. 5\n.F. 4\n??? 3 z\nB.C 2\nAAA 1\n--- 0\n\nNow that all of the bricks have settled, it becomes easier to tell which bricks are supporting which other bricks:\n\n    Brick A is the only brick supporting bricks B and C.\n    Brick B is one of two bricks supporting brick D and brick E.\n    Brick C is the other brick supporting brick D and brick E.\n    Brick D supports brick F.\n    Brick E also supports brick F.\n    Brick F supports brick G.\n    Brick G isn't supporting any bricks.\n\nYour first task is to figure out which bricks are safe to disintegrate.\nA brick can be safely disintegrated if, after removing it, no other bricks would fall further directly downward.\nDon't actually disintegrate any bricks - just determine what would happen if, for each brick, only that brick were disintegrated. Bricks can be disintegrated even if they're completely surrounded by other bricks; you can squeeze between bricks if you need to.\n\nIn this example, the bricks can be disintegrated as follows:\n\n    Brick A cannot be disintegrated safely; if it were disintegrated, bricks B and C would both fall.\n    Brick B can be disintegrated; the bricks above it (D and E) would still be supported by brick C.\n    Brick C can be disintegrated; the bricks above it (D and E) would still be supported by brick B.\n    Brick D can be disintegrated; the brick above it (F) would still be supported by brick E.\n    Brick E can be disintegrated; the brick above it (F) would still be supported by brick D.\n    Brick F cannot be disintegrated; the brick above it (G) would fall.\n    Brick G can be disintegrated; it does not support any other bricks.\n\nSo, in this example, 5 bricks can be safely disintegrated.\n\nFigure how the blocks will settle based on the snapshot.\nOnce they've settled, consider disintegrating a single brick; how many bricks could be safely chosen as the one to get disintegrated?\n\n--- Part Two ---\n\nDisintegrating bricks one at a time isn't going to be fast enough.\nWhile it might sound dangerous, what you really need is a chain reaction.\n\nYou'll need to figure out the best brick to disintegrate.\nFor each brick, determine how many other bricks would fall if that brick were disintegrated.\n\nUsing the same example as above:\n\n    Disintegrating brick A would cause all 6 other bricks to fall.\n    Disintegrating brick F would cause only 1 other brick, G, to fall.\n\nDisintegrating any other brick would cause no other bricks to fall.\nSo, in this example, the sum of the number of other bricks that would fall as a result of disintegrating each brick is 7.\n\nFor each brick, determine how many other bricks would fall if that brick were disintegrated.\nWhat is the sum of the number of other bricks that would fall?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_23.adb",
    "content": "--  Solution to Advent of Code 2023, Day 23\n------------------------------------------\n--  A Long Walk\n--\n--  https://adventofcode.com/2023/day/23\n--  Copy of questions in: aoc_2023_23_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nprocedure AoC_2023_23 is\n\n  use AoC_Toolbox, HAT;\n\n  input_name : VString;\n  skip_header : Natural;\n  n : Positive;\n\n  max_n : constant := 141;\n\n  type Map_Type is array (1 .. max_n, 1 .. max_n) of Character;\n\n  data : Map_Type;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for skip_it in 1 .. skip_header loop\n      Skip_Line (f);\n    end loop;\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, data (x, y));\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show (map : Map_Type) is\n  begin\n    Put_Line (\"Map: -------------------\");\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        Put (map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  r : array (Part_Type) of Integer;\n\n  verbosity : constant := 0;\n\n  procedure Do_Part (part : Part_Type) is\n\n    procedure Walk_from (map : in out Map_Type; x, y : Integer; done_so_far : Natural) is\n\n      more : Natural := 0;\n\n      procedure Flood_Fill (x, y : Integer; ice : Character) is\n\n        procedure Go is\n        begin\n          more := more + 1;\n          if x = n - 1 and then y = n then\n            if verbosity >= 1 then\n              Put_Line\n                 (+\"Yuhu, found the End! Length from Start to End: \" &\n                   (done_so_far + more));\n              if verbosity >= 2 then\n                map (x, y) := 'E';\n                Show (map);\n              end if;\n            end if;\n            --  The answer of the puzzle is the longest path.\n            r (part) := Max (r (part), done_so_far + more);\n          else\n            map (x, y) := 'O';  --  Mark this tile as visited.\n            Flood_Fill (x - 1, y, '<');\n            Flood_Fill (x + 1, y, '>');\n            Flood_Fill (x, y - 1, '^');\n            Flood_Fill (x, y + 1, 'v');\n          end if;\n        end Go;\n\n        procedure Copy_Map_and_Go is\n          copy : Map_Type := map;\n        begin\n          copy (x, y) := '.';  --  Open the icy gate...\n          Walk_from (copy, x, y, done_so_far + more);\n        end Copy_Map_and_Go;\n\n        c : constant Character := map (x, y);\n\n      begin\n        if c = '.' then\n          Go;\n        elsif c = ice\n          or else\n            (part = part_2\n             and then (c = '<' or else c = '>' or else c = '^' or else c = 'v'))\n        then\n          Copy_Map_and_Go;\n          --  Silent alternative: treat this tile as a forest,\n          --  continue on the same map and perhaps find another path.\n        end if;\n      end Flood_Fill;\n\n    begin\n      Flood_Fill (x, y, '$');\n    end Walk_from;\n\n    map : Map_Type := data;\n\n  begin\n    if verbosity >= 2 then\n      Show (map);\n    end if;\n    r (part) := 0;\n    map (2, 1) := 'S';  --  Nice, and prevents going outside...\n    Walk_from (map, 2, 2, 0);\n  end Do_Part;\n\n  T0 : constant Time := Clock;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n\nbegin\n  if compiler_test_mode then\n    --  GNAT runs this program on the actual problem\n    --  data in 5 minutes, while HAC takes forever.\n    input_name := +\"aoc_2023_23_questions\";\n    skip_header := 16;\n    n := 23;\n  else\n    input_name := +\"aoc_2023_23\";\n    skip_header := 0;\n    n := 141;\n  end if;\n\n  Read_Data;\n\n  for part in Part_Type loop\n    Do_Part (part);\n    if verbosity >= 1 then\n      Put_Line (\"Done for part \" & part'Image);\n    end if;\n  end loop;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 2114    (example: 94)\n    --  Part 2: validated by AoC: 6322    (example: 154)\n  end if;\nend AoC_2023_23;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_23.txt",
    "content": "#.###########################################################################################################################################\n#.....#.....#.....###...#.........#.....#...#.......#...###...###...###...#.................#...#...........#.......#...........#...........#\n#####.#.###.#.###.###.#.#.#######.#.###.#.#.#.#####.#.#.###.#.###.#.###.#.#.###############.#.#.#.#########.#.#####.#.#########.#.#########.#\n#.....#.#...#...#...#.#.#.....#...#.#...#.#...#.....#.#.#...#...#.#.#...#.#.............#...#.#.#.#.........#.....#.#.#...#...#.#...#.......#\n#.#####.#.#####.###.#.#.#####.#.###.#.###.#####.#####.#.#.#####.#.#.#.###.#############.#.###.#.#.#.#############.#.#.#.#.#.#.#.###.#.#######\n#.#...#.#...###.#...#.#.#...#.#.###.#.###.....#.#...#.#.#...#...#.#.#...#.#.......#...#.#.###.#.#.#.#...#####.....#.#.#.#...#...#...#.#...###\n#.#.#.#.###.###.#.###.#.#.#.#.#.###.#.#######.#.#.#.#.#.###.#.###.#.###.#.#.#####.#.#.#.#.###.#.#.#.#.#.#####.#####.#.#.#########.###.#.#.###\n#.#.#...#...#...#...#.#.#.#...#.#...#...>.>.#.#.#.#...#.#...#.#...#...#.#.#.....#.#.#...#.#...#.#.#...#.>.>.#.....#...#.....#...#...#...#...#\n#.#.#####.###.#####.#.#.#.#####.#.#######v#.#.#.#.#####.#.###.#.#####.#.#.#####.#.#.#####.#.###.#.#######v#.#####.#########.#.#.###.#######.#\n#.#.#.....###.....#...#.#.....#...#####...#.#.#.#.#.....#...#...#.....#.#.#...#.#.#...#...#...#.#...#.....#...#...#...#.....#.#.#...#.......#\n#.#.#.###########.#####.#####.#########.###.#.#.#.#.#######.#####.#####.#.#.#.#.#.###.#.#####.#.###.#.#######.#.###.#.#.#####.#.#.###.#######\n#...#.#...###...#.#...#.......#...###...#...#.#.#.#...#.>.>.#.....#.....#.#.#...#.#...#...#...#.....#.....#...#.#...#...#...#.#.#.#...#...###\n#####.#.#.###.#.#.#.#.#########.#.###.###.###.#.#.###.#.#v###.#####.#####.#.#####.#.#####.#.#############.#.###.#.#######.#.#.#.#.#.###.#.###\n#.....#.#...#.#...#.#...#.......#...#...#...#.#.#...#.#.#.#...#...#...#...#.....#.#...#...#...#...#...#...#.....#...#...#.#.#.#...#.###.#.###\n#.#####.###v#.#####.###.#.#########.###.###.#.#.###.#.#.#.#.###.#.###.#.#######.#.###.#.#####.#.#.#.#.#.###########.#.#.#.#.#.#####.###.#.###\n#.#...#...#.>.#...#.#...#.........#...#.#...#.#.#...#...#.#.#...#...#.#.#.>.>...#...#.#.#...#.#.#...#.#...#.........#.#.#.#...#.....#...#.###\n#.#.#.###.#v###.#.#.#.###########.###.#.#.###.#.#.#######.#.#.#####.#.#.#.#v#######.#.#.#.#.#.#.#####.###.#.#########.#.#.#####.#####.###.###\n#.#.#...#.#.....#...#...#.........#...#.#.....#...###.....#...#.....#.#.#.#.......#.#.#.#.#...#.#...#...#.#.###...###.#.#...#...#...#...#...#\n#.#.###.#.#############.#.#########.###.#############.#########.#####.#.#.#######.#.#.#.#.#####.#.#.###.#.#.###.#.###.#.###.#.###.#.###.###.#\n#...###...#.......#.....#.........#...#.........#...#.........#.....#.#...#.......#...#...#...#...#...#...#...#.#...#.#.#...#...#.#.#...#...#\n###########.#####.#.#############.###.#########.#.#.#########.#####.#.#####.###############.#.#######.#######.#.###.#.#.#.#####.#.#.#.###.###\n###...#...#.....#.#...#...........###...#.......#.#.###.......#.....#.....#.................#...#.....#...###...###...#.#.....#.#.#...#...###\n###.#.#.#.#####.#.###.#.###############.#.#######.#.###.#######.#########.#####################.#.#####.#.#############.#####.#.#.#####.#####\n#...#...#.......#.....#...#...#...#####.#.#.......#...#.......#.......#...#.........#...........#.......#.........#...#.....#.#.#.#.....#...#\n#.#######################.#.#.#.#.#####.#.#.#########.#######.#######.#.###.#######.#.###########################.#.#.#####.#.#.#.#.#####.#.#\n#.#.....#...#...........#...#.#.#...###...#.........#.........#.......#...#.......#...###.....#...................#.#.....#...#...#.......#.#\n#.#.###.#.#.#.#########.#####.#.###.###############.###########.#########.#######.#######.###.#.###################.#####.#################.#\n#...###...#.#.#.........#.....#.#...#.......#.......#.....#####.....#...#.#.......#.....#.#...#...................#.#.....#...#.....#.......#\n###########.#.#.#########.#####.#.###.#####.#.#######.###.#########.#.#.#.#.#######.###.#.#.#####################.#.#.#####.#.#.###.#.#######\n#...........#.#.........#.#.....#.....#.....#.........###.....#...#...#...#.........#...#.#...#...###.........#...#.#.....#.#.#...#.#.......#\n#.###########.#########.#.#.###########.#####################.#.#.###################.###.###.#.#.###.#######.#.###.#####.#.#.###.#.#######.#\n#.#...#...#...#.........#...#...........#...#...#.............#.#...###.......#.......###...#.#.#...#.......#...###.#.....#.#.#...#.........#\n#.#.#.#.#.#.###.#############.###########.#.#.#.#.#############.###.###.#####.#.###########.#.#.###.#######.#######.#.#####.#.#.#############\n#.#.#...#...###.#.........#...###.....#...#.#.#.#.............#...#...#.....#.#.#...###...#.#.#.#...#...###.......#.#.....#.#.#.............#\n#.#.###########.#.#######.#.#####.###.#.###.#.#.#############.###.###.#####.#.#.#.#.###.#.#.#.#.#.###.#.#########v#.#####.#.#.#############.#\n#.#.#...........#.#.......#...#...#...#...#...#.#.............#...#...#...#.#.#.#.#...#.#.#.#.#.#.#...#.#.......>.>.#.....#.#.........#...#.#\n#.#.#.###########.#v#########v#.###.#####.#####.#.#############.###.###.#.#.#.#.#.###.#.#.#.#.#.#.#.###.#.#######v###.#####.#########.#.#.#.#\n#.#.#.............#.>.#.....>.>.#...#...#.#.....#.........#...#...#...#.#.#.#.#.#...#.#.#.#.#...#.#.#...#.#.....#.###.#...#.....#.....#.#.#.#\n#.#.###############v#.#.#####v###.###.#.#.#.#############.#.#.###.###.#.#.#.#.#v###.#.#.#.#.#####.#.#.###.#.###.#.###.#.#.#####.#.#####v#.#.#\n#...###.......#...#.#.#...#...#...#...#.#.#...#...#.....#.#.#.###...#.#.#.#.#.>.>...#...#.#.#.....#.#...#.#...#...#...#.#.#.....#...#.>.#...#\n#######.#####.#.#.#.#.###.#.###.###.###.#.###.#.#.#.###.#.#.#.#####.#.#.#.#.###v#########.#.#.#####.###.#.###.#####.###.#.#.#######.#.#v#####\n#.......#...#...#...#.....#...#...#...#.#.#...#.#.#...#.#.#.#.#...#.#...#...###...#...###.#.#.....#...#...#...###...#...#.#.....###...#.....#\n#.#######.#.#################.###.###.#.#.#.###.#.###.#.#v#.#.#.#.#.#############.#.#.###.#.#####.###.#####.#####.###.###.#####.###########.#\n#.........#.............###...###.....#...#...#.#...#.#.>.>.#...#.#...#...#...#...#.#...#.#...#...#...#...#.....#...#...#.....#...#.......#.#\n#######################.###.#################.#.###.#.###v#######.###.#.#.#.#.#.###.###.#.###.#.###.###.#.#####.###.###.#####.###.#.#####.#.#\n###...#...#...........#...#.........#...#.....#...#.#...#.......#...#.#.#...#...#...#...#.#...#.....#...#.#.....#...#...###...#...#.#...#...#\n###.#.#.#.#.#########.###.#########.#.#.#.#######.#.###.#######.###.#.#.#########.###.###.#.#########.###.#.#####.###.#####.###.###.#.#.#####\n#...#...#...#.......#.#...#.......#...#.#.....#...#.....#.....#...#...#.......#...#...###...#.......#...#.#.....#.....#.....#...#...#.#.....#\n#.###########.#####.#.#.###.#####.#####.#####.#.#########.###.###.###########.#.###.#########.#####.###.#.#####.#######.#####.###.###.#####.#\n#...........#.#.....#...#...#...#.......#.....#.#.....###...#.....#.....#...#...###...#.....#.....#.###.#.#.....#.....#.......###.....#.....#\n###########.#.#.#########.###.#.#########.#####.#.###.#####.#######.###.#.#.#########.#.###.#####.#.###.#.#.#####.###.#################.#####\n#.........#...#.......###...#.#.....#####.......#.#...#...#...#...#...#.#.#.#.........#.#...#...#.#.###.#.#...###.#...#...###...###.....#...#\n#.#######.###########.#####.#.#####.#############.#.###.#.###.#.#.###.#.#.#.#.#########.#.###.#.#.#.###.#.###v###.#.###.#.###.#.###.#####.#.#\n#.......#...#...#.....#...#.#.#...#...#...#...#...#...#.#.#...#.#.###.#.#.#.#...........#.#...#.#.#...#.#.#.>.>.#.#...#.#...#.#.....#...#.#.#\n#######.###.#.#.#.#####.#.#.#.#.#.###.#.#.#.#.#.#####.#.#.#.###.#.###.#.#.#.#############v#.###.#.###.#.#.#.#v#.#.###.#.###.#.#######.#.#.#.#\n###...#...#...#...###...#.#...#.#.....#.#.#.#.#.#.....#.#.#.###.#.#...#.#.#...#...#...#.>.>.###.#...#...#...#.#...###...#...#.......#.#...#.#\n###.#.###.###########.###.#####.#######.#.#.#.#.#.#####.#.#v###.#.#.###.#.###.#.#.#.#.#.#v#####.###.#########.###########.#########.#.#####.#\n#...#.....#.........#...#.#...#.....###.#.#.#.#.#.#...#.#.>.>...#.#...#...###...#...#...#.....#.#...###...###.....#.......#...#...#...#.....#\n#.#########.#######.###.#.#.#.#####v###.#.#.#.#.#.#.#.#.###v#####.###.#######################.#.#.#####.#.#######.#.#######.#.#.#.#####.#####\n#...........#.......#...#.#.#.#...>.>.#.#...#.#.#.#.#.#.###.....#...#.....###...#.....#.......#.#.#.....#.#...#...#.#...###.#.#.#.#...#.....#\n#############.#######.###.#.#.#.###v#.#.#####.#.#.#.#.#.#######.###.#####.###.#.#.###.#.#######.#.#.#####.#.#.#.###.#.#.###.#.#.#.#.#.#####.#\n#...###.......#...###...#.#.#...#...#.#.....#.#.#.#.#.#.#.......#...#...#...#.#.#...#...#.....#...#.....#.#.#...###...#...#.#.#.#.#.#...#...#\n#.#.###.#######.#.#####.#.#.#####.###.#####.#.#.#.#.#.#.#.#######.###.#.###.#.#.###.#####.###.#########.#.#.#############.#.#.#.#.#.###.#.###\n#.#...#.........#.#...#.#...###...#...#...#.#...#...#...#...#...#.#...#...#.#.#...#.......#...#.........#.#.......###...#.#.#.#.#.#.#...#.###\n#.###.###########v#.#.#.#######.###.###.#.#.###############.#.#.#.#.#####.#.#.###.#########.###.#########.#######.###.#.#.#.#.#.#.#.#.###v###\n#...#.....###...#.>.#.#...#.....###...#.#...###...#...#####...#.#...#...#...#...#...........###.........#.#...#...#...#...#.#.#.#.#.#.#.>.###\n###.#####.###.#.#v###.###.#.#########.#.#######.#.#.#.#########.#####.#.#######.#######################.#.#.#.#.###.#######.#.#.#.#.#.#.#v###\n###.....#.....#...#...#...#.........#...#...#...#.#.#...###...#.#...#.#.#...#...#...........#...........#...#...###...#...#.#.#.#.#.#...#...#\n#######.###########.###.###########.#####.#.#.###.#.###.###.#.#.#.#.#.#.#.#.#.###.#########.#.#######################.#.#.#.#.#.#.#.#######.#\n###.....#...#.....#...#.#...........###...#...#...#...#.....#...#.#.#.#.#.#.#.....#.........#...#...#...#.......#...#.#.#...#...#...#.......#\n###.#####.#.#.###.###.#.#.#############.#######.#####.###########.#.#.#.#.#.#######.###########.#.#.#.#.#.#####.#.#.#.#.#############.#######\n#...#.....#...###...#.#.#.....#####...#.....#...#####.........###.#.#.#.#.#...#...#...#...#...#...#...#...#.....#.#.#.#.###.......#...#...###\n#.###.#############.#.#.#####.#####.#.#####.#.###############.###.#.#.#.#.###.#.#.###.#.#.#.#.#############.#####.#.#.#.###.#####.#.###.#.###\n#.....#...#.........#...#...#.....#.#.#.....#.#...#...#.......#...#.#.#.#.#...#.#.###.#.#...#...#...#.....#.#.....#.#...#...#.....#.....#...#\n#######.#.#.#############.#.#####.#.#.#.#####.#.#.#.#.#.#######.###.#.#.#.#.###.#.###v#.#######.#.#.#.###.#.#.#####.#####.###.#############.#\n#...###.#.#.......#.....#.#.......#.#.#.....#...#.#.#.#.......#...#...#.#.#...#.#.#.>.>.#.......#.#.#...#...#.#.....#...#...#.###...#...#...#\n#.#.###.#.#######.#.###.#.#########.#.#####.#####.#.#.#######.###.#####.#.###.#.#.#.#v###.#######.#.###.#####.#.#####.#.###.#.###.#.#.#.#.###\n#.#.#...#...#...#...#...#.#.....#...#.....#...#...#.#.#...#...#...#.....#.###...#...#...#.....#...#...#.....#.#...#...#...#.#...#.#.#.#.#...#\n#.#.#.#####.#.#.#####.###.#.###.#.#######.###.#.###.#.#.#.#v###.###.#####.#############.#####.#.#####.#####.#.###.#.#####.#.###.#.#.#.#.###.#\n#.#.#.....#.#.#.......###...#...#.......#...#.#...#.#.#.#.>.>.#...#.....#...#...........#.....#.#.....#.....#.#...#...#...#...#.#.#.#.#.#...#\n#.#.#####.#.#.###############.#########.###.#.###.#.#.#.###v#.###.#####.###.#.###########.#####.#.#####.#####.#.#####.#.#####.#.#.#.#.#.#v###\n#.#.....#.#...#...#...###.....###...#...#...#.###.#.#...###.#.#...###...#...#.....#.....#.#...#.#.#...#.#...#.#.#...#.#.#...#.#.#.#...#.>.###\n#.#####.#.#####.#v#.#.###.#######.#.#.###.###.###.#.#######.#.#.#####.###.#######.#.###.#.#.#.#.#.#.#.#v#.#.#.#.#.#.#.#.#.#.#.#.#.#######v###\n#.....#.#.#.....#.>.#...#.#.....#.#...###...#.#...#...#.....#...#...#...#.###...#...#...#...#.#.#.#.#.>.>.#.#.#.#.#.#.#.#.#.#.#.#.#.......###\n#####.#.#.#.#####v#####.#.#.###.#.#########.#.#.#####.#.#########.#.###.#.###.#.#####.#######.#.#.#.###v###.#.#.#.#.#.#.#.#.#.#.#.#.#########\n#.....#.#.#.#.....#.....#...#...#.......#...#.#...#...#...........#.#...#.#...#.......#.....#...#...#...###.#.#.#.#...#.#.#...#.#.#.........#\n#.#####.#.#.#.#####.#########.#########.#.###.###.#.###############.#.###.#.###########.###.#########.#####.#.#.#.#####.#.#####.#.#########.#\n#.....#.#...#...#...#...#...#.#...#...#.#...#...#.#.#.............#.#.#...#...#.........#...#.........#...#...#.#.#.....#...#...#.#####...#.#\n#####.#.#######.#.###.#.#.#.#v#.#.#.#.#.###.###.#.#.#.###########.#.#.#.#####.#.#########.###.#########.#.#####.#.#.#######.#.###.#####.#.#.#\n#.....#...#####.#...#.#.#.#.>.>.#.#.#.#...#.#...#...#...........#...#.#.#.....#...#.......###...........#.....#.#.#...#...#.#.#...#.....#...#\n#.#######.#####.###.#.#.#.###v###.#.#.###.#.#.#################.#####.#.#.#######.#.#########################.#.#.###.#.#.#.#.#.###.#########\n#.......#...#...###.#.#.#.###...#...#...#.#.#...#.....#.........#...#...#.........#.......###.....#...........#...#...#.#...#...###.....#...#\n#######.###.#.#####.#.#.#.#####.#######.#.#.###.#.###.#.#########.#.#####################.###.###.#.###############.###.###############.#.#.#\n###...#...#.#.#.....#.#...#.....#.....#...#...#.#...#.#.....#...#.#.#...#...#...#...#...#...#...#.#...............#...#.#.......#...###...#.#\n###.#.###.#.#.#.#####.#####.#####.###.#######.#.###.#.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.###.#.###############.###.#.#.#####.#.#.#######.#\n#...#.....#...#...#...#...#.......#...#.....#...###.#.......#.#.#.#.#.#...#.#.#.#.#...#.....#...#...........#.....###...#.....#...#.........#\n#.###############.#.###.#.#########.###.###.#######.#########.#.#.#.#.#####.#.#.#.###########.#############.#.###############.###############\n#...............#...#...#...........###.#...###...#...#...#...#...#.#.#.....#.#.#.........###.............#...#...#...###...#.....#.........#\n###############.#####.#################.#.#####.#.###.#.#.#.#######.#.#.#####.#.#########.###############.#####.#.#.#.###.#.#####.#.#######.#\n#...............#...#.............#...#.#.#...#.#.###...#.#.#.......#.#.#...#.#...........#...............###...#...#...#.#.......#.###...#.#\n#.###############.#.#############.#.#.#.#.#.#.#.#.#######.#.#.#######.#.#.#.#.#############.#################.#########.#.#########.###.#.#.#\n#.#.....#.........#.....#.....#...#.#.#.#...#.#.#.#.....#...#.#...###.#.#.#.#.............#.........#...#...#...#.......#...........#...#...#\n#.#.###v#.#############.#.###.#.###.#.#.#####.#.#.#.###.#####.#.#.###.#.#.#.#############.#########.#.#.#.#.###.#.###################.#######\n#...###.>.#...#...#...#.#...#.#.....#.#.....#.#.#.#...#.#.....#.#.###.#.#.#.#...#...#.....#...#...#.#.#.#.#.#...#.#...###...#...#...#.......#\n#######v###.#.#.#.#.#.#.###.#.#######.#####.#.#.#.###.#.#.#####.#.###.#.#.#.#.#.#.#.#v#####.#.#.#.#.#.#.#.#.#.###.#.#.###.#.#.#.#.#.#######.#\n###...#.#...#.#.#.#.#...#...#...#.....#...#.#.#.#.###.#.#.#...#.#.#...#.#.#.#.#.#.#.>.>.###.#.#.#.#.#.#.#.#.#...#.#.#.###.#.#.#.#.#.#.....#.#\n###.#.#.#.###.#.#.#.#####.#####.#.#####.#.#.#.#.#.###.#.#v#.#.#.#.#.###.#.#.#.#.#.###v#.###.#.#.#.#v#.#.#.#.###.#.#.#.###.#.#.#.#.#.#.###.#.#\n#...#...#.###...#...#...#.....#...#...#.#.#.#.#.#.#...#.>.>.#.#.#.#...#.#.#.#.#...#...#...#.#.#.#.>.>.#.#.#...#.#.#.#...#.#...#.#.#.#...#.#.#\n#.#######.###########.#.#####.#####.#.#.#.#.#.#.#.#.#####v###.#.#.###.#.#.#.#.#####.#####.#.#.#.###v###.#.###.#.#.#.###.#.#####.#.#.###.#.#.#\n#.......#...###...#...#.#...#.....#.#...#.#.#.#.#.#...#...###...#.....#...#.#.#.....#...#.#.#.#.#...###.#.#...#.#.#...#.#.#.....#.#.###.#.#.#\n#######.###.###.#.#.###.#.#.#####.#.#####.#.#.#.#.###.#.###################.#.#.#####.#.#.#.#.#.#.#####.#.#.###.#.###.#.#.#.#####.#.###v#.#.#\n###.....###...#.#.#...#.#.#.#...#.#...###...#...#.#...#.#.....#...#...#...#...#.......#.#.#.#.#.#.#...#...#.....#.#...#.#.#.#.....#.#.>.#...#\n###.#########.#.#.###.#.#.#.#.#.#v###.###########.#.###.#.###.#.#.#.#.#.#.#############.#.#.#.#.#.#.#.###########.#.###.#.#.#.#####.#.#v#####\n#...#...#...#...#.#...#.#.#...#.>.>.#.......###...#...#...#...#.#...#.#.#.#...........#.#...#...#...#.........#...#...#.#.#.#.....#.#.#.#...#\n#.###.#.#.#.#####.#.###.#.#######v#.#######.###.#####.#####.###.#####.#.#.#.#########.#.#####################.#.#####.#.#.#.#####.#.#.#.#.#.#\n#.#...#...#.....#.#...#.#.###...#.#.#.....#...#...#...#.....#...#.....#.#.#.........#.#.........#.....#.....#.#.#.....#.#.#.#.....#...#...#.#\n#.#.###########.#.###.#.#.###.#.#.#.#.###.###.###.#.###.#####.###.#####.#.#########.#.#########.#.###.#.###.#.#.#.#####.#.#.#.#############.#\n#...#...#.......#.#...#...#...#...#...###...#...#.#.###...#...###.......#.#.........#.#.....#...#...#.#...#.#.#.#.....#...#...###...#...#...#\n#####.#.#.#######.#.#######.###############.###.#.#.#####.#.#############.#.#########.#.###.#.#####.#.###.#.#.#.#####.###########.#.#.#.#.###\n#.....#...#.....#.#.#...###...............#.#...#.#.....#...#.......#.....#.........#...###...#.....#...#.#.#.#...#...#...#.......#.#.#...###\n#.#########.###.#.#.#.#.#################.#.#.###.#####.#####.#####.#.#############.###########.#######.#.#.#.###.#.###.#.#.#######.#.#######\n#...........#...#...#.#.#.......#.......#.#.#...#.#...#.#.....#...#...###...........#...###...#...#...#...#...###...###.#.#.......#.#.......#\n#############.#######.#.#.#####.#.#####.#.#.###.#.#.#.#.#.#####.#.#######.###########.#.###.#.###.#.#.#################.#.#######.#.#######.#\n###...#...#...###.....#.#.....#.#.....#.#.#.....#...#...#.......#.......#.............#...#.#...#...#.#.........#.....#.#.#...#...#.#.......#\n###.#.#.#.#.#####.#####.#####.#.#####.#.#.#############################.#################.#.###.#####.#.#######.#.###.#.#.#.#.#.###.#.#######\n#...#...#.#.....#...#...#.....#...#...#.#.#.......#.......#.............#.....#...........#.#...#...#...#.......#...#...#...#...#...#.###...#\n#.#######.#####.###.#.###.#######.#.###.#.#.#####.#.#####.#.#############.###.#.###########.#.###.#.#####.#########.#############.###.###.#.#\n#.......#.......#...#...#.#.....#...###...#...#...#.....#.#...........###.#...#...###.....#.#...#.#...#...#.......#.....#.......#...#.....#.#\n#######.#########.#####.#.#.###.#############.#.#######.#.###########.###.#.#####v###.###.#.###.#.###.#.###.#####.#####.#.#####.###.#######.#\n#.......#...#...#...#...#...#...#...###.......#.###...#.#...#.........#...#...#.>.>.#...#.#.#...#...#.#...#.#.....#...#...#.....###.....#...#\n#.#######.#.#.#.###.#.#######v###.#.###.#######.###.#.#.###.#.#########.#####.#.###.###.#.#.#.#####.#.###v#.#.#####.#.#####.###########.#.###\n#...#...#.#.#.#...#.#...#...>.>.#.#...#.......#...#.#.#.#...#.........#.#####.#.#...#...#.#.#...#...#.#.>.>.#.#...#.#.#...#...#.......#...###\n###.#.#.#.#.#.###.#.###.#.#####.#.###.#######.###.#.#.#.#.###########.#.#####.#.#.###.###.#.###.#.###.#.#####.#.#.#.#.#.#.###v#.#####.#######\n###...#...#.#.#...#...#.#.#...#.#...#...#...#...#.#.#.#.#...#...#...#.#.....#.#.#.#...###.#.#...#.###.#.....#.#.#.#.#.#.#.#.>.#...#...###...#\n###########.#.#.#####.#.#.#.#.#.###.###.#.#.###.#.#.#.#.###.#.#.#.#.#.#####.#.#.#.#.#####.#.#.###.###.#####.#.#.#.#.#.#.#.#.#v###.#.#####.#.#\n#.......###.#.#.#...#.#.#.#.#...#...#...#.#...#.#.#.#.#...#.#.#.#.#...#.....#...#.#.###...#.#...#...#...#...#.#.#.#.#.#.#.#.#...#.#.#...#.#.#\n#.#####.###.#.#.#.#.#.#.#.#.#####.###.###.###.#.#.#.#.###.#.#.#.#v#####.#########.#.###.###.###.###.###.#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#\n#.....#.....#.#.#.#.#.#.#.#.#...#...#.#...#...#.#.#.#.#...#.#.#.>.>...#.........#.#...#.#...###...#...#.#.#...#.#.#.#.#.#.#.#...#.#.#.#.#.#.#\n#####.#######.#.#.#.#.#.#.#.#.#.###.#.#.###.###.#.#.#.#.###.#.#######.#########.#.###.#.#.#######.###.#.#.#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#\n#####.........#...#...#...#...#.....#...###.....#...#...###...#######...........#.....#...#######.....#...#.....#...#...#...#.....#...#...#.#\n###########################################################################################################################################.#\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_23_questions.txt",
    "content": "--- Day 23: A Long Walk ---\n\nThe Elves resume water filtering operations!\nClean water starts flowing over the edge of Island Island.\n\nThey offer to help you go over the edge of Island Island, too!\nJust hold on tight to one end of this impossibly long rope and they'll lower you down a safe distance from the massive waterfall you just created.\n\nAs you finally reach Snow Island, you see that the water isn't really reaching the ground: it's being absorbed by the air itself.\nIt looks like you'll finally have a little downtime while the moisture builds up to snow-producing levels.\nSnow Island is pretty scenic, even without any snow; why not take a walk?\n\nThere's a map of nearby hiking trails (your puzzle input) that indicates paths (.), forest (#), and steep slopes (^, >, v, and <).\n\nFor example:\n\n#.#####################\n#.......#########...###\n#######.#########.#.###\n###.....#.>.>.###.#.###\n###v#####.#v#.###.#.###\n###.>...#.#.#.....#...#\n###v###.#.#.#########.#\n###...#.#.#.......#...#\n#####.#.#.#######.#.###\n#.....#.#.#.......#...#\n#.#####.#.#.#########v#\n#.#...#...#...###...>.#\n#.#.#v#######v###.###v#\n#...#.>.#...>.>.#.###.#\n#####v#.#.###v#.#.###.#\n#.....#...#...#.#.#...#\n#.#########.###.#.#.###\n#...###...#...#...#.###\n###.###.#.###v#####v###\n#...#...#.#.>.>.#.>.###\n#.###.###.#.###.#.#v###\n#.....###...###...#...#\n#####################.#\n\nYou're currently on the single path tile in the top row; your goal is to reach the single path tile in the bottom row.\nBecause of all the mist from the waterfall, the slopes are probably quite icy; if you step onto a slope tile, your next step must be downhill (in the direction the arrow is pointing).\nTo make sure you have the most scenic hike possible, never step onto the same tile twice.\nWhat is the longest hike you can take?\n\nIn the example above, the longest hike you can take is marked with O, and your starting position is marked S:\n\n#S#####################\n#OOOOOOO#########...###\n#######O#########.#.###\n###OOOOO#OOO>.###.#.###\n###O#####O#O#.###.#.###\n###OOOOO#O#O#.....#...#\n###v###O#O#O#########.#\n###...#O#O#OOOOOOO#...#\n#####.#O#O#######O#.###\n#.....#O#O#OOOOOOO#...#\n#.#####O#O#O#########v#\n#.#...#OOO#OOO###OOOOO#\n#.#.#v#######O###O###O#\n#...#.>.#...>OOO#O###O#\n#####v#.#.###v#O#O###O#\n#.....#...#...#O#O#OOO#\n#.#########.###O#O#O###\n#...###...#...#OOO#O###\n###.###.#.###v#####O###\n#...#...#.#.>.>.#.>O###\n#.###.###.#.###.#.#O###\n#.....###...###...#OOO#\n#####################O#\n\nThis hike contains 94 steps. (The other possible hikes you could have taken were 90, 86, 82, 82, and 74 steps long.)\n\nFind the longest hike you can take through the hiking trails listed on your map.\nHow many steps long is the longest hike?\n\n--- Part Two ---\n\nAs you reach the trailhead, you realize that the ground isn't as slippery as you expected; you'll have no problem climbing up the steep slopes.\n\nNow, treat all slopes as if they were normal paths (.).\nYou still want to make sure you have the most scenic hike possible, so continue to ensure that you never step onto the same tile twice.\nWhat is the longest hike you can take?\n\nIn the example above, this increases the longest hike to 154 steps:\n\n#S#####################\n#OOOOOOO#########OOO###\n#######O#########O#O###\n###OOOOO#.>OOO###O#O###\n###O#####.#O#O###O#O###\n###O>...#.#O#OOOOO#OOO#\n###O###.#.#O#########O#\n###OOO#.#.#OOOOOOO#OOO#\n#####O#.#.#######O#O###\n#OOOOO#.#.#OOOOOOO#OOO#\n#O#####.#.#O#########O#\n#O#OOO#...#OOO###...>O#\n#O#O#O#######O###.###O#\n#OOO#O>.#...>O>.#.###O#\n#####O#.#.###O#.#.###O#\n#OOOOO#...#OOO#.#.#OOO#\n#O#########O###.#.#O###\n#OOO###OOO#OOO#...#O###\n###O###O#O###O#####O###\n#OOO#OOO#O#OOO>.#.>O###\n#O###O###O#O###.#.#O###\n#OOOOO###OOO###...#OOO#\n#####################O#\n\nFind the longest hike you can take through the surprisingly dry hiking trails listed on your map.\nHow many steps long is the longest hike?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_24.adb",
    "content": "--  Solution to Advent of Code 2023, Day 24\n-------------------------------------------\n--  Never Tell Me The Odds\n--\n--  https://adventofcode.com/2023/day/24\n--  Copy of questions in: aoc_2023_24_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_24 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  capacity : constant := 1500;\n\n  type Hail_Stone is record\n    pos, vel : Point_3D_R;\n  end record;\n\n  type Hail_Stone_Array is array (1 .. capacity) of Hail_Stone;\n\n  type List_Type is record\n    stone : Hail_Stone_Array;\n    last  : Natural;\n  end record;\n\n  --  input_name : VString :=  +\"mini_24\"; skip_header : Natural := 0;\n  --  min_box : Real := 7.0; max_box : Real := 27.0;\n  --\n  input_name : constant VString :=  +\"aoc_2023_24\";\n  min_box : constant Real := 200000000000000.0;\n  max_box : constant Real := 400000000000000.0;\n\n  procedure Read_Data (list : out List_Type) is\n    dummy : Character;\n    f : File_Type;\n    pos, vel : Point_3D_R;\n  begin\n    list.last := 0;\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get (f, pos.x); Get (f, dummy);\n      Get (f, pos.y); Get (f, dummy);\n      Get (f, pos.z);\n      Get (f, dummy);\n      Get (f, dummy);\n      Get (f, vel.x); Get (f, dummy);\n      Get (f, vel.y); Get (f, dummy);\n      Get (f, vel.z);\n      --\n      list.last := list.last + 1;\n      list.stone (list.last).pos := pos;\n      list.stone (list.last).vel := vel;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  data : List_Type;\n\n  verbose : constant Boolean := False;\n  research_mode : constant Boolean := False;\n\n  procedure Intersect_Positive_Time\n    (ia, ib : Integer; inter_x, inter_y : out Real; hit : out Boolean)\n  is\n    ax, ay, bx, by, ux, uy, vx, vy, alpha, beta, den : Real;\n    show_intersection_times : constant Boolean := False;\n    eps : constant := 0.0000001;\n  begin\n    --  We look for times alpha, beta such that\n    --\n    --      a + alpha * u = b + beta * v\n    --\n    --  The times alpha and beta don't need to be equal:\n    --    \"The hailstones themselves don't have to collide,\n    --     just test for intersections between the paths they will trace.\"\n    --\n    hit := False;\n    ax := data.stone (ia).pos.x;\n    ay := data.stone (ia).pos.y;\n    bx := data.stone (ib).pos.x;\n    by := data.stone (ib).pos.y;\n    ux := data.stone (ia).vel.x;\n    uy := data.stone (ia).vel.y;\n    vx := data.stone (ib).vel.x;\n    vy := data.stone (ib).vel.y;\n    --\n    if abs ux < eps then\n      if abs vx < eps then\n        hit := abs (ax - bx) < eps and then abs (ay - by) < eps;\n        beta := 0.0;\n      else\n        hit := True;\n        beta := (ax - bx) / vx;\n      end if;\n    elsif abs uy < eps then\n      if abs vy < eps then\n        hit := abs (ax - bx) < eps and then abs (ay - by) < eps;\n        beta := 0.0;\n      else\n        hit := True;\n        beta := (ay - by) / vy;\n      end if;\n    else\n      --  Both ux and uy are not 0\n      den := (vx * uy - vy * ux);\n      if abs den > eps then\n        hit := True;\n        beta := (ax * uy - ay * ux - bx * uy + by * ux) / den;\n      end if;\n    end if;\n    if hit then\n      hit := beta > 0.0;\n    end if;\n    if hit then\n      --  Only positive time is considered: alpha and beta must be > 0.\n      if abs ux > eps then\n        alpha := (bx + vx * beta - ax) / ux;\n        hit := alpha > 0.0;\n      end if;\n    end if;\n    if hit then\n      inter_x := bx + beta * vx;\n      inter_y := by + beta * vy;\n      hit := inter_x >= min_box and then inter_x <= max_box and then\n             inter_y >= min_box and then inter_y <= max_box;\n    end if;\n    if hit then\n      if verbose then\n        Put_Line\n          (+\"Intersection within test area: \" & ia & \" with \" & ib &\n             \" at point \" & inter_x & \", \" & inter_y &\n             \" beta = \" & beta);\n      end if;\n      if research_mode and show_intersection_times then\n        Put_Line\n          (+\"\" &\n           ia & ';' &\n           ib & ';' &\n           alpha & ';' &\n           beta);\n      end if;\n    end if;\n  end Intersect_Positive_Time;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Do_Part_1 is\n    inter_x, inter_y : Real;\n    hit : Boolean;\n    show_intersection_times : constant Boolean := False;\n  begin\n    if research_mode and show_intersection_times then\n      Put_Line (+\"index a;index b;time alpha;time beta\");\n    end if;\n    r (part_1) := 0;\n    for ib in 1 .. data.last loop   --  Hail stone at b, velocity u.\n      for ia in 1 .. ib - 1 loop    --  Hail stone at a, velocity v.\n        Intersect_Positive_Time (ia, ib, inter_x, inter_y, hit);\n        if hit then\n          r (part_1) := r (part_1) + 1;\n        end if;\n      end loop;\n    end loop;\n    if research_mode and show_intersection_times then\n      New_Line;\n    end if;\n  end Do_Part_1;\n\n  procedure Research_Part_2 is\n    dist_triplet : Real;\n    x_common, y_common, z_common : Natural;\n    low_velocities : constant Boolean := False;\n    sel_1 : constant := 284; sel_2 : constant := 42; sel_3 : constant := 24;\n  begin\n    if low_velocities then\n      Put_Line (+\"index i;index j;index k;sum of L1 of velocities\");\n      --  We list point triplets with mutual velocities that are\n      --  close to each other.\n      for i in 1 .. data.last loop\n        for j in 1 .. i - 1 loop\n          for k in 1 .. j - 1 loop\n            dist_triplet :=\n              Dist_L1_3D_R (data.stone (i).vel, data.stone (j).vel) +\n              Dist_L1_3D_R (data.stone (j).vel, data.stone (k).vel) +\n              Dist_L1_3D_R (data.stone (k).vel, data.stone (i).vel);\n            if dist_triplet < 75.0 then\n              Put_Line (+\"\" & i & ';' & j & ';' & k & ';' & dist_triplet);\n            end if;\n          end loop;\n        end loop;\n      end loop;\n      --\n      New_Line;\n      Put_Line\n        (+\"\" & sel_1 & ';' &\n         data.stone (sel_1).vel.x & ';' &\n         data.stone (sel_1).vel.y & ';' &\n         data.stone (sel_1).vel.z);\n      Put_Line\n        (+\"\" & sel_2 & ';' &\n         data.stone (sel_2).vel.x & ';' &\n         data.stone (sel_2).vel.y & ';' &\n         data.stone (sel_2).vel.z);\n      Put_Line\n        (+\"\" & sel_3 & ';' &\n         data.stone (sel_3).vel.x & ';' &\n         data.stone (sel_3).vel.y & ';' &\n         data.stone (sel_3).vel.z);\n    end if;\n    New_Line;\n    Put_Line (\"Same velocity component as some other\");\n    for ia in 1 .. data.last loop\n      x_common := 0;\n      y_common := 0;\n      z_common := 0;\n      for ib in 1 .. data.last loop\n        if ia /= ib then\n          if data.stone (ia).vel.x = data.stone (ib).vel.x then\n            x_common := x_common + 1;\n          end if;\n          if data.stone (ia).vel.y = data.stone (ib).vel.y then\n            y_common := y_common + 1;\n          end if;\n          if data.stone (ia).vel.z = data.stone (ib).vel.z then\n            z_common := z_common + 1;\n          end if;\n        end if;\n      end loop;\n      if x_common > 0 or y_common > 0 or z_common > 0 then\n        Put_Line\n          (+\"\" & ia & ';' &\n           x_common & ';' &\n           y_common & ';' &\n           z_common & ';');\n      end if;\n    end loop;\n  end Research_Part_2;\n\n  --  procedure Do_Part_2 is\n  --    xb, yb, zb, v, w : Integer;\n  --    ur, vr, wr, xb_r, inverse_tb : Real;\n  --    eps : constant := 0.005;\n  --  begin\n  --    for ia in 1 .. data.last loop\n  --      for ib in ia + 1 .. data.last loop\n  --        if data.stone (ia).vel.x = data.stone (ib).vel.x then\n  --          if verbose then\n  --            Put_Line (+\"\" & ia & \", \" & ib);\n  --          end if;\n  --          xb := data.stone (ib).pos.x - data.stone (ia).pos.x;\n  --          if xb = 0 then\n  --            Put (\"!!\");\n  --          else\n  --            yb := data.stone (ib).pos.y - data.stone (ia).pos.y;\n  --            zb := data.stone (ib).pos.z - data.stone (ia).pos.z;\n  --            for u in -1000 .. 1000 loop\n  --              if u /= 0 then\n  --                ur := Real (u);  --  Test relative velocity u on x axis\n  --                  xb_r := Real (xb);\n  --                  inverse_tb := ur / xb_r;\n  --                  vr := Real (yb) * inverse_tb;\n  --                  wr := Real (zb) * inverse_tb;\n  --                  if          abs (vr - Real (Trunc (vr))) < eps\n  --                     and then abs (wr - Real (Trunc (wr))) < eps then\n  --                    --  vr and wr are actually integers.\n  --                    Put_Line\n  --                      (+\"Ah ha! \" & ia & \", \" & ib &\n  --                        \", u = \" & ur &\n  --                        \", v = \" & vr &\n  --                        \", w = \" & wr);\n  --                    v := Integer (vr);\n  --                    w := Integer (wr);\n  --                    --  Absolute values\n  --                  end if;\n  --                end if;\n  --            end loop;\n  --          end if;\n  --        end if;\n  --      end loop;\n  --    end loop;\n  --  end Do_Part_2;\n\n  --  The following is an adaptation to the HAC Ada subset of the 2nd solution\n  --  to 2nd part by John Perry:\n  --\n  --      https://github.com/johnperry-math/AoC2023/tree/master/day24\n\n  procedure Do_Part_2_By_GB is\n\n    First, Second, Third : Hail_Stone;\n    --  three non-parallel stones\n\n    Found : Boolean := False;\n    --  whether we've found the stones yet\n\n    type Reduction_Matrix is array (1 .. 6, 1 .. 7) of Real;\n    Matrix  : Reduction_Matrix;\n    Pivoter : Real;\n\n    X, Y, Z : Real;\n    --  the solution\n\n    inter_x, inter_y : Real;\n    valid : Boolean;\n\n    eps : constant := 0.0000001;\n\n  begin\n\n    --  find 3 intersecting stones\n\n  Outer_Loop :\n    for Ith in data.stone'First .. data.last - 2 loop\n      for Jth in Ith + 1 .. data.last - 1 loop\n        Intersect_Positive_Time (Ith, Jth, inter_x, inter_y, valid);\n        if valid then\n          First  := data.stone (Ith);\n          Second := data.stone (Jth);\n          for Kth in Jth + 1 .. data.last loop\n            Intersect_Positive_Time (Ith, Jth, inter_x, inter_y, valid);\n            if valid then\n              Third := data.stone (Kth);\n              Found := True;\n              exit Outer_Loop;\n            end if;\n          end loop;\n        end if;\n      end loop;\n    end loop Outer_Loop;\n\n    if not Found then\n      Put_Line\n        (\"Mayday! Did not find three stones\" &\n         \" with mutual intersection in the future!\");\n    end if;\n\n    --  matrix columns set up as\n    --  | dx | dy | dz | x | y | z |\n    --  we want only x, y, z, so this makes for a little less work\n    --\n    --  matrix coefficients determined by some Groebner basis-like methods:\n    --\n    --  * we want to know x, y, z, dx, dy, dz\n    --  * we know First, Second, Third\n    --  * the problem implies the following equations:\n    --       x + dx * t1 = First.pos.x + First.vel.x * t1\n    --    ...and so forth for y, z, dy, dz, t2, t3, Second, Third\n    --  * rewrite the equations to eliminate the quadratic terms\n    --    and you get equations with the coefficients below\n    Matrix (1, 1) := First.pos.y - Second.pos.y;\n    Matrix (1, 2) := Second.pos.x - First.pos.x;\n    Matrix (1, 3) := 0.0;\n    Matrix (1, 4) := Second.vel.y - First.vel.y;\n    Matrix (1, 5) := First.vel.x - Second.vel.x;\n    Matrix (1, 6) := 0.0;\n    Matrix (1, 7) := -(First.pos.x * First.vel.y - First.pos.y * First.vel.x\n                       - Second.pos.x * Second.vel.y + Second.pos.y * Second.vel.x);\n    Matrix (2, 1) := First.pos.z - Second.pos.z;\n    Matrix (2, 2) := 0.0;\n    Matrix (2, 3) := Matrix (1, 2);\n    Matrix (2, 4) := Second.vel.z - First.vel.z;\n    Matrix (2, 5) := 0.0;\n    Matrix (2, 6) := Matrix (1, 5);\n    Matrix (2, 7) := -(First.pos.x * First.vel.z - First.pos.z * First.vel.x\n                       - Second.pos.x * Second.vel.z + Second.pos.z * Second.vel.x);\n    Matrix (3, 1) := 0.0;\n    Matrix (3, 2) := Matrix (2, 1);\n    Matrix (3, 3) := Second.pos.y - First.pos.y;\n    Matrix (3, 4) := 0.0;\n    Matrix (3, 5) := Matrix (2, 4);\n    Matrix (3, 6) := First.vel.y - Second.vel.y;\n    Matrix (3, 7) := -(First.pos.y * First.vel.z - First.pos.z * First.vel.y\n                       - Second.pos.y * Second.vel.z + Second.pos.z * Second.vel.y);\n    Matrix (4, 1) := First.pos.y - Third.pos.y;\n    Matrix (4, 2) := Third.pos.x - First.pos.x;\n    Matrix (4, 3) := 0.0;\n    Matrix (4, 4) := Third.vel.y - First.vel.y;\n    Matrix (4, 5) := First.vel.x - Third.vel.x;\n    Matrix (4, 6) := 0.0;\n    Matrix (4, 7) := -(First.pos.x * First.vel.y - First.pos.y * First.vel.x\n                       - Third.pos.x * Third.vel.y + Third.pos.y * Third.vel.x);\n    Matrix (5, 1) := First.pos.z - Third.pos.z;\n    Matrix (5, 2) := 0.0;\n    Matrix (5, 3) := Matrix (4, 2);\n    Matrix (5, 4) := Third.vel.z - First.vel.z;\n    Matrix (5, 5) := 0.0;\n    Matrix (5, 6) := Matrix (4, 5);\n    Matrix (5, 7) := -(First.pos.x * First.vel.z - First.pos.z * First.vel.x\n                       - Third.pos.x * Third.vel.z + Third.pos.z * Third.vel.x);\n    Matrix (6, 1) := 0.0;\n    Matrix (6, 2) := Matrix (5, 1);\n    Matrix (6, 3) := Third.pos.y - First.pos.y;\n    Matrix (6, 4) := 0.0;\n    Matrix (6, 5) := Matrix (5, 4);\n    Matrix (6, 6) := First.vel.y - Third.vel.y;\n    Matrix (6, 7) := -(First.pos.y * First.vel.z - First.pos.z * First.vel.y\n                       - Third.pos.y * Third.vel.z + Third.pos.z * Third.vel.y);\n\n    --  make upper-triangular\n    --  the following approach is quite naive and not very good in general\n    for Pivot in 1 .. 5 loop\n\n      if abs Matrix (Pivot, Pivot) < eps then\n        for Col in Pivot .. 7 loop\n          Pivoter                 := Matrix (Pivot, Col);\n          Matrix (Pivot, Col)     := Matrix (Pivot + 1, Col);\n          Matrix (Pivot + 1, Col) := Pivoter;\n        end loop;\n      end if;\n\n      for Row in Pivot + 1 .. 6 loop\n        Pivoter := Matrix (Row, Pivot);\n        for Col in Pivot .. 7 loop\n          Matrix (Row, Col) :=\n            Matrix (Row, Col) - Pivoter / Matrix (Pivot, Pivot) * Matrix (Pivot, Col);\n        end loop;\n      end loop;\n\n    end loop;\n\n    --  now clear last two non-pivot columns in last 3 rows\n    for Row in 4 .. 5 loop\n      Pivoter := Matrix (Row, 6);\n      for Col in 6 .. 7 loop\n        Matrix (Row, Col) := Matrix (Row, Col) - Pivoter / Matrix (6, 6) * Matrix (6, Col);\n      end loop;\n    end loop;\n    Pivoter := Matrix (4, 5);\n    for Col in 5 .. 7 loop\n      Matrix (4, Col) := Matrix (4, Col) - Pivoter / Matrix (5, 5) * Matrix (5, Col);\n    end loop;\n\n    --  we now have a matrix whose last 3 rows have the form\n    --    0 0 0 a 0 0 b\n    --    0 0 0 0 c 0 d\n    --    0 0 0 0 0 e f\n    --  this is easy to solve\n\n    X := Matrix (4, 7) / Matrix (4, 4);\n    Y := Matrix (5, 7) / Matrix (5, 5);\n    Z := Matrix (6, 7) / Matrix (6, 6);\n\n    if verbose then\n      Put_Line (+\"X = \" & X & \", Y = \" & Y & \" Z = \" & Z);\n    end if;\n\n    r (part_2) := Integer_64 (X + Y + Z);\n\n  end Do_Part_2_By_GB;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data (data);\n\n  Do_Part_1;\n\n  if research_mode then\n    Research_Part_2;\n  end if;\n\n  Do_Part_2_By_GB;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1)'Image);\n    Put_Line (+\"Part 2: \" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 24192\n    --  Part 2: validated by AoC: 664822352550558\n  end if;\nend AoC_2023_24;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_24.txt",
    "content": "212542581053874, 357959731032403, 176793474286781 @ -88, -256, -240\n154677220587564, 207254130208265, 139183938188421 @ 184, 74, 235\n216869547613134, 38208083662943, 397740686492049 @ 109, 262, -66\n221241619250961, 303902532813154, 249144641113790 @ 48, 24, -112\n432610900189894, 347346225570463, 389169322099761 @ -166, -99, -81\n247078054674939, 279574769079583, 357168683293046 @ 68, -13, -42\n282963504691878, 53019767043895, 238787901458543 @ -17, 399, 62\n337163551253985, 323723171285276, 476752372944125 @ -8, -74, -103\n253985064168104, 111063839515573, 450754418443501 @ -10, 456, -513\n258074760233454, 457117599855759, 244857473415713 @ 49, -247, 92\n314400910480251, 261232162431814, 339725786848352 @ -14, 8, -14\n246590774392044, 268326724153423, 252283137292781 @ -76, 195, -225\n283441229604303, 368965998122557, 461958957382550 @ -8, -135, -282\n175273393192850, 325589084134993, 358406853832354 @ 167, -63, -156\n208105215242940, 346463859222197, 284004541154973 @ 25, -119, -783\n336054085870446, 539099420004527, 243053582150753 @ -125, -451, 41\n192157026866775, 221346796869463, 239193597650948 @ 138, 27, 138\n276769382377332, 404564336355307, 139075528478897 @ -118, -279, 221\n244171538000181, 413561793671125, 231547901494709 @ 6, -271, -7\n247208942851962, 296793553833683, 207661499518285 @ -14, 32, 36\n234192138385646, 334863379919503, 180826848665889 @ -28, -63, 52\n130437043915331, 177551493108966, 166468122354373 @ 338, 448, 129\n253559901772970, 311389465584945, 216687040440642 @ -9, -19, 42\n254322299286702, 321942519715615, 221793429844513 @ -17, -42, 21\n317611519474313, 509405643844478, 492629597734339 @ -24, -308, -221\n312434433255435, 526132170689517, 256217852328836 @ -50, -379, 50\n192520813054515, 351604734054654, 148333436370478 @ 130, -152, 132\n225639342892974, 304654108851055, 198053006284713 @ 19, 39, 12\n264606145094124, 239752767682501, 207210412874243 @ 29, 61, 131\n73119136879824, 45456753334198, 74136546109856 @ 253, 194, 300\n231632956914705, 457605979777570, 302698719514094 @ 26, -414, -234\n229858006692918, 295381637696215, 265115021539193 @ -34, 118, -354\n461793485716737, 253291754164921, 311510874631043 @ -158, 5, 47\n325336710582066, 310550712766927, 330361932845723 @ 5, -61, 46\n272391892781881, 310661548818291, 260226744483606 @ -34, -25, -30\n191540619797068, 314621834402429, 114137462106199 @ 138, -22, 288\n191146615936494, 272599606676084, 172343941415066 @ 139, 136, 110\n267901500435402, 344752144584613, 304856136274139 @ -39, -98, -158\n190703217190290, 247560977233459, 149406776287313 @ 142, 550, 121\n201153500629286, 339132186878755, 150323637135481 @ 35, -57, 45\n179357508767544, 21932393507743, 145226556713621 @ 154, 315, 227\n307987323598344, 301312391795996, 300888123246103 @ -11, -40, 27\n181344541654818, 250938115658739, 239246377640253 @ 196, 440, -384\n324550882422222, 211574061061843, 237485412093545 @ -29, 72, 111\n98537457698304, 238200330125587, 135289135303526 @ 249, 31, 240\n313205485078410, 121081864504891, 172268217697865 @ -104, 348, 163\n284584577159870, 144278803049487, 200681374736457 @ -57, 323, 99\n226456734486356, 282983479210501, 218425710839487 @ -108, 324, -366\n548706725108910, 277311257109343, 307850918038817 @ -217, -28, 69\n275949926976102, 282022314903463, 311454924607825 @ -113, 87, -291\n213263551904504, 318546624732143, 175742955114241 @ 36, 19, 37\n216681369963291, 296454359998620, 462583452318421 @ 82, 10, -495\n219979404537774, 211918469842543, 232459433192801 @ 77, 188, 27\n325980549629430, 547508205102316, 314702156232182 @ -13, -324, 38\n284385758172543, 352024785807952, 218382195747631 @ -128, -120, -5\n190048554539654, 289779355315179, 173904022587641 @ 149, 388, -145\n246873768466142, 272467557005199, 232828642561081 @ -39, 131, -80\n163218080831461, 148606013314170, 142402007207516 @ 176, 164, 230\n343986154477558, 348372021296886, 250152291857989 @ -205, -106, -23\n197767130311944, 180525916592167, 161798814812969 @ 114, 519, 129\n198370970228262, 298346938466104, 174124739099332 @ 115, 54, 102\n380807631586707, 369450765586399, 481309114237823 @ -200, -141, -381\n187175525195694, 309586416720283, 109735015379081 @ 171, 173, 417\n281478516067897, 366561714660494, 230365710762598 @ -204, -184, -132\n208535431591002, 325419351576169, 191516365446671 @ 57, -12, -40\n226624736718348, 308650992940298, 199188859982218 @ -23, 62, -66\n236728026197754, 172425510194479, 206288955041960 @ 79, 131, 146\n405157823215560, 285719256118206, 491621031364803 @ -83, -34, -129\n204644528670384, 339896525956405, 151222667113763 @ -56, -54, -46\n185135616546414, 293907013443535, 166394249527601 @ 179, 231, 10\n238567782335982, 328412098910479, 192473102467361 @ -85, -26, -45\n337502877434493, 307749379575088, 369033005648444 @ -8, -58, 6\n241635494672614, 304729449451093, 326150295954981 @ 51, -27, -95\n243264345725652, 264419513819446, 345867847848017 @ 73, 6, -27\n262661477328582, 274242124962679, 187580319707945 @ -42, 80, 102\n208059705739518, 217157359130755, 219168637501631 @ 115, 85, 120\n242872575971229, 425458083316108, 227500835165921 @ 36, -258, 53\n448263894001344, 301783842143683, 426560436553661 @ -176, -43, -117\n322545182274254, 452642407811057, 305182728508413 @ -21, -227, 33\n75201284514819, 160785119325533, 104951102720081 @ 352, 241, 293\n185323568951310, 233171350573267, 165775283064269 @ 163, 358, 102\n242854931589532, 319092328660893, 243043088450517 @ 18, -38, -17\n216818686888044, 223426989024383, 346281309297331 @ 58, 283, -434\n248624452315030, 297434951348619, 284011728475200 @ 83, -49, 96\n308774084417184, 254923461188383, 324690057597731 @ -22, 27, -20\n477086131906062, 293633862617983, 289717304778929 @ -153, -43, 83\n310556413418768, 388389186178424, 201218392651440 @ -67, -172, 124\n294335453543209, 239407270896468, 327371176340196 @ 6, 40, -8\n198704436992819, 423313637384734, 211494844150179 @ 114, -360, -21\n329848820747522, 171413007628813, 298751280762187 @ -19, 102, 54\n232791155115204, 389793252905721, 200914316887487 @ -56, -314, -82\n371238777825072, 364331369420770, 349467249711398 @ -35, -114, 34\n290194660125822, 286241186809255, 265989895196345 @ -93, 39, -71\n138500514403427, 150096241065480, 90891764345181 @ 270, 386, 345\n342432728761822, 169489883251125, 160900448427412 @ -69, 145, 204\n387284555873510, 268651056280939, 472485507519965 @ -235, 48, -406\n348183642749259, 358775680962680, 425167151051150 @ -26, -110, -64\n214564960481976, 332636582662001, 166341733116147 @ -35, -19, -17\n288352094438008, 172713636729509, 508999993126113 @ 32, 94, -171\n429522310493674, 350751066474876, 353772711184036 @ -241, -106, -110\n235317931818252, 321016228988431, 221782559196323 @ 8, -29, -24\n237395224369976, 271952629687205, 200198427527953 @ 48, 46, 109\n267689676493904, 197692176620362, 371002531720142 @ -151, 456, -664\n245022629101794, 336310573633898, 178670106406896 @ 79, -86, 192\n308555808260267, 235053234862080, 386617281992034 @ 20, 16, -14\n254939001555789, 196490967246088, 344406853138846 @ 46, 120, -66\n198067603029891, 228271655034477, 230280443116238 @ 112, 353, -142\n286182290367015, 324356938662982, 337470234197366 @ 40, -74, 30\n182772323746872, 243078357133489, 180935879286305 @ 182, 418, -11\n334555295661618, 283598866844113, 307163703216413 @ -19, -28, 51\n268032515539496, 179884088413109, 201707373095034 @ 53, 89, 166\n314152706857177, 231973181098005, 294537386515547 @ -10, 41, 47\n211145445957746, 256130578705417, 227544572919273 @ 105, 54, 81\n240281216930434, 308871905093706, 201208104074959 @ -81, 58, -69\n194990331403464, 353680311245143, 148152875882771 @ 96, -217, 54\n376506453102756, 282681817701967, 308014018133222 @ -59, -29, 56\n270559608594507, 293243401201593, 219465840278274 @ -38, 17, 48\n271434227107862, 301909819058233, 255037189953162 @ -157, 57, -212\n228819748864119, 35415178477933, 360982336746131 @ 100, 225, 7\n282571416535269, 237239909717928, 361818410574456 @ 34, 28, -20\n237878607070278, 316580360861695, 326197735422041 @ 42, -39, -160\n182576050978588, 187101572838317, 131079628110881 @ 153, 161, 245\n235076492312502, 318319071558547, 260428708551349 @ -203, 96, -762\n187583408959494, 313306547152243, 102716500573961 @ 189, 318, 643\n239870832918417, 26077551674877, 194534422319897 @ 10, 745, 77\n268344200395759, 336594882856173, 201457637971271 @ -144, -71, -13\n351502642713711, 343426968745552, 327993505552334 @ -54, -94, 8\n203247301060818, 304211148313729, 144668102389835 @ 17, 294, 108\n205287991254828, 326526363823258, 176717703001868 @ 73, -18, 32\n228237293076774, 492607291603871, 215976066898633 @ 49, -457, 39\n210744469193866, 242345551455857, 338364614486931 @ 87, 173, -305\n283795432748766, 324397233772201, 303141716476529 @ 27, -71, 37\n318328668468378, 290176478743420, 393177776909696 @ -9, -32, -60\n296886504660264, 330367685997713, 290768439652901 @ -8, -76, 23\n354925965270690, 204310714489876, 324988197369764 @ -73, 86, -6\n277940901110162, 351813200734015, 35068250706381 @ 26, -105, 370\n302119534267998, 319648005021051, 257122942759009 @ -185, -26, -123\n220643077695684, 355855985807773, 179518771733771 @ 30, -142, 66\n281128245154754, 261417029969318, 390265842706956 @ 47, -10, -20\n401214520647879, 209382315271573, 394433050114910 @ -66, 37, -12\n202419387388134, 370308338321798, 371095720268716 @ 115, -152, -266\n243933688132567, 284238541251243, 160523673406178 @ -60, 127, 134\n207949728449758, 342146025132292, 160034991638202 @ 27, -90, 52\n328107083354006, 506783656792851, 68374835799249 @ -27, -292, 321\n334371695727666, 295677547881937, 372669058678174 @ -209, 21, -342\n425555650358416, 141386636896383, 400700320063993 @ -94, 107, -23\n354111348691934, 360815768065903, 286452836048521 @ -183, -129, -62\n186640407106107, 302586436160656, 178053441373097 @ 172, 200, -99\n184504662208422, 279753007845271, 194263341780489 @ 217, 645, -497\n207498586652070, 122966697911623, 453309639270761 @ 88, 592, -760\n175420575327994, 240376844547933, 227794777853156 @ 159, 37, 122\n164379037426222, 314155556336019, 361113505933531 @ 171, -59, -30\n276158080997198, 255307550628353, 190284041278157 @ 27, 22, 167\n188538116291142, 332645165411655, 164893512402481 @ 166, 10, -105\n206485169181270, 324400373771635, 174538862304413 @ 37, 28, -44\n231705775027484, 354858179856273, 282940665637611 @ 53, -119, -77\n192935594972436, 232318329359044, 140280091724297 @ 125, 770, 173\n195865425610134, 156203126394403, 201075304936541 @ 121, 618, -22\n220291544685654, 60861797261303, 192839119984101 @ 97, 313, 156\n216421547979532, 166625355222409, 138232910764571 @ 33, 645, 215\n454745381031134, 359071031321598, 433358646779191 @ -229, -116, -177\n241211456940334, 274238344824863, 449761596808401 @ 87, -22, -86\n300489403237401, 150600505604740, 311021695401350 @ 12, 130, 36\n351714451571994, 313870670017933, 87623195530631 @ -79, -54, 304\n206304315814166, 322825195619263, 165678725657741 @ 47, 27, 35\n235260754952454, 192089045978143, 324835846533921 @ 88, 81, 21\n234012378392974, 220537666254223, 244419610199201 @ 21, 243, -67\n271646520250074, 328249590902743, 281718062915501 @ 38, -75, 56\n221872342890713, 311155829759331, 169665424751063 @ 96, -49, 191\n234965964033108, 289605268944487, 264575781614519 @ 53, 11, -17\n302656676541801, 314956862712124, 279759708917957 @ 22, -64, 89\n194778772231287, 358987377936095, 94944329588325 @ 100, -269, 633\n213962227655009, 360175350319088, 187183591353131 @ 78, -140, 95\n335872446070469, 310194803249308, 258956779512841 @ -196, -18, -51\n237632929340327, 282862400087895, 329308829827744 @ -54, 155, -578\n195165381881310, 334127994548035, 177008381765921 @ 83, 25, -395\n322431513433582, 335929297302159, 292621591828001 @ -117, -80, -70\n315117522492294, 188045711663619, 217859262699941 @ -11, 94, 140\n373704262775700, 207296292228736, 462531809606177 @ -143, 116, -267\n251431566932470, 262653021312867, 228387402272864 @ -45, 151, -52\n200968557727895, 335950123937744, 148782648944484 @ -28, 20, -56\n236191762393467, 21120063276068, 319730241477691 @ 22, 742, -245\n208913018909190, 375167847286459, 97238860543841 @ -29, -401, 565\n290435031159135, 56359235789263, 318028085602160 @ 28, 227, 36\n205348838719584, 129089359330730, 397134601580767 @ 109, 358, -317\n194757851501280, 310732265284483, 257897724121307 @ 122, 57, -352\n322105170096600, 281140697612407, 384217392018125 @ -40, -9, -101\n227263802927379, 293407939553692, 217416903679568 @ 34, 50, -6\n253024402494847, 472881498291876, 346563578286452 @ -60, -512, -448\n314479634908016, 119470812770471, 423291884678263 @ -102, 343, -326\n285064202741996, 260225765977046, 328922413430668 @ 17, 14, -12\n164764803937924, 131918495543174, 24421731030948 @ 209, 466, 528\n302401846001018, 47953136574059, 415330628001011 @ -43, 389, -220\n136889723461149, 102922183481659, 257049978466682 @ 254, 415, -22\n266977346640134, 399124471391351, 389593482782381 @ 29, -175, -130\n372790937915094, 329723676236983, 408552056960081 @ -242, -66, -337\n295046549007926, 307216389914204, 245279985581636 @ -93, -14, -10\n222962551504923, 300940192862044, 205863476663477 @ 42, 34, 17\n217936499850689, 313784346557728, 244304797861441 @ 86, -36, 21\n167754243520824, 183008145578501, 255319117162995 @ 184, 214, 6\n210177003182478, 429234450438847, 105538845228113 @ 101, -266, 296\n199347157290654, 270021317518867, 163266752925959 @ 99, 261, 88\n236595610312209, 357567541944595, 163695965251100 @ -116, -177, 62\n312426175948804, 126535043607303, 334910821408881 @ 20, 119, 45\n250185142335527, 339957515144567, 186490088641817 @ -40, -85, 77\n187486534782198, 153491915531223, 178050669591013 @ 145, 217, 168\n264452793637374, 364051575147343, 278407165734113 @ -66, -153, -167\n321652447174633, 234494711812364, 293511778578951 @ -94, 100, -45\n101178528277354, 45310253629503, 279722555547721 @ 231, 211, 93\n311483135370989, 117588178673003, 195876215498686 @ -30, 223, 154\n349074097657518, 71980788262470, 67744127629012 @ -53, 236, 322\n205665951950534, 317578175678991, 174079200152461 @ 9, 131, -140\n172224556223070, 207776433045037, 341587542422723 @ 163, 78, -22\n199777030731058, 159408594476631, 309534334024285 @ 108, 565, -396\n464121799742544, 439378219125328, 480156984371951 @ -191, -210, -177\n512533623338691, 269596699742212, 497024716185359 @ -200, -16, -141\n449327916519144, 205855641898298, 303200495165981 @ -131, 50, 65\n283724606928492, 240851979789205, 384065029237529 @ 38, 18, -31\n288013100270877, 208780552824757, 275880042837536 @ 42, 41, 100\n225018718395018, 305644724002975, 271186961007503 @ 73, -21, -28\n252580597893096, 289594241717095, 283259230473967 @ -14, 39, -134\n217696966439229, 236860502115098, 202812154030551 @ 82, 134, 91\n290383585895985, 172960262418583, 413523311841740 @ 22, 107, -88\n246394854383374, 404386901502983, 316452007110281 @ 63, -178, -10\n277440283560394, 298664786803743, 343675845620671 @ 29, -37, -26\n549218613325353, 365039367598781, 370814441177496 @ -212, -115, 10\n314422297180566, 290227116094987, 220524013374437 @ -127, 20, 52\n208288985823519, 332582248866208, 173680963176656 @ 38, -34, -6\n344954667419544, 271844404820980, 373070962444213 @ -11, -24, 9\n253707352980234, 336179622652543, 293095895839541 @ 22, -81, -58\n348619876072741, 233964822099034, 330658038016178 @ -48, 36, 8\n294065185957476, 303581225750131, 130406957718587 @ -14, -35, 246\n299497691666274, 143845614560983, 193269298796021 @ -30, 217, 148\n243761048715324, 305091461548017, 163187922986167 @ -56, 46, 126\n228852534457750, 321833988811099, 195275147618589 @ -19, -6, -24\n210326083482005, 405825122389483, 255008495328029 @ 48, -393, -343\n234154015900814, 320051906908983, 254552486072961 @ 15, -28, -111\n221069337881082, 268544927933243, 253793013055353 @ 40, 152, -161\n350843574391570, 546291208573433, 245148884150221 @ -57, -343, 105\n321884637993916, 151517460880797, 338566691457073 @ -108, 268, -147\n332310394683086, 296925474202815, 290407863681483 @ -133, -5, -62\n238868612579282, 442767280701488, 312738360614324 @ -73, -538, -562\n238005301025171, 315819717023939, 310603161892176 @ 62, -49, -50\n184500511341324, 354706787987715, 106858269141817 @ 184, -175, 409\n218719926572754, 248846852339899, 417842058727985 @ 109, 9, -67\n61527743340558, 41910468004471, 21054306023633 @ 311, 306, 391\n206891968805558, 359036109292941, 96347232076181 @ 71, -164, 395\n358569854122062, 275252683087759, 280731684589601 @ -219, 51, -75\n281134641567294, 255607683726743, 288258712879345 @ -11, 52, -17\n325364111053745, 294010589908703, 211245733791773 @ -82, -13, 113\n268578371026014, 236127445255093, 380797038274583 @ 59, 17, -13\n489485534335218, 226913670756739, 271116263277629 @ -155, 21, 107\n200091726654254, 345151854422543, 355346332534721 @ 125, -97, -106\n288773407987668, 371116294945099, 330355289788371 @ -128, -171, -300\n398345872685398, 211733420030191, 256489704564165 @ -127, 75, 84\n410444070061341, 232446702321753, 270268423194688 @ -80, 17, 106\n223446110503560, 342994867695369, 176936935212271 @ -23, -95, 15\n221456980555537, 346760891427937, 198873039052710 @ 8, -111, -48\n241138246161499, 378379591190555, 197910544306414 @ 44, -161, 118\n239309488603942, 346974551472951, 243277229211186 @ 51, -101, 40\n266720686719534, 249073195909171, 326627536261997 @ 59, 6, 38\n175265275057344, 233389584704983, 166232708483831 @ 228, 519, 48\n199647143220834, 333605166183208, 126338949433076 @ 87, -38, 274\n355059474706240, 112909300036023, 456817283755217 @ -18, 127, -67\n291234253229982, 225827198327447, 300458706607553 @ -17, 89, -19\n289865647604208, 451420237900663, 518182602681917 @ 12, -233, -253\n351557916167787, 226921027459900, 441676807044779 @ -112, 88, -241\n171724416708978, 120198249743035, 113845845697733 @ 210, 720, 308\n324992776605402, 546442272740313, 176464245808959 @ -35, -358, 186\n266166769986634, 268730110669199, 328440341073557 @ 9, 35, -97\n225525857274734, 233012276737543, 309959118198911 @ 75, 111, -88\n183405703797942, 309355721084695, 182533926443609 @ 173, 53, 19\n210515462842953, 291925001904295, 215164290510485 @ -72, 459, -671\n235537482505454, 310690173156743, 156326933471977 @ -21, 22, 154\n273084618253552, 382626888261135, 273689280998585 @ 8, -157, 17\n253722385917350, 315123819243295, 240205666004325 @ 57, -57, 102\n196398380835834, 355900579581511, 153312099518087 @ 109, -169, 118\n283444009699329, 366561045831077, 202002888581270 @ -146, -167, 26\n296532850164962, 253904723261403, 296984689916093 @ 38, -8, 86\n356774602967614, 373148843974943, 387561802202761 @ -67, -131, -74\n252770877244094, 318171858594683, 216752381636081 @ -25, -28, 17\n338919821368038, 232645806842808, 377368303830121 @ -29, 32, -35\n209566211606045, 338493165391956, 150634080385665 @ -72, -46, 21\n328388255345246, 295645021337031, 342359520358565 @ -13, -41, 11\n357923314873354, 213990132914548, 252051459029871 @ -145, 126, 39\n300794330404169, 291383403542233, 331991009111531 @ -28, -15, -61\n171452764273723, 106269888549931, 325980849738994 @ 168, 255, -42\n400651551538638, 227035846405175, 440348818761665 @ -113, 46, -127\n183528864416638, 337358904333282, 149647897440530 @ 155, -82, 206\n407834029671234, 363038317346083, 326507144649005 @ -126, -118, 6\n261232554625244, 272762277507558, 260158766990881 @ -139, 184, -267\n276291421501401, 231191690007043, 332403327250334 @ 32, 47, -8\n213146770430035, 320595954009642, 182342124018161 @ 36, 10, 5\n431072263340031, 549716908674601, 541461834661703 @ -234, -415, -393\n271067118142410, 252860807780751, 293724860670289 @ 25, 35, 13\n230424456187626, 346336855193767, 374228162998841 @ 76, -99, -145\n233683858918340, 451654359126852, 407119183631371 @ 45, -334, -365\n309530132675051, 360560922327322, 427729374335125 @ -118, -132, -399\n171253360815090, 226755112694191, 106314555408725 @ 286, 763, 428\n195185795409569, 365215513552403, 270027401984661 @ 134, -121, 73\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_24_questions.txt",
    "content": "--- Day 24: Never Tell Me The Odds ---\n\nIt seems like something is going wrong with the snow-making process.\nInstead of forming snow, the water that's been absorbed into the air seems to be forming hail!\n\nMaybe there's something you can do to break up the hailstones?\n\nDue to strong, probably-magical winds, the hailstones are all flying through the air in perfectly linear trajectories.\nYou make a note of each hailstone's position and velocity (your puzzle input).\nFor example:\n\n19, 13, 30 @ -2,  1, -2\n18, 19, 22 @ -1, -1, -2\n20, 25, 34 @ -2, -2, -4\n12, 31, 28 @ -1, -2, -1\n20, 19, 15 @  1, -5, -3\n\nEach line of text corresponds to the position and velocity of a single hailstone.\nThe positions indicate where the hailstones are right now (at time 0).\nThe velocities are constant and indicate exactly how far each hailstone will move in one nanosecond.\n\nEach line of text uses the format px py pz @ vx vy vz. For instance, the hailstone specified by 20, 19, 15 @ 1, -5, -3 has initial X position 20, Y position 19, Z position 15, X velocity 1, Y velocity -5, and Z velocity -3. After one nanosecond, the hailstone would be at 21, 14, 12.\n\nPerhaps you won't have to do anything. How likely are the hailstones to collide with each other and smash into tiny ice crystals?\n\nTo estimate this, consider only the X and Y axes; ignore the Z axis.\nLooking forward in time, how many of the hailstones' paths will intersect within a test area?\n(The hailstones themselves don't have to collide, just test for intersections between the paths they will trace.)\n\nIn this example, look for intersections that happen with an X and Y position each at least 7 and at most 27; in your actual data, you'll need to check a much larger test area. Comparing all pairs of hailstones' future paths produces the following results:\n\nHailstone A: 19, 13, 30 @ -2, 1, -2\nHailstone B: 18, 19, 22 @ -1, -1, -2\nHailstones' paths will cross inside the test area (at x=14.333, y=15.333).\n\nHailstone A: 19, 13, 30 @ -2, 1, -2\nHailstone B: 20, 25, 34 @ -2, -2, -4\nHailstones' paths will cross inside the test area (at x=11.667, y=16.667).\n\nHailstone A: 19, 13, 30 @ -2, 1, -2\nHailstone B: 12, 31, 28 @ -1, -2, -1\nHailstones' paths will cross outside the test area (at x=6.2, y=19.4).\n\nHailstone A: 19, 13, 30 @ -2, 1, -2\nHailstone B: 20, 19, 15 @ 1, -5, -3\nHailstones' paths crossed in the past for hailstone A.\n\nHailstone A: 18, 19, 22 @ -1, -1, -2\nHailstone B: 20, 25, 34 @ -2, -2, -4\nHailstones' paths are parallel; they never intersect.\n\nHailstone A: 18, 19, 22 @ -1, -1, -2\nHailstone B: 12, 31, 28 @ -1, -2, -1\nHailstones' paths will cross outside the test area (at x=-6, y=-5).\n\nHailstone A: 18, 19, 22 @ -1, -1, -2\nHailstone B: 20, 19, 15 @ 1, -5, -3\nHailstones' paths crossed in the past for both hailstones.\n\nHailstone A: 20, 25, 34 @ -2, -2, -4\nHailstone B: 12, 31, 28 @ -1, -2, -1\nHailstones' paths will cross outside the test area (at x=-2, y=3).\n\nHailstone A: 20, 25, 34 @ -2, -2, -4\nHailstone B: 20, 19, 15 @ 1, -5, -3\nHailstones' paths crossed in the past for hailstone B.\n\nHailstone A: 12, 31, 28 @ -1, -2, -1\nHailstone B: 20, 19, 15 @ 1, -5, -3\nHailstones' paths crossed in the past for both hailstones.\n\nSo, in this example, 2 hailstones' future paths cross inside the boundaries of the test area.\n\nHowever, you'll need to search a much larger test area if you want to see if any hailstones might collide. Look for intersections that happen with an X and Y position each at least 200000000000000 and at most 400000000000000. Disregard the Z axis entirely.\n\nConsidering only the X and Y axes, check all pairs of hailstones' future paths for intersections.\nHow many of these intersections occur within the test area?\n\n--- Part Two ---\n\nUpon further analysis, it doesn't seem like any hailstones will naturally collide.\nIt's up to you to fix that!\n\nYou find a rock on the ground nearby.\nWhile it seems extremely unlikely, if you throw it just right, you should be able to hit every hailstone in a single throw!\n\nYou can use the probably-magical winds to reach any integer position you like and to propel the rock at any integer velocity.\nNow including the Z axis in your calculations, if you throw the rock at time 0, where do you need to be so that the rock perfectly collides with every hailstone?\nDue to probably-magical inertia, the rock won't slow down or change direction when it collides with a hailstone.\n\nIn the example above, you can achieve this by moving to position 24, 13, 10 and throwing the rock at velocity -3, 1, 2.\nIf you do this, you will hit every hailstone as follows:\n\nHailstone: 19, 13, 30 @ -2, 1, -2\nCollision time: 5\nCollision position: 9, 18, 20\n\nHailstone: 18, 19, 22 @ -1, -1, -2\nCollision time: 3\nCollision position: 15, 16, 16\n\nHailstone: 20, 25, 34 @ -2, -2, -4\nCollision time: 4\nCollision position: 12, 17, 18\n\nHailstone: 12, 31, 28 @ -1, -2, -1\nCollision time: 6\nCollision position: 6, 19, 22\n\nHailstone: 20, 19, 15 @ 1, -5, -3\nCollision time: 1\nCollision position: 21, 14, 12\n\nAbove, each hailstone is identified by its initial position and its velocity.\nThen, the time and position of that hailstone's collision with your rock are given.\n\nAfter 1 nanosecond, the rock has exactly the same position as one of the hailstones, obliterating it into ice dust!\nAnother hailstone is smashed to bits two nanoseconds after that.\nAfter a total of 6 nanoseconds, all of the hailstones have been destroyed.\n\nSo, at time 0, the rock needs to be at X position 24, Y position 13, and Z position 10.\nAdding these three coordinates together produces 47.\n(Don't add any coordinates from the rock's velocity.)\n\nDetermine the exact position and velocity the rock needs to have at time 0 so that it perfectly collides with every hailstone.\nWhat do you get if you add up the X, Y, and Z coordinates of that initial position?\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_25.adb",
    "content": "--  Solution to Advent of Code 2023, Day 25\n-------------------------------------------\n--  Snowverload\n--\n--  https://adventofcode.com/2023/day/25\n--  Copy of questions in: aoc_2023_25_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory (..)\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2023.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2023_25 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  capacity : constant := 1570;\n\n  link : array (1 .. capacity, 1 .. capacity) of Natural;\n  --  ^ To save memory, we use the same array for storing\n  --    the data's information (0 = no link between i and j)\n  --    and for counting visits through edges.\n\n  last : Natural := 0;\n\n  name : array (1 .. capacity) of VString;  --  For display purposes.\n\n  verbosity : constant := 0;\n\n  function Label (i : Positive) return VString is\n  begin\n    return name (i) & '-' & Image (i);\n  end Label;\n\n  input_name   : VString;\n  skip_header  : Natural;\n  mc_iter      : Positive;\n  vertex_limit : Positive;\n\n  procedure Read_Data is\n    use Hash_Maps;\n    hm : Hash_Map_Type;\n    c : Character;\n    key : VString;\n    src, dst : Integer_64;\n\n    f : File_Type;\n\n    procedure Get_Key is\n    begin\n      key := Null_VString;\n      loop\n        Get (f, c);\n        exit when c not in Alpha;\n        key := key & c;\n        exit when End_Of_Line (f);\n      end loop;\n    end Get_Key;\n\n  begin\n    for i in 1 .. vertex_limit loop\n      for j in 1 .. vertex_limit loop\n        link (i, j) := 0;\n      end loop;\n    end loop;\n    Clear (hm);\n    Open (f, input_name & \".txt\");\n    for skip_it in 1 .. skip_header loop\n      Skip_Line (f);\n    end loop;\n    while not End_Of_File (f) loop\n      Get_Key;\n      Insert (hm, key, Integer_64 (last + 1), False, src);\n      if Integer (src) > last then  --  We found a new name\n        last := Integer (src);\n        name (last) := key;\n      end if;\n      if verbosity >= 2 then\n        Put (Label (Integer (src)) & \": \");\n      end if;\n      Get (f, c);\n      loop\n        Get_Key;\n        Insert (hm, key, Integer_64 (last + 1), False, dst);\n        if Integer (dst) > last then  --  We found a new name\n          last := Integer (dst);\n          name (last) := key;\n        end if;\n        if verbosity >= 2 then\n          Put (Label (Integer (dst)) & ' ');\n        end if;\n        link (Integer (src), Integer (dst)) := 1;\n        link (Integer (dst), Integer (src)) := 1;\n        exit when End_Of_Line (f);\n      end loop;\n      if verbosity >= 2 then\n        New_Line;\n      end if;\n      exit when End_Of_File (f);\n      Skip_Line (f);\n      exit when End_Of_Line (f);  --  Blank line after the data.\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  --  Dijkstra stuff.\n\n  list_length_max : constant := 500_000;\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  subtype State_Type is Positive;\n\n  type Node is record\n    len   : Natural;\n    state : State_Type;\n    pred  : Natural;\n    --  `pred` is for backtracking the shortest path, to\n    --  increment the edges counters.\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  inf : constant Natural := Integer'Last / 4;\n\n  function Dijkstra_Algorithm (start, finish : Positive) return Natural\n  is\n    best : array (1 .. capacity) of Natural;\n\n    cur_len : Natural;\n    cur_s   : State_Type;\n\n    procedure Visit (new_vertex : Positive) is\n      len_to, ins : Integer;\n      new_node : Node;\n    begin\n      len_to := cur_len + 1;  --  All edge have a length 1.\n      if len_to < best (new_vertex) then\n        --  Found a better path to target state.\n        best (new_vertex) := len_to;\n        --\n        --  Insert in a sorted way.\n        --\n        ins := explored + 1;\n        for i in current + 1 .. explored loop\n          if len_to < list (i).len then\n            ins := i;  --  Insert here.\n            --  Optional: remove another node\n            --  with the same state and a larger length.\n            exit;\n          end if;\n        end loop;\n        for i in reverse ins .. explored loop\n          list (i + 1) := list (i);\n        end loop;\n        new_node.len   := len_to;\n        new_node.state := new_vertex;\n        new_node.pred  := current;\n        list (ins) := new_node;\n        explored := explored + 1;\n      end if;\n    end Visit;\n\n  begin\n    current  := 0;\n    explored := 0;\n\n    for x in 1 .. last loop\n      best (x) := inf;\n    end loop;\n\n    cur_s   := start;\n    cur_len := 0;\n\n    loop\n      for j in 1 .. last loop\n        if link (cur_s, j) > 0 then\n          Visit (j);\n        end if;\n      end loop;\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_s := list (current).state;\n      exit when cur_s = finish;\n      cur_len := best (cur_s);\n    end loop;\n    return best (cur_s);\n  end Dijkstra_Algorithm;\n\n  busiest : Positive := 1;\n\n  --  We walk from each vertex to another, randomly chosen, vertex.\n  --  On the way, we increment the visited vertices' counts by 1.\n  --\n  procedure Walk_Through_Randomly is\n\n    procedure Mark_Edge (vertex_1, vertex_2 : Positive) is\n      busy : Natural;\n    begin\n      if verbosity >= 3 then\n        Put_Line\n          (+\"  edge \" & Label (vertex_1) & \" to \" & Label (vertex_2));\n      end if;\n      busy := link (vertex_1, vertex_2) + 1;\n      link (vertex_1, vertex_2) := busy;\n      link (vertex_2, vertex_1) := busy;\n      busiest := Max (busiest, busy);\n    end Mark_Edge;\n\n    len : Natural;\n    j, k : Positive;\n  begin\n    for i in 1 .. last loop\n      loop\n        j := 1 + Rand (last - 1);\n        exit when j /= i;\n      end loop;\n      len := Dijkstra_Algorithm (i, j);\n      if verbosity >= 2 then\n        Put_Line (Label (i) & \" -> \" & Label (j) & \": \" & len);\n        if verbosity >= 3 then\n          for lp in 1 .. current loop\n            Put_Line\n              (+\"  list item \" & lp & \": vertex: \" &\n               Label (list (lp).state) &\n               \", predecessor item \" & list (lp).pred);\n          end loop;\n        end if;\n      end if;\n      --  Back-track from j to i\n      loop\n        current := list (current).pred;\n        if current = 0 then\n          Mark_Edge (i, j);\n          exit;\n        end if;\n        k := list (current).state;\n        Mark_Edge (j, k);\n        j := k;\n      end loop;\n    end loop;\n  end Walk_Through_Randomly;\n\n  procedure Show_Busiest is\n    count : Natural := 0;\n    top_x : constant := 5;\n  begin\n  Outer :\n    for busy in reverse 1 .. busiest loop\n      for i in 1 .. last loop\n        for j in 1 .. i - 1 loop\n          if link (i, j) = busy then\n            Put_Line (+\"   \" & Label (i) & \" -> \" & Label (j) & \": \" & busy);\n            count := count + 1;\n            exit Outer when count = top_x;\n          end if;\n        end loop;\n      end loop;\n    end loop Outer;\n  end Show_Busiest;\n\n  procedure Show_Graph_Stats is\n    count : Natural := 0;\n  begin\n    Put_Line (+\"Vertices : \" & last);\n    for busy in reverse 1 .. busiest loop\n      for i in 1 .. last loop\n        for j in 1 .. i - 1 loop\n          if link (i, j) > 0 then\n            count := count + 1;\n          end if;\n        end loop;\n      end loop;\n    end loop;\n    Put_Line (+\"Edges    : \" & count);\n  end Show_Graph_Stats;\n\n  procedure Remove_Busiest_Edge is\n    count : Natural := 0;\n    busiest_i, busiest_j : Positive;\n  begin\n  Outer :\n    for i in 1 .. last loop\n      for j in 1 .. i - 1 loop\n        if link (i, j) = busiest then\n          busiest_i := i;\n          busiest_j := j;\n          count := count + 1;\n          exit Outer when count = 2;\n        end if;\n      end loop;\n    end loop Outer;\n    if count = 2 then\n      Put_Line (\"!! At least two ex-eaquo busiest\");\n    end if;\n    link (busiest_i, busiest_j) := 0;\n    link (busiest_j, busiest_i) := 0;\n  end Remove_Busiest_Edge;\n\n  procedure Reset_Counts is\n  begin\n    for i in 1 .. last loop\n      for j in 1 .. last loop\n        if link (i, j) > 0 then\n          link (i, j) := 1;\n        end if;\n      end loop;\n    end loop;\n    busiest := 1;\n  end Reset_Counts;\n\n  function Count_any_Group_Size return Integer is\n    visited : array (1 .. capacity) of Boolean;\n    counter : Natural := 0;\n    procedure Visit_from (i : Positive) is\n    begin\n      if not visited (i) then\n        visited (i) := True;\n        counter := counter + 1;\n        for j in 1 .. last loop\n          if link (i, j) > 0 then\n            Visit_from (j);\n          end if;\n        end loop;\n      end if;\n    end Visit_from;\n  begin\n    for i in 1 .. last loop\n      visited (i) := False;\n    end loop;\n    Visit_from (1);\n    return counter;\n  end Count_any_Group_Size;\n\n  answer : Integer;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Random_Seed (1);\n  --  ^ We want a reproduceable result, even though\n  --    mc_iter is sufficient *most of the time* when\n  --    the seed is randomized...\n\n  if compiler_test_mode then\n    --  GNAT runs this program on the actual problem\n    --  data in 3 seconds, while HAC takes forever.\n    input_name   := +\"aoc_2023_25_questions\";\n    skip_header  := 43;\n    mc_iter      := 10;\n    vertex_limit := 40;\n  else\n    input_name   := +\"aoc_2023_25\";\n    skip_header  := 0;\n    mc_iter      := 1;\n    vertex_limit := capacity;\n  end if;\n\n  Read_Data;\n\n  if verbosity >= 1 then\n    Show_Graph_Stats;\n  end if;\n\n  for edge_removal_count in 1 .. 3 loop\n    --  Empirical observation: apart from the busiest edge,\n    --  the next top edges in the list of busiest edges are\n    --  not reliable candidates for cutting all three wires\n    --  at the same time.\n    --  Check with `verbosity` >= 1 and by disabling the\n    --  fixed random seed (comment out `Random_Seed (1)`).\n\n    for iter in 1 .. mc_iter loop\n      if verbosity >= 2 then\n        Put_Line (+\"Macro iteration \" & iter & \", shortest paths\");\n      end if;\n      Walk_Through_Randomly;\n    end loop;\n\n    if verbosity >= 1 then\n      Put_Line (+\"Round \" & edge_removal_count & \"; busiest edges:\");\n      Show_Busiest;\n    end if;\n\n    Remove_Busiest_Edge;  --  Snip!\n    Reset_Counts;\n\n  end loop;\n\n  --  Now, we have done three times this : remove the busiest edge.\n  --  AoC promises us that the heap of components can be\n  --  split into two separate, disconnected groups by cutting\n  --  only three wires.\n\n  answer := Count_any_Group_Size;\n  answer := answer * (last - answer);\n\n  if compiler_test_mode then\n    if answer /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & answer'Image);\n    --  Part 1: validated by AoC: 614655\n  end if;\nend AoC_2023_25;\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_25.txt",
    "content": "msv: nlh\nlsd: mfs fpv nlc jjg bbb gmv\nlbf: dxk\njlf: rdb rvx rcl bqc\nfjk: hfb\ntll: rqx pms\nbbk: bst zfs dpb dlq\nklb: ktc nzs xsk hbp\nrvm: jfd skf gkv\nhrq: rmk pmb pts pdf\nvtx: fvh pnn\nttt: gdf scv xrz\nfzd: vdk qsz dnf\nbqm: cxr nvk jfd cgl\nqgn: dbz lrp\njrk: htq nsq klc\npkn: njn fcs xrz\nxsk: gfc tpm\nttg: bdd mkx dxc kdz\nnxg: gbq fqt\nmhg: cfg hdr znv rfn\nfzg: jkg qhx rfl vhp\nlnj: vnc mdj\npms: mdj nfj\ndmb: mqv\nbkr: lzd hdz fdv mzq\nbrq: bmc pls nsv\nbqf: zkf\nxzd: jgs bdd vll qrb\njqj: rhx dxh lvk tvv\nghd: std vzs\nlzh: pgt\ngzd: xzb fdr zbp zjp\ngqp: hch bfb fjv hjx bxd\nvkc: kdt\nhfq: gkj qmt\ndms: dsx pgm xpq qgn vfn\nzxd: kjf thq rcj zmt jht\ndnk: tqx hsl\ngrd: rrv mdv fcp\nrzd: rcj kjr kpq hjk\nqrn: dbl jpm msn\nsph: xxk rkh jkg sff qfb\nkfm: tgt\nqzq: jbg\njlz: zxj xvq znq\npnd: pzh xgr rcl\nttq: tql fcp vcp qhm\nvnk: vfd qcp\nnrq: xcq tql tvc\nhtq: rbm qhx tkt\nhlj: ndl lkx nbp bxz\nsxc: ffz bfm vgh bsg kls jcf\npjv: vll sjp hzm\njlj: bcm\nndh: dpz plz jvl srv\nhnb: zkx jsm\nrvs: jhm\nfkg: rzx\nhsx: rcx\nhqt: lkq fgc\nqbb: tsh dnj bjm\nhdr: tgt cfl\ngtr: fpt\nmch: rgx xck\nmqh: fzc jrt\nkmr: pzd\nxqq: hzz knm fdd zmj\nlxp: nrg nnf dnv fms\nckp: svb cjn vqj\nltb: bsp\nhcz: pzd ljc rvm bvj\nzkx: xtj qvb\nlzg: xzq fnx\nnjz: ztf\nxvx: fpt xqn xhn qfc\nnxf: rfn nqn fkg ddk\ngpz: bcr czd zpm zjd\nfdc: xlk ghq tvg\nplz: rhc dds dtx\nxjc: vtj bsq rkh\nzrf: hzz\nncn: gtr\npts: ftn\nzlx: mxx rcb\nqxx: vrc zst npk\nrhc: dqc\nkds: vcg bjm cxr rkg\nsds: vpz dcv zbq ckq bqd\nvjm: gbq kqk\ndfp: vjm tpm kdv khl gkr\nnbz: zft dxk\npsg: vdr rpv\nkjf: xnq\nhzk: qfc vbt\nmnr: nhf skk zxt rmg\ndrk: qlp xbv\nsdv: pnl zlh dhd\nxxk: fzb tql jpj\nstd: hvb bsg\nndv: sld gdl\npgk: csd nxt cjd xlk\nvsf: jgd kfm trf\nqtk: rhl\nfvg: tgl vcb mjb hpz\nhtz: shx hvc spq fvj jcf nnk hmb\ntvc: lzd thq lht jzd nct\nbdg: lfx\njkg: mtj gsl ktf\nkpc: rcc crj\nmgs: svb tpt\ndgb: qvg\nnbc: bnx jpt pgt\nngj: gnl zkx lvz rgg\nczp: lbs\nsqk: hbc dmb tnx mfs\nsdt: jrt xvr\nkdv: fsj qbh msj\nhpv: xxb jsm\ntrf: jbn\nfpn: bfm\nnnv: ghl dbl jds bhq\nzlh: vxp\nxjt: bgj mhs pzd lxb hqk\npbg: qzq pls zmb rxx rfs ckf\ndsx: nlb bbr xzq\nrhn: cxr vjl\nqlh: cpb jgl tvd bdq\nfhp: jpv dbk\nhrf: tdv rvp vfd trk\nxzb: ksj\ngdt: qnh rvp klf\nchb: hfc fdr tkt\njsq: qrr czg kft\nfjr: xnd\nkjp: gqd\nvdb: mgx\nvrn: cvk\nrkh: mhs rhc gnb\nfvc: pbj fht fdd lbs gxg\ncnr: rhl xjf\nvhp: kgf jht glq\nkqr: fpt scv rpr lzg\npzj: frr dps\nlxj: qsq hcm ngn xng shr\njgh: xvq jcc rnt khl\nrvc: tzm vcp lgl\ncct: vnc pfc sjn fkb kpc hfb\nnvv: gfv ntb\ndqb: czh\nnvk: cts ccz\nzmt: rbm bcx znm xtx\nxbr: pmk xqt nrk zcn dlk xll\nmcx: bdm jsm cst\nmgt: lrd knm dzf\nzgc: lbs qlp ksj\nzpm: mgx qmv\nqhf: zcp nhf vgh fsb\ncfl: pvk mrg pkd cnr\nspq: mmt mhb dqb\nbtt: kpf\nkzd: lrk dqh scd vdb\nlkq: gbr\nnkl: hmm trf kvx kpc\nlqg: mxq zgc bmr fsn klp qgp\ntvj: gdl tgs dlb\nrnq: pkd sjm jfv ndl\nrcm: vcb gqn cns\nnsp: crj cjd dbq\ntmh: fjk ndt pct njj\nxxm: mlp lbf\ngmm: gfm rqz dpk pjx kqt\ntxb: sxn hvc\nrvj: sxf dqh xxm gxp\ngnl: ssg zrf\nrsf: htj vkc\ntfb: lkv\nvbb: fdr skx\nqxq: dbp dzr rcb\nzpx: pcl kzx grm tmj\njcf: ghm ndm\nczd: bsp ccr\nhtp: xtm vrn jhm\ndpd: zcn ckh ghg zbp xjq\nbrf: lkq bqf zpj rzk\ntsh: cqv\nndt: rcb\njlk: jrm\nlzd: xbl\ngmj: snf csz vgr\nllc: cvh xcq lft\nhlr: xxb ddn mff\ncjn: gvx tgt lfz ljc\npnm: lpf ndr bnt zsk pvk dds\nfmg: bmm klc hdz vpz\nmsj: vnc sqb\ntpx: vdb vtj nmn nhf\nqhm: sld kft\nrrk: jfc hcj hsx hbg fpn\ndnr: ngm mps\nvtk: pbj\nxqz: lbx ssf\nnxz: llp vnr tfz\ncpb: fdm tcj xhg\nvnv: sst bcj lzh czp spj\nhrd: sth mff dbz\ncgp: mhm zmj rbq\nhkz: sjx dbq zft kqk\nlxc: gkj\nbmj: rgp\ndmc: gdt rvp xph txb ckg\ntmb: pkd lhs\nkrm: hmm szh jmp\nsst: khg sgv kpf\nsnz: njs bnx rcj kjr hbc zcb vbl\npfv: bbv qtk\nznv: mjb tqt\nxgf: bnc zng vqf dft\nkdz: sld\nldb: plg\nrss: rcb vlq rcx dpz\nhrs: mnf xbl crp\nlsl: tgs vtv fjr bgt\nnqd: hrn mgs trm gkv\njhs: pgm xgh pjz xgb\nhbn: kdt ljc bqf\nscl: xgb hdz\nxnd: lqr\nvjn: hzk dxc dsm hjx\nfjs: jfg jfv nmx btf qnh\nqrb: mlk pmk\nknz: rkg\nncm: sgv sxb\nhqc: nzv vzs tqz\ntfp: klf\nscv: xgb lfl\njft: kmt lrd\nnxs: pnc qfv hdn pnd qvb\nsjv: pct\ncck: mbz klp rlr rvc csr\nsjp: ckf tsg\nrbc: mch vsq nbp bkq\nqtj: lnp dkn\nlrb: hbp zgx\nbxp: sdh kmf rxz\nchz: vxk hrf mrb cxr qnh\nmhf: fpn qxx vdb\nzrv: bdm fnn\ndlk: jjg dzx kjt\nfvm: knm gpc\nkjm: ppd cbk\nrqx: czh\npdq: mhp dft dbk\nfqg: sdt bsv\nkqk: rgx mgk\nlnp: nlc\ntzm: jgg nts bmm jlj\nqks: grj cst skg\nqmt: vgh\nshr: mfs\ntqz: bqf srb\npgm: bgt jlf\nnjn: xvx zfj bpd\nhpc: dxd qpr qbb ndr\nfvk: tdn\nrgx: vxk\ngvj: ssl slr vpr pxf\nczg: frd qdt\nqvs: xvr mxg\ncxz: mdc fgz\nsck: kjk pdg qgp zjj zjp\nmff: tkz kft\ntpm: bsv\nfnf: bcm xqz mbz shr mgt fzj xrm\nftf: dmd thk znk\nvcp: ckq\nssk: jpm sjp rrv hlx tbb\nhfc: mqv\nxdv: jvl rvr vnc\nbdq: ngr llc fzb\ntqd: xcf trm rmr\nvth: dcs tkl rmr zzk\nknm: scv\nxhg: ssg ksn\nfxx: zvz vfz cft chr vbv zrd\nbfm: zgd\nckh: xbv dnq jjb cnz\nxcr: xqt\nlvz: mlk xjq lfx vql\nrtn: njj vqg zsk nmn ldb\nqzc: vfz lrb nzv pbk\nrsz: mdv\nrqd: xmp cst mzz gxg jfr\ngqn: rqk tpm\nghl: pgt\nhch: dxc sbx\nrbj: djb tpm flb\ndbz: pgt\nnfx: clv ptp ktz fbn\nnnf: cns ndl\nmxx: dzc\nxrz: qdt\ndfn: pjx xgr jrm\npqq: rvx\ngdd: hmg nvs\ntbb: xnd mnp jrk\ncsz: rhl\nslb: txb dnj gnb\nmgh: znq klf mqb jpv qgs hph\nstq: fzd zzt ghr dsg\nvjg: kvx\nthq: gdf\nstr: qgs dps\ngrj: rpr fnx\nmkk: dnq scv psg\nnnx: ksx ttt xfp xlh qbl\nqxz: xdc ggf\nqrr: vpd czp\nxnt: xll scl\nlvl: dnj vqf qxq vmp qtb hqx\nzkj: mxx tjp fkg rcx\nrbh: nml zkf rkg kqj\ngxl: rcc\nmng: zmp tdg\ncgm: hqc dxd nqn pdq\nbcm: tkb\nkls: vgh kql fzc\ncpp: dkg nzt mkk ssg\nrvx: jxn\nhdm: kzj\nkdl: shl cjg\nszd: hbf bvv gzf mxx\ncdv: qbf xdz snf mnl zzl\nxgn: dbc gcn zmp vxz\nljk: vpr prj\ncqb: nbz vhz gcn mnl\ncrj: hfb\nbzj: srg ghd thh mmt\nglq: vtv hlx cbs\nvbl: jdb zgn\nqcr: qlz\nzpl: xtm rbm mbz fsn gsl\nlbt: vvv pzk pqq\nhqx: fzc\nskq: hcn vfj bfb\ncrm: xgv fjv hks qkc rts mkb\nfkk: bsq rzk nlh kmr\ndcg: pnv rcm\nndl: kxr\npcl: lxb vzs jvx\nldq: lrp trh dgb ntb\nhzj: scv ptn pmf qsr lpp\nhjk: xqt\nxcq: psp vll jzd\nddk: txv mdg\njbx: frk qpd jht kmp cgk rrn ngr grj\nrqk: tmj\ncbr: knz trm tfz czd\nckk: tpm rmq bvv\ngcq: mzh lzb bgl qsl\nctc: hrn hdr mhb\nlqv: rcc\nsrg: vlb cfg\njtm: psp zhn rdb kzv\ngmr: jft lzh phj\npnt: jgl jds hvm\nrdp: pnn vqg gzv rzx\nmjd: trf rfn fbv\nmgp: crp skx lbx rgp\nlpf: lcn chl\nzmg: xvj ffr\ngcl: zfl prj\njgg: bfb\nhtv: xqz ngr rvd\nvsg: gdf btv fcs\nsnf: sjm\nztg: mdr vgv rxd ddq\nlsg: bcx lzd fpt\nfzj: sjk vtk\ncrp: kdz\nddq: vrn zvl lqr\ngjg: kzx trk qvs jzq\njqd: tfb ghq crj jbs\nlnv: qtp bzr\nrrn: hgm bhq\nmll: bqc xtz rpv zbq\nvrg: xtx\nbkq: nqn btc\nnmx: djb\nmzx: ffr pls slm mqz\ndzn: plz zrd ldb hdm qjx\nzxt: pdf\ntch: lnj jpv gft\nhbt: sqq nzs dtx xqs mch\njqq: bfq hrs jlj khs\nmqz: kjr xgv ghg\nvqj: ldz nvf\nvlx: hgm\nbvj: xph sxf\nzst: lkv dnb qgc sqc\nggx: srb jfd jmg lhj dcg\nnmb: rcj\nkqt: lcm fdd\nkjk: rdt\nrgm: xhn phx jjb rvx\nmnp: bvg fdm\nljc: qjr\nvzj: bdm bds gjm mkb dhz\njsc: lfl phz rdn tdn\nszh: nvs\nqsq: mps jrm cbk\nsmv: cfg ktc\nvnr: sqq\nbms: zlp\nnzt: ssg gfz jbg\ncfm: gnl jdb rlv qdv\nbvg: tgs nbb\nnbj: dbc cjn pdl xcf\ndbh: pzk nts zfl\nscj: vxg\nxnx: ffr ngm qmh\nhqk: qkt\nssm: vpd nbb\nxlk: dzc\nccv: vhp xhg jrm\nxnq: kxv rvd\nvbm: pzk drk nmb ncn\ndqh: gbq\ntvv: dnv kfm xcx\nztn: cvk mzz jff\nkrn: jvx ndt cfz nbp\nqgp: cql bzr qcr\njfg: tdg dtv\nvlb: vnr\nrdz: jkt jgg sfj\nhpx: lkb lcn hvb jbl cqv\nrcx: gqd\nqmv: jbn kvx gzv\ntsv: ggf tbg\nzfz: scd rfn jhr\npjg: vbq thh bnc tjm\npdf: vjl pgg\ntlg: hrn\nfgc: dgc btc\nfcp: nlj\nmdj: vmb pct\nbbd: jhr gsg jqs hbn\nxvq: sbg\nxpz: bgj\njmp: smk\ntdv: cnj tfp\nklc: phx ddn\nvrz: fsb vfz chz qcp szt\nmbg: rzh\nmmt: lql\nfsj: vjl\nvxz: fjk\nmxq: mbg\nzjg: jlh ghq fsj npk\nmnh: szv ltv gbq\nstk: gct vfd crz nrg\nskd: znq dxr dqc dtq\nkbc: pqv mmt pgg zlh\nvgv: hzm fzb\nqgs: lql\npmf: nnp\nljd: lhs ghr mkv sdq tmb\nghg: ktz ndg\nvzq: bpd jth\ncgk: xcq kpq vbb\ngkj: ftn\ngbb: bqm fkg jrt htm\nqbl: rqd nsm btx vkd zrv\nnnl: tcj kpc qrr hch\ncjq: gmx zgn\ntdc: rvs dhz jlk gmq\ngfs: xpf gjg zmp fsj tqz\nvxj: msn hnb vvv zrv qmh\nmlg: qrr hcm\nsfl: hdn hjk vmk jdb\nbzf: ksj nsq zrf drk\ntsg: xmp nct kjr\ncrk: trk gbr pms\nmkn: mlk zzg\nslx: rfl vbl lnv\nzjp: rhz\nxqf: ccv qkc dbs\nbbl: pmb jlz bkq skd\ndzr: vxp\ndzk: gtd lnp mps mzx\nqgl: vxk\nsjh: cgl scd tqd\nvbv: tfp vnk\nssc: qgn qmh frm jsq\njrj: zml lbf zpt mgk\ndbg: mkv gfp cvv lfz\ntbg: drg\nzzl: msj\ndcq: qmt rbj mhs\nnhx: hrs knm ntq mdc\nptv: rst dcq mtc nxz\nkbj: crk hbg\nthp: xjf rsh jvc nnf\nssl: hmj hgh\nhvm: zhn jkl nlj\nhcv: phz vdr mhm\nxhq: scg vmb\nmgx: jvx\nflb: xgx\nbxd: rlr cvh cdn\ntlc: hrd lzh cjq kdj lnp xtj rmb\nvbq: xhq hvb hpz\nzbp: skq qtm\ndsm: qlz\nlcm: qdv vbt\nfrr: cln bsg\nsld: lbx\nfrj: ldz dqb jpv fhp\nmsg: mhv ghl dlk clv\nsjn: gxl hzh\nrst: jgd gqd crj\nvnl: dsm hcn ksx qcr\ngrv: xcf fsj vzc\nlfd: ctc mch\njgq: fgz hgh ftl\nccg: zsd krj zxj gbm\nznn: ptn vgk dkn qvg\nfdv: tsd prj\nszv: tll\nvcb: rzx jvz mhb\ngzb: mxr lxc\njdb: zzg jrm\nzjd: pqv lqv hkm\ncrz: fqt\nsdq: nbz lfd rnl\nrgl: dbq ktd pfv zkv\nkhj: qmh\nzjj: lht qcr\nntb: nct xxb\nbsn: xck\nbpd: jth\nqsj: dkn xdc\ntvg: kfm rqk\nnsq: xvj mzh\nqvg: kjm lzb\nfgn: scl thq rvd jgl\njhx: krm rsf mxg vjm\nsgc: xqt jjb zfl\nkvm: pmf jsl bkr fjv\nrdn: vnl\nngn: vtv\ngpj: bgl rdb tdn\ncft: zcl\nxtz: pjx sth xxb\ncjg: vfd dnf\npjq: hpz vrc pts mhp\nfdn: htj zpp\nbgs: rrt\nzmh: rgx krj xjf\njth: dxb\nfjl: jgd ltb vqg lrk dtq\nzts: jrj sjh gct jmg grv\nhsl: bqc\ntvd: nts xng rhs\nrhz: hdz bcx\nkdj: jgl nmb\nrxd: xlh vbm dsz\nhzm: rfx\nfrd: jlk kxv\nxdz: sdt ltb\npns: tll vgh\nvpz: ptp ksx dmb\nsdh: ssf ksm\nxlh: lxj fpj\nkqj: lbf gzb\nbtx: dbj bmm khg\nchq: ktd qjt hhr pdl\ndnq: fsx\nnmf: sbr jgq ghg\nkzv: qpd smx\nmlp: qng llp txv\ndpk: zfs dxb gvg\nsjx: gft skk zzl\nvxk: xgx\ntgh: djb\nshk: hqk mgh szv\ntlf: txt qks bmj dkn rrt\nltv: kxr lxc\nqbh: jmg\npqv: spm dtx\nbdx: jgs tsv xrm dmb dbj\ndpg: kgg rsf nxt\njcc: vds lch gfp thk\nbjq: nmx cnj jqs rsh\ncgv: dlq lqp tnx\nsrv: rmq cfl\nsff: zcb clv\nxzp: dbb nbc qrn ztn dkm\ndzx: bzr rgp rpr gmq\nlcn: pbk\nhmb: spm ltb\npls: gdf\nhsc: tzz brq vrg tdn\njpv: fdn\nhgh: xpq kmp cfm nvv vrg\ntmn: txt jbg mzh pxf\nqnf: ffz slb mpb pqv\nkhb: kmp pjz lkr\nfht: lpr fcz fdd\nbcr: lrb jmp xcs\nvlq: sqb fqt\ndrq: ccz fdn xvr rvr\njgs: bbr\ntxf: gdd mrb ghr\ncbs: tzz\nsjm: nfj\nxdc: xhn fjr fsx\ngrx: tql\ndrg: qlz\nvcg: cts jrt mrb\ncxc: lrb hzh mst vlb\nzcr: ppc gjm qsr ccb\nmzz: fdm\ncpg: mrb kxp zpp pqv\nxpf: tqt\nbjx: kxr pts\nqdh: szh zgd vqj\nzkf: mgk\nfcc: pdg bcj\nzlt: rhz grd kdj\nsns: scv kgf\nkmp: jkl zmg\nszt: tfb xqs mrb\nhxr: grx nvv zvl xtj\nghr: hdr\nbbv: rpc zzk cqg\nkhs: bqc xnd hsl\nzlp: hfb\ngnn: khl bfm rtn fjq sdv\nkmf: jkl fsx cbs\npdh: xll vgk cdn vtk\nffz: ldz vlb\nlcp: zxj lnd zbr\nqsp: vdr gfz gtr mlg\ntpt: dqh gql skk spm nqn\njzd: xqt\nhph: zft gnb\nsdk: vsg ptp kjf ftl\ndvc: zlp htm djb dbk\nfdd: rzh\ngpf: qzq bhq rmb dbh rrv\ntht: pzh qdt tkt ckf\nhsb: ssm gvn\npnv: tsh\nrhb: sld khj ggf\njbc: chr mdg bxz xdv vkc\nbqz: qkt qmv xgx\npjc: pnl zkv tqt\nsxg: xnx tqx fcc gjm\nmrv: vtt rzx znk dbc gmj\nlcc: pjv vrn xnq zlt\nprq: svb rzt jvz\nrjd: thk pbk kmr xcx\nxfp: phj sns hzz pjx\nrgg: vql bdg bnx sld\nzml: fvj tfp khl\njgd: jgz sbg zmp\nlct: rxl bsc txf\nhfl: gdl xbv\ntsk: xgx dmd\nrhx: bvv hxl\nbnp: psg fbl qdv fsx\nhzt: kvb zmg zkb xpb\nrqz: mnp dzf zfj jgs\nqpd: lbs\nrcl: ksm\nqff: hqt dhd vmp\nmdr: gxg kjk ctj\nqlj: xcr fdr gnl ptk\nkgk: hgm jdb ctj\nkvc: jht qlp vrn\nlhx: mng zbr vjg vtx\ncdn: cbf\nxdb: kmf thq zmb\nfzs: tsk zcl nfz ndr\ndxc: ckq\nvql: nts cbf\nfdm: xbl\nktf: kjf frm xgh\njpt: lhb rpr\nmhc: zfj pmk sdk zgj sbx\nxjq: dbs kmf\nppm: ssf bxd zhn cgp\nxxg: zbr rhc vdb\npbf: fpj drg shf\nbds: cps dgb dxb\nshp: bjx kxp bvj nnk\nxqs: nlh\nbvk: fqg gft vbv sdt\nbzr: tsd\nxcs: bsg txv txb\ndqx: dtq pjc hpg kzk\ndxr: fvh vzs rzb\npjz: zmj qfb xmp\ndzb: lrq dkx ftl fzj\ndbl: hfl cbf gdf crp\nbfp: fpn rnl skk plg\nqsl: xvx\nrjj: mhm tmn mkx qvb\ncts: nfj\nbbb: scj sld\nsqs: zng vnk fqt zkr flb\nqjm: lcn zcl zcp tgl\npbj: ptk\nccb: dfn frm scv\nfgq: vlb dps kbj ndt\nsjg: scv lcm dlb btv\ncqg: qtk\ndhl: gdm fsj\nphf: pnt dkm xqq zgn\nzxq: kql frr dzc zsd\nnzs: nfj xpf\nbnc: mhs dpg\nkmt: tsd\nrmb: xgr mfs\ngxp: tlg dhd\nsgb: skx hlx\npgs: gvx vlb\nqnl: nvf tvg mgs fhp xcx\nmbz: lqr\nmtj: ptk cbk\nklp: vlx\ncfz: xxg llp zkv\nvhz: bms gkv vgr\nfms: gkr\nkhl: kxp\nlml: cqg jdh fjk nxt\ndzf: sdh\nxrt: xqf rsz mhm lrd\ntql: dbj\nqpr: pbk\nzjr: qsz srv hdm mhp dcg\nnfz: bsv gzv ftn\nspj: sns dbj\nzpt: hph\nqfr: rrv slm vrg nsv\nzmb: fvk\nctj: xrp\ncfv: skf kmr rnk kdt\njpj: cbs chb ncn gmr rlv gmx\nxsh: jcc cnj lfd lch lxp hqx\nnjs: jxn lkr fdr\ncps: cjq fcs vbc\ndjv: xpb bmc\nptt: nvf gkj pgg\nzzg: hcn\njzj: zcp ndm xlk bnc\nfcs: dzf\njlg: xkr qnk cqv vfx\nrnt: jzq lrb cnj nvf\nsxr: zqn hsb rdn\nxkk: rcl lzg vpr\nfcz: ksm vlx kdz ghv\nvgr: zpm jfd\nmzq: vrn xcr\nmzh: qfb\ncxs: znk zcp nvk xjf\nxxv: glg gvx mjb gbr\nkjt: rzh zfj pgt\nfjq: hqt bsc hqq qcp\ngnz: kjm fcz vzq pzk\nsxb: sgv pmk\nsvl: hsl xgb\nlgx: xlk zsk qkt zst\nlst: ftl djv xrm xrp dnr\nztx: jbl zpt tgt\nhmm: rzb\nkkf: jlh zzk nkv kfm\nfnj: jbn dnv qjr\nshx: bms rxl fjk\ngfc: qjg zkf\npzh: nct\nqfx: vgk cgv fqx mhv\nfqf: vtv tsv rrn qlp\ncjd: lxc\nfrk: spj dkg bmc\nrrt: bcm\nxbl: rlr\njdh: bfm scg gxl\nktd: mst cqv bxm\nnqj: czh gdd lhs rmr\nnxj: bxm hmg kqb xjc\nrcp: tvg zlh ltv\nxnz: fzb\nhjx: hfc nlj\nvmp: krj qbh\nzvs: cps qhm lft sgb\nskr: vjl xpz hmm krm fdc hfq\njvn: vxp nxg jns msv prq\nndm: rzk gdm\nmpb: smk srb kmr\nxsv: cbk jgg lnv rfx\nnmh: qbh rhn ztf\npzk: fvk lqp rsz\nrlv: vmk\nssg: dnk\nshv: khb kjk shj gmm\nbst: zzg dkn lft cnz\nhxt: scv dgb rxz bxp\njvt: vgv rdt svl jpm bdg zgn\nqfv: gpj xcr xbv pqq\nzng: bms tmj\nksn: dkc hgm cql\nvvx: plg tjp tfz\nzpj: mnl nzv qbb dxk\nrbq: svl\nxrm: nlc tqx vcp\nlft: cdn\nlhb: rpr ksj mhv\ngqs: rpv rrt dkc\nvng: znk dzr pzr nml\ndsg: nmx jmp spf\nhdl: tvv kdl hmb mnh\nhmg: tmj\nbmc: rbq mlk\nzsk: jbn\nfgz: zhn zgj\nphx: mdc\nrhs: psp lzg lsl\nmss: gvn bmj\ntmq: rcp lcp vcb fnj rnt\nvfj: fpt\nsvx: sdh nlb\nzgn: tsd\ndlq: rfs\njrt: qjg\ndkm: jjg kvs\nnzv: qcp zlp\nbtc: fzc\nlpn: ghd vvx mgs mhp tch hpg zkr dft\nnkv: tjp qgl\nnvj: rcc\ntnc: lrq hln qqq vgk dlb\nkdm: dkg sth fvm fdv\nxkr: dbp njz lvk\nbhh: dsz dlb tkb\nqmc: pmf bdm jht mss\nhcj: kdt njj\nbxz: jrh vmb\nqtp: skx mbg\nghm: vjl\njvx: pzr\ngjm: gtr fjv\nmps: mcx\nrhd: xgg lhj jdh qnh\nhtj: sjv\nqrl: fdm xqn vpd mmx\nsbx: sbr gmq\nhbf: rnk str gkj\nlnd: mrg gdd nvj\nmpp: scv jpt tnx sth\njvl: pnn sxf\nscd: znq kxp\nrxl: bqm sjm mkv lhj\nchd: qff zpt bzs npk\nnjd: nvj jfc gvx fpq sjn\nmqj: qpr sjm tfb pzd cln\njvc: htj\ngbm: bqz xpf hqq\nsth: hks\nxgg: rvr gkj hdm\nmqr: ccr mdg lpf gzv\ngkv: mnf fvh\njkd: jds phx nts\nbtf: rhx xqr rzk\nvfh: gsg jbs xvq cfl\nbdm: lrp sjk\nrbm: jhm\nlfx: gvn\nzcb: msn\npmg: vvv jff ksm xzb\nbnt: dcq qjx bxz\nhmj: vbt dgb xnf\nmhm: sbr xmn mqv tdn\npnp: hrq dmc lhs fzd\nznr: szt jvl jgz\nshf: gvg rgp\ncnx: xpz gql jgz pfc\nrcc: ddx\njzs: vmb plg dgc dzc\nvnp: rbq zgj tzz\npkz: qhx jrk ptn zgn vfq lst\nxzg: lzg ncm gsl rlv\ndxh: pzd\nlkx: fms bjm gct\nmth: kmp kcg grd\nhcm: dxc\ntqm: vpr shf dlk dcv\nchr: fkb blr\nztf: dqc\nbpf: skq shr btt hmj\nbtv: tkz mbg qlz\nqgc: vzs vfx ccr\npgg: jhr\nqbf: nsp hhp vqf rzb bfp grm msv\nclg: lqr czp rgp\nbsc: dbk\nrmk: hmg mxg flb vtj\npsz: jnh vbc jkd\nsmx: cnz fdv\nnqn: mnl\nnpm: jgg xnq\nmqv: lrq\nffr: jxn\nkzx: rqx kql vqg\nkgf: lqr\nntq: tbg lfx mzz skg\nqnt: rlr fjr\nmbh: cst kqt tcj dbz\njvz: ccz\nmkb: ggf xdc\nsxn: rzt grm\nzfs: bgl ljk\nlqd: nkl xxm sqc jbl\nvdr: xgr\nhln: ssl vrg hzk\nvxg: cvh dpc lfl pqq\nnxt: lqv\nblr: mgx jvc\nshj: pdg mhv zmj\nbsf: cjd tsh szh hqx\nkrt: gsl psp lzb\njfv: plg hbp\nrfs: mdc\ncdr: zxt str snf pqb\nfpq: gxl tfz ffj lct\nqjr: vlq pnn\ntnt: xgv kxv prj xrz xnt\nlnr: dcs fms bxm gzb\ndnb: nmn xck fqg lcn\ncfj: bms pgs qdh rzt\njjb: sld\nhrp: nkc bnx zrf xll\nslr: jlj hbc kdz\nnnp: xnd sjk sth\nhbg: vjg nxg\nnsm: ppd rfs\ntjm: cvv fcq\nrzv: kmt lrq gcl npm\njdc: fkk zfz fvj mgh\nkzk: pns qjg fsj\nqfc: zfl\ngvn: bvg dlq\nxdd: fqg npk cjg\nrdh: rnk tdv nfz\ntzc: vjg ftf nkv jlh\nlxb: sqb qjg\nnkp: vsq scg hqq xjc\ndbp: qkt dpz dgc\nvqf: xsk\nxgd: ztx kbj vxz\ngfm: dsz khj lbx\nkvg: rlr jth xqt gzd btt\ntjz: sgb xnz vfj qhx\nqvb: tkb kjr\nkcg: jpt ggf fzj\ngdr: zxt rmq ccj\njxv: rjd grm dnj csz hbt\nfpv: jlk zmb lqp\nxmn: pdh dmb\nsqq: nlh fms\ndbb: smx dnr tbg xzb\ngcn: gfc jhr\nmkx: cvk qsl\ncfp: rdz qsj slm ngn\nrts: mzq dbs sgk\npnc: lsg hpv ncn\ncsd: gnb ttr rdp\nbxm: rcm qnh\nfvx: zgx dtq rdh tgl\nfjv: vpd\nqlp: dnk\ncsr: grx jfr kpf ndv lbt\nzbr: spm scd\nnxl: xhg lft sjk\nlhj: tlg\ntdg: qnh cts jvx\ntxt: khj\nhdq: fnx xqn lnp xrz sqk bdg\ndbq: rsh bsv\nnrk: gpc lbx zgc rvs jsm\nkmk: kvx htm shl lpf\nhtm: sqb\nglg: pns ckk svb hsx\nvsq: xvq\nmtc: sjv jvz djb hxl dxk\nvtj: cln\nqkn: mrg gkv mkv bmx\ndmd: hbf kmr ghm\nthh: srb kxr\ndbs: tkt ssf\nvxs: hpv rvd\nsnd: qjr glg dxh dps\njrh: cgl\nktz: pzk lrd\nzpp: tmb zkv\nrxz: bmm\nxvm: mxq ndg xzg xgr\nxhh: pnl fsb hqx\nqqr: vsq hzh kjp ccr\ndhd: zmp\nvfq: svx nbb bdx\nmst: pnv hcj\nhlg: nmf jft xpq dnq\nnlb: djv ngn\nrmr: jfg\njff: ghl psz\ncvv: jzq\ngpc: nsm\njxn: dhz\njsl: zqn bgs jnh sfj\nllp: mgk pbk\nxqr: trk nmx jgr btc\nmvd: gdr xdd qtb shk\nzvl: nlc qnt klp\ngdj: frd ptk lkr jhm rzh\nhhm: jvx hbp mgh bjx zgd\nlql: xpz\nxfn: bgj pgs sxn xhh tgh znr\nnkn: ngn bqd scv zjj\nnnk: nhf rqx qvs\nkqb: tgh\nqjx: dbk tjm\nfnn: jpj bhq\ndbv: hdn mxq sgc glq\nhrr: zzt pnl nvs skf\nsfj: rpr\ntkl: ghm dqc smk mrg bqz\ncgl: nlh hrr\nckg: hbf\nzcl: bgj\nrkz: bfp htj lqv mhf dxd\nqxd: kmk knz klf tjp\njkt: vmk hzm\ndqp: spj scj vkd zjp\nxcf: chl ldb\nbmx: mhb zgx qmt\nlgl: bfb\nnsv: jds pdg\ntrm: vrc\nsrb: bsp vmb\ngql: cqv\nzrd: lql pnv\nzkr: pfv qtb nmh qkt\ngnb: tmj\nfbl: sbr btt zcb rdb\nkvb: skg ndg qkc\nsgv: fbn\ndtx: bsp\nndr: qgl\nzcn: qfc\nrnl: mqh ddx\nldm: zhn qhj jff xzg\nlzb: dpc\nrhr: qsq pgt xhn lzg\nlrk: fzc rsh vzs\nqsz: zcp\nxhn: ptn\nngm: rfl tkb jbg ckf\nzrx: jqs svb\ntkz: tzz\nrkg: skf\nsbg: kfm dnf\nczq: ldz sqs rqs frr\nmsn: cnz ckq\nlqp: frm\nkql: lcn\njnh: qdv ptk\nbbr: dkc nts\nksc: ssm sxr dpk ppd\nrxx: dpc tkz nmb mtj\nvbc: mkn\njns: jrh nkl qhf\nslm: kpf\ndss: dxh pzr dnv xck\nxsp: gxp lvk czh qbh\nvfz: mgk zmh\nshl: nfj ddx gcn\nthk: qgl\ndbc: mnf\nbcj: hgm tkb\nzkb: qfr xnd fpt kgf\nrns: lss cjm rsz vhp\npxf: vmk\nzfc: dnf chl ktc cft ndm\njtx: ksm dcv zcn tnx\nlch: mnf fbv\ngfv: lgl qfb hsb vfn\nlkv: pkd lfz\nhkm: mhp hrn\nxdq: rdt sgk txt znm bhh\nqtb: blr\nldz: rvr\nfcq: vxp zrx dpz\ntgl: fqt bsn\nmnz: ttq jlf ndg qtj\nrqs: ltv szv lnj pzj\nvfx: pct rvp\ntnl: hbn hpg bsn qxd tsk\nxng: vtk qnt\ndcl: hks fvk tdc btx\ndkc: khg cbf\nkxv: ppd xvj\nvdk: plz sjv njz\ndmk: xrp ncm qrb zcr ghg\nfvh: vzs\nppc: sfj cvh\nkvs: xzq dkg vbc bmj\nhdn: rxz\nqng: pgg hvb\ngdm: vkg gbq\nnbp: fvj bsc vkg dgc qng\nphj: ljk nlj\ngmv: xdc dkc fvm hlx\nbdd: czg\nsgk: dxc qtp\nmxr: spf gql kjp\nrmq: vds kgg zkv\njpm: fcp\nfsn: bdd\npfc: hfq ddk\ncfq: xhg tvj fsn pbf\nrgz: gfp hkm rcm hhp ptt\nhpg: ckp vkg\nqjt: mqh smv dhl xcx\nxgh: rvx mdv\nffj: jqs vjg zlx\ntlp: lht bfq sgc hbc\nmcf: drq tqt pzr qsz\ndcs: jrh xph vnk mng lnd\nlhr: vxs qvg krt hnb\nfpj: xzq jjg qkc\nbjm: dtv\ncns: rnk gbr\nccj: cxc fqg tlg\nlpp: jgl kjk lft\nmhs: lfz sjv vfd\nlvk: mhp\nfzn: xnz bbk dcv lfl\ngxg: xkk\nnkf: vfn rsz mkn bbb\njmg: ccz\nlkb: cqg drq gct xvr\ngjf: hfl lzh nrq gvt\nhhr: dft qpr fzd dzr vrc\nkqc: pmf kzv cvk\npqb: vds ltv\nfcx: tgh bsf hsx chd fbv\njfr: mbz jht\ngqb: khg hcv nxl jtm\njfc: rhn kgg\ncrl: zbr xhq vsf czh\nzvz: kjp cvv rhx\nksx: hzz\ndpb: lqr xtj jds gdl\nxgv: ncn\npnk: cxz tzz bgs pxf\nqsr: fnx tgs bgs\ndxt: fbv stk znk pvk\nqdt: jkl\nspf: nvj\nptd: fdd grx rdt sff\ncql: bcj fbn\npmb: zrx fgc zzt bkq\nlhf: bxz znv vfz kbj\nhlx: fpt\nhvc: njz gkv\nphz: bgt vfn\nlss: kft pbj dxb\ngjd: crp dbz qfr bgl\ntrh: sxb lgl tsd\nzzk: gfp nvs vtx\nrfl: xtm\nbzs: qgs gsg mjd vnr\ndgp: vxs xtx jlj rfx gmx bpd\nlpr: cpb dsz hcm\nmkv: ftn\njgr: jqs lkq pqv\nbsq: nlh lql\nnsx: dsm gvg slx zqn\nsqc: vjg fsb\nshq: gft cnr dqb gvx\nfkb: khl\nrmg: kqj pqb trm\ntpd: ttr vzs srg zlx\ngfz: kvc jkt qxz qtm\nmqg: vbc xnf kgk hjk\npdl: xph str\nxvp: jxn kmt bpd fht\nvds: rhl\nnrg: dxr qtk vxz\nznm: mhv mmx\nxpq: jkt\ndxd: kqb\nhbp: shq\nrpc: zxj vjm btc rzb crz\ndhz: zbq\ntcj: xnz rpv\nbgt: tqx\ngsg: chl jbl\ncjm: zbq xtx rhb\nqnk: xqs vxp jcc\nqbq: cfg rqk gbr xdz\nhqq: hqk kqb\nnks: qjx scg jbl fkb msv\nclv: gmq\njzn: khs gfz qsr kjk\nqtm: ndg\ndkn: drg xnf\nqhj: zgj bqd xqn dsm\nrfn: rgx\nnbq: zrd jvc trf hdr\nzfl: mdc\ntgt: ddx\ndtv: jgz mjd smv\nmlk: jgl\nvkg: jlh\nlnt: hlr frk ddn hks\ngtd: ptp dlk dpc\nghv: chb qtm gmx\nqgj: mdv qlp bcx qsl\nbcx: hcn\nbzx: gqs mss fbn dxb clg\nmqb: hph tfp lbf\nfqx: lht vbt bqd\ntrt: knz mdg crz bvv\nhhp: xjf pjc\nkpq: vzq xnt xvj qtj\njpl: qxz ngr qnt cbf jkd xdb\nzfj: fcc\nvkd: skq xmn\npnx: ztf sxf kzj pvk\nkzj: zzt vgh\nxrp: jkl\nnkc: xpq ppc vvv rdn\nvzc: njj zgd cqv\nskg: dmb jzd\ndkx: ctj pzh\nttr: srb kzj\nxvt: rcm dbq kdl ckg\ngzf: dmd hzh ckg\npct: dds gkr\nktc: csz vkc ghq\ndcv: gvg hfl\nxmp: lkr\nzfh: sdt gqn hdr gkr zzl\npxb: nbb fcc gcl dkx\nlrz: kgg xgd hmb mxg spf\nzsd: fms cln\nzgx: zft dnj\nddn: lrp\nmkq: nzt fnn nbc htv\nqqq: scj sgv lgl\nnml: cft smk rzt\nxpb: xtm bcj\nmjb: hpz\nbdp: fcs mth mlg cfp\nkcc: czp vnp dcv gpc\nhxl: qjg rcc\nvtt: dhl gfc pzj\nbfq: vll cxz rvs\nvcq: xnf kqc frd dpb\ngnp: qsj mmx qpd vfj zqn\ngvt: pkn rfx ndv\nbmr: nsm lnv npm\njbs: nqn dds\ngqd: std\nnmn: txv\nkkm: htp vbb svx mmx\nvtq: jzq bsn crk pqv\nkrj: mdj\nntl: lzg hfc qzq vlx psz\nrnk: hxl\n"
  },
  {
    "path": "exm/aoc/2023/aoc_2023_25_questions.txt",
    "content": "--- Day 25: Snowverload ---\n\nStill somehow without snow, you go to the last place you haven't checked:\nthe center of Snow Island, directly below the waterfall.\n\nHere, someone has clearly been trying to fix the problem.\nScattered everywhere are hundreds of weather machines, almanacs, communication modules, hoof prints, machine parts, mirrors, lenses, and so on.\n\nSomehow, everything has been wired together into a massive snow-producing apparatus, but nothing seems to be running.\nYou check a tiny screen on one of the communication modules: Error 2023.\nIt doesn't say what Error 2023 means, but it does have the phone number for a support line printed on it.\n\n\"Hi, you've reached Weather Machines And So On, Inc. How can I help you?\"\nYou explain the situation.\n\n\"Error 2023, you say? Why, that's a power overload error, of course!\n It means you have too many components plugged in.\n Try unplugging some components and--\"\n\nYou explain that there are hundreds of components here and you're in a bit of a hurry.\n\n\"Well, let's see how bad it is; do you see a big red reset button somewhere?\n It should be on its own module.\n If you push it, it probably won't fix anything, but it'll report how overloaded things are.\"\n \nAfter a minute or two, you find the reset button; it's so big that it takes two hands just to get enough leverage to push it.\nIts screen then displays:\n\nSYSTEM OVERLOAD!\n\nConnected components would require\npower equal to at least 100 stars!\n\n\"Wait, how many components did you say are plugged in?\n With that much equipment, you could produce snow for an entire--\"\n\nYou disconnect the call.\n\nYou have nowhere near that many stars - you need to find a way to disconnect at least half of the equipment here, but it's already Christmas!\nYou only have time to disconnect three wires.\n\nFortunately, someone left a wiring diagram (your puzzle input) that shows how the components are connected. For example:\n\njqt: rhn xhk nvd\nrsh: frs pzl lsr\nxhk: hfx\ncmg: qnr nvd lhk bvb\nrhn: xhk bvb hfx\nbvb: xhk hfx\npzl: lsr hfx nvd\nqnr: nvd\nntq: jqt hfx bvb xhk\nnvd: lhk\nlsr: lhk\nrzs: qnr cmg lsr rsh\nfrs: qnr lhk lsr\n\nEach line shows the name of a component, a colon, and then a list of other components to which that component is connected.\nConnections aren't directional; abc: xyz and xyz: abc both represent the same configuration.\nEach connection between two components is represented only once, so some components might only ever appear on the left or right side of a colon.\n\nIn this example, if you disconnect the wire between hfx/pzl, the wire between bvb/cmg, and the wire between nvd/jqt, you will divide the components into two separate, disconnected groups:\n\n    9 components: cmg, frs, lhk, lsr, nvd, pzl, qnr, rsh, and rzs.\n    6 components: bvb, hfx, jqt, ntq, rhn, and xhk.\n\nMultiplying the sizes of these groups together produces 54.\n\nFind the three wires you need to disconnect in order to divide the components into two separate groups.\nWhat do you get if you multiply the sizes of these two groups together?\n\n--- Part Two ---\n\nYou climb over weather machines, under giant springs, and narrowly avoid a pile of pipes as you find and disconnect the three wires.\n\nA moment after you disconnect the last wire, the big red reset button module makes a small ding noise:\n\nSystem overload resolved!\nPower required is now 50 stars.\n\nOut of the corner of your eye, you notice goggles and a loose-fitting hard hat peeking at you from behind an ultra crucible.\nYou think you see a faint glow, but before you can investigate, you hear another small ding:\n\nPower required is now 49 stars.\n\nPlease supply the necessary stars and\npush the button to restart the system.\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Advent of Code 2024 examples.\n--\n--  Some programs work with both HAC and \"full Ada\" compilers like,\n--  GNAT some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject AoC_2024 is\n\n   for Source_Dirs use\n     (\".\",\n      \"..\",              --  For the AoC_Toolbox package\n      \"../../../src\");   --  GNAT's access to the explicit version of the HAT package.\n      \n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\",\n       \"Fast_Unchecked\");\n\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   type AoC_Styles_Checks_Type is\n      (\"Level_0\",\n       \"Level_1\",\n       \"Level_2\");\n\n   AoC_Styles_Checks : AoC_Styles_Checks_Type := external (\"AoC_Styles_Checks\", \"Level_1\");\n\n   for Main use\n     (\"aoc_2024_25.adb\",\n      \"aoc_2024_24.adb\",\n      \"aoc_2024_23.adb\",\n      \"aoc_2024_22_full_ada.adb\",\n      \"aoc_2024_22.adb\",\n      \"aoc_2024_21.adb\",\n      \"aoc_2024_20.adb\",\n      \"aoc_2024_19.adb\",\n      \"aoc_2024_18.adb\",\n      \"aoc_2024_17.adb\",\n      \"aoc_2024_16.adb\",\n      \"aoc_2024_15.adb\",\n      \"aoc_2024_14.adb\",\n      \"aoc_2024_13.adb\",\n      \"aoc_2024_12.adb\",\n      \"aoc_2024_11.adb\",\n      \"aoc_2024_10.adb\",\n      \"aoc_2024_09.adb\",\n      \"aoc_2024_08.adb\",\n      \"aoc_2024_07.adb\",\n      \"aoc_2024_06.adb\",\n      \"aoc_2024_05.adb\",\n      \"aoc_2024_04.adb\",\n      \"aoc_2024_03.adb\",\n      \"aoc_2024_02.adb\",\n      \"aoc_2024_01.adb\");\n   \n   case AoC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n      when \"Fast_Unchecked\" =>\n         for Object_Dir use \"obj_fast_unchecked\";\n   end case;\n\n   Common_Compiler_Options :=\n     (\"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n      \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n      \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n      \"-gnatf\",   --  Full errors. Verbose details, all undefined references\n      \"-gnatq\",   --  Don't quit, try semantics, even if parse errors\n      \"-gnatQ\");  --  Don't quit, write ali/tree file even if compile errors\n    \n   Style_Checks_1 := \n     (\"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",       --  Style: check x:no extra parens\n      \"-gnatye\",   --  Style: check e:end/exit labels present\n      \"-gnatytc\");     --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   Style_Checks_2 := \n     (\"-gnatye\",       --  Style: check e:end/exit labels present\n      \"-gnaty2\");      --  Style: check indentation\n\n   case AoC_Styles_Checks is\n      when \"Level_0\" => null;\n      when \"Level_1\" => Common_Compiler_Options := Common_Compiler_Options & Style_Checks_1;\n      when \"Level_2\" => Common_Compiler_Options := Common_Compiler_Options & Style_Checks_1 & Style_Checks_2;\n   end case;\n\n   Fast_Options :=\n     (\"-Ofast\", \"-gnatn\", \"-ffunction-sections\");\n     \n   Fast_Unchecked_Options :=\n     (\"-Ofast\", \"-gnatpn\", \"-ffunction-sections\");\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Debug_Options ;\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Options;\n         when \"Fast_Unchecked\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Unchecked_Options;\n      end case;\n   end Compiler;\n\n   Common_Linker_Options :=\n     (\"-g\", \"-Xlinker\",\n      \"--stack=0x20000000,0x200000\");\n     --  ^ Absent that, GNAT-compiled programs using lots of recursion\n     --    die with error code 16#C0000005# (Windows, Access Violation)\n     --    - no Ada exception, no trace-back...\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Linker_Options;\n         when \"Fast\" | \"Fast_Unchecked\" =>\n            for Default_Switches (\"ada\") use Common_Linker_Options & (\"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend AoC_2024;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_01.adb",
    "content": "--  Solution to Advent of Code 2024, Day 1\n------------------------------------------\n--  Historian Hysteria\n--\n--  https://adventofcode.com/2024/day/1\n--  Copy of questions in: aoc_2024_01_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_01 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 6;\n  input_name : constant VString := +\"aoc_2024_01\"; n : constant := 1000;\n\n  type List is array (1 .. n) of Natural;\n\n  pair : array (1 .. 2) of List;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in List'Range loop\n      Get (f, pair (1)(i));\n      Get (f, pair (2)(i));\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Shell_Sort (b : in out List) is\n    i, j, step : Integer;\n    step_size : array (1 .. 4) of Integer;\n    stop : Boolean;\n    temp : Integer;\n  begin\n    step_size (4) := 1;\n    for pass in reverse 1 .. 3 loop\n      step_size (pass) := 2 * step_size (pass + 1);\n    end loop;\n    for pass in 1 .. 4 loop\n      step := step_size (pass);\n      --  Do a straight insertion sort with 'step' as\n      --  an increment instead of 1.\n      i := step + 1;\n      while i <= List'Last loop\n        temp := b (i);\n        j := i;\n        stop := False;\n        while j > step and not stop loop\n          j := j - step;\n          if b (j) > temp then\n            b (j + step) := b (j);\n          else\n            b (j + step) := temp;\n            stop := True;\n          end if;\n        end loop;\n        if not stop then\n          b (1) := temp;\n        end if;\n        i := i + step;\n      end loop;\n    end loop;\n  end Shell_Sort;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Do_Part_1 is\n    score : Natural := 0;\n  begin\n    for i in List'Range loop\n      --  Put (pair(1)(i)); Put_Line (pair(2)(i));\n      score := score + abs (pair (1)(i) - pair (2)(i));\n    end loop;\n    r (part_1) := score;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    score, count, n : Natural := 0;\n    cache : array (1 .. 99_999) of Integer;\n    not_counted : constant := -1;\n  begin\n    for i in List'Range loop\n      cache (pair (1)(i)) := not_counted;\n    end loop;\n    for i in List'Range loop\n      n := pair (1)(i);\n      if cache (n) = not_counted then\n        count := 0;\n        for j in List'Range loop\n          if pair (2)(j) = n then\n            count := count + 1;\n          end if;\n        end loop;\n        cache (n) := count;\n      else\n        count := cache (n);\n      end if;\n      score := score + n * count;\n    end loop;\n    r (part_2) := score;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Shell_Sort (pair (1));\n  Shell_Sort (pair (2));\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 2086478.\n    --  Part 2: validated by AoC: 24941624.\n  end if;\nend AoC_2024_01;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_01.txt",
    "content": "57643   17620\n19062   47340\n11105   16109\n72032   30050\n16289   65967\n42361   35795\n45873   16124\n16167   65832\n57216   47340\n15920   71163\n22534   30837\n38721   64603\n27502   32313\n17094   50986\n84849   67526\n20884   64392\n21987   59516\n39419   98547\n10839   29910\n77870   15917\n94474   57604\n29876   18768\n72281   16109\n52066   21561\n11847   24044\n83711   11404\n47340   29941\n54869   62664\n63495   62664\n87421   46184\n12673   51492\n21401   77546\n13800   70131\n35534   46986\n51304   41199\n51515   39683\n25160   55295\n39133   88509\n68329   62664\n56917   84849\n68841   33033\n27693   78397\n82953   22601\n47353   27226\n70002   59980\n74154   16109\n86034   84849\n95639   62349\n45722   59516\n69049   22317\n51692   17620\n39166   65967\n30495   55388\n81255   17869\n60454   41199\n26224   81511\n74983   16124\n55752   90759\n22465   24501\n57854   22943\n94700   59516\n83099   31049\n26617   32773\n23277   52176\n34125   18754\n61685   11874\n49752   44170\n82839   26115\n28748   62664\n19753   73220\n76703   16124\n41076   60454\n94607   98100\n88668   47340\n56446   90759\n93070   65832\n25427   65524\n51967   16964\n23531   92947\n44724   76864\n32642   60237\n54203   22536\n62977   69799\n31242   64392\n94016   75284\n55953   84849\n35527   83890\n54207   16964\n44027   46184\n82186   60112\n72150   28927\n68617   89252\n57085   65832\n18164   39683\n28818   61894\n94464   96385\n73344   17681\n76429   27054\n25559   84215\n24143   65907\n12888   93195\n33654   52859\n13309   67042\n90824   55187\n42199   61494\n99525   33401\n60919   59516\n14832   74668\n83140   90759\n68116   75402\n35265   16124\n30971   57216\n84947   98547\n35362   15902\n98472   65832\n32851   30050\n47123   23601\n37165   73599\n64938   97672\n39094   16964\n32542   84849\n70739   89107\n59747   65832\n51960   87068\n75826   16109\n96621   92566\n80372   60656\n15595   92864\n17009   59796\n87108   16124\n70344   85636\n12951   89107\n25963   41199\n60994   12246\n26308   96930\n58823   37556\n18153   72254\n20975   11570\n42013   30141\n53539   39683\n40729   63401\n10964   17620\n76208   18768\n55734   12636\n29742   14160\n40999   33033\n61760   47123\n57734   85993\n32323   17620\n53967   71169\n41453   60454\n53895   39683\n99823   30156\n12983   20098\n71421   47829\n76964   33049\n82841   87433\n55517   47340\n75661   17620\n22232   16081\n36803   33033\n83930   32773\n54392   29132\n67783   27226\n78834   34040\n46044   60454\n97734   41199\n16374   82621\n23972   39787\n80360   33654\n48876   34378\n11260   16124\n53596   71313\n60950   65832\n37956   90734\n87063   64392\n66760   90734\n24341   90734\n13907   56662\n39084   64270\n30798   22591\n30370   22943\n57538   93797\n41199   60454\n79187   25199\n43099   18768\n13070   20881\n39307   45484\n89252   40350\n94161   81798\n91119   39683\n97429   39599\n64997   20578\n32145   98547\n13342   90759\n82088   58672\n61898   62664\n72616   78897\n17954   71652\n58825   68383\n44525   30658\n28074   33033\n17636   16124\n94958   61724\n48971   47340\n85361   48120\n82391   68794\n69603   23741\n64066   13582\n65092   45163\n49086   32773\n42231   98547\n56734   81797\n76829   30156\n99378   42745\n59516   22285\n18672   47123\n68792   97672\n46265   17620\n28964   77566\n14875   61068\n95708   23528\n38828   65832\n56799   51315\n40443   92737\n64615   32773\n27557   27226\n89585   76621\n67867   61305\n28621   65979\n88258   32773\n73478   16124\n98662   32773\n38098   90759\n76219   18768\n23664   32773\n70807   82839\n64392   16109\n39683   87325\n47297   91952\n25007   37572\n90841   32773\n82423   60454\n56193   59516\n83332   82839\n17826   59516\n95927   82839\n62664   88503\n33750   27771\n51457   90759\n47908   27341\n67000   30050\n66855   14734\n20055   52372\n60010   16109\n30431   95964\n12321   30156\n53585   88159\n55043   18768\n20000   73383\n28871   41199\n82812   89107\n13060   71616\n70027   36310\n80606   30050\n55151   27226\n63800   64392\n35192   66432\n78917   29589\n92483   32773\n10457   20728\n70963   57216\n67927   91119\n36688   67070\n93141   64392\n93362   16124\n81614   94940\n81186   66565\n56418   60166\n64292   70331\n43290   65832\n10656   27226\n38812   40982\n33000   16124\n18100   17109\n37989   85483\n14064   82711\n14399   16964\n22066   72604\n49658   47123\n29682   59516\n59980   19363\n91466   89107\n70211   30342\n35905   27226\n67755   17620\n75456   10664\n54074   65832\n23976   91119\n22224   80267\n78250   16081\n53819   26866\n99580   53011\n49653   89107\n13703   18768\n39210   33033\n13265   19583\n70869   74044\n42643   64392\n97800   80872\n33668   90759\n62475   21888\n64693   83264\n31715   99185\n83449   13990\n33033   91104\n39765   60517\n93890   60670\n23400   17620\n92189   93768\n63780   16109\n73093   50153\n13323   89107\n69167   61436\n48878   55630\n13718   57216\n27903   94896\n69456   16109\n46468   60454\n52145   30596\n20909   89107\n22536   67083\n80514   43159\n98390   36556\n78956   60454\n23497   55983\n15348   47123\n61890   90734\n89951   31879\n20728   79394\n49303   30713\n30422   57216\n73676   33033\n49698   81919\n76046   17620\n45242   84849\n25389   40202\n32448   47299\n59354   82839\n70423   89252\n89306   65967\n59766   27268\n37037   98547\n65021   18895\n54230   18768\n43969   63446\n50630   65832\n54139   88509\n85677   88746\n47692   37399\n21467   22536\n83644   67594\n21789   97672\n13648   90759\n28017   57216\n74883   49798\n16109   72646\n46184   30050\n36000   44597\n33728   22536\n44888   59516\n11222   30050\n36641   78012\n42426   18768\n93707   90734\n82249   39683\n86185   79158\n63476   45090\n52464   24645\n33497   47340\n51699   31223\n67877   36634\n16955   69854\n49928   61017\n16708   62664\n91134   29644\n24080   98547\n16031   91119\n49022   74628\n88710   44253\n22505   27651\n22483   33033\n10981   76873\n74260   90620\n53783   62664\n67774   16124\n56303   66706\n87017   74124\n25003   57216\n54386   20728\n55011   32773\n35564   45090\n43205   90759\n90317   96125\n65967   57216\n27412   88804\n26888   67612\n50833   83419\n90825   16964\n68203   18108\n51609   69179\n69744   65832\n56356   89107\n89107   54941\n88509   65832\n92237   90734\n44066   36406\n80980   58864\n98957   60659\n22264   41199\n60969   33654\n17620   40115\n90800   93572\n62862   64392\n27780   18768\n66419   60454\n70524   86222\n26486   27226\n72422   98298\n90508   30050\n28259   41199\n14239   39683\n21310   86711\n35507   62664\n77638   83310\n10307   33033\n71173   98232\n39165   57216\n92119   86108\n52470   17765\n18950   42325\n55271   29040\n25924   56949\n55619   20728\n48809   18768\n32300   53100\n60316   16153\n44763   74270\n25666   16964\n81291   67521\n60771   93797\n81653   16964\n67405   89107\n79747   52151\n47382   33033\n29989   34981\n50331   44690\n17848   60454\n89637   18768\n98116   64392\n80694   45090\n95798   10999\n78442   99645\n45090   94611\n23385   62664\n86919   59516\n71255   33033\n82002   97672\n89066   16109\n98896   86008\n27000   64545\n99089   90734\n13394   18768\n20748   89107\n88835   47340\n87101   16109\n61684   82505\n87896   16081\n97799   20728\n63040   62664\n85411   89107\n34131   74658\n65406   83937\n91155   99556\n65832   33674\n81208   55861\n85395   46184\n16926   99827\n35793   30050\n12707   57216\n67126   52814\n92795   88509\n91840   84607\n54768   65833\n52180   17819\n53100   30156\n73239   69810\n49380   49485\n80253   76262\n53209   49131\n11121   33033\n44463   39683\n53271   84849\n69448   76937\n36173   63218\n60547   75774\n54971   27226\n44418   65832\n66775   19905\n71561   21069\n32773   91318\n76204   81715\n98547   16081\n24876   22287\n33855   90759\n28306   16554\n30050   12914\n21242   90734\n19505   14213\n54591   48135\n72512   73973\n10186   72386\n98061   42401\n83084   32773\n38957   53473\n56756   98547\n36706   32773\n82325   47179\n24632   90734\n55788   34600\n21147   25888\n97814   89467\n76627   57216\n83496   45700\n35495   16109\n57929   30156\n44008   37332\n68284   20370\n58203   59516\n33603   91682\n91850   39247\n55632   16124\n48086   33894\n96381   10569\n77170   84849\n39336   85833\n74736   15527\n92977   93797\n74412   47340\n99801   58501\n51368   17620\n68476   27226\n21734   45090\n85160   91119\n67622   80512\n33195   32773\n99282   17620\n40016   59575\n70136   10061\n60848   67727\n79546   47112\n71409   16964\n48029   34780\n75919   45090\n26206   47123\n26139   17620\n98726   47340\n75480   16333\n60703   16081\n56290   16109\n20547   97672\n85264   17620\n72745   41885\n11648   15733\n89927   64392\n41626   22536\n40096   98547\n11676   97594\n38937   27226\n95166   92683\n45499   90759\n44553   19438\n58227   32773\n78021   33033\n31576   78113\n25095   59274\n62956   43830\n87587   48890\n37318   26768\n31960   84849\n44972   30050\n47152   55462\n48034   69405\n99245   57216\n51671   20728\n31412   92094\n19038   53100\n30040   16109\n81022   24270\n28727   89381\n63343   62053\n44062   90734\n52098   20786\n32337   69696\n10627   47340\n86438   91119\n11359   97672\n79827   78893\n50991   73474\n41506   64392\n64427   58282\n30314   38013\n55147   51690\n24076   97672\n55139   30156\n84755   65832\n77418   39683\n65841   83092\n89026   17102\n43842   17620\n69091   92274\n45281   97447\n76721   57216\n85918   30383\n75795   30156\n25664   55704\n97570   15961\n52566   56257\n56772   46184\n66023   70725\n70877   60352\n58489   17620\n97243   16081\n90065   96590\n15509   87622\n16396   64392\n52851   96477\n27226   46960\n90734   16124\n69265   45713\n52153   56385\n62294   56305\n60456   47123\n22359   59516\n72820   22831\n16060   88509\n48347   11949\n93708   16109\n40506   97672\n34923   16152\n82726   16124\n75211   45090\n42580   26606\n55998   60454\n36766   57216\n49855   37173\n95715   64233\n88333   46280\n43573   94103\n58068   43319\n65789   67256\n26337   16081\n41559   39630\n94353   22943\n60210   48776\n31864   81825\n43486   89107\n89008   29137\n40463   22547\n69990   30050\n43940   56443\n77221   18768\n75112   98547\n10957   78948\n74710   12120\n59368   89107\n32133   33654\n75434   72998\n14918   89107\n78742   51635\n47615   59414\n92968   71551\n34542   22943\n38734   20291\n10118   56801\n43713   55518\n82778   90734\n90759   30050\n65951   35684\n60584   97672\n74575   65365\n79698   39683\n25005   97672\n87205   41199\n61821   69895\n91262   36850\n59774   16124\n25663   56501\n59643   18768\n91239   18768\n67918   27226\n90338   27226\n46014   25578\n83831   87690\n61964   47340\n93797   89252\n31368   90759\n25677   59638\n98724   62664\n45567   23553\n58366   44041\n97070   22943\n42402   45061\n30156   39747\n21792   97672\n88704   43711\n86958   65967\n87735   69189\n46436   97038\n67398   89243\n25402   95547\n75281   39683\n10908   56544\n13665   32898\n14289   22943\n78567   19318\n58378   27226\n70508   16670\n27417   79914\n39259   31265\n75173   18768\n67055   58536\n94446   58240\n13538   93924\n47472   98146\n73403   95703\n80112   90734\n53479   39683\n68774   79739\n15947   88002\n98908   95443\n34832   33654\n49962   97672\n37504   59516\n75818   52244\n61492   45090\n46636   36056\n60015   16109\n91286   46184\n37897   91119\n92495   32773\n86458   93797\n39276   61612\n22884   56365\n71464   45090\n32095   87760\n54595   27226\n24423   94229\n22187   91119\n82210   48731\n19488   88509\n65566   68008\n77921   62589\n17295   92247\n91582   45090\n24317   89107\n68159   94508\n81663   79967\n78357   23724\n36492   65832\n53202   85336\n64614   36692\n13683   30156\n46365   82672\n61031   18768\n52374   45090\n24823   97672\n90438   32489\n14871   87616\n65089   20993\n37779   16124\n39308   12698\n32476   80660\n61005   17620\n22943   46184\n87147   89107\n25126   13389\n16978   93342\n60815   72087\n84082   93797\n73857   67867\n18643   64984\n90549   61047\n30337   32773\n62788   84849\n36450   91530\n18667   27226\n31868   17135\n34793   50284\n87706   89107\n24983   76729\n49759   58359\n88262   76480\n75939   64392\n19997   88556\n62343   56462\n45616   97672\n45860   93888\n68344   11535\n55812   68813\n58211   30050\n57040   57926\n60518   32773\n71099   57155\n24428   57216\n54582   90308\n55276   55066\n58848   20728\n75393   97672\n11569   68342\n88739   60454\n92898   83347\n91074   19081\n68506   78420\n28953   64392\n40480   68489\n78476   33654\n52052   90759\n38383   69088\n94501   58424\n11804   92541\n88802   72137\n14159   20700\n31951   25669\n71802   90759\n51736   93797\n40245   33196\n76174   79841\n65410   39683\n77053   79537\n47630   62664\n22202   73334\n67248   27226\n18768   84849\n75554   41199\n91793   16109\n15692   97672\n78398   96505\n64570   60454\n85672   37902\n32952   93797\n72503   46027\n62594   47340\n14375   98105\n98715   68010\n68922   64392\n14526   19785\n47522   65951\n58875   93129\n90570   60939\n36853   47817\n72716   53863\n64202   27240\n18894   93797\n16184   62664\n18595   45090\n68531   45090\n29435   94452\n48615   33033\n90773   97672\n65539   16964\n37091   16124\n85835   90759\n93470   32585\n71460   16320\n67920   93186\n71775   80052\n31403   74944\n68444   89107\n57842   65832\n12734   35998\n14195   41229\n63687   73891\n19494   65967\n28761   70887\n64063   50742\n90511   17620\n47699   90759\n99339   74495\n64610   87080\n30124   39683\n44098   39683\n92946   60454\n63078   71049\n69198   19253\n81067   66283\n27276   62664\n60707   16124\n92750   10833\n15611   93797\n80632   22536\n81434   30050\n31643   89107\n12277   46282\n94027   98547\n65878   46619\n88364   49881\n66635   33033\n70736   46184\n94291   73977\n96756   21223\n74141   98354\n99623   64392\n47960   28999\n67373   91119\n44303   97672\n24370   41607\n41710   47340\n27632   22536\n14584   38508\n12530   20728\n99369   33033\n47344   18768\n69327   16541\n51570   11107\n29199   46184\n16964   61946\n95237   29761\n22379   90759\n85798   41199\n25053   27180\n61660   62664\n41800   95048\n16124   35616\n63219   28270\n81668   39683\n75520   79737\n99726   16081\n38012   93797\n38268   13109\n92610   26416\n27885   91119\n21596   24011\n67364   97672\n75268   98704\n91852   21659\n62389   84076\n10196   53612\n92074   47123\n29408   31697\n21662   32940\n13219   89107\n13114   21512\n48531   31805\n71249   20665\n67554   79621\n86260   59516\n87497   70849\n16230   46623\n38758   90759\n84298   30050\n84242   16124\n95389   86465\n77666   73820\n79652   44579\n83324   62664\n53778   57216\n43407   83484\n99150   59782\n16081   29507\n73980   17620\n63828   58641\n47913   59516\n67136   97390\n97672   90734\n98377   75087\n36910   16109\n61140   93797\n69501   96356\n91030   45251\n37044   16124\n71591   39683\n87886   64392\n51030   65967\n12076   32551\n82030   60454\n28642   95851\n45176   73711\n44774   92783\n35230   73053\n85460   78500\n95631   66420\n77427   84991\n26839   90759\n98740   64392\n55636   51814\n14543   16109\n71485   61007\n78254   68306\n28704   60454\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_01_questions.txt",
    "content": "--- Day 1: Historian Hysteria ---\n\nThe Chief Historian is always present for the big Christmas sleigh launch, but nobody has seen him in months! Last anyone heard, he was visiting locations that are historically significant to the North Pole; a group of Senior Historians has asked you to accompany them as they check the places they think he was most likely to visit.\n\nAs each location is checked, they will mark it on their list with a star. They figure the Chief Historian must be in one of the first fifty places they'll look, so in order to save Christmas, you need to help them get fifty stars on their list before Santa takes off on December 25th.\n\nCollect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!\n\nYou haven't even left yet and the group of Elvish Senior Historians has already hit a problem: their list of locations to check is currently empty. Eventually, someone decides that the best place to check first would be the Chief Historian's office.\n\nUpon pouring into the office, everyone confirms that the Chief Historian is indeed nowhere to be found. Instead, the Elves discover an assortment of notes and lists of historically significant locations! This seems to be the planning the Chief Historian was doing before he left. Perhaps these notes can be used to determine which locations to search?\n\nThroughout the Chief's office, the historically significant locations are listed not by name but by a unique number called the location ID. To make sure they don't miss anything, The Historians split into two groups, each searching the office and trying to create their own complete list of location IDs.\n\nThere's just one problem: by holding the two lists up side by side (your puzzle input), it quickly becomes clear that the lists aren't very similar. Maybe you can help The Historians reconcile their lists?\n\nFor example:\n\n3   4\n4   3\n2   5\n1   3\n3   9\n3   3\n\nMaybe the lists are only off by a small amount! To find out, pair up the numbers and measure how far apart they are. Pair up the smallest number in the left list with the smallest number in the right list, then the second-smallest left number with the second-smallest right number, and so on.\n\nWithin each pair, figure out how far apart the two numbers are; you'll need to add up all of those distances. For example, if you pair up a 3 from the left list with a 7 from the right list, the distance apart is 4; if you pair up a 9 with a 3, the distance apart is 6.\n\nIn the example list above, the pairs and distances would be as follows:\n\n    The smallest number in the left list is 1, and the smallest number in the right list is 3. The distance between them is 2.\n    The second-smallest number in the left list is 2, and the second-smallest number in the right list is another 3. The distance between them is 1.\n    The third-smallest number in both lists is 3, so the distance between them is 0.\n    The next numbers to pair up are 3 and 4, a distance of 1.\n    The fifth-smallest numbers in each list are 3 and 5, a distance of 2.\n    Finally, the largest number in the left list is 4, while the largest number in the right list is 9; these are a distance 5 apart.\n\nTo find the total distance between the left list and the right list, add up the distances between all of the pairs you found. In the example above, this is 2 + 1 + 0 + 1 + 2 + 5, a total distance of 11!\n\nYour actual left and right lists contain many location IDs. What is the total distance between your lists?\n\n--- Part Two ---\n\nYour analysis only confirmed what everyone feared: the two lists of location IDs are indeed very different.\n\nOr are they?\n\nThe Historians can't agree on which group made the mistakes or how to read most of the Chief's handwriting, but in the commotion you notice an interesting detail: a lot of location IDs appear in both lists! Maybe the other numbers aren't location IDs at all but rather misinterpreted handwriting.\n\nThis time, you'll need to figure out exactly how often each number from the left list appears in the right list. Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of times that number appears in the right list.\n\nHere are the same example lists again:\n\n3   4\n4   3\n2   5\n1   3\n3   9\n3   3\n\nFor these example lists, here is the process of finding the similarity score:\n\n    The first number in the left list is 3. It appears in the right list three times, so the similarity score increases by 3 * 3 = 9.\n    The second number in the left list is 4. It appears in the right list once, so the similarity score increases by 4 * 1 = 4.\n    The third number in the left list is 2. It does not appear in the right list, so the similarity score does not increase (2 * 0 = 0).\n    The fourth number, 1, also does not appear in the right list.\n    The fifth number, 3, appears in the right list three times; the similarity score increases by 9.\n    The last number, 3, appears in the right list three times; the similarity score again increases by 9.\n\nSo, for these example lists, the similarity score at the end of this process is 31 (9 + 4 + 0 + 0 + 9 + 9).\n\nOnce again consider your left and right lists. What is their similarity score?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_02.adb",
    "content": "--  Solution to Advent of Code 2024, Day 2\n------------------------------------------\n--  Red-Nosed Reports\n--\n--  https://adventofcode.com/2024/day/2\n--  Copy of questions in: aoc_2024_02_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_02 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_02\";\n\n  r : array (Part_Type) of Integer;\n\n  data : array (1 .. 100) of Integer;\n  last : Natural := 0;\n\n  function Check_with_Hole (hole : Natural) return Boolean is\n    cols : Natural := 0;\n    i, i1, d1, d2 : Integer := 0;\n  begin\n    for col in 1 .. last loop\n      if col /= hole then\n        cols := cols + 1;\n        i1 := i;\n        i := data (col);\n        d2 := d1;\n        d1 := i - i1;\n        if cols >= 2 and then abs d1 not in 1 .. 3 then\n          return False;\n        end if;\n        if cols >= 3 and then d1 * d2 < 0 then\n          return False;\n        end if;\n      end if;\n    end loop;\n    return True;\n  end Check_with_Hole;\n\n  procedure Read_Data is\n    f : File_Type;\n    is_safe_part_2 : Boolean;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      last := last + 1;\n      Get (f, data (last));\n\n      if End_Of_Line (f) or End_Of_File (f) then\n        if Check_with_Hole (0) then\n          --  Report is safe without removing any level.\n          r (part_1) := r (part_1) + 1;\n          r (part_2) := r (part_2) + 1;\n        else\n          is_safe_part_2 := False;\n          for c in 1 .. last loop\n            if Check_with_Hole (c) then\n              is_safe_part_2 := True;\n              exit;\n            end if;\n          end loop;\n          if is_safe_part_2 then\n            r (part_2) := r (part_2) + 1;\n          end if;\n        end if;\n        last := 0;  --  Clear data (report).\n      end if;\n\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 332\n    --  Part 2: validated by AoC: 398\n  end if;\nend AoC_2024_02;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_02.txt",
    "content": "48 51 52 53 52\n86 87 88 91 91\n22 25 28 31 32 36\n65 66 68 69 71 72 75 82\n39 42 41 44 47\n20 21 22 19 20 22 23 22\n25 26 27 29 31 34 33 33\n54 57 59 61 58 59 60 64\n17 19 20 22 25 26 24 31\n86 88 90 91 92 92 93 95\n23 25 25 28 26\n56 57 59 60 61 61 62 62\n73 75 76 76 79 83\n10 13 16 16 18 21 23 30\n43 45 49 52 55 58 59 61\n69 72 76 77 75\n6 9 11 14 18 18\n72 74 77 81 84 86 87 91\n18 19 22 26 29 32 39\n2 5 8 13 16 17\n67 70 72 79 78\n17 18 23 26 26\n68 70 73 79 82 86\n71 72 73 79 81 86\n14 13 14 17 20 22 25 27\n70 67 70 71 74 71\n84 83 84 87 88 88\n29 27 30 31 32 36\n80 78 79 80 82 87\n45 42 44 46 49 46 47 49\n41 38 39 41 38 41 42 41\n69 66 64 65 65\n87 86 89 91 89 92 96\n30 29 30 32 29 32 37\n83 80 80 83 86 87 89 90\n56 55 55 57 56\n50 47 49 51 51 54 54\n8 7 7 10 11 15\n15 14 14 15 16 18 21 26\n24 21 25 28 31 33 35\n36 34 36 37 41 38\n43 40 44 46 46\n87 84 86 90 94\n34 31 34 36 40 41 48\n57 55 57 60 66 68 71 73\n42 41 46 48 50 49\n48 46 53 56 56\n86 83 85 87 92 96\n67 64 70 72 78\n56 56 57 58 61 63\n54 54 55 57 59 57\n73 73 75 77 79 81 81\n30 30 31 33 36 40\n64 64 65 66 68 70 73 80\n55 55 53 55 58 60 63\n80 80 77 80 83 86 85\n55 55 56 59 58 59 61 61\n31 31 32 30 34\n38 38 37 40 46\n75 75 76 79 81 81 83 86\n70 70 71 71 72 69\n13 13 15 18 18 21 21\n22 22 25 28 28 32\n72 72 75 76 76 83\n65 65 69 72 75 76 77 80\n43 43 46 48 52 51\n21 21 22 24 28 30 30\n55 55 59 61 63 66 69 73\n13 13 16 17 21 27\n61 61 64 66 68 74 76\n73 73 74 79 80 79\n22 22 25 27 30 37 37\n69 69 70 75 79\n80 80 86 89 95\n29 33 35 36 39 42 45\n62 66 69 71 72 75 78 77\n31 35 36 37 38 38\n53 57 60 62 65 68 69 73\n45 49 50 51 53 54 55 61\n37 41 43 41 42 44 47 49\n87 91 93 90 91 93 92\n21 25 26 23 26 28 28\n10 14 13 15 18 21 25\n13 17 20 22 23 20 23 30\n72 76 76 77 78\n19 23 26 26 24\n80 84 84 85 85\n39 43 46 46 50\n9 13 15 16 16 18 24\n81 85 88 90 93 97 98\n37 41 43 47 45\n24 28 32 35 36 39 39\n40 44 45 49 51 52 56\n42 46 50 53 56 63\n4 8 14 16 17 20 22 23\n30 34 40 42 40\n42 46 47 48 50 57 57\n69 73 78 81 85\n41 45 47 53 59\n57 63 64 65 68\n78 83 86 88 90 92 90\n38 43 46 49 50 50\n15 20 21 23 26 29 33\n22 27 29 30 36\n69 74 76 79 82 84 83 86\n7 14 11 14 13\n19 26 25 28 28\n67 74 75 77 76 80\n60 67 68 66 69 71 76\n76 83 85 86 88 88 89\n78 84 84 85 87 90 91 89\n15 21 21 23 25 27 28 28\n63 69 69 71 73 74 78\n57 64 64 65 72\n39 46 47 50 51 55 56 59\n80 86 89 91 95 97 94\n4 11 15 16 16\n5 11 13 17 21\n56 61 64 66 67 71 73 78\n9 14 17 20 27 30 32\n80 86 87 92 91\n64 70 72 75 82 82\n23 30 33 35 42 46\n54 61 64 67 72 79\n90 88 85 84 87\n96 94 92 90 87 84 84\n57 56 54 52 50 49 48 44\n51 49 46 43 42 37\n25 22 19 21 20 17 14 13\n55 53 52 49 51 50 53\n6 4 7 4 4\n20 19 16 17 16 14 10\n79 76 73 70 73 71 65\n94 91 91 88 87 84\n67 65 63 62 59 59 62\n18 16 14 14 11 11\n55 53 51 50 47 46 46 42\n39 37 34 33 33 27\n54 51 47 46 43\n31 30 26 25 26\n43 40 39 35 34 34\n98 97 94 90 89 86 82\n79 78 76 72 70 68 61\n42 41 40 37 34 27 24\n30 28 25 22 15 17\n80 78 76 69 68 67 67\n57 54 49 48 46 42\n82 81 80 74 73 70 68 61\n12 13 11 9 7\n44 46 45 43 45\n75 78 77 75 75\n66 67 64 63 59\n84 85 82 81 78 76 75 70\n57 58 60 58 55 54 53 52\n52 53 54 52 55\n82 85 83 80 81 79 77 77\n25 27 26 23 24 23 20 16\n53 56 53 50 51 46\n87 90 90 87 84 82\n14 17 14 13 13 15\n84 87 86 86 86\n24 26 25 25 23 20 17 13\n26 29 28 27 26 23 23 16\n74 75 71 68 66 64\n96 97 94 91 87 85 87\n56 59 58 54 54\n65 67 66 62 58\n67 70 66 65 63 62 57\n84 86 83 76 73 71\n58 59 56 53 50 45 48\n86 87 82 79 79\n28 31 29 24 20\n84 86 81 80 74\n90 90 89 86 83 80 79\n8 8 7 5 4 3 5\n29 29 28 26 24 23 20 20\n41 41 38 35 34 31 30 26\n54 54 53 50 45\n82 82 79 78 77 79 76\n96 96 93 90 88 89 90\n65 65 64 62 65 64 64\n11 11 13 10 9 8 6 2\n34 34 37 35 30\n8 8 8 7 6 5\n38 38 38 36 37\n16 16 16 14 13 10 10\n16 16 14 14 12 8\n70 70 67 65 65 59\n51 51 50 46 43 41\n45 45 43 39 41\n75 75 73 70 68 67 63 63\n83 83 81 77 75 71\n68 68 64 62 59 52\n99 99 97 92 91 90\n47 47 41 38 41\n66 66 64 62 61 56 56\n94 94 87 84 80\n73 73 71 64 62 60 53\n18 14 13 12 10 9\n84 80 78 76 74 71 69 71\n87 83 82 80 77 74 74\n54 50 47 45 42 40 38 34\n24 20 18 15 9\n60 56 53 55 52\n51 47 46 47 50\n46 42 39 37 38 38\n54 50 48 47 50 46\n77 73 76 74 73 71 69 63\n53 49 47 46 45 45 44\n19 15 13 13 11 8 6 7\n46 42 40 40 39 36 36\n96 92 92 91 87\n27 23 23 22 19 14\n93 89 87 84 83 79 76 75\n62 58 57 54 50 53\n98 94 91 87 86 86\n74 70 67 63 60 56\n82 78 75 71 69 68 65 59\n51 47 45 44 37 36\n72 68 66 60 59 60\n62 58 57 52 50 50\n35 31 24 21 17\n72 68 65 62 57 52\n94 87 86 84 83 82\n99 94 91 90 88 86 87\n40 35 32 31 30 30\n95 90 88 87 83\n90 84 81 78 76 74 71 66\n62 57 56 58 57 56 53\n29 23 24 22 25\n87 81 78 79 79\n16 9 8 9 8 4\n23 16 19 16 14 13 7\n80 73 70 67 67 65\n88 81 79 77 75 75 78\n25 19 19 18 16 16\n76 69 68 67 66 66 64 60\n26 19 18 17 17 10\n26 21 19 15 13\n47 40 36 35 37\n92 87 83 81 79 77 76 76\n42 35 34 30 28 27 23\n31 24 21 17 16 13 11 6\n73 67 66 63 61 59 53 52\n58 52 50 45 44 46\n31 24 17 14 11 11\n32 26 21 20 17 14 10\n45 40 34 33 31 28 21\n61 62 64 67 70 72 70\n29 30 32 34 34\n89 90 92 93 97\n26 28 31 32 35 42\n88 90 87 88 91 93 96 99\n68 71 74 76 77 74 71\n83 85 84 85 85\n57 58 59 57 61\n27 30 32 35 33 34 37 44\n59 60 63 63 66 67\n76 78 79 82 84 84 85 82\n44 47 50 50 53 54 55 55\n23 25 25 28 32\n11 14 17 17 20 27\n49 51 54 55 56 60 63\n52 55 57 61 60\n35 36 38 42 44 44\n9 11 15 18 19 21 25\n78 81 82 86 89 95\n54 56 61 63 66 69\n86 89 96 99 96\n31 34 35 37 38 44 45 45\n70 71 76 78 81 82 83 87\n29 31 33 38 39 40 41 48\n68 66 68 69 70\n84 81 82 84 87 89 87\n72 70 72 75 75\n18 15 17 18 22\n8 7 10 12 13 16 19 24\n7 6 9 6 7\n61 58 60 63 61 63 62\n52 49 52 55 56 54 56 56\n77 76 77 79 76 78 82\n72 69 66 67 74\n35 34 35 37 37 38\n59 58 58 59 56\n51 49 49 52 52\n49 48 48 51 54 56 60\n41 40 42 43 43 46 49 56\n81 79 83 85 86 89 90\n93 92 96 97 99 97\n35 32 33 34 38 38\n4 2 3 7 8 11 14 18\n45 42 46 47 50 57\n56 53 54 57 64 65\n67 66 68 69 72 79 82 80\n45 44 47 50 52 59 61 61\n14 13 20 23 27\n51 49 50 53 54 60 62 69\n80 80 82 84 87\n71 71 73 75 76 79 81 78\n39 39 42 45 45\n68 68 70 73 74 78\n68 68 70 72 79\n89 89 88 91 92 93\n89 89 90 87 89 91 94 92\n21 21 22 24 22 23 24 24\n46 46 47 44 45 48 50 54\n17 17 15 16 17 23\n79 79 79 82 83 85\n44 44 46 46 47 48 45\n96 96 96 98 98\n3 3 3 6 8 12\n5 5 8 8 11 14 21\n78 78 81 85 88 90\n3 3 7 10 12 15 13\n15 15 19 20 22 23 26 26\n9 9 10 14 17 21\n13 13 17 18 19 25\n14 14 19 20 21\n86 86 91 94 95 93\n57 57 58 63 63\n1 1 4 7 12 15 16 20\n60 60 63 66 71 76\n9 13 16 19 21 24\n52 56 58 61 63 64 62\n77 81 84 86 89 89\n9 13 14 17 20 21 25\n60 64 65 67 68 69 70 76\n30 34 33 36 39 42 45 46\n88 92 93 96 95 94\n1 5 4 5 6 6\n57 61 63 66 69 71 68 72\n51 55 53 54 61\n20 24 25 25 28 31 34 37\n66 70 70 72 70\n91 95 96 96 96\n53 57 59 62 64 64 68\n4 8 10 10 12 19\n43 47 51 53 55 58\n49 53 55 56 60 61 64 62\n28 32 36 39 39\n79 83 84 88 90 94\n48 52 54 56 60 66\n71 75 76 81 82\n39 43 50 52 50\n39 43 44 50 53 56 59 59\n40 44 46 47 50 56 60\n42 46 49 55 60\n21 27 29 31 32 33 34\n27 32 33 36 37 34\n68 75 76 78 78\n3 10 11 14 17 18 19 23\n5 10 11 13 16 22\n17 24 26 28 30 32 30 31\n30 36 37 35 34\n34 40 38 40 40\n84 90 91 93 94 92 96\n1 6 3 4 7 8 10 16\n58 63 66 68 70 73 73 74\n61 68 68 70 71 70\n3 10 12 12 13 13\n8 14 16 16 17 20 21 25\n76 82 85 85 86 92\n3 8 10 13 14 15 19 21\n47 52 53 56 60 58\n85 91 92 93 94 98 99 99\n74 80 81 82 83 87 90 94\n77 83 87 89 90 95\n54 59 61 63 66 73 74 77\n41 48 49 56 54\n68 74 77 80 87 87\n13 18 24 26 30\n15 20 23 26 33 36 43\n40 38 35 32 30 28 30\n56 53 52 50 47 45 42 42\n93 92 91 90 89 85\n22 19 16 14 12 9 4\n40 37 34 33 31 32 30 28\n37 34 35 33 31 32\n61 58 61 60 57 57\n19 17 14 11 13 11 8 4\n85 84 81 80 83 81 79 74\n17 15 15 13 12 11 10 9\n76 74 73 73 71 68 69\n22 20 18 17 17 14 11 11\n75 73 71 71 67\n94 91 90 90 87 86 84 77\n29 26 22 20 19\n62 61 59 58 56 52 55\n75 73 70 68 64 64\n23 20 17 13 12 8\n79 76 75 72 70 66 59\n39 36 34 31 24 21\n36 35 34 28 25 22 25\n80 78 77 76 73 68 68\n22 19 17 15 10 8 4\n80 78 76 71 68 67 61\n81 83 82 79 77 75 74 71\n27 30 28 25 22 19 18 19\n16 18 16 15 14 12 12\n51 53 50 48 44\n51 54 52 49 43\n15 16 14 17 15 13 11 8\n68 69 72 71 68 67 70\n19 22 23 21 20 20\n16 18 16 19 16 12\n38 40 38 35 36 33 30 23\n76 78 75 74 74 71 68\n19 21 21 19 16 14 17\n59 60 60 59 58 58\n33 35 33 31 31 28 26 22\n32 35 35 33 27\n57 58 54 52 49 46 43 40\n34 35 34 30 29 26 28\n52 55 52 48 48\n49 50 48 45 44 40 38 34\n40 42 39 37 35 31 30 23\n74 75 73 70 67 64 58 55\n15 18 16 11 9 10\n36 37 36 34 32 31 25 25\n81 82 80 73 69\n89 91 88 86 79 76 69\n20 20 17 16 15\n85 85 84 82 81 78 79\n63 63 62 60 59 59\n87 87 84 81 77\n36 36 35 33 32 31 25\n62 62 64 61 60 57 55\n58 58 55 58 61\n36 36 35 32 35 35\n36 36 34 32 33 29\n93 93 92 93 87\n33 33 30 30 27\n88 88 87 86 86 87\n95 95 92 92 92\n35 35 35 32 28\n59 59 56 56 49\n69 69 67 63 62 61\n14 14 10 9 7 6 3 5\n72 72 70 69 65 64 64\n73 73 72 69 65 62 61 57\n47 47 46 42 36\n65 65 64 61 58 52 50\n37 37 30 28 26 28\n89 89 87 82 82\n19 19 17 14 7 6 2\n24 24 22 21 15 8\n44 40 39 38 35\n72 68 65 64 67\n46 42 39 38 36 33 32 32\n88 84 81 80 78 77 73\n90 86 83 80 79 76 70\n49 45 42 39 41 40\n95 91 90 91 92\n34 30 31 30 27 27\n46 42 41 44 41 40 36\n84 80 77 78 73\n29 25 25 22 21 20 19 16\n79 75 75 73 71 74\n64 60 58 55 55 54 51 51\n83 79 77 74 74 72 71 67\n86 82 79 79 77 75 69\n44 40 36 33 30 28 27\n52 48 47 43 40 43\n38 34 30 27 25 25\n40 36 33 29 26 22\n67 63 61 59 55 49\n94 90 87 82 79 78 75\n48 44 42 37 35 34 37\n61 57 54 47 45 45\n94 90 87 82 78\n60 56 53 50 43 38\n88 81 78 75 74 71\n98 91 90 89 88 91\n92 85 83 81 79 77 74 74\n30 23 20 19 17 13\n37 32 30 27 25 24 19\n66 59 57 56 57 55 54\n90 84 83 86 85 83 84\n16 10 9 12 11 10 10\n68 63 60 57 58 55 51\n91 86 83 84 79\n36 29 29 27 26\n49 44 44 42 44\n87 82 79 76 76 73 73\n48 41 38 38 36 33 32 28\n23 17 14 13 10 10 4\n80 74 70 68 65\n64 58 57 53 52 51 52\n25 20 17 14 13 9 8 8\n47 40 37 33 32 28\n76 69 65 64 63 60 57 52\n40 35 34 27 26 23 22\n24 19 18 15 12 6 8\n73 66 64 61 58 51 51\n98 91 86 84 82 81 77\n68 62 61 54 51 48 41\n24 28 32 33 35 38 40 40\n10 10 12 10 13 16\n95 92 90 86 84 82 80 81\n33 37 40 44 42\n83 80 78 77 73 70\n65 71 72 75 76 79 80 85\n11 6 4 3 2 1\n62 66 69 70 73 75\n57 60 62 69 70 73 74 80\n58 61 58 54 54\n92 93 92 89 87 86 86\n28 32 36 37 40 44\n38 40 40 42 40\n83 77 76 73 68 66 63 60\n40 41 44 46 48 48\n91 87 84 87 85 85\n1 1 8 10 8\n9 9 10 14 16 21\n91 92 93 96 97 94 95 95\n45 42 45 47 50 54\n45 50 51 52 53 55 58 56\n26 23 27 28 31 33 35 35\n86 89 88 87 86 84 77\n22 22 24 25 26 29 30 36\n33 34 38 39 40 41 42 41\n45 44 45 47 47 49 50 50\n42 39 38 34 33 31 25\n11 10 9 7 2 1 1\n18 17 16 10 9 7\n51 46 42 39 38 37 34\n42 43 43 41 34\n44 42 46 49 47\n28 24 21 19 20 17 11\n11 15 17 20 20 25\n78 72 69 63 62 61 60 60\n40 44 47 49 50 50 53\n17 22 25 28 32 29\n38 34 33 33 34\n80 78 76 76 76\n69 65 64 59 56 55 55\n3 8 10 12 15 19 21 21\n4 1 1 3 5 7 8 11\n97 97 96 93 91 88 85 82\n26 27 34 35 33\n57 57 58 61 63 70 72 76\n20 22 20 21 20 17 16 16\n59 63 61 62 64 67 68 72\n37 39 37 39 42 44 46 47\n39 33 32 29 28 24 24\n52 46 43 42 39 36 38 38\n76 73 72 71 73\n44 41 44 47 51 52 57\n46 43 40 37 31\n52 52 52 54 60\n24 31 32 32 34 35\n20 20 23 26 27 27 29 31\n41 43 44 46 49 53\n13 19 19 22 25 31\n62 58 57 55 53 56 57\n53 51 54 54 58\n79 75 71 69 69\n33 33 31 29 28 25 22 22\n84 80 73 70 68 67 65 61\n42 40 41 43 49 50 52 53\n23 23 25 27 29 31 33\n21 22 18 16 14 8\n97 93 92 93 91 90\n78 82 88 90 90\n58 52 49 51 48 47 40\n75 75 78 76 71\n29 28 26 24 18 16 14 7\n51 55 52 54 59\n23 26 21 19 22\n36 36 36 37 39 37\n76 70 69 69 66 65 63\n65 69 71 72 73 72 72\n41 41 40 34 32 30 24\n48 44 41 39 37\n85 83 86 89 90 90\n73 79 82 83 86 88 91 95\n2 7 8 12 14 17 19 21\n5 5 6 8 9 12 12\n63 63 64 71 74 77 77\n18 16 18 19 25 27 29 34\n77 77 74 73 70 68 70\n7 11 16 19 16\n27 26 33 36 37 37\n44 42 41 39 41 38\n94 95 94 93 86 85 83\n77 77 78 75 78 78\n83 79 78 78 75\n30 32 31 25 22 21 20 14\n13 16 15 13 10 6\n17 21 23 26 32 33\n48 52 49 50 53\n92 89 87 84 82 81 81\n68 64 62 56 54 51 54\n41 43 40 37 35\n34 30 29 27 30 26\n31 28 29 28 30 35\n22 24 25 26 28 29 32 31\n62 65 61 58 55 53 49\n67 74 78 80 82 85 88 93\n23 21 22 24 24 23\n93 90 88 85 85 83 78\n56 62 61 64 65 70\n54 61 62 63 65 68 66 66\n84 81 80 76 75 72 69 65\n71 71 70 67 68 68\n33 33 35 38 41 45 48 49\n32 29 35 36 37 40 37\n52 58 61 62 62 60\n21 18 18 21 26\n81 81 83 87 87\n79 79 78 79 82 83 86 84\n94 94 91 88 87 85 82 75\n92 88 87 85 83 81 78 78\n30 30 28 27 26 26 23 26\n40 36 32 30 29\n59 59 62 65 65 66 66\n39 46 49 50 50 50\n13 13 13 11 8\n1 3 6 7 10 7 10 14\n76 77 74 71 71 68 70\n30 27 29 26 28\n95 95 94 90 86\n35 36 34 32 29 24 22 18\n24 27 28 31 34 36 35 34\n46 46 48 47 54\n81 74 74 73 72 68\n54 52 53 57 59 60 63 66\n41 39 42 41 37\n31 29 32 30 32 32\n77 73 70 63 58\n19 16 18 23 26 30\n15 18 19 17 20 26\n26 30 32 36 37\n44 43 46 48 47 51\n78 80 83 84 85 92\n4 9 11 12 13 15 17\n60 61 63 67 70 72 72\n41 37 36 36 32\n43 41 39 37 35 30 32\n21 25 26 31 35\n21 22 23 24 31 31\n81 86 93 96 95\n89 89 92 95 99 98\n63 62 65 63 65 67 66\n68 62 59 60 59 56 53 49\n26 27 25 22 19 13 12 12\n86 89 88 84 82 80\n19 19 20 27 30 32 37\n56 59 61 63 63 65 68 72\n64 71 74 73 74 76 79 83\n17 11 9 7 6 1 4\n25 19 18 16 14 12 8 2\n85 81 78 77 73\n25 25 23 21 17 20\n52 51 49 47 44 42 38\n60 56 53 53 52 52\n21 23 25 23 20 23\n21 21 18 14 12 10 7\n24 26 24 21 18 18 15 14\n73 68 66 64 62 58\n46 49 56 58 60 62 66\n47 54 56 58 58\n33 33 32 35 31\n91 86 84 83 81 84\n6 8 9 10 12 18 21 22\n57 53 52 49 44\n82 78 77 77 70\n42 43 42 42 38\n67 65 64 62 60\n91 93 94 95 97 99\n85 86 87 88 91 94\n36 34 32 31 28 25\n23 22 20 18 16 13 10 7\n88 91 94 96 97\n92 93 95 96 97\n23 24 26 29 32 35\n94 91 89 88 86\n45 44 41 40 37 36 34 32\n98 95 92 89 86 84\n74 71 69 68 65 64 63 60\n24 26 27 29 30 31\n23 20 18 17 16 15 13 11\n92 91 89 88 85 83 81 80\n86 89 91 94 96\n37 36 34 33 32 31\n10 12 15 17 19 22 23\n55 53 50 47 46 43 42\n22 19 16 13 12 10 8 7\n36 38 41 44 45 48\n39 37 36 34 32\n78 80 81 82 85 87 89\n57 58 59 60 63\n72 69 67 66 64\n71 74 76 77 80 81 83 86\n39 40 43 44 47 48 51\n38 37 34 31 29 26 25 23\n4 7 9 10 12\n30 28 26 25 24 22 21\n24 25 28 30 31 32\n49 47 46 44 43 41 40\n45 48 49 50 51 52 54\n43 45 48 49 50 53 55\n64 61 59 57 55 54 52 51\n40 41 42 45 47 50 51 52\n43 41 39 37 36 34\n69 68 65 64 61 60\n4 7 9 12 13\n35 34 33 32 30 28 25\n55 54 53 51 48\n59 61 62 65 66 67 70 71\n81 80 77 76 75 72\n86 85 83 80 78 76 75 73\n94 92 91 89 88\n95 93 92 90 88 85 82 80\n73 75 77 78 79\n43 41 38 37 35 34 32\n15 16 17 20 21 24\n28 27 24 23 20 17 14\n60 57 54 53 50 47 44\n74 72 70 68 66 63 60\n60 61 63 64 67 70 72 73\n77 78 79 82 85 87\n24 21 20 18 17 16 14\n35 34 33 31 28 27\n29 28 26 25 23\n29 31 32 33 36 37 40 42\n59 62 65 67 69\n70 68 65 63 61 58\n66 69 72 75 77 78 79 81\n97 95 93 92 91\n46 45 44 42 39 37 36 35\n46 44 43 41 38 35\n17 14 13 12 9 6 5\n6 9 10 12 13\n27 24 23 22 19 17 16 15\n78 76 75 72 69 66 65\n11 10 8 7 5\n66 68 69 70 71 73 74\n82 80 79 78 75 72 71 68\n99 96 94 91 89\n57 55 53 51 48 46 43 42\n10 11 13 16 19\n37 40 41 43 46 48 51\n5 6 7 8 9 12\n83 84 87 88 91 94 96 98\n76 75 74 72 71 69 68\n11 14 16 17 20\n48 47 45 42 41 39 37 34\n11 14 15 17 18 19\n64 61 59 56 53 51 50\n68 66 63 62 61\n24 26 27 30 31 34 37 38\n71 73 75 78 80 82 85\n37 39 40 41 42 44 45 48\n22 23 25 26 28 31 32\n37 34 32 31 28\n26 27 30 32 33\n43 44 47 49 52 54 55\n49 46 45 44 43 42\n94 92 91 89 86 83 82\n31 32 34 35 36 37 40 43\n95 94 91 90 88 86 85\n31 33 36 37 40 43 44 45\n75 72 71 70 69\n78 75 72 71 69 66 65 64\n53 51 48 46 44 43\n64 63 62 60 59\n39 42 45 48 49 52 55 56\n91 88 86 84 82 80\n12 15 18 20 21 22 25 26\n41 39 38 37 35 33 31 30\n44 41 40 39 36\n14 16 19 22 25\n56 57 59 62 64\n99 97 95 94 92 91 89 87\n83 81 79 77 76 73\n52 54 56 58 59 61 63\n47 49 51 52 54 55 58\n18 21 22 23 26 27 28 29\n39 41 43 45 46 48 50\n44 43 42 41 38 36\n76 73 70 68 66 63 62\n37 34 32 31 28 25\n40 38 37 34 32 29\n58 55 53 50 48 46\n39 36 33 32 30 27\n43 44 45 47 48\n23 26 27 29 32 33 34\n90 87 85 83 81 80 78\n19 20 21 23 24 27\n76 75 73 72 71\n83 82 79 77 75 73 72\n19 17 15 13 11\n72 70 69 68 65 63 60\n56 54 51 48 46 44\n52 51 48 46 43 40\n33 32 31 28 27 24 21\n11 10 8 6 5\n92 89 87 86 84 81 79\n86 87 89 91 93 95\n59 61 64 67 68 69 72 75\n28 31 32 35 36 39 41\n86 89 90 93 94 96\n76 79 82 83 86 87 88\n29 27 26 23 21 20\n51 53 54 56 58 61 62 65\n77 78 81 83 84 87 88\n38 40 41 42 44 47\n47 45 44 43 41\n56 59 62 64 67 70 71\n9 11 14 16 19 20\n29 28 27 24 21 20\n30 27 25 23 20 19 16 13\n84 83 82 79 77\n46 49 50 53 54 55 56\n21 24 25 27 29 32 33\n14 15 16 18 20\n85 82 79 78 77 76 75 73\n63 60 59 57 55\n32 34 37 40 41 44 45 48\n53 56 58 59 61\n12 11 9 8 5 4 3\n84 81 78 77 76 75 73 72\n44 43 42 39 37\n76 73 70 68 67\n86 89 91 93 94 97 99\n77 80 81 82 85\n19 16 13 11 9 8 5\n19 22 24 27 30\n18 20 23 24 26\n64 66 68 69 72 74 77 78\n78 75 73 72 70 67 65 64\n37 38 41 43 46 48\n36 35 34 31 28 26 24 21\n27 30 31 34 35 37 39 41\n80 83 84 86 89\n61 64 66 69 70\n50 53 54 57 60 61 62 63\n57 60 63 66 69 70 73\n60 57 54 52 49 48 45 43\n48 46 43 41 39 37 35 33\n21 22 23 24 26\n64 65 68 69 71 74\n46 49 50 51 52 54 56\n20 18 16 15 14 13 11 9\n34 32 29 27 24 21 18 15\n16 14 12 11 10\n18 19 22 24 25\n53 51 48 46 44 42 39\n77 74 72 69 68 66 65\n25 22 21 20 17 14 13\n33 30 28 27 25 22 19 17\n29 28 26 23 21\n40 39 38 36 33 32\n63 60 57 54 52 49 47 45\n84 85 86 89 91 93 96 99\n20 23 24 25 28\n6 8 9 12 14 16\n52 53 56 59 62 65 66\n51 54 57 58 61 63 65\n36 34 33 31 29 28 27\n61 62 65 66 69 70 71 74\n25 26 29 31 34 37 40 42\n48 47 46 44 41 40\n31 34 37 39 42 43 46 48\n95 93 91 88 85 83 80 77\n75 72 70 68 67 66\n15 18 21 22 23 26 29 30\n94 93 90 89 88 87 84 82\n36 34 33 31 29 26\n65 64 63 60 59\n12 14 17 19 22 25 28 30\n20 18 15 13 11 8 7 4\n11 13 15 16 19\n71 69 66 65 64 61\n61 62 65 67 70 73 74 76\n51 49 46 45 43\n61 59 58 56 53 50 48\n29 31 33 36 39 42 45 47\n74 76 79 82 84 86\n93 90 87 84 83 82 81\n70 72 74 77 79 80 81 83\n89 90 93 95 98\n41 42 44 46 48 50 53 54\n31 29 26 24 23 20 19\n33 30 29 27 25 22\n82 83 86 87 88 89 90\n38 40 41 43 44\n71 68 65 62 61 58\n88 86 83 82 80 77\n80 82 84 87 89 90\n15 12 9 8 6 3\n67 64 62 59 56\n52 54 55 57 59\n9 8 5 4 3 1\n23 26 28 31 32 35 36\n44 47 48 49 52 55 57\n14 16 17 18 21 24\n38 41 43 45 47 48\n89 88 87 86 85 82\n97 96 93 91 90 88 87\n18 15 12 9 7 5\n45 46 48 51 54 56 59 61\n95 92 90 88 85 82\n96 95 93 92 91 89 86\n33 34 36 37 38\n16 19 21 24 27 29\n74 72 69 66 65 64 62\n27 25 23 21 20 17\n64 66 68 69 70 72 73 75\n6 9 12 15 16 19 22\n14 11 8 5 4 3 2\n47 50 53 56 57 60 63\n81 84 86 89 90\n36 37 38 41 43 44\n45 42 40 39 36 35 33 31\n49 46 45 42 41 38\n59 57 54 52 49 46 44\n25 23 22 19 16\n43 44 45 48 51\n6 9 11 13 16\n75 74 71 69 68 67 64\n59 56 55 52 51\n70 72 75 78 79\n33 31 28 26 23 22 21\n38 41 44 47 49\n26 23 21 20 19\n8 9 12 14 16 19 22\n54 55 57 59 61\n16 18 19 21 23 25\n82 79 78 76 75 73 71 68\n38 39 40 41 44\n96 95 93 92 91 88 87\n24 27 30 33 35 37 38\n47 50 53 55 57 59 61\n22 19 16 13 12 9\n35 37 38 41 42 43\n3 6 9 10 12 15 18\n37 40 41 44 45\n48 51 54 56 59 60 61 62\n42 41 38 37 36 34 31 28\n97 96 93 90 88 87\n47 45 43 42 39 38\n18 15 13 12 9 8 6\n81 83 86 88 89 90 92 94\n32 29 26 24 21 19 16 13\n68 67 66 65 62 61 58 56\n44 43 40 37 35 34 33\n57 56 55 53 50 47 45\n18 15 13 10 8 6\n87 85 82 80 77 75\n58 56 54 53 52 49 48\n51 52 55 57 58 60\n17 16 15 13 11 8\n27 29 32 35 38 39 40 43\n38 40 42 45 48 50 52 53\n62 63 66 68 70\n92 91 90 88 85 82 81 80\n3 6 9 12 14\n75 78 81 84 87 90\n48 45 42 41 40 39\n72 73 74 75 76 78 79\n50 52 55 56 59 62\n83 81 80 78 75 73 71 68\n30 33 34 37 40 42\n43 46 48 50 51 52\n30 28 27 24 22 19\n56 54 51 50 48 46 43 40\n29 30 32 35 37 38 39 40\n74 73 72 70 68 67\n80 78 77 75 73\n21 18 15 12 9 7 6\n42 43 44 46 48 50 51\n35 32 31 28 25 22\n69 71 72 75 77\n79 76 75 73 72 70 68\n53 54 56 59 61 64 65\n42 39 37 36 35\n22 25 28 31 33\n20 18 15 13 12 11 9\n34 36 39 40 42 43 46 49\n17 19 20 23 25 27 30\n30 33 35 36 39 42 44\n26 24 21 20 17 15\n44 42 40 39 37\n70 71 72 74 77 79 82\n45 42 40 39 38 35 32 30\n17 18 19 20 23 25 28 30\n89 92 95 97 99\n94 93 90 88 85 83\n62 65 67 70 71 73\n79 76 75 73 71 70\n17 15 13 12 9 6 4\n74 71 68 66 64 63 60\n41 40 37 35 32 30 27 25\n19 22 25 26 27\n38 41 42 45 48 51\n94 92 89 86 83 80\n46 49 50 52 55 56 57\n78 75 74 73 71 70 68\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_02_questions.txt",
    "content": "--- Day 2: Red-Nosed Reports ---\n\nFortunately, the first location The Historians want to search isn't a long walk from the Chief Historian's office.\n\nWhile the Red-Nosed Reindeer nuclear fusion/fission plant appears to contain no sign of the Chief Historian, the engineers there run up to you as soon as they see you. Apparently, they still talk about the time Rudolph was saved through molecular synthesis from a single electron.\n\nThey're quick to add that - since you're already here - they'd really appreciate your help analyzing some unusual data from the Red-Nosed reactor. You turn to check if The Historians are waiting for you, but they seem to have already divided into groups that are currently searching every corner of the facility. You offer to help with the unusual data.\n\nThe unusual data (your puzzle input) consists of many reports, one report per line. Each report is a list of numbers called levels that are separated by spaces. For example:\n\n7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9\n\nThis example data contains six reports each containing five levels.\n\nThe engineers are trying to figure out which reports are safe. The Red-Nosed reactor safety systems can only tolerate levels that are either gradually increasing or gradually decreasing. So, a report only counts as safe if both of the following are true:\n\n    The levels are either all increasing or all decreasing.\n    Any two adjacent levels differ by at least one and at most three.\n\nIn the example above, the reports can be found safe or unsafe by checking those rules:\n\n    7 6 4 2 1: Safe because the levels are all decreasing by 1 or 2.\n    1 2 7 8 9: Unsafe because 2 7 is an increase of 5.\n    9 7 6 2 1: Unsafe because 6 2 is a decrease of 4.\n    1 3 2 4 5: Unsafe because 1 3 is increasing but 3 2 is decreasing.\n    8 6 4 4 1: Unsafe because 4 4 is neither an increase or a decrease.\n    1 3 6 7 9: Safe because the levels are all increasing by 1, 2, or 3.\n\nSo, in this example, 2 reports are safe.\n\nAnalyze the unusual data from the engineers. How many reports are safe?\n\n--- Part Two ---\n\nThe engineers are surprised by the low number of safe reports until they realize they forgot to tell you about the Problem Dampener.\n\nThe Problem Dampener is a reactor-mounted module that lets the reactor safety systems tolerate a single bad level in what would otherwise be a safe report. It's like the bad level never happened!\n\nNow, the same rules apply as before, except if removing a single level from an unsafe report would make it safe, the report instead counts as safe.\n\nMore of the above example's reports are now safe:\n\n    7 6 4 2 1: Safe without removing any level.\n    1 2 7 8 9: Unsafe regardless of which level is removed.\n    9 7 6 2 1: Unsafe regardless of which level is removed.\n    1 3 2 4 5: Safe by removing the second level, 3.\n    8 6 4 4 1: Safe by removing the third level, 4.\n    1 3 6 7 9: Safe without removing any level.\n\nThanks to the Problem Dampener, 4 reports are actually safe!\n\nUpdate your analysis by handling situations where the Problem Dampener can remove a single level from unsafe reports. How many reports are now safe?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_03.adb",
    "content": "--  Solution to Advent of Code 2024, Day 3\n------------------------------------------\n--  Mull It Over\n--\n--  https://adventofcode.com/2024/day/3\n--  Copy of questions in: aoc_2024_03_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_03 is\n\n  use AoC_Toolbox, HAT;\n\n  input_name : constant VString := +\"aoc_2024_03\";\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data (part : Part_Type) is\n    i, j, a, b : Integer;\n    f : File_Type;\n    s : VString;\n    enabled : Boolean := True;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get_Line (f, s);\n      Scan_Line :\n      loop\n        Scan_Expression :\n        for fake in 1 .. 1 loop  --  Just for the comfort of the EXIT statement.\n          i := Index (s, \"mul(\");\n          exit Scan_Line when i = 0;\n\n          if part = part_2 then\n            j := Index (s, \"do()\");\n            if j in 1 .. i - 4 then\n              enabled := True;\n              Delete (s, 1, j + 3);\n              exit Scan_Expression;\n            end if;\n            j := Index (s, \"don't()\");\n            if j in 1 .. i - 7 then\n              enabled := False;\n              Delete (s, 1, j + 6);\n              exit Scan_Expression;\n            end if;\n          end if;\n\n          Delete (s, 1, i + 3);\n          exit Scan_Expression when Length (s) = 0 or else Element (s, 1) not in '0' .. '9';\n          a := 0;\n          while Length (s) > 0 and then Element (s, 1) in '0' .. '9' loop\n            a := a * 10 + Character'Pos (Element (s, 1)) - Character'Pos ('0');\n            Delete (s, 1, 1);\n          end loop;\n          exit Scan_Expression when Length (s) = 0 or else Element (s, 1) /= ',';\n          Delete (s, 1, 1);\n          exit Scan_Expression when Length (s) = 0 or else Element (s, 1) not in '0' .. '9';\n          b := 0;\n          while Length (s) > 0 and then Element (s, 1) in '0' .. '9' loop\n            b := b * 10 + Character'Pos (Element (s, 1)) - Character'Pos ('0');\n            Delete (s, 1, 1);\n          end loop;\n          exit Scan_Expression when Length (s) = 0 or else Element (s, 1) /= ')';\n          if enabled then\n            r (part) := r (part) + a * b;\n          end if;\n        end loop Scan_Expression;\n      end loop Scan_Line;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data (part_1);\n  Read_Data (part_2);\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 173529487\n    --  Part 2: validated by AoC: 99532691\n  end if;\nend AoC_2024_03;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_03.txt",
    "content": "~-mul(858,892)?@#mul(380,985)what()[^what()%mul(340,11)~*}don't())/~-mul(849,387)%-why()when():how()>-,what()mul(605,504)what()~:]what();how()who()];mul(771,783)?^ who()}~?>mul(111,830))@ ~mul(329,797)%'why()why()mul(125,409)-*/where()()@&!why()mul(390,37)when(974,538)#/when()){/don't()/mul(20,990)}?%{(who()mul(627,567)(how()'<(#%how()mul(387,315){;%who()%#from()mul(868,680)}^$mul(862,19)mul(847,689)>((#@when()}mul(339,156)+/{}@{^%[why(231,704)mul(236,754)]'^where(978,690)mul(460,872)#'*mul(518,944)>mul(301,886))mul(477,933)^mul(685,909)who())]what(288,791)mul(170,434){ &where()~(@where()mul(191,104)mul(637,600)&select()why())~select()mul(534,617)?mul(763,508){from()when(22,266)+who() when()mul(204,352)when()mul(426,122)-<*where()'$ why()mul(192,980)[(#[!$-}mul(798,208)''[!where()what()select()mul(295,727))#)}($<?<mul(452,502)(don't()mul(737,492)>,$%where(539,126)what()when()select()'@mul(311,541),?don't()#select()!}!(}&?mul(100,142)),-}%mul(222,856)~$;>!from()where()mul(758,901)mul(757,796)mul(976,686);@'~+-{#who()mul(26,971);mul(404,362)^~who(417,106)what()#mul(186,691)from() %#+{/mul(67,433)-who()!-+!mul(184,469)*when()[&when(458,221)<$mul(163,556)^)]?,'}&+who()mul(514,239)~)(mul(143,441)'how(741,776)~who(766,575)when();>*^mul(281,143)+!>;+:mul(767,44)#<mul(490,849)> when()why()don't()how()from()[from()from(){mul(436,519)what() *who();@{,>do()%'mul(19,540)when()mul(643,539)~when(812,543)mul(527,639)-!mul(409,379)where()/(mul(168,491)#$>]mul(432,333)@%<when();{?what()^mul(819,413)'where(65,845)}-' ^@don't()?how()when()>><mul(591,832)where(600,755)]who()}do()!^-$what()from()select()'#mul(572,956)@#:what()from(),]mul(303,346) when()$$how()@%/#$mul(857,344)/what()where()mul(969,234)$!#when()>>&who()(mul(113,494)%where()why()when()mul(659,592)<why()!<}mul(429,162)[who()*>#(/'mul(72,670)when()^^mul(369,596)mul(631,168)-why()()[*}mul(330,968) $why()where()mul(230,139)don't()@)@<mul(849,413)-when(){*?]mul(821,9)mul(753,277)]{&when()%:mul(262,360)what()mul(65,276)don't()])who();where()$!,(-mul(952,221)+:/{where()where()mul(608,843)'>where())%}where()&,}mul(875,661)~don't()':why(){mul(793*:mul(399,702)!://select()@when()why()do()@mul(488,581{?{&<who(617,140)@how()mul(156,982)why()'&<where()*:{mul(452{-+$$*/mul(202,724)]#:#why()+??(#mul(607,2)@^mul(20,845)#{+#[/#~/mul(111,872)how()select()]<how())'how()mul(921,254)$:;/where() ~why()}?mul(558,122)@how()<<who()mul(992,319)what(734,450)[^mul(498,490)/mul(632,639)when()]from(){why()]$[who(664,268)mul(401,695]!>how()&select()!<'mul(912,311)why()! })@+}mul(128*mul(626,752)%mul(49,60)[,who()what()select()<what()mul(24,8)>)@@]*]why(937,788)from():mul(945,658)<]don't()where()how(515,644)@+'select()how()mul(369,665)/],<when(){( $how()mul(361,594)$select()&:{:$when()mul(52,806) #from()@when()where():>mul(263,185)where()^why()why()@what()mul(82,407)mul(464,537)[mul(871,333)^mul(560,227)-why()mul(966,203)$what()+where()#mul(101,21)}%how(),)^who()>,select()mul(667,565)('what(),%select()(@mul(500,204:''<~'why(477,559)<do()>)[where()mul(698,648);how(){&?what()^@[%mul(280,395)>~, mul-#/%:where()>where():mul(170,746)don't()}($:@mul(998,876)*~<[mul(121,366)-?#;how()>from() ::mul(804,883)^-[  (:mul(100,354who(544,766)+,]>!['/;mul(949,115)\n[^!})from()&mul(617,518)*how()(:@who()what()/mul(591,163):what()?{'do()!/when()!$mul(394,797)]how(620,741)!:!mul&%mul(523,862) ~}where()why()}from()! @do()mul(270,205)from()[&^mul(577,474)?{*/why()*what()mul(656,30)where()+#,@mul(295,616)why()/mul(8,267))-^when()who(610,661)'mul(182,139)select()}select()!when();;mul(492,992)?how()~($who(716,562)%/mul(702,654))*>mul(126,386)[mul(351,400)select()%$[!}{+mul(98,266)mul(924,5)*'(^:[}!?mul(112,163)+!?where()mul(987,791)mul(943,488)how()mul(698,312)&:@from(442,439)~%~:mul(235,520)%mul(248,221&>/;select()what()) ~@from()mul(546,261)'mul(956,953why(458,937)when()~!where();mul(442,916)%;)&(mul(410,237)where()~why()[+?[mul(169,337)what()who()&what()mul(901<where()#&who(808,156)-mul(322,634)>/mul* don't()mul(999,662)*]&/'#<+<select(621,69)do()>,^}'mul(365,260){{?,,}from(520,861)where()what()mul(325,208): when()+>{!;mul(335,726)#',:>@?mul(48,443![mul(130,626)!{</#%*select()mul(806,140)'']'~mul(697,649)&,+??[%?how()mul(515,385)mul(878,769)^when()&what()]:$)*%don't()#){/mul(119,439)-[,+!'don't()^<what()~^-[(-%mul(791,824)+>^don't()*?-*[%>mul(934,995),how()@from()'<mul(907,832)?% who()(*[do()%:where()what()>#mul(433,843)why()<}$}how()-mul(754,464)when()why()mul(992,113);]/{%mul(87,293^]how()why()~&when()*#mul(589,979)@-&select()/%mul(218,248);mul(536,581)when()mul(215,212)/%when(66,857)@what()+mul(958,271) '%#who()&{mul(239,197)}what()$>{*'select()mul(365,443)>why()how()what()%mul(885,496how()when()}{@/ mul(589,42)^:;who()where()why() !how()(mul(574,947)*;where():&where()%]<{mul(572,4)$mul(232,716)when()<?>when()mul(928,697)^(where()mul(301,501)-mul(100,436)#~?mul(708,770): @:@)!*mul(89,177)><where()]mul(699,985)(-)do()#who()mul(194,358)why():when()/why()where()mul(103,669)#mul(779,400)@when()~/;/({mul(760,763&-when()%]where()*#mul(781,829)*select()><@+ {when()+mul(926,998);>,)?,$)mul(813,382)}from(728,403)^mul(497,820)where()(?why(454,153)!select()}*!don't()what()from()}&}<?)([mul(379,305)!when(): don't() ~~why()@&%mul(953,224))![*)/mul(802,693):;mul(126,477)-when(409,550){mul(238,713)!/!why()-}+>?how()mul(432,895)$!+mul(743,149)$!why(704,998)when()mul(229,683)((when()from()#&{mul(217,869)^)?)?what() select()}mul(765,209)who():}%{mul(448,553)[:-,don't()what()<,}from()where())mul(543,719)from(415,153)why()!'?^~mul(666,540)mul(922,877)mul(416,636)+#;$select()'mul(971,485)from(964,539)where()^ *who()/mul(35,594)<:mul(207,585)~*}'<when()>[]#mul(815,776){?%&*@?mul(385,133)['!:who() )mul(439,846)&)mul(529;?>;#mul(677,906)^& ()mul(75])how())mul(481,206)who()why()$^ from();what()'why()do()(%^&)mul(277,454)>where()where()$-#select()+/don't()what()select()]mul(295,126)why();from()mul(203,301){#mul(572,420){%(-*mul(929,786)do()mul(107,813)mul(921,668)'^+++!:[;mul(587,921)mul(242,920)mul(933,463)why()mul(340,196)'--']-mul(623,675)select()what()mul(656,927)<$)from()where(473,933)]~mul(408,566)!>$mul(373,541)}%*^)mul(346,14)>&how()@^-(&;mul(993,735)select()*{mul(990,221)*from():[ mul(940,96)/how()^>#;select()/#?mul(624,249)>mul(160,974)]^mul(589,900)&$[?[<-!select()mul(512,717)^/&mul(226,478)* ';'+from()?@~mul(224,929)!when()^what()where()'@'>~mul(451,87)\nwhen()%how()where()how()what() mul(59,36)how()where() )><when()[(mul(776,247)when()# &why())}?mul(331,460)]how()/why(382,926)&*mul(494,482)'*;~#/select()?who(828,76)mul(205,327)~:how(),^how()why()mul(466,546)+'~&mul(481,829?who()!{+who()from()^(%>mul(270,950)--mul(864,193)$!!from()[+when()do()?&]from(){?who()mul(576,443)}>*what()mul(60,617)]where(){*}what(16,936)*:mul(613,575) @$%%'mul(930,241)!~when()<+what()&{mul(189,41)don't()how()%who()how()mul(79,681){']{({ mul(615,354)~#&{mul(863,397)<?;how()mul(264,31>@?(mul(469,991)!mul(97,649)'%{where()/{+*}when()mul(429,913)[ >where()>](when(654,639)),mul(763,148):!~do()%+*',mul(646,831)~*$!?>mul(632 @?from()[mul(165,564)#mul(464,289)from(),mul(197,442)~[&mul(739,935)how()where()!],mul(583,831){mul(4,501)mul(912,584):select()(when()>&& &what()mul(836,498)where(987,400)*${mul(983,648)+~]don't()&,how()'^[*({mul(180,898)mul(982,907): select()($what()mul(294,259)do()where();>mul(130,154)mul(566,682)how()-:from()/ )^mul(50,250)~@select()(->mul(65,434)mul(865,288)+$don't()#+-<when()mul(348,972)#{^*<who()&,mul(545,238)select()mul(736,427)$from()mul(24,605)select():mul(183,229) do()-$where()$where()how()#[why(){mul(440,221)?when(171,776)$mul(930,461)?mul(118,801)how(162,609)where()'why()@ ;:$mul(538,213)>mul(875,123)@@>?mul(606,377);do();!where(){mul(267,543):]','# #*why()mul(31,575)#;who() *<$mul(797,419)'what()}when():what()/mul(627,73)'how(218,429)who()]*$,$from()mul(221,471)$ ;what()mul(38,106)?-&!~&from()mul(117,669):how()mul(422,348)(:/]mul(568,980)when(){~where(490,375)<(& mul'*)'where();##:}mul(34,144)mul(352,352) select()-when()/where(365,161)mul(571,634)mul(373,66)}how()don't()where()@>$$(!&mul(532,260))!mul(304,873)select(676,286)?#<,why(),<!do()/what()]?~^where(558,20)mul(744,233)^''mul(119[/%where()why()%who()mul(797,726)~*why()mul(743,436)?/-why()mul(399,351)mul(398,28))what()(when()/$what(169,128)>^~do()%@~where()mul(56&+select()>select()what()mul(670,288)< $:+<mul(706,866),)when()when()from()mul(391,781)~mul(142,120)>[$~what(){@!%mul(422,126)(who()?from()}*}mul(459,923)mul(38,243)^)!who()::#from()/mul(845,589)^/when()'#when()~,'select()mul(454,166)who()~>when()^when()?'@where()mul(237,855)~from()from()why()mul(233,606)]@mul(947,750)!@*}who()(@%mul(252,951)[from(995,363))}),when()who()+where()mul(368,442)>from()where()select()from()what()^?mul(190,689)mul(337#who()*when()/*mul(652,631);,*why()+select()>}where()%mul(839,296)>&%,@}$mul(723,530)who(685,511) %~where(782,449)mul(36,917);]]{mul@where()!&*%why()mul(191,759):why()what()$mul(900,773):$who() *{mul(426,740) why(396,306)/from()why()*%}'+do()@!'how()%^/mul(970,462)when()who()!-mul(535,35)}from(377,342)when()/(how()who()-}:mul-what()/how()?*^how()mul(217,447)/]?%!mul(495,690)}#<{?,do()+-why()<mul(613,900)<@when()@)from()mul(590,34)-why()mul(524,292)>mul(3,559)who()+what()mul(942,139)})when()who()<-]'what()what()mul(218,316)how()mul(669,389),<+mul(861,165)why(){^}[mul(594,386what()who(){mul(801,662)mul(852,2)-mul(458,479)//mul{don't()mul(826,480)>mul(954,968)$;mul(871,184)from()select()**<]!mul(503,290)#select()where()?do()mul(154%[&how()?mul(279,673)-[don't()$]why()-what(754,13)mul(841,495)where()}{mul<-'##!/usr/bin/perl@~mul?what()<^-@/>from()!mul(573,383)where()-{#mul(420,579)when(977,697)when() &@##from()+}mul(314,487)\nwho()+from()where()mul(878,982)]~mul(812,80)?select()don't()how()];mul(986,548)/how(311,658)/select()(don't()(select()select(533,328)<^+from()what()why()@mul(786,152)*<[ }},)mul(30,285)mul(721,12)#(-{what()mul(70,496)^when()-/how(420,87)select()what()]$mul(645,406);-~where()>do()~&^(,}$#$mul(993,357)?/select()}do()+from()~@mul(661,590))what()*!?]*!'mul(19,345)-why())select(){%(% don't():*#when()~select()mul(910,416)}mul(550,400)<from();/)$who()mul(107,198)*^;what()*mul(585,659)]}<*[mul(408,612)(how()+'[don't()select()mul(910,993)({[who(895,379)>when()]~mul(515,93)&where()mul(412,99);(;+mul(611,500%what()%,from()when()mul(822,769),-*(([$(mul(153,856)why(){mul(476,25)do()-mul?from()<<[why()&mul(859,60)what()]+ :how()what(434,726):^from()do()}*?}?mul(432,641)>%<why();where()mul(722,325)who()why()do()'$,>?!mul(93,484)++}?mulwho()#>who()select(): why()mul(889,212)>]?where()&mul(808,71)<*/'-+select()mul(523,619)+#where()mul(324,306)why()';why()}mul(337,315)~:what():^?-$from()mul(924,137)mul(444,59)why()[from()how()who()mul/how()>mul(304,707)'select() select()mul(224,915)mul(991,306)[>$! &how()>/mul(719,679)how()select()mul(65,620)from()#'~:]<mul(906,303)}what():how()&%^select():{mul(644,751),^,&,!*'@mul(323,720)why()>+-from()]mul(971,857)how()#[~~]?%mul(230,961)from()from())# } where()mul(330,14)>mul(411,981)}}<)mul(304,453)how()from()$who()mul(573,848)% ;:<mul(23,887)>from()(~select()!mul(542,790)}'#mul(530,502)%$(-#$mul(358,540)mul(10,361)when()where()<}&where()mul(429+!*$~)mul(446,812)%when()don't()>~>^what()select()why()from()where()mul(330,214) -[mul(731,164)/mul(776,235)mul(240,20)who()^what()']@!-who()%don't()(( )'!how()why();>mul(941,911)'?where()from()how()/mul(489,746(select(725,995)-from()?;when()%]%<mul(293,629){;what();(~!<mul(176,456)<~who(252,77)who()~{why()?]&mul(587,279){%?]from()<?mul(313,626)@[/how()+&don't()mul(298,798@!'&when()~(#[mul(827,523)from()$ where()who()%mul(54,803))*mulselect()%mul(500,731)mul(946,993&;{/;where()^where()mul(795,350)where(),~  @^how()-]mul(995,399)%who()do()where()mul(911,909$(?!$]]~what()mul(151,846)[select(636,807)mul(111,19)where(){^mul(730,317)who()^do()'~#]$/$@<>mul(555,315),how()#%!><from();mul(845,939)>?mul(664,596how()+'-who()from(51,408)mul(605,672)?!%from()) #}don't():}mul(579where()mul(243,699)mul(321,902)*!/mul(465,704)*when()[*how()mul-!mul(15,80)}#}mul(413,156)(;mul(71,288)/$;'don't(),how()+[;$who()%$when()mul(516,863)mul(268,600)(</from()~how()'<how()where()mul(715,920)&,mul(989,598)[~where()where()mul(635,110);from()*mul(843,35)&*}@[how(232,546)'-+ mul(979,532)[do()&mul(649,85)]how(832,401)-;mul(876,724)-[mul(432,417)!from()select()]mul(967,886'mul(561,191)#mul(660,865)-}~#mul(736$mul(623,276)from(93,634)^<&-+!@(how()mul(543,427)]#what()from()mul(247,751))from()where()+/^@!;?mul(919,365)where()]&!{-:~why()mul(220,330):]&mul(919,207)-&who()?*how()#%mul(759,323)!how()how()mul(695,755)[{mul(426,127)-{% /~mul '*&how()who()^(mul(797,201)'mul(509from()when()(@(<()don't() :&mul(852,261)<#^]from()mul(981,414)(</who()*do()(+where()*'why()what(229,53)+mul(954,398)mul(148,957)what()^&*mul(92,295)select(){mul(146,508)  who()}[>mul(602,939)who())>)<&'!mul(323,967)?mul(673,398)):&#}>>{!mul(501,484)<;who(969,453)-who(624,921)-)<-mul(72{-//!mul(576,751)mul(318,331)mul(707,186)+how()mul(660#how()!+#?where()mul(547,453)\n[what()?->+[mul(266,969)what()from()%^!how()?mul(236,335) )'<>,&!-where()mul(563-select()(mul(405,969)when()[%;why():$]mul(266,763)what()~#-<how()?mul(574,316))^;//}:when()}}mul(798,955)%?(%}*>{+don't()~+-mul(68,150)#{{?%:mul(422,966)select()mul(143,33);mul(917,142))]'>mul(23,457);'what()why()-where()}/>mul(66,911)&&':(>why()>mul(413,27)mul(772,64)mul(266,512)%$<what()who()*-)mul(169,905))where()do()~where(),how()^:what()mul(584,453{#&&:how():,how():%mul(937,5)mul(974+:when()where()~}+-<mul(356,901)~?]when()select()mul(933,555)&'-mul(728,399){&>*[why()<mul(862,418)?>:where(),@%^',mul(750,295)*]:<mul(491,8)#^&mul(801,442)where()where()@/how()+where(17,463)(select()mul(460,732)*what()}/-})>mul(17,60)!!}*from(975,930)mul(763,134)mul(463,381)when()(select()where()+{?what()mul(755,843)!why()+>mul(24,584){mul(105,734)$why()@where()!+what()%what()mul(5,111)#^;?{^/?^~mul(24@>when()what()where()#from(284,9)when(437,59)mul(978,337))+:(select()mul(996,373)(what(188,513)@ ]from()}mul(370,765)~$mul(490,904))]/%who()why()/mul(123,978how()why()[who()~%how(180,982)<mul(251,677)!%(>@:mul(343,157)![/*^mul(157,976)who()from() select()]+?+do();)&)<from()!/select()mul(143,894)]<*,?mul(900,759)]:%@:mul(496,2)*don't())-$# ?!>mul(734,420)$%(select()>'mul(143]mul(4,351)mul(279,828)'}^mul(108,132) #how()why()}mul(573,602)}@mul(747,126)where()'@mul(247>why())when()+::^&from()mul(843,212)^mul(612,743)[mul(204,899)$mul(174,265)%]mul(864,804)-from()how()%%mul(674,431)^^#[(@:&*mul(619,935)select()//~^mul(70,941)why()select(405,825)why()who()@mul(112,658)'+(@!$who(){select()do()from()from()@how(846,925)mul(417,888)~{: who()&-;mul(285,186)-+what(){/+-mul(24,944''mul(935,370)why()?~ +mul(468,38)'why()(/mul(704,512)%mul(946,591,<);from()select(290,495)*{:<do(),)/mul(522,493)(^mul(182,31)/mul(330,74);'%:mul(793,487)-;where()who(){where(590,54)(mulwhen()@ :]!mul(812,795)(:mul(468,59-(how())where()',;mul(263,506);^why()mul(159,826)(,: /$mul(179,478)[,(who()>['%mul(554,965)<why(920,323)mul(3,344)do()]why()mul(353,389)' )+)%from()do()select()#>(~mul(308,534)mul(6,373)^how()@%&how()~mul(669,386)when() 'mul(33,652)mul(950,268)::mul(98,181)]^how()'!mul(982,613)how()&where()]what()how()do()[from()#[? mul(929,452)<$$<who();^]don't()&what()-]}<&from(),~mul(721,96)$}^[what(272,30)&who()mul(107,629)why()why()where()-how()/}from()+mul(718,337) *mul(49,736)why()&/'where(888,569)#&where()]+mul(728,703)!'> mul(506,408)-mul(670,674)how()mul(645,104)do()(>[%from()@'who()&%mul(45,884)mul(895,714)mul(871,6)},?&;!select()#where(779,295)^mul(113,370)why())%[select()[,^' mul(976,960)][%mul(828,993){}}mul(135,443)>what()mul(344,20)>where()/) :@mul(564,715){([,]'mul(675,478)#*@who()>]$*+mul(94,992}<mul(565,578)/mul(85,827)mul(565%do()/+{[mul(956,611)what()mul(807,414)]what()how(521,834)]where()}>from()mul(288,445)mul(72,57)*/})how()[how()!mul(543**%who():what()mul(345,778){mul(462,244)from()[@*who(),+mul(591,870)#select()%mul(779,654)$+%%@ mul(920,934)?-select()-}mul(247,709)@$why()mul(179,824)(when(989,252)?mul(422,816)$[from()#who()<mul(672,845)mul(118,135)\n*what()}[*how()?why()mul(386,104)[from()];mul(208,918))){(+<how(),:how()mul(694,384)@!-*{mul(69,248)?',what(), ^<;mul(902,984)*mul(369,924)^?^mul(594,537)>@,when(),mul(922,47)@mulwhy()-mul(890,397)-^/+'select()[&!who()mul(547,6)-]>:^;mul(870,938),~?[%mul(8,689!>*@!]mul(311,244)->how()$when()'}mul(213,766)$:!+ mul(620,644)%where()mul(430,127)%{[mul(682,585)mul(245,26)don't()mul(510,688)where()]-mul(844,443)/@+who()?who()when()mul(453,182)mul(928,131)<select()who()(]mul(422,986)[&&who()[how()$mul(54,860)!]{;mul(549,103)<%;mul(807,173)/mul(513,515)@mul(852,657)'#when(293,457)$&+why()mul(694,888)*why()mul(912,542)$$!:$mul(776,404^$$}&(mul(965,836)-what()*:]mul(97,471)/*~]what(){[what()mul(241,843)where()[^mul(639,208'}(- who()how()mul(869,533)how()who()what()select()%don't() where()(why(811,325)!<where()^~;mul(955,806)][)])+,% mul(207,798):&who(),<where() how()mul(857,424::,]mul(250,416)select()'{mul(815,806)[)/@mul(285,41)$mul(901,755)from()!)?why()){!mul(78>?&'{[+@?,mul(55,18)mul(795,739):}what())@$]'mul(377,34)&,~*why()<do()<mul(795,39)where()$%+?>/@who()mul(467,127))&how(28,925)mul(955,519)}where(830,382)$when()[-why()/+mul(310,139)mul(217,931)!mul(574,122)!mul(227,82)where()mul(940,851) {mul(545,758)<select()?[mul(720,337)mul(52,940)~how()from(855,795)*mul(664,962)>:from()%~/mul(937,897)mul(665,919)^&/  &what()mul(23,37),select()%*mul(98,952);mul(171,967)who()$+]when()%$mul(426,870)<<;;why()[do()@mul(28,286)-what()([+select()why()do()<^+what()^?~-mul(246,992)/mul(938,936)'$>when()mul(18,736)%?how()-what()from() <do()mul(994,498);<,how(800,873)[%/&mul(260,162)why()]when())(what()}#don't() mul(99,24)(*!@]]mul(490,150)~mul(47,794)$#}where()(who(){what():mul(369,830)mul(24,75)where():(,@)]$~mul(509,783)mul(914,160)+mul(619,799)&@~how()from()mul(445,64)*>when()select()mul(37,387)}<[}?+how()#&?mul(779,369)select()mul(750,510)%[,'from()>who()mul(13,97)what(547,477)why(859,962)?,where()mul(806,879)mul(577,179)#from()+>where(705,292)what(712,121))when(227,970)*mul(942,336)& who())!<mul(345,567)/-select(838,572)-~'*)why()[mul(12,866)@^where()?<mul(985,870)where(503,821);^mul(803,551)'[%#where()-who())mul(38,22)^}$who()?,how()%what(528,476)who()mul(486,865)<(/mul(714,503)%%,$select()]mul(299,58)-when()~why()-}mul(684,388) /^<:[;:don't()why()who()<who()-{mul(413,975),>*mul(992,750):from()<:+-mul(938,672)mul(55,872)mul(354,183)>+(+mul(520,932)#from():}{who()$mul(675,973)@^@%mul(58,468)/select()what()->]mul(343,375)^ ,%mul(480,300)where()(/*$mul(695,676)how()where(),-!:from()mul(363,212)~(!where()-[what()don't()mul(614,594))mul(569,802)'mul(995,471)~&$:^:how()how()-^mul(853,428)-;-%what()(from()+do()'where()() !{^?#mul(376,780)select())where()select()&{-,{,mul(894,646)select()*< @}*[}}mul(332,665)[\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_03_questions.txt",
    "content": "--- Day 3: Mull It Over ---\n\n\"Our computers are having issues, so I have no idea if we have any Chief Historians in stock! You're welcome to check the warehouse, though,\" says the mildly flustered shopkeeper at the North Pole Toboggan Rental Shop. The Historians head out to take a look.\n\nThe shopkeeper turns to you. \"Any chance you can see why our computers are having issues again?\"\n\nThe computer appears to be trying to run a program, but its memory (your puzzle input) is corrupted. All of the instructions have been jumbled up!\n\nIt seems like the goal of the program is just to multiply some numbers. It does that with instructions like mul(X,Y), where X and Y are each 1-3 digit numbers. For instance, mul(44,46) multiplies 44 by 46 to get a result of 2024. Similarly, mul(123,4) would multiply 123 by 4.\n\nHowever, because the program's memory has been corrupted, there are also many invalid characters that should be ignored, even if they look like part of a mul instruction. Sequences like mul(4*, mul(6,9!, ?(12,34), or mul ( 2 , 4 ) do nothing.\n\nFor example, consider the following section of corrupted memory:\n\nxmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))\n\nOnly the four highlighted sections are real mul instructions. Adding up the result of each instruction produces 161 (2*4 + 5*5 + 11*8 + 8*5).\n\nScan the corrupted memory for uncorrupted mul instructions. What do you get if you add up all of the results of the multiplications?\n\n--- Part Two ---\n\nAs you scan through the corrupted memory, you notice that some of the conditional statements are also still intact. If you handle some of the uncorrupted conditional statements in the program, you might be able to get an even more accurate result.\n\nThere are two new instructions you'll need to handle:\n\n    The do() instruction enables future mul instructions.\n    The don't() instruction disables future mul instructions.\n\nOnly the most recent do() or don't() instruction applies. At the beginning of the program, mul instructions are enabled.\n\nFor example:\n\nxmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))\n\nThis corrupted memory is similar to the example from before, but this time the mul(5,5) and mul(11,8) instructions are disabled because there is a don't() instruction before them. The other mul instructions function normally, including the one at the end that gets re-enabled by a do() instruction.\n\nThis time, the sum of the results is 48 (2*4 + 8*5).\n\nHandle the new instructions; what do you get if you add up all of the results of just the enabled multiplications?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_04.adb",
    "content": "--  Solution to Advent of Code 2024, Day 4\n------------------------------------------\n--  Ceres Search\n--\n--  https://adventofcode.com/2024/day/4\n--  Copy of questions in: aoc_2024_04_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_04 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 10; n_p_3 : constant := 13;\n  input_name : constant VString := +\"aoc_2024_04\"; n : constant := 140; n_p_3 : constant := 143;\n\n  a : array (-2 .. n_p_3, -2 .. n_p_3) of Character;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in a'Range (1) loop\n      for j in a'Range (2) loop\n        if i in 1 .. n and then j in 1 .. n then\n          Get (f, a (i, j));\n        else\n          a (i, j) := ' ';\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n  begin\n    for i in 1 .. n loop\n      for j in 1 .. n loop\n\n        case a (i, j) is\n\n          when 'X' =>\n\n            --  Search_Ver:\n            for fake in 1 .. 1 loop\n              exit when a (i + 1, j) /= 'M';\n              exit when a (i + 2, j) /= 'A';\n              exit when a (i + 3, j) /= 'S';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n            --  Search_Diag:\n            for fake in 1 .. 1 loop\n              exit when a (i + 1, j + 1) /= 'M';\n              exit when a (i + 2, j + 2) /= 'A';\n              exit when a (i + 3, j + 3) /= 'S';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n            --  Search_Hor:\n            for fake in 1 .. 1 loop\n              exit when a (i, j + 1) /= 'M';\n              exit when a (i, j + 2) /= 'A';\n              exit when a (i, j + 3) /= 'S';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n            --  Search_Counter_Diag:\n            for fake in 1 .. 1 loop\n              exit when a (i - 1, j + 1) /= 'M';\n              exit when a (i - 2, j + 2) /= 'A';\n              exit when a (i - 3, j + 3) /= 'S';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n\n          when 'S' =>\n\n            --  Search_Ver_Inv:\n            for fake in 1 .. 1 loop\n              exit when a (i + 1, j) /= 'A';\n              exit when a (i + 2, j) /= 'M';\n              exit when a (i + 3, j) /= 'X';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n            --  Search_Diag_Inv:\n            for fake in 1 .. 1 loop\n              exit when a (i + 1, j + 1) /= 'A';\n              exit when a (i + 2, j + 2) /= 'M';\n              exit when a (i + 3, j + 3) /= 'X';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n            --  Search_Hor_Inv:\n            for fake in 1 .. 1 loop\n              exit when a (i, j + 1) /= 'A';\n              exit when a (i, j + 2) /= 'M';\n              exit when a (i, j + 3) /= 'X';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n            --  Search_Counter_Diag_Inv:\n            for fake in 1 .. 1 loop\n              exit when a (i - 1, j + 1) /= 'A';\n              exit when a (i - 2, j + 2) /= 'M';\n              exit when a (i - 3, j + 3) /= 'X';\n              r (part_1) := r (part_1) + 1;\n            end loop;\n\n          when others => null;\n\n        end case;\n\n      end loop;\n    end loop;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n  begin\n    for i in 1 .. n - 2 loop\n      for j in 1 .. n - 2 loop\n\n        case a (i, j) is\n\n          when 'M' =>\n\n            --  X1:\n            for fake in 1 .. 1 loop\n              exit when a (i + 1, j + 1) /= 'A';\n              exit when a (i + 2, j + 2) /= 'S';\n              exit when a (i,     j + 2) /= 'M';\n              exit when a (i + 2, j)     /= 'S';\n              r (part_2) := r (part_2) + 1;\n            end loop;\n\n            --  X2:\n            for fake in 1 .. 1 loop\n              exit when a (i + 1, j + 1) /= 'A';\n              exit when a (i + 2, j + 2) /= 'S';\n              exit when a (i,     j + 2) /= 'S';\n              exit when a (i + 2, j)     /= 'M';\n              r (part_2) := r (part_2) + 1;\n            end loop;\n\n        when 'S' =>\n\n          --  X3:\n          for fake in 1 .. 1 loop\n            exit when a (i + 1, j + 1) /= 'A';\n            exit when a (i + 2, j + 2) /= 'M';\n            exit when a (i,     j + 2) /= 'S';\n            exit when a (i + 2, j)     /= 'M';\n            r (part_2) := r (part_2) + 1;\n          end loop;\n\n          --  X4:\n          for fake in 1 .. 1 loop\n            exit when a (i + 1, j + 1) /= 'A';\n            exit when a (i + 2, j + 2) /= 'M';\n            exit when a (i,     j + 2) /= 'M';\n            exit when a (i + 2, j)     /= 'S';\n            r (part_2) := r (part_2) + 1;\n          end loop;\n\n          when others => null;\n\n        end case;\n\n      end loop;\n    end loop;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 2483\n    --  Part 2: validated by AoC: 1925\n  end if;\nend AoC_2024_04;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_04.txt",
    "content": "SXMXXMXMASXXXMASXXAMXMMXSAMAMMMXSXMSASMMMXXSMSAMMMMXMAMXASAMAMXSAMXAMXXMXMXMMMSXMXSAMXSSXASXMASMSXMASMSSSMMSSMMXMASMSMMMMXMMSAXXMXXSXSXXXXXX\nMXMMMSAXSAMMMXMASMXSAXSAMXMASAMASAMXMAASMMSXXSAMXSAMMSSSMSAMASASMSSSMXSSSMXSAAMMXMMASAMXSAXSMSMXMAXAMAAAAMSAMASMSAMMASAAAMAAXXSMMMXMAMAMSMSA\nSAAAXSASMMAMAXXAAXXSASMASXSASASASXMAMXMMAXSMXSAMXMAXSAAAASXMAMASAAAAAAAXAAASMSMMSASXMASAXXAMXMSMSMMSMMMSMMMAMMMAMAXSASXMSAMXSMXAXMASAMAMAAXX\nSSSSXXXMASMSAMSSXMAMMMXXMAMAMAMAMASMSMASMMXMASMSMSMMMXSMMMSMXSAMMMMMMASXMMMSXAAASXMXSAMASMMXAMAMAXXMAAXAXSXXXSMXSAMMMSXSMMSXMAMSASXXXSXSMSMX\nXAMXMMXSAMXMAXAAASMSMSMMMXMXMSMMMXMAXMAMXMAMMSAAXMASXMAAAAAXAMXSXXASXMAMXSMMAMMMSAMXMAMAMMMMSSMSMSMSXMSMSMXMXXAAMAMXXSXMAMSXMSMMASAMXSAMXAAX\nMAMAXMAXAXSMSMMSMMAXAXXASASAAXAAMAMXMMXSASAMXMXMXSAMXXXSMSSMXSAXMMMXAMSAAXAXAXAAXAMXSAMXMXXAMMXSAAAAXMXMAXAMXMMMMMMXMMAMSMMXSXMXSMAMAMMMSMSA\nMAMMMMXSSMAAAXAMXMMMSMSAMASXXSAMSMSAXSASXSMSSMMXXAMMMMXMMMAMMMXXSASMSMMMMSMSMSMXMAMAMXAAAMMMSMAMXMMMXSASXSASASMSAAMSSMAMXAMXAXMSASAMXSMXAMXM\nXSXSAXAXXAMSMSMMAMXMAAMXMXMMMMXXMASMSMMXASAAAAMXMMXAAXAAAMMMSMMMSAMAMXAAAAAAAXAMSAMSMMSSSXXSAMASAMASASAMXSMXXXAMXMSAMXSXSAMMMXSAASXMMSAMMSAS\nXMASASXMXSXXAMASAMAMMSAXMAMXSSSMMMMMXASXXMMSSMMMAXSXMSSSMSMAAXAXMSMAMSSSSMSMXMAMXAMXAXAMAMXSASASASMAAMMXMMMXSMAMAXMAMAAAMMASXMAMMMMSAXMAXMAS\nSMAMAAMXMXAMMMASASASXMXXMASAMAMSAXAXXAMXAXAXXXAXSAMMMMXAAAMSSSXXAMMMMMMMMXAXAMXSSMMSSMMMSAMSMMMSMMXMXMAAXAAASMMMSSSMMMMSMSASASMXXAAXSXMSAMMM\nSMXMMMXSXMXMXMASASASASAXSAMMSMXSMSSSSSMSSMAMMXMSMASXAASMMMMAMXMMAMMASMMASMXSXSAAXAAAAAAAMAXXXAXMAXAXMXSMSSMMSAXAAXAXXXAAAMASAMXMASMMMMXXXMAS\nXXXXASAMXXAAMMMSAMAMXMAMMXMMAXMMMAXXAAAAXXMMAASMXAMXSMXXMXMXMAMXAMSASASAXAMXAMMXMMMXSMMSSSXMSMSMSXMAXMAAAXMASMMMXSMSMSAMXMAMMMAAMMXAAAAMASMS\nMSMMXMASASMSMAAMXMXXAMSMXXXSAMAXMXSMMMMMXXMMXMSAMMSXMMMMMSMSMSSSMXMMSMMMSMSMXMASAXSXMAXMAXAAAAAAXMSXMAXMXXXAMXAMXMAMXMAMXMAMAXMSMSXSSSMMAMXX\nMAAXXSAMMXAAMMMSMMSAMXMSMSMMAXSAMMAAASAXMAMASAMXMASAAMAAMAAAAAMASXSMMAAXAAAAMXAASAAASMMMAMMSMSMSMMAMMMSSSMSAMAMXAMAMASAMASXSMSAAAAMAMXMMSSMX\nSSSMMMSSXMMMSXXAAXAAXXMXXAAAAXXAMAMXMMAXAMXXXAMXAXSSMSSSSMSMSMXAMXMAXSMSMSMMAMAXMXMXMSAMXMXAXAAXXXAMAXXAAAAAXSSSMSASXSAMXMAAAMXMMMASAAMAMAMM\nMAAAXAXMAXSAXMSSSMSSSSSSSSSMSSSSMSSSMSSSSSMMXAMXAMMAMAAAXAXMXXMSSSMSMXASXXMMXAMXSMMMAXXSSSSSXMSMMSMSSSMSMMMSMAAAXSAMAMMMAMMMXMAXMXMXMSMAXAMM\nMSMMMSMXAMMMMAXAMMXAAAAXMAMAAAXMAAXAAAMXAAXMASMSMXSAMMSMMMMXMASAAAAAXMAMMSAAXSSMSASMSMAXAAAMSMAAXXAAAMAMAMSMMMMMMMMMSMSMSASMXSMMMAXASMXSMMSS\nXMAMAAMMSXMASXMMMMMMMMMMMAMMMMMMMMSMMSSMSMMAXXAMXASASXMXSXAASXMMSMMMXMSMAMMMSXAASMXAAMMMMMMMAMSSXMMMSMMSAMMAMXAXMXAXMASAMXSXAXXASMXMMAXMASAM\nASAMMMSAMASAMMAAXXAXAAXAMASAAAAAAXXXAMAMXXMSMSSMMXXAMAMAMXXMSMMAMXAMSMAMMSAXXXMASMMSMSMASXMMAXAMAXXXAAXSAXSAMSMSSSMXMAMAMASMMMSASAASMSMSXMAS\nXSASXAMAMMMMXSSMSSSSSSXSSXMMSSSSMSSMXSMMSXXMAMAASXMSXMMAMMSAMXMXSMSMAMAMASMSMXXAXXAXMAMASMSMXMASXMSSMSMSSMMXMAXSAMSAMASXMASAMAXAMAMSAXAXMXAA\nAMAMXXXSMSASAAAAXAAMAXAMXMMAMXMAMSXMASXASMMMSMSMMAAAASMXSAAMSMMMSAAXMSXSAMXAAASMMMMXSAMXSAMXSMMMAXAAXXMXMXAXSMSXMASXXASXMASAMSSMMMMMMMXMXMXM\nSMAMMSXMXSASMSMMMMMSAMXMAMMAMXXXMXAMASMMMAXAAXAAMSMSSMAMXMAXAASAMSMSXAASMMSSXXSAAXXAMASXMASASAAMSMSSMMMAMXXMAMXAXAXMSMSAMASAMXAAAXAAXAXSXMAS\nMXMXXMASAMXMAAXAAAXMASXMASXMSSXMMSXMASAMSSMSSSSSMAAMXMXMMMMMSXMAXASAMXXXAAMMSXSXMXMMSXMASAMXSMMMMAMXAASASAMSSMSAMXXXAASXMASMMSXMMSXSSSXMASAS\nSASXXSAMASAMXMSSSSMSAMXMASAAAXAAAAAMXSAMXMAXXXAMAMXMAXAMAAAAMASMMMAMXSXMMMSAAMMAXMAXMXXXMXSXSXMXXAXSSMSAMXXAMXSAMASAMXMAXAMXXMAXXXXXAXSSMMMS\nSAMAAMXMXMASXMAXMAAMXXAMSMMMMSMMSSSXASXMAMMMSMSMXMAMMXSSSXSASMMMXMSXAXMASAMMMASAMMSXSMSAMXSAMASMSMMXMAMXMSMMXAMAMMSXXSSSMMSMMASMAMSMAMXMAAAM\nMAMMSMSSMMAXMASMMMSMMSXXASAMXSAAXMXMASMMASAMXAAAASMMSAAAMAMXAAAMMMMMXSMSMASAXMMSSXMAMMAMXMXASXMAAXAAMAMSSXAAMMSSSXMXMMAMXXAASAMMAAAAXMXSSMMS\nSXMAAXXAAMAXXXXMAAAAMASMSXXMASMMXMAAAXAXASAAMSMSMSAAMMMMSXMMSSMSAAAMXSXAXSSXXSAAXXMASAMAASXMMMMSMMSXSAXSAMMMMMAMAXXMAMAMMMSXMAXMXXMSAMXMXMAX\nMAMSSSSSMMMMSMASMSSSMASMASAMXSXXASXSSMSMMMMMXXAAMMMMXXXMAMXAAAMSMSASAXSMMXXAMMMMSXSASAXXXSAMXMAAXXMXSXSXSAXAXMMMMXMAMSAMXAXAMXMMSMXXAMASAMXM\nSAMMAAXXXMAAAAMMAMMAMXMXMASXAMAXXXMAXAMAAXXSMSSMSMASMAXXMSMMXSMSAXXMMMMSASMMMAAMXAXASAMSMSAMAMSSSXMAMMSAMXMMSSXAXMXSXSASMSSSMXSAAXAXSMASMSSS\nSXSMAMXMAXMMSSMMXMSMMAAXSAMMAXSXSAMXMMMMXSXAAAAMMMAMAMMXMMMSXMAMAMSMMMAAXMASASXSSMMMMAMAAMASXMAMMAMAMXMAMXSMAMSMSMAMAMAMAAAAAAMSSMMAXMXSAAAS\nSXSAMMMXMMMAMAMXAXAXSSSXMASMSAMMSAMASMSMAMMMMMSMMMAXSSSXASAXAMMMSXXXAMXMSSMMAMAAXMASMXMMSSXMXMAXXAXASXMXSXXMAMAMAMMSMSAMMMSMMMXMXXMASAMMMMXM\nXAXMMMXASAMMSAMXMMXXXAXAMXMAXMSASAXAXAAMASASAXMAMXMXAAMXAMMSAMAAXAMMMSXXMASMSMMXMSAMXMSXAMASXSAMMSSMAASAMXXSMSMMAXAAMMAXSAMMMSMAMXMMSXMASMMS\nMMMAAXMASXSXSAMXSMMSMAMAMMMXMXMASAXSMSMSXSASXXSAMASMMMMMSAXMASMSSSMASAMXSAMMXMAXXMXSAAXMXXAMXMASAMAASXMAXAMXAAMMMSMSSSMMMMSAAASAMASXSAMXSXAX\nAASXMSMAXAXASMMMSAAXXXAAMMSMMXMMMAMXAAAAAMAMAXSXMAXAMAXXXASXAXAAXMSXSAMAMAMMAMXSMAMSMMMSMMXSXSAMXSSMMMSAMSSMMXSAMSAAAAAXAXMMSXSXXAMAXAMAMMSS\nSMXAAXMMMMMMMXXAMXXMMMMMSAAAXAMSMAMMAMSMMMAMMMMMMMMMMXXXMASMSMMMSMSXSAMMSMMSMMAXMAMXMXAAAAMMAMMMAXXAMMSAMXAXMAXASMMMSMMMMSSMXXMMMSMMXAMAXAAA\nXMMMXMAMAXAAXXMSSSMMXAAMMXXSSMSXAMXXAMMMSXXXAAAXMXAMXMMSMXMAXAAXAAMASMMAAXMAMSAMXXSAAMSSMSSMAMASMXMXMASMMXXMSSXMMMSAXAAAXAAASAXMAMASMSXSMMSS\nMAAXXMMSSSSMSAMXAAXASMMSASMMAMMMMMXMASXASASASMSSMSXSASAAAAMXMMSMMSMMMMSXMASAXMASAMMMSMMAMAAXAMXAXAAAMMSASXSAAMAXAXMASMSSMSSMSAMMSMAMAXAXMAMM\nAMSSXSAMMAAAAMXMXMMXXAAMAMASAMXSASXSXMMMMAXMMSAAXAASAMSXSASASMXAAXAXXXAAXAMXXSAMAXXAAASAMSMMSSSSSMSXSASAMAMSMSMMXXMXMAAXMAXAMXMAMMXMAMSMSSSS\nMAMAMMASMAMASMAAASXSMMMSASMMMSXSASAMXSXMXMXXMMMXXSMMXMAXMXXASAXSSSMMSMSAMXXAMMSSMMMMMMSXMXAAMXAAMXMAMXMAMXMAXAXSSXMMMMMMMMMXMAMASAMMXSAAAAAX\nSXMAMSAMXXXAXMXSAMAMAXAAAMXAXAAMMMAMAMXSAMMSXMXXMMAMXMSSMAMSMMMXAAXXMAXXMAXSXAAMXAMXSMMMMAMXSMMMXAMXMMSASMXSSMMAMAMXMMMAASXSXSMAMAMAXSMMMMMM\nAASMMMAMASMMSXMMXMAMAMSSMMSMSMAXXXAXASMSASAMAXAAXSAMAXAAMAMAAXSMSMMSMMMMMMXXAMMSXXXASAAXMAMXMAASXSXMAXMXMAMMAMXMSAMAMSASAXAMAXMMSSMMMSXMAMXM\nSXMAXSAMXAAAAMMAMSXMAMXAAXAAMXAMXSMSXMASAMXSAMXSMAMSXMMXMMSSSMMMAMMMAAMSSXXMAMMMMMMXMMMMMASXXSMSAXSAAMMAMXMSAMMXMXMMXAMMXMAMMMSMAMAMASMSASAM\nMMSSMSXSSSXMSMMAMSASMSXSMSMSMMSSMAXSAMMMMMMMASXAXMMSMXSAMXMMAAASASAMSMSAMXXMXMXAAAAAMXXSXAXMAXXMAMASAMSMSMMSAMMSSSSSSMMASXMMMAXMAXXMAXXMMMAS\nAAMXASAMXAMMAXMAXMMSAAAXASAXXXAAXXMMAMAMSAMXAMAMSXSXAAXXMASMMMMSASAXAXMAMMSSMMMSXSSXSAASMMMXAMASASMMSXAAXXASMSAMXAAAXXMASMAAMMSMMSMMSSMXSMMM\nMSSMXMAMMMXSASMSSMAMMMSMAMXMMMSSMSASMMMMSASMAMMAAXMMMMSMMMMMSAASAXMMSXSAMMAAAMAXMMAAMMSMAAAMASASASXAXSSSSMXSAMASMMMMMXMASXSMSSMMAAAMAAMMSAXX\nXMAMMMMASMMMASXAAMXMAAAMAMSSMAAXMMMAMXXMSAMXAMMXMASASXXXAMAAXMMMAMSAMASXSMSSMMASAMMMMXAMMMMAXXMMMMMMXAMAXXSMXMSMXSAMMASXMAXSMAAMSXSMXXMASAMX\nAMMMMAAMAAAMXMMSMMMSMSSSXMAAMSSSXSXSAXXAMXMSSSXAXXXAXAXSXMMSXMXMMMMASXMAMMAAXMXSXMASXSMSSMMSMMMAAMAMMMMAMMMSMXMAMSASAASXMAXASMMMMMXXSMMMSSMX\nSSMMSASMSSMSMAMAXAAAXXXMAMSSMMXMASAMSAMXMAMXAMXSXMMMMSMMAMXXAMXXMSMXAASXXSMSMSMSASXAXSXAAAAAAAMMMXMXASMSSXAASAMAMMAMMMMAMSMMMXSASXAAXAXXXMSX\nXAAAAMXMAXAAXAMXMMMMXMASXMAXXXXMAMAMXXMAXSSMMMAXAMAAAAASXMASMMXMMXSMSXMAMSAXAAASMMMMMSMSMMMSSSSXSAMXASAAMMSMSXXAXMXMXASAMMASAMMASMSSMMMSAMXM\nSSMMSMSMSMSMSMSXMSMSASAMAMMSMSMMAXSMMMSMSMSAXMAXAMSMSSMMMSMSXSXAXAMMMAMXAMXMSMMMSAAAASAMMXAMXXAASAMMSMXMAAAAXMXSSSSMSMSASXXMAXSAMAAMAMAXMSMA\nMAAMXAXAXMXMXAMMAAASAMXSXSXAAAAMMSMAAMAMAASXMMSSSMXXAXXAMAMXMMMSMASASXSXAXMAMXXASMXXXMAMXMMSSMMMMAMXAAXXMSSXXSAXMMAAAASXMAMSAMMASXMMMMSMXAXX\nSSMMMMMMMMAMMSMMMSMMXMMXMAMMXSSMMAXMMSASMMMAXMAAAMMMSMMMSASXXMAMSAMASASXMSXSSSMMMMMXAMXMASXAAAASXMMMMSMXMAMAAMMSASMMMXMMMSAMXSSMMMXSSMAMSMSA\nMAMXXAAAASASAAXAAXAAMSXAXXASAXAXSAMXXSAMXMAMAMMSMMXAXAAAMAMAAASMMXMXMAMMMMAAAAMXAAAAMSAMXAMSSSMSAAAXSAMXMASXSMXSAMMAMSMAMXSMAMMMASASXMAXAAMM\nSMMMSXSSXXAMMMSMSSXMAXSXSSMMXSAMMAMSMSMMMMMXXXMMMXMSSSMSSXMMSMXAMAMAMXMSAAAMMMMSMMMXXAASXMAMAXASXMAMXAMXMAMAXAXMMMMAMASASMMMMXAMXMMMASMSMSMM\nAXAXMAXXMMMMSXMAAMAMMXAMMAXSAMMMMXMAAXXMSASAMXAMSSMAXAAAAXSXXASMMASXMMSSXSXSXSAMMAXSSMMAMXXMAMXMXXMMSSMMMSMXMMSMSASAXMSXMAASMSSSMSXSAMMAMXMM\nSSSSSXMASXMXMAMSMMXAMXMAMAMMMSASMMXMSMXAXASASMXMAMMASMMMSMSAMXMAMAXAAXAXMMMSXMASXAMXAXAXMASMMMSXXSAAAMAAAAXASMAAXAXMSMMMSSMMXAAAXAXMAMSXXAMM\nAAMAMXMXMASMMSMMAMSXXAXSXMSAXSMSAAXSAMXSMAMAMMAMMSMXSXXXAAMSMMSSMAMSMMMMAXAXAMAMMSMSAMSXSAAXMASAASAMXSSMMXMASMMSMSMMAAAMAMXSMMMMMMMXMXMASMSM\nMXMAMMMMXMXXAAMSSMMMMSXXAAMXMXXSMMXMASAMMAMMMSMMXAXAMXMSMSMAMMAAMAXMAMXXSMMSSMASAMMMSMAAMXSAMMMMMSSMXMASMAMSXMAMAMXXSSMSASASXSAXASAMSAMXAMAX\nSMXAXAMXASMMSXMAAAAAAXASMMMSXSMSXSMSXMASXXSAAAASXSMMSMXAMAXMSMSSMXSXAMSMXAAAAXSMASXAAMMSXSMMSSXSXXAMMMAAMXMXAASMMMSXMAMXAMASASMSAMAMSASASXSM\nAAMXXMMXAXAMXXMXSSMSMMMMXAXXAMAMASAXXMAMAAMMMSSMMMAMAASMSXSMAXMAMXAMAMXASMMMSMXMAMMAXXXXXMAASXAMASMMAMSSMMSMSMXAXAMXMMSMMMAMAMXSAMXMSAMXXAMX\nASASXSMSSSSMMMSMMMAAXAXMXXMMAMAMMMSMXMASMMMSAMXMXSAMSXMMAMMXSSSXMMSSXSMXMAAAAMAMMSSMMSAMXSAMMMXMASXSMMAAMASAMXSSMMSAMSXMSSSMMMASASAMXSAMMAMM\nAMXMMAAAXXAAAAAAAMSMXMAMSMSSMXXSAXMMSSMSXXAMASASMSXMMASXAXMAXAMXMAMMASXMMSMSXXAMXAAAAMASAXASMSAMAXAMXMSSMXMAMAMXAAMAXSAMXAAAXMXSMMXSAASAMXMA\nXXMXSMMMSSSMMSSMMMAXSSMXAXMAASMMMXSXAAXMXMXSMMASXMMMSAMSMSMMSAMAMXSMAMASXMAMMSMSMSXMXSASMMSMAAMMMMSASAXXMASAMXXXMMMSMSAMMMMMMMXXXXAMAXMSMXXS\nMXAXXAAXXMASXXAASXMMXAXSXSMMMMAASMSMSSMMMSAMXMASAXMAMAMAXAMXXXXSAMXMASAMAMXAMAAAAAASXMASMXMMMMXMSAXAMXMXMXAMXMSSXSAAASAMSAAAXXMMMMSMSMXAXMAM\nSMSXSSMSXSMMSMSMMAXAMXMAAXAXSXSMMASAXXAAAAASXMASXXMAXMXMXSASXSXMAMXSXMASXMAXSMSMSSMMAMSMMAAMXSAAMMSXXMASMSMSMAXAAMXXXSAXSXSSSXAAAXMAMXSMSAAM\nAMMAMXAMXSXMAMAMXXMSAAAMMMMSAAMXMAMXMXXMXMMMMMMXXAMAMSXSMXMSAMMSAMXXMMXMAXSMXMAMXMXSMMMASMSMAMMSMAMXSMSAMXAAMXMMMMSMAXMMMXMMMMSSSXMAMASAXXSA\nMAMASMMMASAMMMSMMXSMXMSAXAXMMMMAMXSAMSSSMXMAMASMSMSMSMASAMXMXMAMAXMASMASXMMAMMSXSMASMAMMMMAMXMMXMXSASXMASMSMSXXXAAAMXMSASASAAXMAMXMASXMAMAMX\nXMSAMMAMMSAMXAAASXMSSXMXMASMMMSAMAMXAAAAXASASASAMAAXAMXMMASAAMSSSMSAMSMMSXMAMAAMXMAMMAMXAXAMMMSSMMMXXASMMMMAMXSSMSSMSASASASMSSMAMXXMMXMMXXXX\nXXMMSAMXMMAMMMMSMAAASAMXSAXAAXMAMSSMMMSMMMSAMAMAMSMSSSMMMASXMSMXMAMXXXXAMMSXMXSSXMASXMSSMSMXAAMAAXMXMAMMAXMAMAXAAXAAMAMAMAMAMAMSSMSSMSXMASAA\nMMXMXMMSXSSMMSMXXSMMSMSMMMSMMXXAMXAXMXMMSXMAMSMSXAAXAMMSMASAMXMAMAMMSMMXMAXAXAXAXMASAAAMMAMMMSMMMMMAXAMMSXSAMMSMMMMMMMMMMXMXSAMXAMAAAAAMAMMX\nAAAMMSXSAXAAAMAAMXAAXMAAAAAAAAXSSSSMSMAMMXMXMXAXSMSMMMSAMASAMXSASASAMXSSMSSMMMSMMMMMMMMMMASAMAASMSSMSASMMMSXSXAAAAAXAAAMMXMASMSSMMSSMSXMSSXS\nMSMSASAMXMSMMSMMMXMMMAXXMMMSMSAMXAAAMSMMMSAMXMXMASAAXXSASMSAMXSXMAMAXAXAAAMMAMAXAAAAAMMMSASASMXMAAAASAMXMASXMXSSSSSSSSMMAAMXSAMXAAAAMXXAXAAX\nMAMMXMMMMXMMAXAMXXSXSSSSSSMMAAXAMXMMMAMXXSAMSAMXMAMAMMMMMASAMXMXMXSSMSSSMMMSASMSSSSSXSAAMMSMMXAMMMMMMAMSMAMSMAXMMAAXMMMSSXSAMAMSMMSMMAMMAMXM\nSASMMXMAMASMSSSMSMAAAAMAAMMMSMSXAMSMSASAASAMSMSAMAMMMAAMMMMMSASXSAAXMAXAAXXXAMMAAMXAMXMMXAMMMXMXSAMSSXMXMASAMXXXMMSMMSAAMSMXSMMMMAXXMXMXXSSX\nSASAAASASAXMXAAAAMMSMMMMMMAAAXXAXSAMSASMMMMMXASMXMXASXXSAMXMSASAAMMMMMSSMMMMSMMSSMMMMMSSMMSAMXSAMAAAMAXMAMMASMMSAAXAAMMXSAXAAMASMASASMSSXAAS\nMMMMXXMAMXSMMSMSMMXXAXMMMSMSSSXXMMXXMMMMMAASMMMAASXMXAMXXXAMMAMMMSXSAXMASAXSXAAAAMXXSAAMSXSASAMAMMMAXXMASXSMMAASMMSMMAXMAMAMASASMMSAMAAMMSMX\nSSMMXSMXMMAXXXMMMXXSXMASXAAAAMAMMXMAMMAMSSXMAMMSMSASMSMSSSMSMSMMMSASXMSASXSASMMSMMMAMXSMSMSSMASAXSXSSSSXMMAXMMMSAMXMSSSMASMMAMMSAMMAMMMMAAXS\nAMASAAMMSSSXSMASAAMAMXAXSMMMSMSAASMMSMMMAXMMSMMMAMAMXXAAMAAAXAASXMAMAXMAMXMMXSMMMSMMMAXAXXMAMMMMXMAXAMXAMSSMMSXSXSAAXXAMXSAMXSASAMSXMAMMXSAA\nMSAMMSXAMAMAXSAMMXMAMMMXMMAMAXXSMSAAAASMMSMAMAMMSMMMSMMMSMMMSSSMXMAMMMMXMMXAMXXAAXAXMAXMMMSXMXAMXMMMAMMMMAMAXAAMAMXMASMMXSMMAMMSXMMMSASXMXAM\nXMASXMMSSMMAMMMSAASAMASAAXMSMSMMXSMMSXMAAAMASAMAXMAAXAXXMAAXMMMAXSXSAMAAMAMMXMSMSMXMMMSSXXAAMSAMXSXSAMAXMASMMMXMAMAXMAXXMMXMASASMSMASASXMXMX\nSMMMAXMAMMMXSSMMMMMASXMSXMAAXAASAMXAXXSMMASXXAMXSSMSSMMSXSSMSAMMMSASMXMXMMAXSAMXAASMSMAAXASXMAXXAXXMAXSSSMSAAAAXAMMXXSXSASAMXMXSAAMMMXMASAMX\nSASMSMSASMSSMXMASXSXMMMAMSSMXMXMMMMMSASAMXSASMMMMAMAAXAAMAMASAXSAMXSXMXMMSSMAXSMMSAAAMMMMMMMSXSMSMMMSMXAAMSXMMMSASXMXAAMAMASMMMMXMXMSASASASM\nSAMAXASASAXAXMMMSAXXAMMMMMASXMASASAMXAMAMMMMMAAMMAMSSXXMSAMAMSXMXSXSAMSAAAAXAMMASXMAMMAXAXAAMMXAXXSAMMMSMMSXSAMAAMAASMMMSMMMAAXMASXASASXSAMX\nMAMXMAMXMMSMMAXSMMMMSMAXXSAMXSMSASXSMMXAMAAASXMMSMMXMXMXXMXSXMMSMMASAMMMMSXMSAMXMAXSMSMSSSMSSMMSMAMASMXXAMSAMXSMMMXMMAXXAASMSMSMAXMMMXMXMAMM\nXXMXMXMAAXSXASXMAAXAASMMXMMXAMXXASXXAMSSSSXMMXAXAMSMMMAMSMAMAMAAAMAMAMXSMMXAXMSASMMXAAXAAAMAAAMMMXAXAAASAMMXMASAMXAXXXMMSSMAMAXMAMSASAAXMSMS\nMMXXMAXXSMSMMMSMAMSSMSMMSAAMSMMMMMXMSMAAMAXSMSAMMMAAAXXSAMMSAMSSSMXSXMXMAMMXMXSASMAMXMMMSMMSSXMXMXMMMMXSMMMMMXSXMXASMXSXMAMMMMXAXXMAMMMSMAAX\nASMMXSSMXXSAXAAXAXAMXXMASMMXXAMAMAXXAMMXMXMXAXXAASXSMSMSASASAMXMMMMMMMSSMXMASAMAMMXMASAXAAXXMASAMAAAXSMMMAAASXMAXSAMXAAASAMXASMSXSMSMSASMMSM\nSMMAAXAMSASMMSSMSMMXSXMASASASXMSMSSMSSSXAASXMSSSMSMMAAASAMAMMXSAAAAAXAAAMXSASAMSMXXSMSAXMSMSSMMASMSSSXMASMSXSASAMMMMMXMAMMXSMXAAXSAMAMAMAXMM\nMAMMMSAMMAMXAXMXXMSMSXMASAMASAAXAXAXAAMMSMMAXAAAAMAXSMXMXMMMSMMSMSSMSMSSMXMXSMMXAMXXXMMSMMAASXXXAMXXAXSXMXMASMMMSASMMXMSMXAXAMSMMMAMXMASMMMM\nSXMXXSAMMMMMXSMAXAAMSASAMAMAMMMMSMMMMSMAMASMMMSMMMMMXMAMXSAAXAAMXMXMAAXAMXAAMASXMMSMSAAMXMMMXXMXSMSMMMXASXSAXAMXMASAAASXSMSSSMAAAXXMXMAMAAAA\nMAMSAMXMAAAAAXMMSSMXSAMASMMXMXAAXAXMXMASMAMXAXMXXAAAMSMSAXMXMMMSAMXAMXSAMMMXSAMAAXMASMMSAMSMSAMAMAAAMAMMAMMMSMMMMAMMMMSAMXMAMSXSMSASXMMXSMMS\nMAMXASMSXSMMMSAXXAXAMXMXMASXSSSSMMMSAMXXMASASXMASXXXAAAMMSMSMSAXMASMXASAMSSMMXMXMMMXMAMSMSAXSAMSSSSSMXAXMAXAAAAMMASXSSMMMSXSMXMXAMMMAXSAMAXA\nMSSMASAMXXMASXXMXMMAXMASMXMAMAAAASAXXMASXMSXXAMASAAASMXMXAAAAMSXSAMXSASAMXAMASXASASMMSMMXMAXMAMXAAMXMMXSXMMSSSMSSMSAMXAAMXAMXXAMMMSSMMMASAMM\nSAAMAMAMMMSMMMXAAXMXXASMMSMAMMMMMMASMSAMXMXMSMMASMXMXAMSXMSMSSMMMASXMASMMMXMASAXSASMAMASXMMSSSMMMMMAMSASAMXMXXXXAMXAMMSMSMSMSMSMSMMASXMXMAMX\nXMMMASAMAXAAAAMSMSMMMXAXAAXMMXXSXSXMAXXMAMAAAXMXSXMMMMMAAXAAXAAASXMMMXMASXMMXMXAMXMMSMAMAAAAXXXXAAMASMASAMSMSSXMMXXAMXXXXXMXSAXAAASMMMMASAMX\nMXXSXSXSXSXSMXMAAAAAMMMMSSSSMSMSAMAMSMMSASASMSMAMASAAMXSMMMSMXXMMAMXSASMMAAMAXXMXXXAAMAXSMMSSMSXSSSXSMXMAAAAMMAMSSSMSAMASXMXMAMSSXMXSASMSSSS\nSSMSASASASAMXMSMSSSMSAXMAXAAAASMAMMMMAXSXMAMMSMMSAMSMSAMMAMXMSSMSAMAXXSXSMMMSMMAXMMXXMMXMXXAAAAAMXMAMXXXASMSMSSMAAAAAASMSAMMMXMXXXMASASAXMXM\nMAAMMMAMAMMMSXSMXMAMSXXXXMSMSMSSMMMAMSMSMMXMMMAMMMXAXMAXSMSSXAAXMAMXMXMXMASAMXSAMXMMSASAMXSSMMMMSAMXMASMMMXMXAAMMSMMMXAXSAMAAMASAAMAMAMAMMAS\nSMMMXMAMMMXXSAMMASAMMMSSMAXAAAMXSAMXXXAMXXAMAXXMMMSMSSSMAAAMMMMMSSMSAMXASXMASAMASAAASAMAXAXXXMAAXAMMMAMAAAMSMSSMXMAXSMMASAMXSASXSXMXMMMAAMAS\nAAXMASXSSMMXMAMSMSAMXMAAMAMSMSMXSXSXMMMMSSXSMSMAMXXXXAMXMMMSXSSMXMASMXSXSAMXMXSASMSMMXSAMSSMMMMSSXMAMXSSMMMAAXMASMMMSAXAXAMXAMAAMSXAMASXSMXS\nXMAMXXSAMXMMSAMAMXXMAMSMMXXXXXMASMMAXSMAASMXMAAAMMMMMAMASAMMAXMAAMMMAXMMXXMXXAMASXXXMAMAMXAMXXAXMAMSXXXMAXSSSSXAXAXXMXMMMSAMXMMAMSSMSASAXMMS\nMMMSMMXMSAMXSASMSSMSXMXXMXMSMMMMSASMMMMMXSMAMMSMSAAMSMXAXAXMMMMSMMASMAMMSMMXMMSMMMMMMMMMMSMMMMSSXSMMMAMXSXXAAMMMMAMSSSMSAMXXAMXAXMAMMASXXMAM\nAAAAAXAASXXASXMXMXAAMXMXSAAAAAAAMXAMAAMMMSASXAAAMXXXAMMSSMMXSAMXMXMAXAMAAAMMSMAMAXSAXMXSAAAAXAAXXMASAXSAMMSMSMASAAXSAAXMMMASXMSSSSMMMMMAMMAS\nMMSSXSAXXSMASMMXMMSMSASASMSMSSMSSSMSSMXAXMAMMMMSMAXMASAMAMAMSSXMMSXMSSSSMSMAAXAMSMSMSAAMXSXMMSXSAMAMXAMASASXAMAMMMMMMMMAXMXMSAAXXXXXXAAAXMAS\nSAMXXSXMAXMAMAMAXXXXXAMMXAMMAAMAMXXAAMSSSMAMAAAMMSMSMMXMAMAMMASAMXAXAXMAMXMSSMXXMASXAMMSXMASAMMAAMXMMSSMMASMMMSMSXAXAAMAXMMAMMMMSSMSSMSASAAS\nMAXMAXAMSMSSSSSSSMSSMXMMMSMMSSMSSSMMSMAAAMASMMMSAMAXMSSSSSSSXSAMXSMMMMMMMMAMAMSAMAMSAMXXASMMMSMSSMXXXAAMMXMAXSMASASMSSSMSAMAMMAAXAAMAMXASMSM\nSASMMSMMXAAAXAAAAMAMMSMMAXXXMAXAAXMAXMMSMMXMASMMMMXMMXAMMAMMMASMXMASXXMAXMAMAMMAMSMXMXSMMMAAMMAAXXMASMMMSAMSXXMAMAMAXAMAMXSASMMSSXMMAMMXMMAM\nMASAXMAAMMMXMMMSMMXSAMAMASAXSXMMSMSMSSMAMSSMAAMAMSMMSMXMMXMASMXMAXXSAMSAXSAMAMMSMMMASAMAASXMSMMMSXSAMAAASASAAMMMMMMXMMMXMASASMXMAMMMXMASMSMS\nMXMMMXMMSXSMMXAXAMXMASMMMXMMMXMAXAXAAASXMSAMAMMAXAASXAXAMXXASXSMMXAMAMMMMSASMSAXAMXXMASMMSAXXXMAAXMASXMMSXMAMAAAASMMSMSAMAMXMXASXXMAXAMXXAXA\nMMMXAAXXMAMXMAMSAMAMAMXAMXSAXAAXMAMMSMMXXSAMAMSXSSSMMMAMMSMASAMASMMMSMXXASXMAAMMMMASMAMAAXMSMSMMMSMAMMAMXMMSASMMMMAAMAAAMXSAMSMSXAXSXMMASMSM\nSAMMSMSAMAMAMAAXMMXMASMXMASXSXSAMMAMXAXXXSAMXMAMXMAAASMAAXMAMAMAMAMAMMXMXSAMMMMAXMAXMAXMMMMAAMXSXMMAMSAMXMAXMMMSSSMMSMSXMAMAMSXMMSMXASXAXXAX\nSXSAAMSMMMMXMMSMSMASAMAAMAMMMMMAMMSAMXMAMMMSMXAAAXMMMAXMASMASAMXSXMASMMSMSAMXASXSMSSSMMXAAXMSMAXAASMXSAMXMSSXSAAAAXMXXMAMMSAMMAAAAASAMMMMSAM\nXAMMXXSAASMSAAAAAAMSAMSXMXMAAASAMXMASAAAMAMAXXXMMSMASXMSAMXASMSMSAMASMAAAMMMSMSAMXXAAMASMSSXXMASXMMSAMXASMMXAMMMSMMXMAMSMASASMMMMSAMXSASMASA\nMMMSMAMSXXAAMMMMMMAMAMXAMXSSSMSASXMMSMSMMASMSSMMAAXAMSAXMMMMSAMASXMASMSMMMSAXXXXXSMMMMAXXAAMXMXSAAMXSMXXXAAMXMSXXXMASMXMMASAMXXAXXXMAXXSAAMM\nAAAAMXMXXMAMXASMSMAMSMSASAAAMXSAMAXXXMAXMMSAAAASXMMSSMSMAAAMMMMXMMMXSMMAXXMMSSMSMAASXMXSMXMMXSSXMASAXXMSSSMSAMXXAXXMAMMAMAXAMXMSSSSMASXXMMSX\nXMSXMXMAASAXXMMAXMAMAAXAMMMMMAMASAMXASMSAAMMMMMMAAAXSAMMSSMSASMXAXXAXAXMXSAAAMAAMMXMXMASMSSMAXMASXMASAAMAMAXMAMXSSMMAXXAMSSMMMAXAAXMXMMAXAXX\nSMMXMAMXMSASMXMMMSMSXSMXMAXMMXSAMXMXMMAMMXMAXAASMMMSMMMAAAASASMSAMMSSSMAASMMSMSMSXMASMASXAAMMMSAMXMMSMSMAMXMXXSMAAXMMXSASMAMXMMMMMMMSSSMMSSM\nMAAAXAMXAXASAAXXXAAAAXMXSXSSMASMSASASMAMXMSXSSMXAASXAAMMSSMMAMXSSSXMAMMMMSXMAAAAXAAMAMAMMSXMAAXMMXSAXMAMASMSXMAAXSMAAAXXMMAMXAAAXAMXAAXXAAAX\nMMMMSSSMSMMMXSSMSXSMXMAXMMSAMXSASASASXXSAMMMAXAXSMMSMMXMAXXMMSAMXMAMXMASXXAXMSMMSMMSAXXXXAMMSMMSMAMASXMXMSMAAXXSAMMMMSSXSMSMMSMSXMSMMXXMMXMM\nSXSXXMAAXXXMAXXXAMXMAMMASXSAMXMAMMMAMXMMMAAAMSMMMAMXXAXMMMXMASMASMXMXSXSMSSMMAXAMMASMSSXMASXAXAAMXSMMAMASXMMSMAMMSAXAAAASAXAAMAXXMXAXMSXSASA\nAAMXMSMMMSMSMMXXMAAAAXSXXMSAMMMSMSMMMMXSSSSMXMAASAMMMMSSMMAMXSXXSAMMMMXMAAMMSAMMSMMSAMXASAMMMMSMSAMXSAMXSAMAAMXMXSAMXSMXMASMMMAMAXSAMXAASASX\nMMMAXAAAAAAXASASMSMXMMAMXMSXMXMAAAMXSAMXAXXMSMMMSAMXAAAAASXXMXMMMMXAAXXMMMSAMXXXAMAMMSSMMAMASXXXMMMMXXSMSAMSXMASXMXXXAXXMMMXXMAXXMXMAMMMMAMA\nXAMSSSSMXSSXMMASMASAXSASMAMAMASMSMSAAXAMSMSXSASASXMMSSSSMMAMSMMAAXMMMXXMAMMXSMSMSMMSAAAXSSSXSAXXMASXSAMXMAMXASAMMAMMMMSAMASXSSSSXAAMSMMXSAXX\nSXSAAMXMAMAMXMXMMASXMSASXAXAXMSAMXMMXMMSAAAASAMXMAXAMXMAMXAXAAXMSSSSMSSSMSAMMAAAXAMMMSSMAASAMXMMXMAAMXMXSXMMAMMSMAMXAXMASASAXAAMMMMXMXMAXMMM\nXMMMSSSMMSAXXXMXMXSAMMXMXXXXXMMMMXAXAXSAMXMAMMMMSAMSSSSSMSASMSMAMAAXAAXAMMAMMSMMMAMXMXAXMMMMXMASAXMSMXSAMMXXAXMAXASMMMSAMXMAMMMMMASMXSMMXMMM\nXSXMAMAAASMMMASXMASAMAXMXMSMSAAAXXSMXSAAAXXXXMAAMASAAMAMAXAAAMMAMMMMMMSSMSSMAXAXSAMAXXAXXXAMXMXMMSAAAMXAXAMSXMSSSMXAXAMMSMXMAXSMSMSAASXMASMA\nXSASXSMMXSXSAAXAMAXXMMMXAAAAAMSMXAMXXAXMAXMXSSMMSMMMSMAMMMSMMMSXSXMXSAAXMAAMAMSXSASXSMXMMSMSAMASXMXSMMSSMMXSAMXAAMSSXMSXAMAXMAXMAXMMMMAAXAAX\nMSAMXXXMASXMMMSSMSSXAMASMSMSMMAMMXMMAMXSXSMAAAAXSAMSAMXSMAAXXXMXMAMMMMSSMSSMXXMASMMMXMASXAXAAMASMSAMAAXAAMAXMMMSMMXXAAAXASMSSSXSSSSMSSSMSMSM\nAMXMXSXSSSXMAMAXAXXMSAMXAAAAXSASXMSMSXAMAAMMSMMMMAMXASAAMSSXSAAASAMMSXMAXAAMSAMXMXAXSXASXXSSSMASMMASXMMSMMMXSAAMXMASMMMXXXAAAAAMAXXAAAXAAAXA\nMXMASMAMAXASXSMMXMXAXASAXMXMXMXSMAAAXXSSSMXXAAXASMMSMMASXXMASMSMMSSXMASXMMSXSMSMMXSSMMXMXXMAXMSMMSAMAAXMMMAASMSSXMAXASXMXMSMMMMMAMMMMSMSMSMS\nXAMXAMAMXMMMAAXSSMSMSASAASXXAMASASMSMMMAMXASXSMXXMAAXMAMXXMMMXXMXXXXSMMMXXAXMXSMAAMAMAAMXSMMMMMAXXMSMMXXAMMXSMAMAMMSMMAASAXASXAXAXAAAXAXAAAA\nASXSMSMSMSAMXMMSAAMXMAMMMXAXSMASMXAAMAMAMXXMAMXMSSSMSMASMXSAMSAMXMXAXAAMMSSMAAMMMMSAMSMMAMXXAMXSMAMXAAASMMMMSMASAMAAMSMMAASAMSSSMMSSSMXMSMSM\nMMAMXAAAASASXMMSMMMXMXMSMSMMAMMSXMSMXSMMSASMMMAXXAAAXXSXXAXAMMMMXMAMXSMSAAAXMAMXAXMXMXAMMSASXSAMMXMSMMXXAAXXXSAXAMMMXXSSXAMAMXXAMAXAAMSAAAXA\nXMAMMMXMMSXMAAXXXSXMMAXAAAMAXSAMXXASMXMXMMMASMMMMXMMMMMXMXSXMSASMSSXAXMMMSSMXSXMMSMSMMXMXMAMXMMSMMAXXMSSSMMMXMSMSMSMSAMXMXSXMXSAMXMMAMSSMSMM\nMSASASMSASASXMMSSMASMMSMSMMMXXMASXAMMASAMXSAMAMXXMSMSASXMASMMSASAAMMSMAAAMAMAMAMAAAAMMSSSMSMXSAAAXXXXAMAMAAMSAMXXAAAMMMAXMAMXAMAMXMMXAXAMXAX\nAMASAMAMAXAMAMAXAMXMAMAXMASMMMXXXMMMSMMASAMXMAMMSSMAMAMXMXSAXMMMMMSAMSSMMSAMXSAMSMMMMXAAXAAASMSXSMMMSMMAMXMSMAMAMAMMMASAMXMXMXSAMXMAMSSMMSSM\nMMMMMMAMMSMSAMMSSMMSMMXMXAMXMXXXXASAMXSMMMSMSAMAMAMMMAMAXXXMXMXSXMMMXAXAXMXMASAMXMASXMMXMMMXMAXMAAAAXXMAMXSXXAMXXAMXMXMAMXXXXMXAXAXXSAAAAAAX\nXSXAASXMAAMXASAAAAASXSASASMASMMMMXMASAXSAXAMSXMSSSMXSMSMSMSMSMASAMAMMMMMXMMMXSSMSAMAAASASXSXMAMSSSMSSMSMSMSASXSXSMSXMSMSXMASXMSSSMSMMMSMMSXM\nAAMSMSXMMSXSAMMSMMMSASASAASASMAAAASXMASXMMAXSAXMAXMAXAAMAAAAAMASAMXSAXAAMMASXMASXAMSMMMASAMXMAMAAMAMXAAAMAMXMXMASAAAAAAXAAAMMAAMAAMAXMMXMAXS\nAXXXAXXXMAXMXMAMAMXMMMMMXAMXSXSXSASXMXMXMASASAMMAMSAMSMSMAMSMSMSXMXSMSASXSXSAMXSSXMAXAMXMXMAMMMMSMMMMSMSMXMASXMAMXSSMMAMAMASMXMSMMMSXMASXMAS\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_04_questions.txt",
    "content": ""
  },
  {
    "path": "exm/aoc/2024/aoc_2024_05.adb",
    "content": "--  Solution to Advent of Code 2024, Day 5\n------------------------------------------\n--  Print Queue\n--\n--  https://adventofcode.com/2024/day/5\n--  Copy of questions in: aoc_2024_05_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_05 is\n\n  use AoC_Toolbox, HAT;\n\n  type Rule_Line is record\n    a, b : Integer;\n  end record;\n\n  rule : array (1 .. 2000) of Rule_Line;\n  last : Natural := 0;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_05\";\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data (part : Part_Type) is\n    dummy_separator : Character;\n    f : File_Type;\n    update : array (1 .. 100) of Natural;\n    lu : Natural;\n    already_correct, correct : Boolean;\n    tmp : Integer;\n  begin\n    Open (f, input_name & \".txt\");\n    last := 0;\n\n    while not End_Of_File (f) loop\n      last := last + 1;\n      Get (f, rule (last).a);\n      Get (f, dummy_separator);\n      Get (f, rule (last).b);\n      if End_Of_Line (f) then\n        Skip_Line (f);\n        exit when End_Of_Line (f);  --  Empty line\n      end if;\n    end loop;\n\n    lu := 0;\n    while not End_Of_File (f) loop\n      lu := lu + 1;\n      Get (f, update (lu));\n      if End_Of_Line (f) or End_Of_File (f) then\n        already_correct := True;\n        loop\n          correct := True;\n          Scan :\n          for i in 1 .. lu - 1 loop\n            for j in i + 1 .. lu loop\n              --  put(update (i));\n              --  put(update (j));\n              --  new_Line;\n              for r in 1 .. last loop\n                if rule (r).b = update (i) and then rule (r).a = update (j) then\n                  correct := False;\n                  already_correct := False;\n                  exit Scan when part = part_1;\n                  --  Swap the pages\n                  tmp := update (i);\n                  update (i) := update (j);\n                  update (j) := tmp;\n                  exit Scan;\n                end if;\n              end loop;\n            end loop;\n          end loop Scan;\n          exit when correct or already_correct or part = part_1;\n        end loop;\n        --  Put_Line(ok);\n        if already_correct then\n          if part = part_1 then\n            r (part_1) := r (part_1) + update ((lu + 1) / 2);\n          end if;\n        elsif correct and then part = part_2 then\n          r (part_2) := r (part_2) + update ((lu + 1) / 2);\n        end if;\n        lu := 0;  --  Clear data (update).\n      else\n        Get (f, dummy_separator);\n      end if;\n    end loop;\n\n    Close (f);\n  end Read_Data;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n\n  Read_Data (part_1);\n  if not compiler_test_mode then\n    Read_Data (part_2);\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 5166\n    --  Part 2: validated by AoC: 4679\n  end if;\nend AoC_2024_05;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_05.txt",
    "content": "96|89\n15|17\n15|93\n55|49\n55|82\n55|72\n37|87\n37|26\n37|33\n37|12\n52|57\n52|89\n52|67\n52|19\n52|38\n58|97\n58|22\n58|91\n58|93\n58|32\n58|12\n61|49\n61|87\n61|58\n61|39\n61|63\n61|52\n61|84\n33|51\n33|49\n33|21\n33|71\n33|44\n33|97\n33|57\n33|67\n54|41\n54|56\n54|26\n54|96\n54|39\n54|44\n54|95\n54|52\n54|45\n88|57\n88|84\n88|55\n88|89\n88|91\n88|32\n88|25\n88|63\n88|33\n88|69\n24|26\n24|37\n24|45\n24|33\n24|25\n24|69\n24|15\n24|56\n24|87\n24|84\n24|63\n32|24\n32|21\n32|93\n32|62\n32|51\n32|72\n32|41\n32|71\n32|19\n32|95\n32|17\n32|53\n13|55\n13|65\n13|87\n13|96\n13|69\n13|25\n13|24\n13|26\n13|84\n13|33\n13|52\n13|39\n13|79\n31|25\n31|96\n31|55\n31|45\n31|61\n31|49\n31|39\n31|87\n31|58\n31|12\n31|37\n31|84\n31|89\n31|24\n93|38\n93|51\n93|62\n93|17\n93|44\n93|41\n93|79\n93|53\n93|65\n93|88\n93|56\n93|19\n93|71\n93|97\n93|24\n87|21\n87|19\n87|17\n87|89\n87|97\n87|93\n87|62\n87|55\n87|57\n87|15\n87|82\n87|22\n87|12\n87|63\n87|33\n87|49\n53|56\n53|37\n53|71\n53|54\n53|97\n53|17\n53|31\n53|88\n53|51\n53|79\n53|13\n53|61\n53|38\n53|95\n53|19\n53|47\n53|72\n71|51\n71|61\n71|37\n71|69\n71|96\n71|24\n71|87\n71|39\n71|65\n71|95\n71|47\n71|31\n71|79\n71|44\n71|88\n71|54\n71|84\n71|26\n84|58\n84|25\n84|77\n84|89\n84|82\n84|63\n84|57\n84|52\n84|33\n84|55\n84|17\n84|12\n84|26\n84|49\n84|67\n84|93\n84|53\n84|32\n84|91\n21|65\n21|39\n21|41\n21|56\n21|52\n21|37\n21|88\n21|62\n21|31\n21|47\n21|79\n21|61\n21|51\n21|69\n21|13\n21|72\n21|24\n21|54\n21|84\n21|95\n69|45\n69|57\n69|89\n69|33\n69|84\n69|58\n69|91\n69|63\n69|82\n69|96\n69|25\n69|15\n69|67\n69|49\n69|39\n69|93\n69|32\n69|87\n69|52\n69|12\n69|55\n49|17\n49|79\n49|67\n49|51\n49|54\n49|22\n49|57\n49|93\n49|72\n49|77\n49|38\n49|13\n49|82\n49|62\n49|44\n49|21\n49|95\n49|71\n49|32\n49|15\n49|53\n49|19\n47|58\n47|57\n47|39\n47|63\n47|89\n47|96\n47|33\n47|93\n47|91\n47|26\n47|45\n47|55\n47|25\n47|15\n47|82\n47|69\n47|67\n47|77\n47|32\n47|87\n47|49\n47|52\n47|12\n25|57\n25|32\n25|62\n25|63\n25|33\n25|77\n25|71\n25|19\n25|91\n25|21\n25|38\n25|72\n25|97\n25|93\n25|95\n25|12\n25|15\n25|82\n25|54\n25|53\n25|22\n25|67\n25|49\n25|17\n65|26\n65|52\n65|63\n65|47\n65|77\n65|91\n65|12\n65|39\n65|82\n65|96\n65|61\n65|56\n65|15\n65|49\n65|55\n65|88\n65|58\n65|25\n65|84\n65|87\n65|45\n65|89\n65|69\n65|33\n62|71\n62|45\n62|52\n62|95\n62|44\n62|56\n62|61\n62|39\n62|72\n62|65\n62|41\n62|31\n62|37\n62|97\n62|96\n62|47\n62|24\n62|69\n62|79\n62|84\n62|13\n62|54\n62|51\n62|88\n63|57\n63|97\n63|19\n63|15\n63|21\n63|77\n63|72\n63|54\n63|13\n63|67\n63|51\n63|71\n63|53\n63|38\n63|49\n63|17\n63|93\n63|95\n63|41\n63|32\n63|22\n63|82\n63|44\n63|62\n57|67\n57|93\n57|44\n57|54\n57|19\n57|79\n57|56\n57|38\n57|62\n57|21\n57|53\n57|13\n57|37\n57|22\n57|24\n57|31\n57|72\n57|17\n57|95\n57|65\n57|71\n57|51\n57|97\n57|41\n77|19\n77|79\n77|31\n77|22\n77|21\n77|67\n77|97\n77|62\n77|54\n77|82\n77|32\n77|51\n77|71\n77|53\n77|44\n77|95\n77|38\n77|57\n77|41\n77|24\n77|13\n77|93\n77|72\n77|17\n19|62\n19|97\n19|39\n19|21\n19|13\n19|54\n19|69\n19|88\n19|79\n19|45\n19|47\n19|56\n19|51\n19|84\n19|95\n19|72\n19|31\n19|61\n19|24\n19|44\n19|37\n19|41\n19|65\n19|71\n39|84\n39|67\n39|91\n39|12\n39|32\n39|53\n39|87\n39|25\n39|63\n39|89\n39|96\n39|58\n39|15\n39|49\n39|38\n39|52\n39|33\n39|22\n39|55\n39|57\n39|77\n39|93\n39|26\n39|82\n79|87\n79|88\n79|26\n79|61\n79|24\n79|52\n79|47\n79|37\n79|33\n79|91\n79|84\n79|65\n79|45\n79|63\n79|25\n79|39\n79|31\n79|56\n79|12\n79|58\n79|96\n79|69\n79|89\n79|55\n41|87\n41|79\n41|65\n41|39\n41|44\n41|55\n41|61\n41|37\n41|84\n41|58\n41|52\n41|45\n41|69\n41|56\n41|96\n41|47\n41|13\n41|51\n41|24\n41|31\n41|88\n41|25\n41|26\n41|89\n12|41\n12|77\n12|71\n12|67\n12|97\n12|93\n12|91\n12|82\n12|63\n12|62\n12|19\n12|32\n12|57\n12|21\n12|54\n12|38\n12|95\n12|53\n12|15\n12|49\n12|72\n12|17\n12|33\n12|22\n91|71\n91|63\n91|77\n91|49\n91|57\n91|51\n91|53\n91|33\n91|38\n91|82\n91|93\n91|62\n91|32\n91|41\n91|15\n91|22\n91|97\n91|21\n91|54\n91|17\n91|72\n91|95\n91|67\n91|19\n51|61\n51|26\n51|87\n51|65\n51|44\n51|84\n51|24\n51|39\n51|45\n51|52\n51|56\n51|96\n51|79\n51|47\n51|13\n51|89\n51|12\n51|69\n51|55\n51|31\n51|25\n51|58\n51|37\n51|88\n95|56\n95|58\n95|41\n95|39\n95|96\n95|79\n95|26\n95|47\n95|55\n95|45\n95|31\n95|61\n95|88\n95|84\n95|89\n95|65\n95|69\n95|44\n95|52\n95|87\n95|37\n95|24\n95|13\n95|51\n22|47\n22|21\n22|31\n22|62\n22|88\n22|45\n22|79\n22|97\n22|41\n22|37\n22|19\n22|61\n22|13\n22|24\n22|54\n22|69\n22|65\n22|44\n22|51\n22|95\n22|17\n22|71\n22|56\n22|72\n97|51\n97|31\n97|41\n97|54\n97|61\n97|71\n97|84\n97|45\n97|47\n97|95\n97|24\n97|26\n97|79\n97|96\n97|37\n97|72\n97|52\n97|69\n97|13\n97|44\n97|56\n97|65\n97|88\n97|39\n38|61\n38|31\n38|47\n38|65\n38|44\n38|88\n38|41\n38|37\n38|95\n38|62\n38|56\n38|79\n38|22\n38|17\n38|19\n38|97\n38|21\n38|71\n38|24\n38|51\n38|54\n38|72\n38|69\n38|13\n82|32\n82|53\n82|79\n82|17\n82|37\n82|44\n82|57\n82|31\n82|38\n82|54\n82|95\n82|13\n82|41\n82|19\n82|72\n82|24\n82|62\n82|71\n82|21\n82|93\n82|51\n82|67\n82|22\n82|97\n44|45\n44|87\n44|37\n44|47\n44|25\n44|56\n44|84\n44|58\n44|24\n44|89\n44|69\n44|13\n44|79\n44|26\n44|88\n44|52\n44|31\n44|91\n44|39\n44|12\n44|55\n44|61\n44|65\n44|96\n72|52\n72|65\n72|54\n72|84\n72|88\n72|44\n72|26\n72|96\n72|47\n72|37\n72|79\n72|39\n72|69\n72|71\n72|87\n72|95\n72|56\n72|31\n72|24\n72|41\n72|45\n72|51\n72|61\n72|13\n26|17\n26|57\n26|91\n26|67\n26|12\n26|89\n26|15\n26|32\n26|22\n26|82\n26|77\n26|38\n26|33\n26|55\n26|63\n26|49\n26|21\n26|58\n26|93\n26|19\n26|25\n26|53\n26|87\n26|62\n17|88\n17|45\n17|71\n17|44\n17|41\n17|79\n17|19\n17|97\n17|62\n17|39\n17|69\n17|54\n17|72\n17|37\n17|13\n17|47\n17|61\n17|21\n17|51\n17|31\n17|56\n17|24\n17|95\n17|65\n45|89\n45|53\n45|39\n45|52\n45|87\n45|63\n45|12\n45|91\n45|67\n45|32\n45|33\n45|93\n45|82\n45|57\n45|15\n45|77\n45|25\n45|96\n45|38\n45|84\n45|55\n45|58\n45|49\n45|26\n67|71\n67|61\n67|19\n67|95\n67|97\n67|21\n67|56\n67|41\n67|79\n67|24\n67|65\n67|37\n67|38\n67|22\n67|54\n67|72\n67|17\n67|51\n67|31\n67|13\n67|62\n67|88\n67|44\n67|53\n89|53\n89|25\n89|97\n89|93\n89|91\n89|62\n89|22\n89|54\n89|32\n89|15\n89|82\n89|38\n89|12\n89|17\n89|33\n89|49\n89|57\n89|19\n89|63\n89|21\n89|72\n89|77\n89|67\n89|71\n56|52\n56|87\n56|96\n56|25\n56|45\n56|63\n56|89\n56|88\n56|82\n56|61\n56|26\n56|33\n56|58\n56|84\n56|12\n56|39\n56|55\n56|15\n56|91\n56|47\n56|77\n56|32\n56|49\n56|69\n96|58\n96|22\n96|49\n96|77\n96|82\n96|32\n96|57\n96|19\n96|21\n96|87\n96|55\n96|33\n96|38\n96|15\n96|63\n96|17\n96|53\n96|12\n96|67\n96|26\n96|25\n96|91\n96|93\n15|19\n15|54\n15|13\n15|77\n15|38\n15|31\n15|72\n15|32\n15|41\n15|51\n15|71\n15|44\n15|53\n15|97\n15|95\n15|82\n15|67\n15|57\n15|21\n15|79\n15|62\n15|22\n55|33\n55|15\n55|93\n55|12\n55|38\n55|22\n55|89\n55|58\n55|21\n55|62\n55|67\n55|19\n55|97\n55|91\n55|17\n55|32\n55|25\n55|57\n55|63\n55|77\n55|53\n37|77\n37|25\n37|91\n37|49\n37|52\n37|58\n37|15\n37|63\n37|89\n37|56\n37|39\n37|47\n37|96\n37|88\n37|84\n37|69\n37|65\n37|61\n37|55\n37|45\n52|12\n52|82\n52|96\n52|53\n52|77\n52|58\n52|25\n52|49\n52|93\n52|55\n52|22\n52|33\n52|26\n52|32\n52|87\n52|15\n52|63\n52|91\n52|17\n58|19\n58|25\n58|21\n58|71\n58|62\n58|67\n58|82\n58|15\n58|33\n58|89\n58|49\n58|77\n58|63\n58|38\n58|17\n58|57\n58|53\n58|72\n61|32\n61|26\n61|57\n61|77\n61|47\n61|33\n61|96\n61|45\n61|55\n61|25\n61|12\n61|82\n61|15\n61|93\n61|91\n61|89\n61|69\n33|53\n33|63\n33|77\n33|62\n33|19\n33|54\n33|38\n33|32\n33|93\n33|72\n33|82\n33|22\n33|95\n33|17\n33|15\n33|41\n54|55\n54|51\n54|13\n54|87\n54|58\n54|65\n54|88\n54|47\n54|79\n54|84\n54|31\n54|24\n54|69\n54|37\n54|61\n88|61\n88|87\n88|82\n88|12\n88|39\n88|15\n88|49\n88|52\n88|77\n88|47\n88|26\n88|58\n88|45\n88|96\n24|39\n24|12\n24|91\n24|61\n24|52\n24|88\n24|96\n24|49\n24|47\n24|65\n24|58\n24|55\n24|89\n32|57\n32|65\n32|37\n32|67\n32|38\n32|44\n32|97\n32|13\n32|31\n32|79\n32|54\n32|22\n13|37\n13|88\n13|91\n13|31\n13|56\n13|58\n13|61\n13|47\n13|45\n13|12\n13|89\n31|63\n31|91\n31|65\n31|26\n31|88\n31|33\n31|56\n31|47\n31|52\n31|69\n93|72\n93|54\n93|37\n93|22\n93|31\n93|21\n93|67\n93|13\n93|95\n87|25\n87|38\n87|53\n87|32\n87|58\n87|67\n87|77\n87|91\n53|44\n53|62\n53|65\n53|21\n53|41\n53|24\n53|22\n71|55\n71|13\n71|45\n71|52\n71|56\n71|41\n84|96\n84|38\n84|87\n84|22\n84|15\n21|44\n21|45\n21|71\n21|97\n69|26\n69|53\n69|77\n49|41\n49|97\n47|84\n\n79,65,51,72,41,95,37,24,97,61,13,44,21,38,71,56,17,31,47,62,22,88,19\n62,97,72,71,54,95,41,51,44,13,79,31,24,37,65,56,88,61,45,39,52\n13,79,21,69,97,54,22,17,56,51,44,65,72,19,71,61,88,62,24,41,95\n54,95,13,79,31,24,56,88,61,47,39,84,52,96,55\n56,69,39,52,26,55,89,25,91,15,82\n37,21,24,51,19,72,54,44,56,95,41,71,22,38,17,62,67,88,65,31,97\n79,51,97,84,61,41,21,95,71,72,62\n65,56,88,47,69,45,39,84,52,96,26,87,55,58,89,12,33,63,49,15,77\n72,41,54,19,95,13,65,24,44,38,62,22,71,97,93,31,57,37,53,67,21\n21,32,79,51,67,53,44,19,15\n57,13,19,93,82,67,79,53,22,62,41,71,54,21,32,17,72,44,51,15,38\n97,72,71,95,41,51,44,13,31,24,37,65,88,61,47,69,84,52,96\n17,21,72,95,41,51,44,79,65,56,88,47,45\n79,24,37,65,56,88,47,69,45,39,52,87,55,58,89,25,12,91,33\n62,97,95,41,51,44,13,56,52\n56,69,89,25,33,49,15,77,82\n62,71,54,95,45,39,52\n95,49,77,17,44,54,38,57,97,67,62,22,13,82,32,41,19\n41,51,44,13,79,31,24,37,65,56,88,61,47,69,45,84,52,96,26,87,55,58,89\n39,84,52,96,26,87,55,89,12,91,33,63,49,15,77,82,32,93,67,53,38\n12,15,77,32,93,53,22,19,62\n31,24,37,61,84,89,63\n47,39,84,96,26,55,58,91,33,15,77,32,93\n61,47,69,39,58,25,91,33,49,15,77,32,57\n12,91,25,96,45,13,58\n33,77,57,38,19,62,72\n51,67,71,19,53,54,32,93,17\n37,65,56,88,47,69,39,84,52,96,26,87,58,89,25,12,91,33,63,49,15\n15,77,57,93,17,21,62,97,54,95,13\n87,88,65,26,13,58,39,37,47,55,25,89,51\n63,19,72,89,49,25,15,67,62\n41,51,79,37,45,52,89\n31,65,56,88,61,47,69,45,39,52,26,87,55,58,89,25,12,91,63\n91,32,55,77,25\n96,91,52,37,84,31,12,55,39,87,89,69,24,25,65,88,47,45,33,58,26,79,56\n63,25,15,56,61,45,96,52,87,88,39,49,58,26,89,91,84,69,47,77,65\n26,87,55,89,33,49,15,82,32,57,93,53,38,22,17,19,21\n12,32,82,53,57,96,15,52,91,63,33\n62,45,61,44,54,88,52,97,69\n67,22,19,21,62,97,54,95,51,44,79,24,37,56,88\n41,51,44,13,79,31,65,56,88,61,69,45,39,84,52,96,26,87,55,58,89\n56,63,52,33,47,82,58\n38,93,15,84,57,22,89,91,26,53,67,96,82,77,25,32,63,58,33\n53,82,67,32,58,87,22,38,93,26,25,57,91,96,33,63,49,89,12,19,17,55,15\n96,26,55,58,89,25,91,33,63,15,77,57,93,67,53,38,17\n33,49,15,77,93,53,38,22,97,71,54,41,51\n26,87,58,89,12,91,33,77,32,57,93,67,53,38,21\n61,47,69,39,87,55,58,89,33,63,15,82,57\n44,38,15,51,53,72,62,22,95,93,41,17,71,82,97,19,13,32,21,79,57,54,67\n41,95,54,52,39,56,26,72,71,37,65,24,51,13,88\n24,65,88,45,39,84,52,26,55,58,89,25,12,91,33,63,49\n24,52,55,87,56,89,65,33,84,12,58,39,45,88,31,91,37,25,79,47,96,61,26\n88,39,24,63,25,61,33,37,56,96,31\n21,62,97,72,54,41,51,44,31,24,37,65,56,61,47,69,45,39,84\n88,61,69,45,39,84,52,96,26,87,55,58,89,25,12,91,33,63,49,77,32\n67,96,15,93,87,52,39,26,69,77,58,32,91,82,63,84,12,55,57\n38,93,51,71,31,97,57,21,72,13,41,44,65\n84,96,87,89,12,33,63,49,15,77,32,57,53\n61,47,39,55,25,12,33,82,57\n89,25,12,49,32,67,38,19,62\n82,93,97,71,54,79,24\n89,91,55,25,12,32,97,63,93\n62,97,72,54,95,41,51,44,13,79,31,24,65,88,61,45,39,84,52\n97,93,71,21,67,95,54,33,91,22,72,32,82,63,53,12,57,77,49\n13,24,47,69,84,96,87,58,25,12,91\n65,25,89,37,24,58,55,49,69,63,61,87,56,33,39\n13,49,54,32,22,62,19,44,97,57,38,71,15,51,82,93,21,53,67\n87,55,89,25,12,91,33,63,49,15,77,82,32,57,93,67,53,38,19,21,62\n91,63,49,38,17,97,41\n93,67,53,38,22,17,19,21,62,97,72,71,54,41,44,13,31,24,37,65,56\n84,52,26,87,58,89,25,12,91,33,63,15,82,32,93,67,53,38,22\n22,17,21,62,97,71,95,41,51,44,79,24,65,56,61,47,69\n51,89,45,69,26,56,24,88,61,47,39,31,44,65,96,25,55,37,58\n88,31,56,69,26,13,39,37,96,55,45,61,58,24,65\n21,24,41,72,93,53,17,65,13,54,62,95,38,57,37,31,97,19,71,22,67,51,79\n15,77,22,91,67,17,49,82,72,12,32\n32,93,67,53,22,17,19,21,62,71,54,41,51,13,24\n31,24,56,88,61,45,39,96,26,87,55,89,25,12,91,33,63\n72,95,41,51,44,13,31,24,37,65,56,88,47,69,39\n88,58,52,24,26,13,89,25,39,84,45\n21,62,51,13,37,65,84\n33,77,82,32,67,38,17,97,71,95,51\n12,33,91,53,21,82,32,15,57,93,17,38,77,67,89,87,62,25,58\n79,26,55,24,39,88,89,51,31,47,52,58,37,25,56,61,84,44,13\n56,31,45,39,91,52,79,12,96,69,13,37,25,88,87,89,24,65,58,84,61\n53,38,17,97,71,54,41,13,24\n89,93,53,33,87,25,77,57,63,19,91,15,22,38,21,12,58,32,67,82,17\n71,97,79,17,13,54,44,41,22,21,93,57,32,38,31\n97,72,71,54,95,51,44,79,65,56,88,69,45,52,96\n77,87,49,25,67,89,15,33,55,93,17,91,38,12,82,53,63,26,52,96,22\n49,77,82,32,53,62,41,51,13\n39,57,55,89,82,25,93,49,96,45,58,33,53,67,12,77,91\n17,31,21,95,69,41,61,79,13,72,47,88,97,44,62,65,51,45,24\n25,12,91,33,63,77,82,32,57,93,67,53,38,22,19,21,62,97,72,71,54\n62,71,54,41,51,24,37,65,88\n41,44,13,79,65,56,61,69,45,52,96,26,87,58,89\n62,72,51,44,88,61,84\n37,65,56,61,47,69,45,52,96,26,87,55,33,49,15\n47,69,45,96,26,55,58,25,12,63,49,15,77,82,93\n37,26,52,65,55,15,63\n19,57,17,77,67,58,22,72,12,62,53\n56,41,72,96,47,97,88,24,52,84,45,37,51\n32,53,21,62,95,41,44,79,37\n38,22,62,72,79,41,37,53,56,24,44,19,51,31,97,54,71\n96,39,58,25,61,55,13,47,65,84,52,12,89,87,56,91,45,69,37\n45,67,32,93,63,53,96\n79,95,69,96,54,87,71,26,52,65,41,44,31,24,51,84,61,37,56\n32,93,17,19,97,71,54,95,44,79,24\n45,63,25,69,58,93,87,33,12,49,84,55,47,89,26\n61,56,58,37,44,95,26,31,96,87,39,65,52,51,88,84,13,45,24,41,47,79,69\n31,61,58,33,47,24,79,52,87,89,91\n63,84,52,32,77,93,91,87,96,53,55,57,82,12,26,22,67,89,25\n71,54,95,51,24,88,47,69,84,52,26\n69,45,39,84,52,96,26,87,55,58,89,12,63,49,15,77,82,32,57,93,67\n25,12,82,57,93,53,54\n62,97,54,95,44,13,24,65,56,69,45,84,52\n26,87,89,25,12,49,53,38,22,19,21\n79,56,88,47,69,96,89,12,33\n57,93,53,38,19,62,71,54,41,44,79,31,65\n15,77,32,22,19,62,97,72,71,54,95,41,51,13,79\n49,77,32,93,67,53,17,62,97,72,71,51,13\n26,25,89,49,58,24,37\n25,12,33,63,49,15,82,32,93,67,38,22,21,62,97,71,54\n13,31,24,37,65,56,88,61,47,45,39,84,26,87,58,89,25,12,91\n51,44,24,65,56,88,47,96,87\n71,54,51,44,13,79,31,65,88,61,47,69,39,52,26\n55,89,25,12,91,33,63,49,77,82,32,57,93,53,38,22,17,19,21,62,97\n19,62,71,95,51,13,79,31,37,56,61,45,39\n33,63,15,77,67,17,97,71,51\n93,17,62,54,51,44,31,24,56\n51,93,19,53,13,21,95,44,67,41,17,24,31,22,38,62,79,72,56,65,37\n49,12,63,97,72,91,21,15,57,93,19,32,71,82,77,22,62,53,67,38,25,17,54\n93,62,41,54,53,67,72,17,71,91,97\n63,15,97,54,95,41,44\n26,61,84,54,45,41,51,52,87,37,13,47,88,39,56,65,55\n89,25,12,91,33,63,49,77,82,32,57,93,67,53,38,22,17,19,21,62,97,72,71\n25,49,72,53,71,57,91,15,17,82,22,67,54,38,62,63,77\n88,47,96,26,58,91,33,77,82\n71,53,67,54,72,95,21,17,41\n97,72,71,54,95,41,51,44,13,79,24,37,65,56,88,61,47,69,45,39,84,52,96\n71,54,51,13,79,37,56,47,69,26,87\n89,96,24,56,47,33,49,65,87\n69,45,39,84,52,26,87,55,91,33,57,93,67\n24,38,57,13,22,19,53,37,44,72,31,65,97,21,67,79,51,62,41,17,71,93,54\n13,12,25,84,79,96,55,65,89,44,24,31,61,88,39\n91,87,57,49,19,15,62,53,89\n26,87,58,89,25,12,91,33,77,82,57,93,67,53,38,22,17,19,21\n84,51,26,69,44,72,61,31,95,88,47,41,39\n15,67,33,38,52,53,32,12,17\n12,53,82,19,95,49,54,72,33,21,63,32,67\n32,93,53,22,21,72,54,95,51,44,79,31,37\n49,77,57,38,97,72,54,51,13\n31,37,56,88,61,47,69,84,52,96,87,55,58,91,63\n13,71,24,88,44,79,19,72,95,65,56,41,67,21,31,62,54\n63,49,15,77,82,32,57,93,67,53,38,22,17,19,21,62,97,72,71,95,41,51,44\n65,13,26,69,56,96,87,37,31,84,24,71,95\n61,96,89,91,33\n26,89,93,57,52,12,91,63,53,33,15,49,82,67,39,84,55,87,96,25,45,58,77\n52,91,82,25,88,77,45,55,32\n71,19,62,95,77,57,79,13,97,72,41\n53,38,22,17,19,62,97,72,71,54,95,41,51,44,13,79,31,24,37,65,56,88,61\n53,19,21,62,97,72,71,54,95,41,51,44,13,79,31,37,65,88,61\n44,71,67,54,51,77,82,72,31,38,32\n93,82,63,67,25,72,49,62,12,33,53,58,57,21,38,22,19\n19,21,62,71,41,24,37,65,56,88,61,47,69,45,39\n95,17,54,57,21,72,63,82,32,51,44,38,77,62,67,71,41\n15,63,88,12,39,37,91\n52,96,87,55,49,15,32,93,53,38,17\n63,55,91,89,45,31,56,65,26,96,37\n32,57,93,67,38,22,17,19,21,62,97,72,71,54,41,44,13,24,37\n69,12,32,87,88,77,47,58,96,89,49,84,39\n12,91,63,49,32,17,62,97,71,54,95\n31,19,44,47,71,51,62,17,97,88,37,79,61,24,22,13,21,65,56\n45,12,25,26,84,13,24,65,37,58,79,87,44,55,39\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_05_questions.txt",
    "content": "--- Day 5: Print Queue ---\n\nSatisfied with their search on Ceres, the squadron of scholars suggests subsequently scanning the stationery stacks of sub-basement 17.\n\nThe North Pole printing department is busier than ever this close to Christmas, and while The Historians continue their search of this historically significant facility, an Elf operating a very familiar printer beckons you over.\n\nThe Elf must recognize you, because they waste no time explaining that the new sleigh launch safety manual updates won't print correctly. Failure to update the safety manuals would be dire indeed, so you offer your services.\n\nSafety protocols clearly indicate that new pages for the safety manuals must be printed in a very specific order. The notation X|Y means that if both page number X and page number Y are to be produced as part of an update, page number X must be printed at some point before page number Y.\n\nThe Elf has for you both the page ordering rules and the pages to produce in each update (your puzzle input), but can't figure out whether each update has the pages in the right order.\n\nFor example:\n\n47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n\nThe first section specifies the page ordering rules, one per line. The first rule, 47|53, means that if an update includes both page number 47 and page number 53, then page number 47 must be printed at some point before page number 53. (47 doesn't necessarily need to be immediately before 53; other pages are allowed to be between them.)\n\nThe second section specifies the page numbers of each update. Because most safety manuals are different, the pages needed in the updates are different too. The first update, 75,47,61,53,29, means that the update consists of page numbers 75, 47, 61, 53, and 29.\n\nTo get the printers going as soon as possible, start by identifying which updates are already in the right order.\n\nIn the above example, the first update (75,47,61,53,29) is in the right order:\n\n    75 is correctly first because there are rules that put each other page after it: 75|47, 75|61, 75|53, and 75|29.\n    47 is correctly second because 75 must be before it (75|47) and every other page must be after it according to 47|61, 47|53, and 47|29.\n    61 is correctly in the middle because 75 and 47 are before it (75|61 and 47|61) and 53 and 29 are after it (61|53 and 61|29).\n    53 is correctly fourth because it is before page number 29 (53|29).\n    29 is the only page left and so is correctly last.\n\nBecause the first update does not include some page numbers, the ordering rules involving those missing page numbers are ignored.\n\nThe second and third updates are also in the correct order according to the rules. Like the first update, they also do not include every page number, and so only some of the ordering rules apply - within each update, the ordering rules that involve missing page numbers are not used.\n\nThe fourth update, 75,97,47,61,53, is not in the correct order: it would print 75 before 97, which violates the rule 97|75.\n\nThe fifth update, 61,13,29, is also not in the correct order, since it breaks the rule 29|13.\n\nThe last update, 97,13,75,29,47, is not in the correct order due to breaking several rules.\n\nFor some reason, the Elves also need to know the middle page number of each update being printed. Because you are currently only printing the correctly-ordered updates, you will need to find the middle page number of each correctly-ordered update. In the above example, the correctly-ordered updates are:\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n\nThese have middle page numbers of 61, 53, and 29 respectively. Adding these page numbers together gives 143.\n\nOf course, you'll need to be careful: the actual list of page ordering rules is bigger and more complicated than the above example.\n\nDetermine which updates are already in the correct order. What do you get if you add up the middle page number from those correctly-ordered updates?\n\n--- Part Two ---\n\nWhile the Elves get to work printing the correctly-ordered updates, you have a little time to fix the rest of them.\n\nFor each of the incorrectly-ordered updates, use the page ordering rules to put the page numbers in the right order. For the above example, here are the three incorrectly-ordered updates and their correct orderings:\n\n    75,97,47,61,53 becomes 97,75,47,61,53.\n    61,13,29 becomes 61,29,13.\n    97,13,75,29,47 becomes 97,75,47,29,13.\n\nAfter taking only the incorrectly-ordered updates and ordering them correctly, their middle page numbers are 47, 29, and 47. Adding these together produces 123.\n\nFind the updates which are not in the correct order. What do you get if you add up the middle page numbers after correctly ordering just those updates?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_06.adb",
    "content": "--  Solution to Advent of Code 2024, Day 6\n-------------------------------------------\n--  Guard Gallivant\n--\n--  https://adventofcode.com/2024/day/6\n--  Copy of questions in: aoc_2024_06_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_06 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 10;\n  input_name : constant VString := +\"aoc_2024_06\"; n : constant := 130;\n\n  map : array (1 .. n, 1 .. n) of Character;\n\n  d0 : Direction;\n  x0, y0 : Positive;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data is\n    f : File_Type;\n    c : Character;\n  begin\n    Open (f, input_name & \".txt\");\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        map (x, y) := c;\n        if c = '^' then\n          x0 := x;\n          y0 := y;\n          d0 := north;\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  verbose : constant Boolean := False;\n\n  visited : array (1 .. n, 1 .. n) of Natural;\n\n  procedure Show_Map (ox, oy : Integer) is\n  begin\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        if visited (x, y) > 0 then\n          Put ('X');\n        elsif ox = x and then oy = y then\n          Put ('O');\n        else\n          Put (map (x, y));\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n    Put (r (part_2));\n    New_Line;\n  end Show_Map;\n\n  procedure Do_Part_1 is\n    x, y, nx, ny : Integer;\n    d : Direction;\n  begin\n    for yy in 1 .. n loop\n      for xx in 1 .. n loop\n        visited (xx, yy) := 0;\n      end loop;\n    end loop;\n\n    x := x0;\n    y := y0;\n    d := d0;\n    loop\n      visited (x, y) := visited (x, y) + 1;\n      case d is\n        when north => nx := x; ny := y + 1;\n        when east  => nx := x + 1; ny := y;\n        when south => nx := x; ny := y - 1;\n        when west  => nx := x - 1; ny := y;\n      end case;\n      exit when nx not in 1 .. n or else ny not in 1 .. n;\n      if map (nx, ny) = '#' then\n        d := Turn_Right (d);\n      else\n        x := nx;\n        y := ny;\n      end if;\n    end loop;\n\n    for yy in 1 .. n loop\n      for xx in 1 .. n loop\n        if visited (xx, yy) > 0 then\n          r (part_1) := r (part_1) + 1;\n        end if;\n      end loop;\n    end loop;\n\n    if verbose then\n      Show_Map (0, 0);\n    end if;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    x, y, nx, ny : Integer;\n    d : Direction;\n  begin\n\n    for obs_x in 1 .. n loop\n      for obs_y in 1 .. n loop\n        if map (obs_x, obs_y) = '.' then\n          --  Free cell: set obstacle here.\n\n          for yy in 1 .. n loop\n            for xx in 1 .. n loop\n              visited (xx, yy) := 0;\n            end loop;\n          end loop;\n\n          x := x0;\n          y := y0;\n          d := d0;\n          loop\n            visited (x, y) := visited (x, y) + 1;\n            if visited (x, y) > 4 then\n              --  We arrived on this cell at least twice from the same direction.\n              r (part_2) := r (part_2) + 1;\n              exit;\n            end if;\n            case d is\n              when north => nx := x; ny := y + 1;\n              when east  => nx := x + 1; ny := y;\n              when south => nx := x; ny := y - 1;\n              when west  => nx := x - 1; ny := y;\n            end case;\n            exit when nx not in 1 .. n or else ny not in 1 .. n;\n            if map (nx, ny) = '#' or else (nx = obs_x and then ny = obs_y) then\n              d := Turn_Right (d);\n            else\n              x := nx;\n              y := ny;\n            end if;\n          end loop;\n\n          if verbose then\n            Show_Map (obs_x, obs_y);\n          end if;\n\n        end if;\n\n      end loop;\n    end loop;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Do_Part_1;\n  if not compiler_test_mode then\n    Do_Part_2;\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 5461\n    --  Part 2: validated by AoC: 1836\n  end if;\nend AoC_2024_06;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_06.txt",
    "content": "....#.................#......................#..........................#..................#....##..#...........#.................\n...................................#...............................#......#..#...............................#....................\n..........................#................#......##.....#.....................................#...............#..#...............\n.......................................................................................................#..........................\n...................#....#.........................#..............#.....#......................................................#...\n.....#.........................................................................................................#..................\n.........................................................#....................#..#............#................#..................\n..............#...............#..................................................................#......#.........................\n.........#.....#.......#......#.......................#.............#..#........#.......#............#.......#....#..#.......#....\n........................#....#...............................................#...#.#.........................................#....\n.........................#........................................................................#.....................#.........\n.#..........#...#...............#..................#...#......#.................................#....................#.......#....\n............................................................#......#.........................................................#....\n.......................#...#..................#.#.............#......................#.............#..............................\n............................................................................................................#.........#...........\n....#..................###........#.............................#.#....................#..........#.....................#.........\n................................................................................................#.......................#.#.......\n..........................................................................#........#...#.................#.......#................\n..........................#.#..#.#...............................................#..........#..............................#......\n..............#........#.#...............#............................#..........#....................................#........#.#\n#..................................................................................................#...........#................#.\n...............................................#........................................#.................................#.......\n.....#..#......#.......#..............#........#........#...........................................................#.............\n.......#..........#.......#.#...........#................#.................................................#......................\n....#.....#...............#....#.......#...#.............................................................#...................#....\n............................................#....#.......#................................#......#......................#.....#...\n.....................#...................................#....#...........................................................#.......\n..#..............................#...........#...........................#.................................#......................\n........#.............................##...................#.....................#................................................\n................#.#.#......#...............................................#...###.........#....#.................................\n.......#.............#.............#...........#..#...............................#..................................#.....#.....#\n.....#...#.......#.........................................#..............................#........................#.............#\n...............................................#.....#..............................................................#.............\n.........#.......................................#.......................#...........#............................................\n.......................#.....#.....................................................#....................................#.........\n.............................#......................#.....................#..............#..#.......................#.............\n......#......................................#.......#.....................#.....#...........#..........#.....................#...\n..................................................#....................#.......#....#.......#...#.................................\n......................................#......#........#.....#........................................#.............#..............\n#......................#.#..............#.....#.........#...............................#...............................#.........\n#......#...............#.........................................................................................#..#.............\n.#..............................................#.................#.......#.......................................................\n...#.......#.....#.............#...................................................................................#..............\n..........................#........#........#.....................................#........................#..............#..#....\n.......#..........#.......#...................................................#.##.....#.#.........#....#.................#.......\n..##...................#.......................................#..............#.#........#........................................\n#.......#..............#...........#.....#....#....#............#........#..................................#.#.........#.........\n..................#.......................................................................................................#.......\n............................#.........#....................#...............................#..........#...........................\n.............#.....................................................................#.....#.................#......................\n...#...#............#..........................#..........................................#.......................................\n..#.............#.#........................#...#.......................#.........#....................##....#.....................\n...........................................................................................................#.........#...#........\n.............................#.#..........................................................................................#.......\n....................#........................#.#......#...............#......#.............................#......................\n....#...#.......#..................#..........................................................#........................#..........\n.#...........#..............................................#...........................................#.........................\n..............................#...........#...........................................#.........#...........................#....#\n............#.......#......#....#.......................................................................#.........................\n.........................................#...#..................#..................#.....................................#........\n................#..................#........#.........................#...................#......................................#\n............................................................#.....#........#......................................................\n..............................#............#.........................................#.............#.......#..#...................\n...#............#........................................................................#..................................#....#\n..............................#.......#.............#.................................................#...........................\n.....#.................................................#..........#...............................#..##..........................#\n.............#.........................................................#.............................#..#..............#........#.\n....................#...............#................................................................................#....#......#\n........#....#..#...........................................................................#................#..............#.....\n....#......................#...............#..........#......#.........#..^....#..........#..................#.......#............\n...........................#.#...................................................#...............................#................\n#..#.........................................................#.....#........................#.....................................\n.#.#....#.......................................#......#..........#................#..#...........................................\n...#.....#..........#...................#.......#............................#....................................................\n.............#......................................................#............#.....................#.....................#....\n...................#.............................................................................................#................\n...................#.....#...................................................................................................#....\n................#............#......................#.......#..................#..#.....................#..............#........#.\n#....#...................................................................#.......##....#..........#...............................\n.........................................#............#......#.......................#........#..............#.#..................\n.##........#.....#...........................................................................................#..............#.....\n#...........................................................#.......#....#......#..#...................................#..#.#.....\n.............#........................................#...............................#...........................................\n......................#..................................................................#..................................#.....\n...#.#........................................#.................................................................................#.\n.............#.......................#............................#.#................................#.......#..#...........#.....\n...#..#...............................................................................#................#..........................\n.......#.............................#............#..#........#.....#.........................#..................#................\n......#...............................................................................##.................................#....#...\n........#..................#.......................................................................#......#..........#............\n...........#.......#........#..........................................#........#..............#.................#.........#......\n...................#..............................#...............................#.....................#.....#...................\n.............#..#..................#.#..#.....#..#..........................................................................#.....\n..............................#...................................................#.......................#..............#........\n.......#......................#.............................#...........................#.....#...#.................#........#....\n.........#.......#....##..........................................................................................................\n........................................................................#......................#..................................\n.......................#..........##.#................................................#..#.....#......#......#.................#..\n......................................#......................................................................#....................\n.....................................#....#...............................................#...#.....#.......#...#...........#.....\n...................#..#................................................................................#..........................\n..............#.................#..............................#..............#...........#.#..................#...#.............#\n................#..#......#.........................#.....#.....#..............#..#.........................................#.....\n.....#.........................#........................................#.....#.......#...........#...................#...........\n......#....................##......................................................................................#..............\n............................................................................###...............................#...................\n#..................................#......#..............................................................................#.......#\n.....#...................#.....#............................................................#.....................#...#...........\n.......#......#........................#.....................#.#..##............#......#.................#.....................#..\n.....#..............#.................#........#..................#..#..........................##.....#..#...................#...\n........#................#................#...........#.........................................#....................#............\n.........#.........#....#................#........#........#...............#....#.................................................\n...........#...#............#..................#.............................#.#..#....................#.#........................\n.#............#..#..#................#.#................................................................##.............#..........\n...........#.......................#.........................................................#....................................\n..#..........................#...........#......#................................#.#..............................................\n............................................................#..................#...........#.....##.................#.............\n....#.........#............................##..........................................#.....#....#..........#....................\n..................#..............#........#........#....................#..............#....................#.....................\n....#...................................#.....................................................#.............#...................#.\n.........#...........#...#.............................#.............##..#................................................#.#.....\n............................##..............#................#..#........................................#....................#...\n.............................#.#......................................................##.....#..................................#.\n.............................................................................#..................#...#.................#...........\n........................#...........#..................#......#...................................................................\n.....#.......................#......#................#............#..................#.................................#..........\n#..........#...................................................................#...................#...#...............#..........\n....................#............................................#...............#........................##....#..#..............\n.#.....#............................#...............#.#.#..........................#.........#..............#.....................\n.............................#....................................#..#......#........................#............................\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_06_questions.txt",
    "content": "--- Day 6: Guard Gallivant ---\n\nThe Historians use their fancy device again, this time to whisk you all away to the North Pole prototype suit manufacturing lab... in the year 1518! It turns out that having direct access to history is very convenient for a group of historians.\n\nYou still have to be careful of time paradoxes, and so it will be important to avoid anyone from 1518 while The Historians search for the Chief. Unfortunately, a single guard is patrolling this part of the lab.\n\nMaybe you can work out where the guard will go ahead of time so that The Historians can search safely?\n\nYou start by making a map (your puzzle input) of the situation. For example:\n\n....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#..^.....\n........#.\n#.........\n......#...\n\nThe map shows the current position of the guard with ^ (to indicate the guard is currently facing up from the perspective of the map). Any obstructions - crates, desks, alchemical reactors, etc. - are shown as #.\n\nLab guards in 1518 follow a very strict patrol protocol which involves repeatedly following these steps:\n\n    If there is something directly in front of you, turn right 90 degrees.\n    Otherwise, take a step forward.\n\nFollowing the above protocol, the guard moves up several times until she reaches an obstacle (in this case, a pile of failed suit prototypes):\n\n....#.....\n....^....#\n..........\n..#.......\n.......#..\n..........\n.#........\n........#.\n#.........\n......#...\n\nBecause there is now an obstacle in front of the guard, she turns right before continuing straight in her new facing direction:\n\n....#.....\n........>#\n..........\n..#.......\n.......#..\n..........\n.#........\n........#.\n#.........\n......#...\n\nReaching another obstacle (a spool of several very long polymers), she turns right again and continues downward:\n\n....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#......v.\n........#.\n#.........\n......#...\n\nThis process continues for a while, but the guard eventually leaves the mapped area (after walking past a tank of universal solvent):\n\n....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#........\n........#.\n#.........\n......#v..\n\nBy predicting the guard's route, you can determine which specific positions in the lab will be in the patrol path. Including the guard's starting position, the positions visited by the guard before leaving the area are marked with an X:\n\n....#.....\n....XXXXX#\n....X...X.\n..#.X...X.\n..XXXXX#X.\n..X.X.X.X.\n.#XXXXXXX.\n.XXXXXXX#.\n#XXXXXXX..\n......#X..\n\nIn this example, the guard will visit 41 distinct positions on your map.\n\nPredict the path of the guard. How many distinct positions will the guard visit before leaving the mapped area?\n\n--- Part Two ---\n\nWhile The Historians begin working around the guard's patrol route, you borrow their fancy device and step outside the lab. From the safety of a supply closet, you time travel through the last few months and record the nightly status of the lab's guard post on the walls of the closet.\n\nReturning after what seems like only a few seconds to The Historians, they explain that the guard's patrol area is simply too large for them to safely search the lab without getting caught.\n\nFortunately, they are pretty sure that adding a single new obstruction won't cause a time paradox. They'd like to place the new obstruction in such a way that the guard will get stuck in a loop, making the rest of the lab safe to search.\n\nTo have the lowest chance of creating a time paradox, The Historians would like to know all of the possible positions for such an obstruction. The new obstruction can't be placed at the guard's starting position - the guard is there right now and would notice.\n\nIn the above example, there are only 6 different positions where a new obstruction would cause the guard to get stuck in a loop. The diagrams of these six situations use O to mark the new obstruction, | to show a position where the guard moves up/down, - to show a position where the guard moves left/right, and + to show a position where the guard moves both up/down and left/right.\n\nOption one, put a printing press next to the guard's starting position:\n\n....#.....\n....+---+#\n....|...|.\n..#.|...|.\n....|..#|.\n....|...|.\n.#.O^---+.\n........#.\n#.........\n......#...\n\nOption two, put a stack of failed suit prototypes in the bottom right quadrant of the mapped area:\n\n....#.....\n....+---+#\n....|...|.\n..#.|...|.\n..+-+-+#|.\n..|.|.|.|.\n.#+-^-+-+.\n......O.#.\n#.........\n......#...\n\nOption three, put a crate of chimney-squeeze prototype fabric next to the standing desk in the bottom right quadrant:\n\n....#.....\n....+---+#\n....|...|.\n..#.|...|.\n..+-+-+#|.\n..|.|.|.|.\n.#+-^-+-+.\n.+----+O#.\n#+----+...\n......#...\n\nOption four, put an alchemical retroencabulator near the bottom left corner:\n\n....#.....\n....+---+#\n....|...|.\n..#.|...|.\n..+-+-+#|.\n..|.|.|.|.\n.#+-^-+-+.\n..|...|.#.\n#O+---+...\n......#...\n\nOption five, put the alchemical retroencabulator a bit to the right instead:\n\n....#.....\n....+---+#\n....|...|.\n..#.|...|.\n..+-+-+#|.\n..|.|.|.|.\n.#+-^-+-+.\n....|.|.#.\n#..O+-+...\n......#...\n\nOption six, put a tank of sovereign glue right next to the tank of universal solvent:\n\n....#.....\n....+---+#\n....|...|.\n..#.|...|.\n..+-+-+#|.\n..|.|.|.|.\n.#+-^-+-+.\n.+----++#.\n#+----++..\n......#O..\n\nIt doesn't really matter what you choose to use as an obstacle so long as you and The Historians can put it into position without the guard noticing. The important thing is having enough options that you can find one that minimizes time paradoxes, and in this example, there are 6 different positions you could choose.\n\nYou need to get the guard stuck in a loop by adding a single new obstruction. How many different positions could you choose for this obstruction?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_07.adb",
    "content": "--  Solution to Advent of Code 2024, Day 7\n-------------------------------------------\n--  Bridge Repair\n--\n--  https://adventofcode.com/2024/day/7\n--  Copy of questions in: aoc_2024_07_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_07 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_07\";\n\n  n : constant := 100;\n\n  r : array (Part_Type) of Integer_64;\n\n  type Row_Type is array (1 .. n) of Integer_64;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n\n  procedure Read_Data is\n    left : Integer_64;\n    len_left : Integer;\n    data : Row_Type;\n    last : Natural := 0;\n\n    function Check_1 return Boolean is\n      b : Integer;\n      x : Integer_64;\n    begin\n      if last = 1 and then left = data (1) then\n        return True;\n      end if;\n\n      for i in 0 .. 2 ** (last - 1) - 1 loop\n        b := i;\n        x := data (1);\n        for pos in 2 .. last loop\n          if b mod 2 = 0 then\n            x := x + data (pos);\n          else\n            x := x * data (pos);\n          end if;\n          exit when x > left;  --  Too big, give up.\n          b := b / 2;\n        end loop;\n        if x = left then\n          return True;\n        end if;\n      end loop;\n      return False;\n    end Check_1;\n\n    function Check_2 return Boolean is\n      b : Integer;\n      x : Integer_64;\n      concat : VString;\n    begin\n      if last = 1 and then left = data (1) then\n        return True;\n      end if;\n\n      for i in 0 .. 3 ** (last - 1) - 1 loop\n        b := i;\n        x := data (1);\n        for pos in 2 .. last loop\n          case b mod 3 is\n            when 0 =>\n              x := x + data (pos);\n            when 1 =>\n              x := x * data (pos);\n            when others =>  --  0\n              concat := Image (x) & Image (data (pos));\n              if Length (concat) > len_left then\n                --  Too big, give up.\n                x := 0;\n                exit;\n              end if;\n              x :=  Integer_64'Value (To_String (concat));\n          end case;\n          exit when x > left;  --  Too big, give up.\n          b := b / 3;\n        end loop;\n        if x = left then\n          return True;\n        end if;\n      end loop;\n      return False;\n    end Check_2;\n\n    dummy_separator : Character;\n    f : File_Type;\n\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      if last = 0 then\n        Get (f, left);\n        Get (f, dummy_separator);\n        len_left := Length (Image (left));\n      end if;\n      last := last + 1;\n      Get (f, data (last));\n\n      if End_Of_Line (f) or End_Of_File (f) then\n        if Check_1 then\n          r (part_1) := r (part_1) + left;\n        end if;\n        if (not compiler_test_mode) and then Check_2 then\n          r (part_2) := r (part_2) + left;\n        end if;\n\n        last := 0;  --  Clear data (calculator terms & factors).\n      end if;\n\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put (+\"Part 1:\"); Put (r (part_1)'Image); New_Line;\n    Put (+\"Part 2:\"); Put (r (part_2)'Image); New_Line;\n    --  Part 1: validated by AoC: 850435817339\n    --  Part 2: validated by AoC: 104824810233437\n  end if;\nend AoC_2024_07;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_07.txt",
    "content": "12427056279= 3 5 3 8 3 22 1 651 5 3 1 6\n554266023266= 835 7 40 9 7 66 323 3 6\n156802= 957 23 8 2 5\n451396= 2 21 3 3 4 969 8 8 3 11 4\n541800= 6 8 8 350 8 7 2 7 4 5 5\n502= 43 53 5 397 4\n564543133= 3 4 47 54 3 133\n185183376789= 47 3 775 7 4 939 202 7\n10300720= 359 30 5 16 331\n10114285876= 8 80 7 2 19 3 2 861 3 4 6\n6658354= 4 62 5 8 354\n1679555006712= 7 4 7 9 4 17 8 883 3 2 2 6\n3281626= 4 1 8 1 5 6 242 5 7 6 45\n646984854= 1 6 767 4 924 50 2 6 9\n15435205= 8 6 2 6 97 117 1 5 9 8 1 5\n323223= 2 7 6 197 3 381 27 3\n14719245= 801 75 4 31 6 163 7 2\n384800550= 513 83 590 129 5\n843710637122= 71 2 965 5 12 998 4 1 3\n2785998= 15 9 1 2 25 70 1\n20879049= 2 52 28 6 1 533 9 6 9 9\n28589067= 227 894 5 70 51\n7231832= 677 763 7 59 2\n1131570= 8 64 691 26 8 33 99 9\n448728996= 6 82 57 76 80 16 1 35\n38586511= 86 437 653 351 511\n1017223= 77 4 25 33\n20416= 48 78 451 74 46 7 29\n56987487= 63 1 2 42 67 8 1 962 9\n6098476= 69 63 660 14 5 76\n1395810072= 442 510 4 1 5 43 4 6 6\n49896817= 557 56 3 81 72 7 88\n3849663743508= 3 1 81 2 8 6 373 1 3 51 1\n1963977= 9 68 48 74 4 209 8\n11735601= 446 49 537\n5853= 50 58 3 1 18\n2945091= 999 5 7 1 88 4 7 7 3 408\n385659= 3 9 1 6 8 5 7 9 2 597 34\n13416= 41 9 4 8 6\n6845472302= 97 93 215 684 302\n1112504= 74 2 87 7 472\n54440= 4 2 9 35 8 9\n445835058612= 7 43 6 341 9 586 11\n6027221856= 41 4 7 882 9 5 9 8 9 888\n26490050= 37 8 1 2 8 11 5 1 1 2 4\n5200= 2 29 89 1 38\n9746919= 6 4 7 78 3 284 945 7 27\n1356978= 50 5 89 241 3 4\n28681= 75 370 27 8 896\n113054413= 226 5 5 43 90 21\n1692= 4 49 98 7 635\n1789551225= 97 13 5 5 499 7 9 99\n152347805= 6 397 4 895 3 353 1 39\n655047= 39 145 479 988 3\n4835382339= 73 80 468 4 3 2 14 8 29\n13503378578= 424 13 309 78 578\n932087= 97 834 1 8 2 87\n2828= 4 9 4 4 7\n2663212860= 329 52 296 1 5 89 90\n8879504= 88 1 78 1 501\n4992196576175= 21 4 2 9 5 8 5 70 62 81 8\n25625354= 1 75 81 1 2 53 54\n546379203959= 6 3 3 712 3 8 36 36 3 5 6\n41783203= 47 889 167 9 30\n7328754= 2 673 9 594 854 3 3 6\n391236= 65 5 250 611 1 97 2\n225642= 4 40 178 143 469 53\n448848= 87 2 8 1 51 69 48\n4650= 4 371 169 1 98 8\n326690= 8 10 67 2 6 1 3 49 996\n27492032= 619 1 33 421 6 51 6 75\n191745655= 655 123 4 34 7\n25256= 69 8 41 1 8\n1440= 74 16 2 395 865\n76638936= 5 96 6 7 8 384 2 68 9 6 4\n16475979= 63 97 4 7 5 9 79\n2948707379= 8 8 102 32 2 23 280 2 5\n139295624= 7 6 16 9 2 7 5 9 8 6 32 72\n464621= 357 4 26 5 3\n237265609378= 61 5 176 442 93 81\n67396998= 69 4 941 56 1 6 6 736 4\n17731594= 8 7 82 6 6 2 78 4 1 2 3 1\n38794833350= 1 5 2 765 74 979 2 7 50\n1511975= 70 77 4 1 975\n3479377= 369 73 41 94 61\n30750833673= 3 349 764 6 1 153 1\n3236809= 66 2 40 119 9\n218349= 3 42 70 15 7 349\n1389960358= 515 5 54 495 87 271\n104= 7 93 2\n135021376= 2 96 2 973 59 3 28 4\n467432= 649 1 276 2 1 25 491\n3824775= 4 6 6 33 4 8 7 7 75 573\n618569001= 61 856 8 905 96\n3510= 177 93 44 5 366\n131985= 96 24 57 655 5\n16202819= 1 3 926 58 42 861 9 3 1\n3411269120= 64 14 932 43 95\n36000444= 4 72 6 76 828 47\n1633755= 6 62 432 16 127 27\n972911772212= 5 4 4 2 5 12 99 9 9 209 4\n13240902895= 7 5 2 71 195 16 433 9\n122248101= 863 13 392 356 548\n56140560365= 783 6 7 32 705 36 6 1\n48197812= 7 982 6 4 2 92 406 7 9\n23433= 75 3 1 92 5\n1732374= 4 1 5 93 590 4 45 3 7 6\n36502= 7 8 70 4 129 7 5 1 7 2 22\n2510281833807= 715 1 8 13 27 28 5 80 7\n5040243= 4 8 7 60 237 3\n2332657654= 85 7 6 72 4 6 2 518 1 52\n135673= 32 6 4 15 643\n1063567= 296 49 681 8 7 5 8\n5083677= 105 9 10 2 24\n13560481= 64 57 2 3 1 70 291\n39721250= 90 947 63 8 76\n30247= 13 5 255 29 33 3 1 9 2\n2604= 89 4 78 6 1\n1483313= 685 482 942 4 6 7 1 3\n4072802= 9 93 23 868 74 2\n819216581= 1 637 2 6 4 6 8 9 3 5 80 2\n367230334= 9 33 62 8 230 332\n2398440= 9 1 903 7 33 79 1\n1732799= 74 43 68 2 445 4 5 4 2\n7084389272= 63 1 1 921 4 7 7 2 3 4 6 1\n10959= 6 7 6 576 6 9\n13407283= 315 3 51 541 8 83\n378826569= 4 8 33 7 52 828 8\n14261= 7 7 8 927 9\n173854= 6 7 4 8 5 4 6 1 40 1 9 44\n57783= 4 1 9 33 256 4 1 1 2 2 6 3\n19425406= 2 76 7 326 3 8 6 1 7 805\n1619775= 531 8 9 25 3\n29867= 9 3 614 88 1 4 8 6 3 7 19\n655= 2 51 45 502 6\n274409943= 946 241 29 5 3\n2518= 247 8 518 17 7\n3569675730= 40 46 7 4 47 509 95 62\n62041462= 878 7 5 5 557 4 9 1 46 4\n51320839626= 252 76 84 35 75 319\n4534248981= 83 967 3 85 78 9 6 4 3 3\n15568060= 126 22 605 922 5 90\n13024055= 5 74 4 88 54\n141= 45 92 6\n291251791= 6 515 7 6 745\n1761366933= 74 23 352 4 294\n994404= 4 8 6 48 123 32 8 452 4\n76514= 6 7 98 600 14\n5058051= 71 482 91 4 185 3 91\n2216287993= 9 42 8 936 35 66 61 7 4\n12894510= 6 7 1 7 7 307 2 4 4 426\n64522175595= 6 452 21 7 497 2 6 602\n7303887494= 25 5 609 5 5 84 8 7 49 7\n4155= 822 5 46\n374608580613= 2 3 616 25 8 58 796 46\n23207960= 197 65 4 515 43\n443412841610= 479 22 8 40 46 914 9\n6789655= 17 254 466 1 92 55\n7625964= 76 25 95 5 6\n1741= 1 9 1 9 22\n180931249= 723 724 5 5 50\n3493889717= 41 8 85 6 5 99 1 8 1 883\n262770906= 568 976 2 2 79 3\n251029= 65 5 26 715 64\n3507640= 216 75 6 2 15 642\n211904= 13 48 6 344\n522= 7 5 3 5\n3810= 7 3 379 9 8 8 530\n460174478= 6 8 5 2 4 876 6 8 8 9 16\n660268231= 77 70 2 5 849 62 870\n6128325= 98 5 807 63 75\n4669= 3 87 5 6 7 154\n37269025921= 374 58 23 83 80 9\n44644811817= 7 7 3 6 3 85 786 1 1 8 1 6\n16012= 65 4 6 19 8 1 3 7 9 1 8 6\n2736304425= 30 841 8 695 3 156\n51616= 724 58 2 47 8 2 1 7 7 2 2\n270916= 5 8 8 50 172 9 19\n3340= 4 679 475 7 142\n350635929= 2 5 7 6 73 3 1 796 2 2 5\n104348= 1 51 3 8 7 3 8 2 8 6 476 8\n49388638= 3 8 6 3 21 4 7 2 8 629 3 5\n679606950492= 19 436 446 98 8 83 5 6\n90546= 90 53 6 2 5\n505494= 1 758 666\n1354= 779 443 25 9 98\n17895006361= 9 44 65 1 2 6 750 6 361\n186277= 2 44 5 7 2 18 23 7 43 1\n92249344= 27 192 35 2 47 32 8\n6570= 6 155 412\n5264531371= 1 657 4 26 5 65 6 2 59\n864129820150= 465 94 72 2 45 226 95\n73453752= 7 1 4 8 3 76 210 4 831\n100776= 1 77 9 7 8 7 775 38 3\n341785221= 874 1 13 1 391\n6488622= 84 4 356 18 207\n146011741= 70 1 2 6 61 486 697\n3271= 6 305 16 4 1\n582909893= 259 25 8 8 873 892 9 5\n780= 9 7 9 9 746\n3290654498= 32 90 489 161 4 494 4\n12801= 540 35 696 2 89\n464472216= 4 1 562 4 4 717 871 9 8\n1495= 1 396 440 92 500 66\n805473= 80 680 380 706 633\n461553= 90 959 6 20 5 43 411\n74990463= 4 31 8 1 9 6 931 4 592 5\n5768093342= 9 5 7 2 592 688 9 78 5 6\n2243= 15 9 87 86 69\n11837412709= 785 14 6 9 5 4 698\n1291692080932= 92 1 26 372 140 932\n1436857560988= 6 4 4 8 357 9 92 1 1 6 43\n329661792269= 6 86 7 6 6 4 2 59 5 3 3 90\n1839165= 92 5 5 949 19\n505911537= 3 69 2 62 8 7 21 470 67\n6035327022= 7 5 8 581 8 483 9 5 6 9 2\n13893971398= 2 14 6 2 4 3 5 746 900\n131628160= 765 22 6 344 5\n257664= 18 6 8 2 8 61\n5627412= 7 72 2 2 7 95 9 6 3 8 3 12\n767366= 95 2 805 760 188 55\n577347= 8 9 593 4 863\n571= 9 4 66 69 400\n13728= 6 5 994 60 215 73 6\n519998220= 6 8 8 91 5 9 57 275 8 9 1\n343275= 46 4 19 5 995\n54549= 20 3 3 250 171\n114723458963= 7 3 230 1 6 899 9 89 64\n34001983= 5 77 3 69 635 771 2\n5310= 29 61 1 3\n8917506= 3 5 7 4 315 2 32 9 234\n749965= 3 481 6 5 761 6 7 9 3 1 4\n6920410040783= 59 87 474 100 40 785\n1285810= 43 38 6 30 8 760 75 8\n6504567036023= 591 324 276 110 23\n39312817= 8 1 4 1 66 2 7 6 1 6 810 7\n31945133= 45 557 71 4 75 70 6\n14822498693= 162 4 35 80 1 891\n20101915756= 235 611 7 7 8 2 9 2 4 2 2\n7211517= 13 4 63 9 56 2 5 661 7\n486695= 51 2 3 95 7\n77338= 5 3 1 3 99 4 8 8 5 285 54\n15735= 1 84 1 185 4 6\n1308827965= 7 5 1 31 1 90 891 37 56\n41036= 496 81 197 6 657\n77442240512= 5 1 7 925 886 8 364 8 4\n178800585= 2 3 9 4 4 4 10 6 729 2 9 6\n191563683819= 87 231 2 6 122 5 3 819\n1580= 2 83 88 33 76 7 4 94 6\n2524028= 5 38 41 4 9 9 68\n1371= 1 6 85 2 1\n20180153709061= 6 2 5 89 5 903 9 5 9 3 2 1\n5348= 650 46 50 5 6 842\n7574880= 152 9 2 9 38 2 3 5 1 86\n180263798= 630 8 697 2 41\n135637= 451 5 5 895 39\n193645= 857 4 5 6 1 9 4 35 2 9 7 4\n2209115606= 97 7 360 50 628 9\n158736= 6 877 6 399 7 4 9 4 1 8\n8191921= 855 5 5 638 3 1\n70319106= 80 257 380 433 9 9\n300940= 4 686 436 91 8\n124= 2 60 4\n2054222905284= 7 73 7 532 7 9 1 18 638\n3852485577= 804 37 568 4 57 585\n7733360= 9 44 7 4 6 3 1 2 6 2 6 292\n137876= 40 8 239 5 1 3 1 6 3 3 2 4\n8607831= 859 11 162 50 484\n495232= 2 1 3 42 786 1 5 6 3 7 4 5\n242862437= 62 445 8 8 11 35\n6621686= 5 5 5 1 3 922 7 2 8 8 8 6\n7604= 6 169 8 7 3 9 6 5 427\n89227= 7 932 95 19 2 1\n5776= 232 7 3 903 1\n45069696= 4 157 9 48 36 18\n161643300= 926 4 910 191 1\n26868960342= 397 94 800 38 9\n333724133= 91 3 79 28 78 3 9 39\n4049582505842= 218 86 6 40 28 6 8 60 6\n38981085= 1 4 33 1 8 7 29 9 29 7 9 4\n88293150= 5 274 2 286 3 66 5 3 5\n571913273753= 1 7 563 913 2 7 3 5 2 5 3\n255816565= 500 1 15 51 565\n22656504= 75 52 155 3 40\n5037237= 7 70 3 1 685 30 862 1 9\n843118= 4 8 4 3 3 9 8 748 14 6 94\n165818013= 7 741 8 74 54\n30367= 45 664 3 324 82 78\n1248741970= 9 8 46 8 142 680 394 5\n121360516= 9 3 8 1 4 6 7 6 8 598 96 1\n595928718= 744 8 160 18 931 20 4\n229253= 804 4 71 822 4 91\n24354727= 722 6 7 4 861 780 6 7\n828734019865= 666 36 436 17 39 694\n107802= 68 7 9 2 9 8 3 65 1 7 2 9\n6909840084= 480 5 5 914 1 9 9 7 21\n67574887954= 2 7 9 3 29 485 3 795 1 3\n80117581952= 950 38 56 9 843 2\n4341626= 9 9 2 268 24\n64179026= 49 8 9 7 1 55 3 2 27 7 8 2\n39320134= 7 437 4 459 5 833 7\n39231675= 4 7 777 855 57\n2917615= 7 1 643 7 8 9 8 9 247\n76131594= 1 177 627 7 98\n69998078= 64 9 6 8 2 367 73 7 8 1\n6937280= 4 8 17 15 6 3 2 5 760 8\n176737= 8 897 508 23 5\n69538171= 13 443 2 8 806 7 1 68\n357696643= 46 324 8 3 3 3 4 2\n19806500021567= 565 9 625 2 5 7 2 6 9 6 8\n1831104= 1 6 809 561 4\n90536995= 3 6 8 3 189 14 6 5 2 7 9 5\n30610466= 34 9 10 4 67\n108330= 4 7 2 2 2 471 5\n2078527= 2 7 41 739 6 439 301\n2738759568= 7 42 4 2 5 8 3 4 99 7 2 3\n2125570= 8 497 4 46 5 2 5 5 54\n12120409= 109 18 58 250 24 409\n338023= 613 1 67 71 5 2 7 7 3 4\n14584= 5 1 8 5 86\n116860285= 1 6 3 160 2 50 6 4 72 87\n53282559= 5 3 282 5 5 7\n46965024966= 757 5 62 2 4 965\n308893= 11 2 8 7 69 4 1 82 6 4 7\n203220= 27 6 2 94 540 7 4 669\n7850309= 9 5 3 36 6 6 21 88 12 5\n595056931= 8 36 2 21 616 931\n22230= 55 51 884 16 6\n68686892= 70 6 722 481 92\n123516= 112 9 5 52 2 94\n445040= 3 6 5 97 87 7 1 678 5 8\n1379473= 7 1 3 9 39 7 7 1 7 8 9 744\n577124515= 6 47 892 270 245\n1990431900= 998 67 2 793 548 9 3\n385832= 82 49 96 91 6 7\n42255489= 7 8 939 3 484 4\n470= 364 51 6 1 48\n97711378199= 977 11 37 1 7 199 1\n19493527= 7 2 759 2 39 1 241 51 1\n782908337= 8 24 5 5 626 76 19\n425193= 1 537 4 77 688 7 2\n115915142= 7 5 3 7 208 4 8 1 17 3 6 2\n2732= 8 2 29 70 2\n48697176= 178 771 6 27 4 7 38 3 8\n897561= 5 9 327 8 4 1 57 3 3 567\n44027= 95 83 247 3 58\n34314052= 75 2 986 4 301 41 8\n38591798= 399 10 52 186 518\n56857776= 5 4 23 9 61 5 7 76\n1495= 6 2 7 8 8 5 5 6 72 54 7 6\n1665265= 5 3 89 410 45 331 9 5\n145680408675= 4 9 419 4 4 408 674 3\n5965317120552= 7 2 1 456 6 56 5 64 554\n2419624368= 60 9 7 6 7 8 635 8 7 7 2 3\n120212= 26 92 1 5 5 537\n1544730757552= 790 143 61 50 391\n50250860= 2 7 988 6 84 4 200 2 2\n6144650= 67 317 4 4 649\n938= 36 24 74\n3582735= 562 35 122 6\n7130101416= 9 1 8 70 56 2 8 3 5 6 86\n114876= 94 3 44 45 2 18 1 627 2\n10753200639= 8 5 71 18 52 28 8 2\n748= 6 56 90\n122935376= 8 96 15 1 9 51 59 4 4 79\n30240723944= 12 1 473 6 7 9 9 8 394 2\n1132= 32 589 4 500 7 1\n523= 49 3 6\n10735945123= 2 8 5 8 9 41 2 7 635 12 3\n349141893129= 6 550 836 52 5 1 963 3\n2970495= 7 847 501 1 57 6\n227240795= 553 45 76 5 798\n6201= 78 8 540 1 63 9\n322171047= 4 9 874 7 27 6 86\n342112130= 1 33 211 2 128\n527649= 48 4 6 4 13 7 38 8 5 6 3\n242559363052= 67 9 4 85 3 9 3 630 5 4\n962= 879 35 39 6 1\n563393= 8 85 896 6 12 5\n212505= 5 16 57 85 8 74 2 20 2 9\n1201= 8 3 8 4 789 24 312\n259335373= 1 7 4 5 9 3 4 1 3 46 32 8\n1497577545545= 3 765 138 725 6 9 7\n4446072= 45 50 2 988 72\n3916= 46 388 9 8 372\n15162562= 4 816 238 3 560\n14450297= 4 9 37 78 49 93 2 21 8\n2578194502= 54 4 82 36 66 4 875 2\n37351= 71 2 7 6 94 5\n62832442= 3 6 37 9 7 5 8 7 542 8\n38973= 94 6 228 61 75\n661997= 66 19 88 6 6\n709= 3 27 49 49 73 496 3 9 1\n4367700475= 8 4 566 215 3 3 997 2 2\n328739= 1 724 24 72 85 2 2\n207366= 384 6 3 3 4\n104848968= 8 98 4 6 8 66 9 2 6 54 7\n127344= 27 44 683 4 168\n7932172= 8 38 484 5 2 172\n2754000= 234 81 6 4 425 3 51 24\n909986= 8 44 4 6 2 5 8 7 6 7 7 7\n44597= 445 69 7 12 9\n748244= 7 1 99 6 98 8 3 53 4\n29674500= 76 885 490 73 6\n20135958947= 402 1 7 5 10 85 8 946\n139668= 357 1 41 998 68\n972= 1 6 59 22 1\n809500= 48 5 36 424 466 37 5\n15993846= 39 897 8 729 57 45\n439929401952= 43 992 93 9 44 75 50\n25053= 1 3 2 4 4 3 8\n19210481= 74 7 67 236 81\n29385628= 5 6 946 307 56 63 65\n210880133085= 44 1 8 78 6 4 9 4 2 5 249\n91393425= 182 11 62 5 67 2 1 3 9 5\n98124= 2 732 67 28 4 4\n24650065440= 76 450 2 99 364 4 5\n116388725= 1 1 121 2 61 1 3 4 3 8 9 2\n7476908378= 747 6 90 78 5 77 1\n58420= 7 817 96 19 5 76\n10606404= 23 1 6 83 926\n178010= 996 1 777 84 623\n4954535792640= 435 2 644 5 9 7 92 61 1\n1195764= 2 65 9 3 10 412 1 6 397\n39193416= 505 9 353 9 216\n6654027= 1 70 61 6 39\n1130903171= 883 518 1 8 16\n1170420= 487 4 30 81 20\n253743= 11 17 194 1 9\n405720= 7 13 69 311 955 8\n1015923= 6 9 47 79 83 68 3\n10538269546= 56 8 437 235 4 6\n8343= 677 249 9 9 1\n2007882= 2 8 74 5 7 8 9 402 2 694\n5270243= 20 831 253\n16738245= 5 9 184 79 2 5 3 9 5 37\n834249= 7 28 360 642 63\n108410793= 49 79 753 61 28\n32176521= 336 28 4 883 2\n570330= 9 4 16 597 339 302 9 2\n468520= 67 9 69 2 6\n4046008= 66 327 61 55 4\n26265204422= 679 742 422 2 73 2 8 6\n229= 127 73 22 4 4\n288910= 28 8 831 6 73\n949182= 58 73 3 224 7 87\n55638= 87 634 14 87 3 8 368\n3438732966= 9 9 3 9 2 91 6 8 4 312 9\n1090577000387= 5 4 52 88 4 3 7 50 9 7 2 2\n1367893818= 9 409 59 2 637 9 5 8 3 6\n6699= 1 4 4 3 72\n9014897= 8 469 76 12 86 62 4 97\n46407= 8 3 843 9 8 6 142 85 16\n38= 13 6 5 6 8\n5472046634994= 21 2 29 367 89 4 99 1\n35992250= 4 703 509 1 6 47 6 47 1\n437614423219= 972 3 5 8 8 155 93 9 2 1\n56110916= 890 5 446 819 6\n56479317484= 51 50 247 5 58 4 444 5\n384= 6 128 56 2 4\n710496= 10 8 740 8 12\n532040= 42 548 9 97 943\n24095= 41 6 33 9 47 31 2 316\n969496385774= 9 9 1 98 92 8 53 4 7 3 72\n91959= 3 79 13 90 29\n2566398922= 2 7 9 81 6 413 62 853\n3425= 70 39 640 53\n945989120= 10 161 931 19\n99686839= 9 9 6 3 2 3 59 9 27 12\n1215180= 40 446 60 6 5\n187385= 77 61 61 9 3 825 3\n2935383102= 2 257 98 70 130\n51339= 4 5 812 7 1 7 4 97 8 7 18\n1387980028932= 81 5 918 8 6 994 43 1\n14550071987= 92 53 500 71 900 82 6\n11932737= 3 7 8 1 819 4 5 614 4 4 8\n1888477= 5 9 75 2 559 60 9 7 658\n720516= 4 318 6 827 9 619\n6346= 27 78 8 3 6\n18076176= 1 829 4 3 1 1 4 592 6 6 6\n383939244= 5 65 5 73 133 33 9 453\n174276= 5 1 967 30 1 157 55 3\n54871772= 86 839 1 456 76\n62562= 786 95 71 7 4\n95673724= 22 2 48 453 4 7 77\n1407900= 50 1 19 57 26\n188871577= 5 9 8 4 7 129 6 8 257 8 8\n29797632= 40 53 136 600 9 6\n762624287= 133 9 6 7 9 95 8 9 9 4 1 4\n5311278= 46 716 26 2 69 668 9\n14390442= 1 1 14 90 7 93 697 90 2\n38143333= 17 4 8 8 92 6 8 7 3 8 408\n522548= 768 9 87 466 70\n8735836482= 429 4 93 7 931 741 9\n26425157= 8 373 8 394 229 22 55\n61960= 6 4 968 9\n13680= 38 99 53 9 8\n253971240= 184 695 662 2 518 3\n40577051= 84 70 4 8 479\n8552= 3 992 5 69 8\n6721479438= 3 3 4 94 11 9 5 8 86 5 8\n78193003= 9 5 7 9 1 8 183 8 1 763\n107829= 4 547 463 301 82\n31071077946= 291 841 491 2 722 38\n60978= 417 8 3 155 6\n85981666= 3 7 170 3 21 2 3 5 2 4 9 5\n7362= 7 945 6 38 703\n58242= 8 6 828 9 30 3 5 4 66 2\n4075= 9 5 352 7 408\n2484607586= 637 13 62 7 6 329 3 86\n18816= 5 8 2 3 11 43 4 8 2 112\n2768866= 8 459 8 67 87 2 73 8 8\n4256479= 37 3 98 593 114 4 4 7\n13315217= 7 59 9 69 77 5 228 5 2 7\n95584639= 9 55 846 32 6\n47650502420= 6 1 7 2 2 3 2 2 592 33 7 7\n1114026= 17 68 630 98 87\n2991360= 591 1 187 64 2 30\n75109= 70 5 1 33 64 168 6 7\n21908287= 7 33 95 6 661 25 1 4\n47090556= 9 869 79 2 9 596\n23985780= 46 91 10 573\n34076= 8 85 50 69 7\n194928707= 18 5 8 1 921 7 6 6 3 9 5 4\n1804453= 7 535 3 80 9 5 3 94 781\n1161588602= 29 9 733 6 6 53 2\n2643840079= 4 6 40 9 1 4 75 34 1 3 78\n12231768= 50 96 57 8 3\n22053= 315 1 7 3\n59127088135= 7 99 74 291 797 132\n209537664= 5 5 1 8 4 1 6 92 220 8 8\n26634957= 1 85 2 4 2 24 816 3 714\n3940518666= 36 3 80 28 442 3 3 1 8 1\n12161796610= 49 56 7 998 6 245 43\n199948= 61 976 3 192 268\n15654= 5 192 3 7 2 6 62\n146720= 31 6 58 8 96\n1772= 73 6 482 778 74\n105802= 4 9 6 226 764 99 73\n1410441620754= 671 6 3 8 867 21 51\n1278730= 717 4 39 53 216 1 4 2\n1755915= 2 178 6 64 3 1 52 6 7 63\n111843603828= 2 157 2 341 794 433 3\n227276742914= 911 297 551 84 6 5 1 6\n188988963= 7 489 8 9 22 8 7 90 6 5 3\n2518558236= 94 687 396 39 6 786\n179452851= 26 69 50 2 8 11 38 3\n4483617753= 771 6 52 55 7 83 2 84\n3045905= 5 8 9 319 62 7 3 4 78 1 8\n11261535713= 3 250 769 3 5 714\n3854= 344 8 2 31 5\n1487109= 835 5 356 1 808\n2489= 83 176 8 8 6 3 4 388 8\n13541635031= 564 234 793 24\n29416717243= 462 527 212 14 3\n176849= 162 8 2 1 52\n73467964416= 868 704 2 258 233\n25815023= 1 64 62 5 650 2 8 62 8\n98= 4 9 5 42 15\n6487913759= 5 6 7 4 9 791 1 2 753 6 1\n3527= 45 18 1 7 8\n461767= 565 816 99 628\n760= 46 9 8 2 3 8 2 3 6 5 318 7\n1202974088= 5 39 7 2 2 7 165 632 1 8\n24185454= 2 4 442 552 60 94 6\n5237162784= 744 1 9 9 6 6 8 8 6 1 7 81\n75160511= 1 2 8 75 92 9 9 40 1 5 11\n203314725= 681 6 653 85 191 747\n165316= 21 4 9 4 74\n217= 51 157 9\n2985686= 4 5 8 749 59 8 4 864 83\n6236226= 8 959 7 9 86 92 8\n23190= 6 5 773\n3585388362400= 8 936 913 202 5 416\n245815119= 76 340 1 7 46\n770044= 9 5 550 33 2 6\n531732= 63 3 1 928 924 3\n53482062= 3 6 716 8 550 9 55\n428281604= 7 198 7 85 57 549\n102148233= 4 1 6 9 5 907 3 9 4 5 235\n156141= 1 11 5 8 2 8 39 8 1 5 1\n3406245075= 905 82 68 9 675\n8992= 1 40 4 27 48 16\n8125201052= 812 5 20 10 52\n1186311= 7 2 91 7 8 38 1 7 2 161 3\n846893376= 86 8 287 32 981\n1260411= 7 9 65 2 21 79 89 194\n2137656811665= 44 777 7 41 42 7 3 682\n7628618= 9 5 1 2 2 25 8 9 6 728 4 3\n4284404= 6 4 352 764 401\n1953248008= 9 6 1 619 8 550 62 1 3 6\n23217= 59 4 203 61 71\n201456= 40 5 872 578 3\n1441638= 2 28 4 79 596 6 8 54 33\n6923652= 1 47 116 4 847 41 924\n80960930= 176 5 92 93 2\n1142233984= 8 9 847 406 64\n1478491= 29 8 3 9 634\n158600757= 996 272 4 4 6 521 23\n682984325= 8 2 1 7 860 4 8 8 48 2\n426= 7 59 8 5 2\n176333692= 732 2 7 2 2 7 5 6 55 64 2\n1944= 877 835 2 5 225\n14785562880= 76 3 4 22 4 5 89 6 3 23\n222447224873= 669 8 2 369 2 9 10 6 1 4\n97661641= 6 9 4 1 9 5 2 6 90 40 3\n1346404= 732 9 279 132 2\n638099= 69 924 8 531\n4826320= 2 580 1 1 9 7 1 460 2\n5424478= 6 903 6 476 3\n174745089= 9 44 932 9 6 4 9 2 5 54 9\n49666959984= 8 869 8 798 7 8 10 48 7\n13790117510= 3 9 8 93 531 6 7 8 6 7 8\n1158= 38 4 1 5 435 289 8\n2461918479= 246 1 918 479 1\n37175171= 76 5 62 4 97 4 9 792 4\n6855= 7 66 15 52 5 42 6 759\n10202049= 300 4 907 37 49 6 58\n32659503291= 9 7 8 5 3 9 4 2 318 6 3 8\n119110203559= 50 9 52 1 62 772 5 6 2 9\n286389091119= 1 81 5 7 2 2 9 741 112 2\n1729945= 5 616 77 47 4 32\n12666905955= 45 1 7 3 29 3 459 985\n741595172= 30 78 166 3 22 762 8\n1236667= 47 52 506\n190= 3 7 9\n25153920494= 15 4 3 79 3 24 11 246 2\n3990535857= 63 341 839 7 9\n4418193= 31 2 177 80 6 267\n11286445296= 778 8 23 77 258 56\n876672511= 7 2 122 575 3 64 2 55 2\n10080485= 29 62 2 4 5 7 16 5 480 5\n193818= 193 1 17 701\n4322= 33 64 44 7 47\n10731634711= 50 3 32 17 685 86 8\n3734528= 9 59 32 5 9 8 2 8 7 512\n1912249= 237 8 1 9 8 5 3 269 2 7\n986442912= 586 25 2 57 75 882 38\n2052= 57 5 9 68 84 5 9\n360552= 24 6 6 67 35 54\n50657277= 388 2 85 768\n831901772= 83 2 37 79 9 3 5 62 72\n132361= 4 61 2 2 361\n27312518714= 9 3 2 11 8 93 51 8 717\n86741323257= 18 408 6 124 38 56\n56676545931= 3 4 227 5 7 429 3 8 4 9\n3595708= 2 9 274 9 9 3 3 275 4 1\n5175468= 5 4 3 8 85 5 1 729 8 4 4 6\n73015409730= 6 5 838 2 88 223 6 74 6\n197559600= 379 594 20 58 7 5\n1980192= 6 6 30 18 4 8\n246000= 4 4 70 47 25 38 200\n429= 5 9 378 6\n48175277= 29 769 45 98 8 9 59 6 5\n1646= 1 5 538 9 643 4 439 8\n168824= 18 91 50 13 8\n78074= 747 28 55 1 516\n2605050= 1 826 90 7 5\n464453= 2 75 1 5 708 8 5\n85549= 94 27 9 9 626\n3593392= 4 795 9 44 17\n8929787= 924 36 93 12 9 49 5\n204815029= 204 8 150 28\n441987= 1 626 992 7 39\n1104672465971= 5 5 2 6 4 672 460 5 9 70\n187704= 7 975 91 36 27\n4074= 97 6 7\n137722= 8 2 86 70 50\n1988= 283 7 5\n514083842= 918 8 7 380 2 43\n1638= 3 6 46 459 32 3\n74762172= 70 4 1 762 172\n1779191747= 355 5 4 191 749\n220802= 2 3 4 80 30\n26027520= 229 8 3 457 18 399 80\n34859430= 1 3 311 3 2 261 6 7 7 5 5\n10896747904= 19 11 71 57 905\n6046305385= 920 2 9 657 8 3\n65477902626= 7 1 2 3 3 680 5 7 1 1 39 8\n18668556= 27 942 734\n35140= 389 9 13 2 5\n41271300835140= 733 581 2 4 97 33 580\n58892856= 396 627 649 177 199\n8702400028= 440 4 4 222 875 29\n708207= 3 4 63 73 42 68\n2267548393= 35 55 7 25 483 48 8 34\n158740626= 623 52 7 32 7\n37165412= 447 975 1 99 22 3 4 1 4\n87584= 8 391 31 135 1 8 7\n1438547106= 45 38 317 161 945\n504983= 8 4 6 1 604 8 371\n14519220930= 93 1 14 159 90 97\n949379= 9 58 991\n300867840= 81 8 963 6 62 65 3 3\n50593616= 4 20 9 71 98 413 9 8 1 6\n15598080= 326 497 62 396 96\n8680959= 96 4 549 2 9\n1354365818046= 7 93 16 9 9 47 1 940 46\n2365= 4 7 9 9 431 687 347 6 3\n37026= 9 2 2 18 422 4 3 1 5 5 2 3\n72608= 8 254 3 2 137\n395449= 7 8 4 1 24 1 2 5 21 144 1\n23639040= 5 76 33 6 608 324\n28177014753= 505 871 557 5 3\n66765514217= 3 179 3 1 5 2 1 3 3 7 1 5\n275038= 53 4 51 27 9 94 3 6 79\n4059426114= 7 4 4 90 9 7 2 258 3 15\n1558696408= 7 773 6 77 90 37\n72339600= 4 209 1 4 6 1 5 9 3 2 5 40\n654= 6 6 7 42 7 5 44\n15902= 691 154 38 18 6\n991782= 991 22 7 1 552\n60835= 60 8 38\n924485= 37 3 33 642 5\n4249823= 11 2 6 33 828 3 3 23\n47841349= 4 4 70 44 7 353 318\n74786945= 63 9 24 4 63 7 744 8 65\n25553824= 25 5 527 6 8 34 9 92\n244489= 116 4 3 7 7\n232787240= 3 91 95 931 28\n168883= 2 61 1 2 40 8 84\n10517265= 156 62 5 766 8 9 8 72\n21531469614= 2 976 729 57 302\n498= 1 53 2 9 3\n35119420617= 2 5 7 949 499 5 5 2 3 4 5\n51053418= 4 1 79 8 488 8 69 42\n9064910= 866 428 982 7 37\n101985094351= 4 400 7 2 7 37 8 7 7 5 3 6\n284804116= 678 3 2 5 6 2 67 7 6 2 3 3\n3304056= 550 4 4 7 213\n105853334787= 43 2 5 2 6 9 7 9 7 90 78 7\n8881534= 25 71 5 6 531\n1433046= 1 21 270 9 545 27 759\n13727957= 8 324 4 1 79 9 1 57 2 9 6\n10591349= 37 162 30 22 3 462\n49205= 8 4 1 6 422 500 51 245\n812346909= 77 797 1 5 125 58 4 6 3\n56448843= 56 7 144 84 3\n86848= 7 7 7 7 56 8 1 1 4 4 2 32\n5763= 10 7 4 7 65 35 6\n7147742595255= 12 5 6 3 73 73 91 9 29 5\n5946090= 16 6 25 192 86 85 3\n1950322773= 16 8 3 15 61 8 5 9 335 7\n80001341= 41 7 302 13 4 71 955\n189269= 249 758 325 9 193\n24353171198= 74 3 8 36 5 13 249 3 3 3\n21988928= 7 22 4 8 5 26 19 169 8\n8857= 393 3 77 7 68\n87464047546= 57 4 9 3 28 5 4 53 22 45\n576270130= 38 7 4 98 22 2 6 1 50 12\n1038237= 2 5 38 227 10\n16437242= 1 8 8 6 1 118 19\n118533= 238 6 88 357 8\n55755= 4 8 3 2 1 4 94 6 55 5 59\n1878= 46 30 20 470 8\n188107538= 9 3 7 369 3 4 9 2 4 7 253\n6986478= 847 5 41 2 49 22 4 1\n56073= 576 1 7 462 9\n16147623= 299 6 9 927 696\n172299= 6 6 8 39 8 4 420 7 4 8 2 9\n19707121= 14 8 80 277 72 542\n4807047= 85 84 1 56 8\n103399= 4 4 93 614 944 842\n415241080= 2 40 2 4 8 48 3 7 877\n39496683225= 99 941 494 8 25\n65523806= 284 958 81 49 651 5\n10531660= 8 8 609 4 3 9 9 40 2 578\n251905= 57 8 38 702 3 70 2 745\n54818482= 137 81 4 251 82\n1318= 993 314 13\n797843199= 92 271 6 128 25\n253960= 9 1 8 47 300 55 3 8 94\n312486050= 4 3 93 8 6 60 3 5 8 7\n20412576= 68 790 237 779 76\n32860= 4 804 203 4 8 81 8 6 4\n6763= 31 3 4 7 2 6 7 7 140 4 8 7\n125419236697= 6 7 53 7 9 7 67 2 2 468 2\n480424= 71 9 5 2 373\n26062600= 548 3 42 4 6 732 474\n66809704= 5 78 89 9 9 5 5 1 67 3 6\n704520= 5 8 710 6 2\n5532597= 6 2 7 5 6 3 7 3 3 5 2 485\n90883= 32 28 8 4 80\n5795286550= 5 1 795 286 549\n351162= 43 8 2 44 474 9\n2179214380= 2 4 609 1 57 505 7 916\n828= 46 47 558 67 6 99 5\n26940060= 614 4 365 86 80 4 5 63\n75738= 31 5 2 6 4 89\n138382641= 45 3 6 51 198 72 8 10\n7881700869= 36 9 349 83 243\n48585= 59 423 17 7 361\n2649371051236= 306 5 5 9 6 4 4 9 2 809 4\n1599= 599 618 1 5 375 2 1\n11245= 849 83 80 112 4\n20025747125= 9 1 12 9 39 873 125\n304159954= 2 6 7 9 7 7 8 15 995 5\n174669224220= 6 5 684 442 81 12 159\n27806031= 5 3 7 590 702 77 749 1\n7817= 7 21 52 168 5\n176057= 55 32 57\n319278= 48 67 3 3 11 894\n4064102= 200 1 4 66 2 36 301\n1294= 8 4 2 3 1 663 1 5 515 3 6\n40524= 40 69 617 2 6\n14779018942= 5 78 29 3 4 9 932 7 61 3\n113488760= 4 1 648 4 18 947 815 8\n41492589= 514 468 684 43 4\n4857= 8 76 4 52 25 256\n470973600= 2 7 778 6 1 60 5 9 5 32\n500361= 61 82 1 20 44\n22257= 7 2 32 32 14 2 753 6\n34936254697= 698 7 2 5 5 37 2 7 72 8\n6130747= 28 252 7 31 63\n621094920= 24 815 93 8 995\n25081134120= 91 3 352 31 5 8 5 343\n575932900= 57 9 81 5 3 36 77 3 1\n7237736= 714 7 57 7 26 66 8 5 63\n8371616= 157 845 9 82 9 805 1 6\n2270829= 415 7 7 652 21 7 29\n291305= 6 85 67 72 10 49 6 6 7\n909249513= 35 1 9 73 4 5 7 8 187 6 3\n7452225= 6 360 5 5 3 1 5 8 5 5 33 1\n92774412762= 4 89 3 10 302 4 1 595 8\n186042= 949 4 49 36 2\n10280455589= 4 5 9 3 804 1 554 92 96\n4222018= 7 4 9 3 4 3 1 467 5 2 337\n517625= 95 22 1 46 2 96 753 3 5\n5126817530= 2 439 493 8 3 7 47 4 3 2\n28996334= 57 909 54 44 3\n35154= 4 9 31 1 87 6\n26120= 6 71 6 5 3 6 30 2 6 1 5 4\n381682302= 50 76 6 84 589 3 4 3 4 3\n7152040= 74 17 3 6 4 5 9 8 5 1 89\n84383= 6 8 7 43 36 743 83\n938542735821= 521 412 3 18 59 58 21\n296700= 1 1 3 856 345\n1565677140234= 392 4 42 12 95 234\n102060855978= 462 319 13 2 2 7 761 3\n23908402876= 90 388 5 840 287 6\n8716682= 454 534 165 63 120 2\n36326= 34 95 402 6\n38384656= 1 97 2 94 2 8 833 9 7\n1457826837= 10 70 2 589 308 98 5\n1344414= 322 5 2 834 6\n12427020= 7 789 75 9 5 6\n722534456= 2 8 8 9 9 3 9 980 3 3 3 3\n885= 2 6 5 68 1\n82339793544= 8 2 33 9 7 93 5 44\n56161976= 11 66 47 463 75\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_07_questions.txt",
    "content": "--- Day 7: Bridge Repair ---\n\nThe Historians take you to a familiar rope bridge over a river in the middle of a jungle. The Chief isn't on this side of the bridge, though; maybe he's on the other side?\n\nWhen you go to cross the bridge, you notice a group of engineers trying to repair it. (Apparently, it breaks pretty frequently.) You won't be able to cross until it's fixed.\n\nYou ask how long it'll take; the engineers tell you that it only needs final calibrations, but some young elephants were playing nearby and stole all the operators from their calibration equations! They could finish the calibrations if only someone could determine which test values could possibly be produced by placing any combination of operators into their calibration equations (your puzzle input).\n\nFor example:\n\n190: 10 19\n3267: 81 40 27\n83: 17 5\n156: 15 6\n7290: 6 8 6 15\n161011: 16 10 13\n192: 17 8 14\n21037: 9 7 18 13\n292: 11 6 16 20\n\nEach line represents a single equation. The test value appears before the colon on each line; it is your job to determine whether the remaining numbers can be combined with operators to produce the test value.\n\nOperators are always evaluated left-to-right, not according to precedence rules. Furthermore, numbers in the equations cannot be rearranged. Glancing into the jungle, you can see elephants holding two different types of operators: add (+) and multiply (*).\n\nOnly three of the above equations can be made true by inserting operators:\n\n    190: 10 19 has only one position that accepts an operator: between 10 and 19. Choosing + would give 29, but choosing * would give the test value (10 * 19 = 190).\n    3267: 81 40 27 has two positions for operators. Of the four possible configurations of the operators, two cause the right side to match the test value: 81 + 40 * 27 and 81 * 40 + 27 both equal 3267 (when evaluated left-to-right)!\n    292: 11 6 16 20 can be solved in exactly one way: 11 + 6 * 16 + 20.\n\nThe engineers just need the total calibration result, which is the sum of the test values from just the equations that could possibly be true. In the above example, the sum of the test values for the three equations listed above is 3749.\n\nDetermine which equations could possibly be true. What is their total calibration result?\n\n--- Part Two ---\n\nThe engineers seem concerned; the total calibration result you gave them is nowhere close to being within safety tolerances. Just then, you spot your mistake: some well-hidden elephants are holding a third type of operator.\n\nThe concatenation operator (||) combines the digits from its left and right inputs into a single number. For example, 12 || 345 would become 12345. All operators are still evaluated left-to-right.\n\nNow, apart from the three equations that could be made true using only addition and multiplication, the above example has three more equations that can be made true by inserting operators:\n\n    156: 15 6 can be made true through a single concatenation: 15 || 6 = 156.\n    7290: 6 8 6 15 can be made true using 6 * 8 || 6 * 15.\n    192: 17 8 14 can be made true using 17 || 8 + 14.\n\nAdding up all six test values (the three that could be made before using only + and * plus the new three that can now be made by also using ||) produces the new total calibration result of 11387.\n\nUsing your new knowledge of elephant hiding spots, determine which equations could possibly be true. What is their total calibration result?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_08.adb",
    "content": "--  Solution to Advent of Code 2024, Day 8\n-------------------------------------------\n--  Resonant Collinearity\n--\n--  https://adventofcode.com/2024/day/8\n--  Copy of questions in: aoc_2024_08_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_08 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 12;\n  input_name : constant VString := +\"aoc_2024_08\"; n : constant := 50;\n\n  map : array (1 .. n, 1 .. n) of Character;\n\n  type Antenna_Type is record\n    x, y : Positive;\n    c    : Character;\n  end record;\n\n  a : array (1 .. 2500) of Antenna_Type;\n  l : Natural := 0;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        map (x, y) := c;\n        if c in 'a' .. 'z' or c in 'A' .. 'Z' or c in '0' .. '9' then\n          l := l + 1;\n          a (l).x := x;\n          a (l).y := y;\n          a (l).c := c;\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show_Map is\n  begin\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Put (map (x, y));\n      end loop;\n      New_Line;\n    end loop;\n    New_Line;\n  end Show_Map;\n\n  verbose : constant Boolean := False;\n\n  procedure Do_Part (part : Part_Type) is\n\n    procedure Plant_Antinode (xa, ya : Integer) is\n    begin\n      if xa in 1 .. n and then ya in 1 .. n then\n        map (xa, ya) := '#';\n      end if;\n    end Plant_Antinode;\n\n    dx, dy : Integer;\n\n  begin\n    for i in 1 .. l loop\n      for j in i + 1 .. l loop\n        if a (i).c = a (j).c then\n          --  Create andinodes:\n          dx := a (j).x - a (i).x;\n          dy := a (j).y - a (i).y;\n          case part is\n            when part_1 =>\n              Plant_Antinode (a (i).x - dx, a (i).y - dy);\n              Plant_Antinode (a (j).x + dx, a (j).y + dy);\n            when part_2 =>\n              for m in -n .. n loop\n                Plant_Antinode (a (j).x + m * dx, a (j).y + m * dy);\n              end loop;\n          end case;\n        end if;\n      end loop;\n    end loop;\n\n    --  Count the antinode locations:\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        if map (x, y) = '#' then\n          r (part) := r (part) + 1;\n        end if;\n      end loop;\n    end loop;\n\n    if verbose then\n      Show_Map;\n    end if;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Do_Part (part_1);\n  Do_Part (part_2);\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 409\n    --  Part 2: validated by AoC: 1308\n  end if;\nend AoC_2024_08;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_08.txt",
    "content": "........0.......................c.................\n........a.........................................\n.......0........................................r.\n.....W............................................\n..............Z..F.......................c........\n..F....a.....................c.......Lr....5......\n............................v.......L5............\n..................0.....v............r...E........\n...a..........................p..E..5...7L.m...Z..\n......j..0............z.....p.........E...........\n...j...S...W.7................J........4..........\n......W........X...............................4..\nW..........................p................M.....\ni........Z....................L.............U.....\n.....z....j..X..............................b....M\n........................Z......m..................\n....f.........X........J................4......H..\ny..................p............X.JvmR.U..........\n..................................................\n................................4.................\n.........N........................U...............\n........u...q.......5....J..7.................M...\n.y..i.F...z..........................9x.....A.....\n...i.....2...zw....Y.........................M....\n............Bu.................I...........U......\n..f.....2.......k...........b.........I.......x...\n.f............................................G...\n.O...o.......f...............7.t..Q.G.............\na.....N....i2.........g..o...RI........G..........\n......oy...q..........N..H........sQ..............\n....y..2............K........b........9...m.......\n.......w...............b....Y........G.......A....\n......uO.w............q.k..Y.....v.............A..\n...u...K....O..............I......................\no.O.........w.......Y.........R.Q..............T..\n......................t...3........k...x...C9.....\n.............q........3..6......t............Q.x..\nV......................N..............S...........\n..............6....K...............1...n..P.......\n......8..........................T....H.........1.\n..................s....t.....3....H.......n.......\n......K.g6...B...........h..T..l.....P.....9......\n..................l....k..T....h............1....e\n............6.........l.......h.....Pe..C.........\n...........s.V....................e..........C....\n.....8...V.......s.g...........n......e...........\n..V......B.g...........l.8........................\n......B.................R..3...............1.....S\n........................h...................S...CP\n..................................................\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_08_questions.txt",
    "content": "--- Day 8: Resonant Collinearity ---\n\nYou find yourselves on the roof of a top-secret Easter Bunny installation.\n\nWhile The Historians do their thing, you take a look at the familiar huge antenna. Much to your surprise, it seems to have been reconfigured to emit a signal that makes people 0.1% more likely to buy Easter Bunny brand Imitation Mediocre Chocolate as a Christmas gift! Unthinkable!\n\nScanning across the city, you find that there are actually many such antennas. Each antenna is tuned to a specific frequency indicated by a single lowercase letter, uppercase letter, or digit. You create a map (your puzzle input) of these antennas. For example:\n\n............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............\n\nThe signal only applies its nefarious effect at specific antinodes based on the resonant frequencies of the antennas. In particular, an antinode occurs at any point that is perfectly in line with two antennas of the same frequency - but only when one of the antennas is twice as far away as the other. This means that for any pair of antennas with the same frequency, there are two antinodes, one on either side of them.\n\nSo, for these two antennas with frequency a, they create the two antinodes marked with #:\n\n..........\n...#......\n..........\n....a.....\n..........\n.....a....\n..........\n......#...\n..........\n..........\n\nAdding a third antenna with the same frequency creates several more antinodes. It would ideally add four antinodes, but two are off the right side of the map, so instead it adds only two:\n\n..........\n...#......\n#.........\n....a.....\n........a.\n.....a....\n..#.......\n......#...\n..........\n..........\n\nAntennas with different frequencies don't create antinodes; A and a count as different frequencies. However, antinodes can occur at locations that contain antennas. In this diagram, the lone antenna with frequency capital A creates no antinodes but has a lowercase-a-frequency antinode at its location:\n\n..........\n...#......\n#.........\n....a.....\n........a.\n.....a....\n..#.......\n......A...\n..........\n..........\n\nThe first example has antennas with two different frequencies, so the antinodes they create look like this, plus an antinode overlapping the topmost A-frequency antenna:\n\n......#....#\n...#....0...\n....#0....#.\n..#....0....\n....0....#..\n.#....A.....\n...#........\n#......#....\n........A...\n.........A..\n..........#.\n..........#.\n\nBecause the topmost A-frequency antenna overlaps with a 0-frequency antinode, there are 14 total unique locations that contain an antinode within the bounds of the map.\n\nCalculate the impact of the signal. How many unique locations within the bounds of the map contain an antinode?\n\n--- Part Two ---\n\nWatching over your shoulder as you work, one of The Historians asks if you took the effects of resonant harmonics into your calculations.\n\nWhoops!\n\nAfter updating your model, it turns out that an antinode occurs at any grid position exactly in line with at least two antennas of the same frequency, regardless of distance. This means that some of the new antinodes will occur at the position of each antenna (unless that antenna is the only one of its frequency).\n\nSo, these three T-frequency antennas now create many antinodes:\n\nT....#....\n...T......\n.T....#...\n.........#\n..#.......\n..........\n...#......\n..........\n....#.....\n..........\n\nIn fact, the three T-frequency antennas are all exactly in line with two antennas, so they are all also antinodes! This brings the total number of antinodes in the above example to 9.\n\nThe original example now has 34 antinodes, including the antinodes that appear on every antenna:\n\n##....#....#\n.#.#....0...\n..#.#0....#.\n..##...0....\n....0....#..\n.#...#A....#\n...#..#.....\n#....#.#....\n..#.....A...\n....#....A..\n.#........#.\n...#......##\n\nCalculate the impact of the signal using this updated model. How many unique locations within the bounds of the map contain an antinode?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_09.adb",
    "content": "--  Solution to Advent of Code 2024, Day 9\n-------------------------------------------\n--  Disk Fragmenter\n--\n--  https://adventofcode.com/2024/day/9\n--  Copy of questions in: aoc_2024_09_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_09 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_09\";\n\n  r : array (Part_Type) of Integer_64;\n  s : VString;\n  type Disk is array (0 .. 180_000) of Integer;\n  d : Disk;\n  l : Integer := -1;  --  Last block\n  free : constant := -1;\n\n  type Block_Descriptor is record\n    id  : Natural;\n    pos : Natural;\n    len : Natural;  --  Possibly length of free blocks becomes 0.\n  end record;\n\n  --  Following arrays are \"cheap vectors\".\n  --  In \"full Ada\" we would use Ada.Containers.Vectors\n  --\n  free_list, file_list : array (1 .. 10_000) of Block_Descriptor;\n  last_free, last_file : Natural := 0;\n\n  procedure Read_Data is\n    f_in : File_Type;\n    b : Natural;\n    is_file : Boolean := True;\n    invalid_file_id : constant := -1;\n    file_id : Integer := invalid_file_id;\n  begin\n    Open (f_in, input_name & \".txt\");\n    Get_Line (f_in, s);\n    Close (f_in);\n\n    for i in 1 .. Length (s) loop\n      b := Character'Pos (Element (s, i)) - Character'Pos ('0');\n      if is_file then\n\n        --  File block:\n\n        file_id := file_id + 1;\n        --  Files are always of length > 0\n        last_file := last_file + 1;\n        file_list (last_file).id  := file_id;\n        file_list (last_file).pos := l + 1;\n        file_list (last_file).len := b;\n        for j in 1 .. b loop\n          l := l + 1;\n          d (l) := file_id;\n        end loop;\n      else\n\n        --  Free block:\n\n        if b > 0 then\n          last_free := last_free + 1;\n          free_list (last_free).id  := 0;  --  Don't care\n          free_list (last_free).pos := l + 1;\n          free_list (last_free).len := b;\n          for j in 1 .. b loop\n            l := l + 1;\n            d (l) := free;\n          end loop;\n        end if;\n      end if;\n      is_file := not is_file;\n    end loop;\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    k : Integer;\n    dc : Disk := d;\n    lc : Integer := l;\n  begin\n    --  Move individual blocks from the right to the left,\n    --  for compacting the disk (and fragment it by the way):\n    k := 0;\n    while k < lc loop\n      if dc (k) = free then\n        while lc > k and then dc (lc) = free loop\n          lc := lc - 1;\n        end loop;\n        exit when k >= lc;\n        --  dc (lc) is a file block to be moved.\n        dc (k) := dc (lc);\n        lc := lc - 1;\n      end if;\n      k := k + 1;\n    end loop;\n\n    --  Checksum:\n    for i in 0 .. lc loop\n      r (part_1) := r (part_1) + Integer_64 (i * dc (i));\n    end loop;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    dc : Disk := d;\n    from, to : Integer;\n  begin\n    --  Move contiguous blocks to compact the disk:\n    for i in reverse 1 .. last_file loop\n      for j in 1 .. last_free loop\n        exit when free_list (j).pos > file_list (i).pos;\n        --  Free space candidate is left to the file first block's position.\n        if free_list (j).len >= file_list (i).len then\n          --  There is enough room on the left to move the entire file\n          --  as contiguous blocks.\n          --  NB: AoC is kind and did not require overlapping moves (would\n          --  have been a slightly more difficult special case)...\n          from := file_list (i).pos;\n          to   := free_list (j).pos;\n          for k in reverse 0 .. file_list (i).len - 1 loop\n            dc (to + k) := dc (from + k);\n            dc (from + k) := free;\n          end loop;\n          --  Update file & free lists:\n          file_list (i).pos := free_list (j).pos;\n          free_list (j).pos := free_list (j).pos + file_list (i).len;\n          free_list (j).len := free_list (j).len - file_list (i).len;\n          exit;\n        end if;\n      end loop;\n    end loop;\n\n    --  Checksum\n    for i in 0 .. l loop\n      if dc (i) /= free then\n        r (part_2) := r (part_2) + Integer_64 (i * dc (i));\n      end if;\n    end loop;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Do_Part_1;\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1))) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Do_Part_2;\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put (+\"Part 1:\"); Put (r (part_1)'Image); New_Line;\n    Put (+\"Part 2:\"); Put (r (part_2)'Image); New_Line;\n    --  Part 1: validated by AoC: 6340197768906\n    --  Part 2: validated by AoC: 6363913128533\n  end if;\nend AoC_2024_09;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_09.txt",
    "content": "4321114116413220541570577637245222444021661592171263865885224732273825869312483167708567817674108840154724814020488319597433518153794891419711843176705367457679452376442217873733926272917445955965888693468662976755233261564921212689858670822660921045521689325943861594792490217120327169792723237499587216904596599872121716859263956010994733457813596119487219392335736372245437169845898643189872245098246593768525719380823858692982841997272433155826154557589241449370746452694744461120803257817535871172861258399540791614671067669690485675575933779748639948612937974158443365681381337526776774557741709676398828286316936658527222644790712081652079243716718611714699591264889640908296877633397167645451824070692546271790612617368492387914819957451645126977652136993264543623984384273362998737586428844228427296633769815863805665473967815551981495259377432875783190113477509081634710887810853437713320802968906322258914297070369853573125859475605183363166665329463965516862161297928888617275265155104615907291186595883452383619243819833884714240719940259088646582164654782873155710965164503170548756254577791371262615158875962165429840846220173176672970878450984584757470954558851240499851819135176896339517949559592010834183236225915786392844753971771793218825354086948632255319742470157416924228693257901121299548413048685467541823787196394337517443937526888558491143659311349383956767396432628441416997634281956812854725174313273077916694598269211890567042477033257983257160403158507232419567166311591163292917407821414886113847306035342651999622606188754969403283241121901850207333124593501645469311878494651918804390694545382750561942479545387589151426228333806175831818618494733754688552211119951431572377692121656717159962743198155099237435107282505324506857964249375143308986135817237797135928386281215430721911948241474760431551459886778627335289222234881513785592697542215865548616194646447290367944374636461661493544386976889897712197475479439284583466543522118184824277279544578397564821711844992157299072334544344347393518638415773194913160896241788887377413377910983999937821871575474330796944125124876935907831408948197599769748848468774946693089334245425064251832141337715019849016633180483280473463373469937330402148711175395642486870187930578986661661949150469828729648275129308716375696783413712450946119371155924062393761249225972820323293384444425054794157242189298697518415872861359697737982562718141021917969125832586393135398622427718665355173468650992010379831649180938096823577641054289969506454168791105968599514496071384326353674647229327396894513563423623911413867293312219062414042644222883627246350422260746018339683356399199818442796773048636727648879712035861312999284254812337320868944982526426180896240994851136933868646545715693417557173996121562641842781856213787259527966922844811928228251547046163980684936233822204467873781809924138487141164222260364059366166934060789376123195576129499292509370965413491936736789428734228663605638966713362492208042333420734550628573965989212192423214196569296363527715854172857343352695102138309955132462967357823645689395129654103733491624536981708445212611445279314796423830412478444388406353248455802158481642919297188637397343942282327629574139202993427430448412546532703421297366159234324841957243915910452836224850677662527196569625593775634174766638612913666885258045577938861855311390752252783046428076922838226068623447986491125231645180541554778110436281493541901854839657993766703187708195435110913941368565534722398784628620526343405445368526137747556153507651854394702491513777992653327519186340975477847496488878752093428930771399803170458833725450926978652731839282911250373122871990577319189354515713604175863759179737991051514750527246614825992546437560382241327435449375219756271021485811632048364251373298727230612711876021119171548289774899737731501046109853298634274828683092782124317750895240508756337089107999759468191617527615944451672234885574425316718748434078221077819646502057489592913199296210883535911544982034487321212629114867383868686878985084131330576553356120833533954492809892223317939489667862535718593632663831604567127434314014229368954478686646103728896042953192651519276579803263559577913090598270654298681358951431222459563845954510162235864077732831174541723027325025116013983768653224598842348749981797674191761893263795132525327325192588375818981539382887576766224756281349278566602233546774288911763371413377431912394844955714932557807661545335615687315285992586648443886643165128951292864455345594656679355779244057993229857938482481947798249591724927613062657712604098122250782760151834129858837123411864705792974869574354889538867756922422726798931221558775769727881758826071478185599055376169264799383751155589729514451253358863358215893058403355182966171435544826595034886765837084142520341327194075203730745285209075829874921957462131201390378043993158623797173576734240156155452544599381177278588448847356477959337225543952343954698893738347292822194269995946849594638850225650173992575664115935141112725073803782429176945128394580838114482299997252782724186074418943845233743442398247196559241594506196627165144248133934611766663681613712316415467431955546533285892666424331669792322352673286789814893956552174882147128298833640248151621180367829809933463829712429885344754340374326164350266629732441149538333452867687539344879826214447997574683065894656585496617544624296772388351486914042866418825791272674972519789594162261956127145736671823569353836365674096941379827192439529108480115954339179141142855874417477178312435372387176761798559152951755417227292686132689174530518858328127284839408274825323577746985765795789213810465380694797446886587977573429852612247361299350906842239959882180674969894087597655754114102155749039971871291553356863967671873197765582984918919140282938406213709790619237114679132588209483221452326183733518462987818873437573175192237316863817464681484468901275849737846137277615793565215879612967456532377419849883842487144473315889739285138695723581105761583560448549974360315857923122873531754047846347318420878318112893255868443756939555745886405465834939983220798590651849177077605353864889174968742748442944306875319335117782901685672750385822689782227432291691759237513521754297753835254468722115723127928367431953993686856869349894323668489587143796451493508341886492408361363577505983379786692749683120429736376746466957245272921375692920149078588995673571288259578375948056789251477253158817748168454499871495181671278891968654608712766574653052992533637433534073889245394276631746942681841015643292592182943131942632384437554330306923515181465221505956806372638157855025666490354658753549794057976165112426103638225294735483541928218915443586328290759924556353147812609911965457924899921096899371307391302224886331937785799084918169416117501692883543402022994171224536195467264626998878744958286666442582289288102172359520318919117074228585511048171417636714148667252013863440485321953084226966521353352637806769315018247940273880208965901540187171226792716899578461947134948058957452428519142838519031109118174137639541446329453866774269224556394759603636963794585527971410576779151499902590752475765674506816776549764514922799169675753231508956748715412547611344949042972655169344364167289447858964479935166949527985135361445836673388302779233339437687584668573625291019966630413198934236923532377453507517171567617394808651198084218372246247159114269062174915709064194639282458669270463892394923748920667531455531844293637910719565391811379353168289672797936212994835838881158770603414118415153821829127705948414952103876785693821864517024873114439268399033609954588026101172375931983178258079311434278424326983718065776537483521564083779911382417409856813428435580583455462035491638854284135549941838939999925882858855956643847937482250613099327149234859527318731459513080381831518246379783314915158823921230746526501724905619808116909470109262498841256310336157368064183440203822319726158528203554443569671628645691513617383471509487668794278375677536295475298334144623981796399878979118924040111889958327103765326067841183441034424425899687962114245625932660637243202616379410815470583780776115563751162228628222417532799514515178688739693249586023492911474323644958412130867620254184887935503258979771677620333724833965649756313514273147587539171484709740836633202969793864288213608287704058787046753515204412974853314734609451506375761093197758969925776878488166271121642488974529166441684838433160517024162646926010653669949791916485103446258284963420911022176467238245289775268559948222212130333761575020156314289284659297204647487434297510216159422547824314653545254523803812531915142657583842241193442286141431396838912698668150208469286733137732127382472251809267259741244726715963317535887853294822315836221384121214336192199812604921652971333722189314647238406346716571629931599324772149122996604761973677681280762114212891867213146635765812239828187043208923556476639992523011958539223687268385136594375311422162868239394733366595699545814392877352457599391352787027801530568459535084455343789244947759902924979560413913426760437871405956551431437674694641415516294196497813893967211595696131667842617197642921407365877211856556254135312662757440442187807065295455366384856386758917394484508182319143598092402319809119367546667571624996519067541757805981615682897141757046153884993477338399184313644572934044293387841515687296617046799232226122475270642588596454336736484114964761426629768194755114296567266437996134797076902323601612658797708767691367472051768728636962377494602045146933279853636185988288419338803059606119822121573154308265266058742928928633679957416393953291964437155627877498373655949865879692336168519098625755643124606212773043191057683488153014532644376635169846642687215886909622501091321277744273707555964665653297316958866416686718594525108249308760273863174651846660601017498218905218191327924653122889653987748335881793598873222016351729471564851783193060587471749248735755734858858119644343838996737924778526147013321652812061614587515235723289414296137673809012664277601969105358777669677577327872999217561759421626109654295042875249222745149771163617543543688975359247208116611014768117832711869436205546556168133082197814168175328927484928339626205077659830782257906315414995756828666929779432365314953979283787693288935784483450887370235155583679376823629814855155706270865091449074597341593219569429697271281878617541829736893614135677383848323599686750374973321045879796113980469647154844735028751934769129291063841439824632795126156669776780368076573820566426377490748642101694313924351780656869536466855999817090719960562986867029874152538143298257617022486283931319679945816567798752856926807591637179809990791713557535122758837159874890218888717077374295694942291858973216585858673254665785378588276478215162783916701218849754863525762699212885416528623929242475675695469934273970895988577525403489632820768216623138994417301821729135821098457467373796248579672354192736529248745042894224904098885144109074233198573666204098543729715697777812804331124170435726665770264320539220167776631693379727472524627913466669736835289363636385477356437328648227559321675076399329723212152473686722294391655671507816268154831796379793384316155189903591338484715477841646207942788766753966914484852028348858944368435491839921267988405761204270855868464955891911288337157457181327888386628921447824649448678382342358382967708910207344285614711363883032583151921955798960457354751216597789864597293263726749824318517870432590689094941214161577201415909490256328652669562652619865296282929693653427413873189788311645177196504986854920549587273497525381924414323838645054988895388714824368609517575070979756145681296531214630676266306598414571812943193264453758709324797518567631676645427463212627923639505018243571142376865896313115784920593465218688537650843595763760759794436161335496565974725333349190181588345527121074292541751768894959473515656719943375323558352147103033668467691947177042993850557674293166685212647533105722197476371536171245334462575299556061148013608517743615558516382543173123864121167529258881407757954219704379233527337646533285984918612122205741225897332563354998944967617732229336906879765573849429365575452688924386173741884396973612405780503787307463978280806946437412402596946985941935707128266099928197163125767164545567263146357942171930656299248445375354935716946053581174673148487925888881261432561184599752517166975073678984616450272333132763979919971962984080879093439578125884662155948717808716338257454087327463741569423864247443955566132439989682948716964367849418821429157541634270626465994996511480491285478371469925499010667193942120101370672385249435966940769996572420961552746191278366693080901698779358624998151824306686192084378493551014518066272421529355953859136391422477579863774829184025967557594040575741319674402785296927795462831584623972471832884040339274829627158451712790395732311375868844548018992247931685722255987340686918972223942989855391399232336361187522728766613995309641656445537997334221704678916089283315979318528613262172143539379458734790637992384534549819763113415718987260235494106483783561287642581089459089181386578224405957268813464461814747265088424971475315281987392146256285251832957624209559163754748532155114667461355777561427432128679091734014692225198815814935752821187669627855433788304533603535859540525849282530499699827742419325221127534322709285899640516432825741305175903968574997348630471241398221823365612087563199237210972592712536357153443436428975743771631222934410772849299928735160368375129497124662267230427247416614282897595137787981673393214613933029245415193144559485416721361435332463304247769532746526629924571769797862108254534337755428419124534767643330581026736463958840176642936592228574957337293890305193898270682983257562463011804246111949791316161391541280315557862349256890222236485369278472707110282999444613298125543223296757173543693923689688236648434544729365721447438286728357967981293482981094729329359267461187505929161441446750604518633592812751888589197325935059319267973651812327211274575527488847884251643216553762919213423361994658112578461035845795398886238918737198691539863073213763722154735764662485262818147847995340662076864030744773351333374080536885242013213289628680624140895023652794781777495350414673712743824913122717585183406019627017737334484765879984357513348570213153675917869073101626319629942044543586655715408574591284946882374067416087117018898020353843578772444551403125215675109121419878265376755289923246393376981513403017944568433527501924888366829612382486798355468756116150607893998512762475165110989639665338874061912124124145139078184938679816619817634913429486321248798744826795194468154794994475209969615011984024423318482917573594439664825572437338665636419635935079818414548414592781415025394782523448945943608979271729584555484625221973535534312367734920997313994782209560272827978696977441216839314812542948879582628157119837692387434314699877305973321619154259452436657743604939384814446077134483379426745193973745134696826946935695449958504989269487657443188642972551457210864717438558191447581123597763495581619756687166373890754276523716707924492932372886597130681955488887201032231187341123552213845612959122285852607974187029327929792238208226278649265282341660192887237668671555448027611932135389447532856549182369446037952174171825663681149428378897849564118358612033535917716317499131797757541383105250194978203846838566976940141921554542747985879171781697116251744692321157905169184556349199843357814188673013985537535349326441114077326231258825234022659357133871548575786240437552753048695141253147218156254837669568351873644230227965765873131481622118595179281895622954496652936839479614161836527799434533205124271422116835358971276229653395109352873191494342237342461846167526829977812826604830188392455833928515102269871161193618284055148790214019991759389295404253364181271523795871913949398388434154292584337110442320437060266045589057984934659074784969468697442917875733159363377424489494734053878645998464939861551767197816208170645630786167424254951751311272423559185467583975389634892740681373796582866410288087614168892159723658975316709947442681124331842495602168505595545073714284531348156290633562548351693649258134181957266823947668917069813466652882978119934929269910171716838663964133265654238875654893801163738778769269938760806863517885301464165935795277882876696222452864583388975339574494709053544463299463889722493637509874531259161841519950899343594862258845642724245195539659226471672110927493595244389198306993688779781186116197221356448755642797446782767846373794568559528920899751179047719420367152761788115071115864177121755938642375745358883830333977876818522620137969509244171685428828608180597383325328579742981955509288737536125562397675377466547460585158209130829523376729638379244357769994736280547918894710809188553526228798675121943695954067898355309649523623521875619479419316363939529525796520757986434941205191146228866838108965458135547710831352804822271930481895557050168871361841177078137113422318294861941795519024145863907088921097522263771980972285341455862850433432601973693518839938412481252759368224833891701532523572722135671827298859657194827340209651646475798361745425287131617672387268503258649566574590613825554027155395718458651217795626496771931822466736223334967986855454737871433525121891134674221396658515434790511733296689784961383946152622835659316877601986606920659537435256396691492636379999451196556471566964958186383339468655995554515983856728673321982454368138343054338471738388527245727299878936294687822957826297624892794252983594252129773629365642155026969784122740788219898447387475742356683189961246169693499897444083687665464042189884162690655142969224899952165144599541639893793081258847167030726666398198102652827031195654829283367968109398422944411534273441546653627691273347965997119968196592553348255930497246129567435525582748726828771458206228921947967028187288313865377675342693888942702138617755339335355064771932138945266498123285628751316622845867722386619781929242781814951876581929483985964696863751554779188997157889441679654186465135244950943355351087144885679820541962836957805352236763761320879317431248609575643590688728117634946611691622241834828862521986135958194322996329343823938329589974416224597064556131163512101169435099473543852385772977247491582648406218239651786918169246822634379680416567335899186456606636773297566839364270799947419138657876949733817831747453589595464510125235552030289231445983809357436071721715628927395734154731442379984169925923921993747591987682832565811499577174376932199366894181969653481193304631753493479681825176325062219360584017968524762814862882302186903639389631435119836968707561529552813911395582511113645753964436982974184567996956491557424193671412896959339812569630979181787076177650146233442311174964754188295551784873679151304650225191907546514940683716157389344854311010168676134726856468852036954132272598409183843034219074918324865479141755546332575733492957845360507412509241761313806311944365159338752080718756706476427137167763559324925866326911533249245773106584364653871781114823415949702318474418738265688053978583876326258151586824275191385991347649439025898765596395507266135612264314874021189798567064733389296874133438816029512010711177384987283424948768653051799643299745381332867060459860572342458821628140289297711230852310341158388687585820324322501271814864926571947059767568433988689255364928651289422622392267275154404595472193275012321858675228765385611695647228125522464689905226789517144581467059212194833613889441565251682987108972285566824932765849894449146351245595393529776839424852485537494698127153701072623482794638807974927663982192809086315494991329946557154575512634504776406971742957666498799156187975257783197571956826811830117974624782289085907327396295284564395625275867717552842987395575245482432528429444767941114410138943483186229460348039436\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_09_questions.txt",
    "content": "--- Day 9: Disk Fragmenter ---\n\nAnother push of the button leaves you in the familiar hallways of some friendly amphipods! Good thing you each somehow got your own personal mini submarine. The Historians jet away in search of the Chief, mostly by driving directly into walls.\n\nWhile The Historians quickly figure out how to pilot these things, you notice an amphipod in the corner struggling with his computer. He's trying to make more contiguous free space by compacting all of the files, but his program isn't working; you offer to help.\n\nHe shows you the disk map (your puzzle input) he's already generated. For example:\n\n2333133121414131402\n\nThe disk map uses a dense format to represent the layout of files and free space on the disk. The digits alternate between indicating the length of a file and the length of free space.\n\nSo, a disk map like 12345 would represent a one-block file, two blocks of free space, a three-block file, four blocks of free space, and then a five-block file. A disk map like 90909 would represent three nine-block files in a row (with no free space between them).\n\nEach file on disk also has an ID number based on the order of the files as they appear before they are rearranged, starting with ID 0. So, the disk map 12345 has three files: a one-block file with ID 0, a three-block file with ID 1, and a five-block file with ID 2. Using one character for each block where digits are the file ID and . is free space, the disk map 12345 represents these individual blocks:\n\n0..111....22222\n\nThe first example above, 2333133121414131402, represents these individual blocks:\n\n00...111...2...333.44.5555.6666.777.888899\n\nThe amphipod would like to move file blocks one at a time from the end of the disk to the leftmost free space block (until there are no gaps remaining between file blocks). For the disk map 12345, the process looks like this:\n\n0..111....22222\n02.111....2222.\n022111....222..\n0221112...22...\n02211122..2....\n022111222......\n\nThe first example requires a few more steps:\n\n00...111...2...333.44.5555.6666.777.888899\n009..111...2...333.44.5555.6666.777.88889.\n0099.111...2...333.44.5555.6666.777.8888..\n00998111...2...333.44.5555.6666.777.888...\n009981118..2...333.44.5555.6666.777.88....\n0099811188.2...333.44.5555.6666.777.8.....\n009981118882...333.44.5555.6666.777.......\n0099811188827..333.44.5555.6666.77........\n00998111888277.333.44.5555.6666.7.........\n009981118882777333.44.5555.6666...........\n009981118882777333644.5555.666............\n00998111888277733364465555.66.............\n0099811188827773336446555566..............\n\nThe final step of this file-compacting process is to update the filesystem checksum. To calculate the checksum, add up the result of multiplying each of these blocks' position with the file ID number it contains. The leftmost block is in position 0. If a block contains free space, skip it instead.\n\nContinuing the first example, the first few blocks' position multiplied by its file ID number are 0 * 0 = 0, 1 * 0 = 0, 2 * 9 = 18, 3 * 9 = 27, 4 * 8 = 32, and so on. In this example, the checksum is the sum of these, 1928.\n\nCompact the amphipod's hard drive using the process he requested. What is the resulting filesystem checksum? (Be careful copy/pasting the input for this puzzle; it is a single, very long line.)\n\n--- Part Two ---\n\nUpon completion, two things immediately become clear. First, the disk definitely has a lot more contiguous free space, just like the amphipod hoped. Second, the computer is running much more slowly! Maybe introducing all of that file system fragmentation was a bad idea?\n\nThe eager amphipod already has a new plan: rather than move individual blocks, he'd like to try compacting the files on his disk by moving whole files instead.\n\nThis time, attempt to move whole files to the leftmost span of free space blocks that could fit the file. Attempt to move each file exactly once in order of decreasing file ID number starting with the file with the highest file ID number. If there is no span of free space to the left of a file that is large enough to fit the file, the file does not move.\n\nThe first example from above now proceeds differently:\n\n00...111...2...333.44.5555.6666.777.888899\n0099.111...2...333.44.5555.6666.777.8888..\n0099.1117772...333.44.5555.6666.....8888..\n0099.111777244.333....5555.6666.....8888..\n00992111777.44.333....5555.6666.....8888..\n\nThe process of updating the filesystem checksum is the same; now, this example's checksum would be 2858.\n\nStart over, now compacting the amphipod's hard drive using this new method instead. What is the resulting filesystem checkum?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_10.adb",
    "content": "--  Solution to Advent of Code 2024, Day 10\n-------------------------------------------\n--  Hoof It\n--\n--  https://adventofcode.com/2024/day/10\n--  Copy of questions in: aoc_2024_10_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_10 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_10\";\n\n  n_max  : constant := 56;\n\n  nx_max : constant := n_max;\n  ny_max : constant := n_max;\n\n  subtype Range_X is Integer range 1 .. nx_max;\n  subtype Range_Y is Integer range 1 .. ny_max;\n\n  type Map_Type is array (Range_X, Range_Y) of Integer;\n\n  map : Map_Type;\n  n : Point;\n\n  procedure Data_Acquisition is\n    c : Character;\n    f : File_Type;\n    x, y : Natural := 0;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      y := y + 1;\n      x := 0;\n      Get (f, c);\n      loop\n        x := x + 1;\n        map (x, y) := Character'Pos (c) - Character'Pos ('0');\n        exit when End_Of_Line (f);\n        Get (f, c);\n      end loop;\n    end loop;\n    n.x := x;\n    n.y := y;\n    Close (f);\n  end Data_Acquisition;\n\n  r : array (Part_Type) of Integer;\n\n  --  Walk (part 2: all possible paths) to all possible points with a 9.\n  --  Since we always go up one level above, we don't need to mark visited cells.\n  --\n  procedure Hike (x, y, level : Integer; part : Part_Type) is\n  begin\n    if x in 1 .. n.x and then y in 1 .. n.y and then level = map (x, y) then\n      if level = 9 then\n        r (part) := r (part) + 1;\n        if part = part_1 then\n          map (x, y) := -1;  --  \"Erase\" the summit (we count only one path to it).\n        end if;\n      else\n        Hike (x - 1, y, level + 1, part);\n        Hike (x + 1, y, level + 1, part);\n        Hike (x, y - 1, level + 1, part);\n        Hike (x, y + 1, level + 1, part);\n      end if;\n    end if;\n  end Hike;\n\n  procedure Find_Hiking_Heads is\n    map_orig : constant Map_Type := map;\n  begin\n    for y in 1 .. n.y loop\n      for x in 1 .. n.x loop\n        if map (x, y) = 0 then\n          --  Part 1: walk to all possible summits.\n          Hike (x, y, 0, part_1);\n          map := map_orig;\n          --  Part 2: walk all possible paths to all possible summits.\n          Hike (x, y, 0, part_2);\n        end if;\n      end loop;\n    end loop;\n  end Find_Hiking_Heads;\n\n  T0 : constant Time := Clock;\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Data_Acquisition;\n  Find_Hiking_Heads;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer'Value (To_String (Argument (1))) or\n       r (part_2) /= Integer'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: score  : \" & r (part_1));\n    Put_Line (+\"Part 2: rating : \" & r (part_2));\n    --  Part 1: validated by AoC: 737\n    --  Part 2: validated by AoC: 1619\n  end if;\nend AoC_2024_10;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_10.txt",
    "content": "43217654309879876104563234589896761012345656543098901001\n34108903212368123233472105676787851299856567832187812652\n45677814301457014312986345589876940387765678943046543743\n56789325100876525800345276430105432456566589858956769821\n65438456912963436901236187621234501223455410767349874430\n74321067803451107898547093412012982016764323101210143561\n89412210987430210789698892102123673107895214589723652678\n78601521856521345678721743089034543212345605679854781789\n66789430545678934505430654898745672212236765434765690878\n55676545038943213216765989601654981300129870121012345969\n46543216127657804389834808762347690456789983498141456452\n65454307233456934870126712354878765565210012507230987321\n54567898332110125961015645403969234674323215616546576010\n65658983021001876854324106912452128789321308723455678901\n76543212137892965348933217832141089873410419678964987652\n89862901236543501267018363101033210565566566569873788543\n89871876544345652106529854892123521454479877654012699830\n78100703454278743212434763763014672343287778943210581021\n65210212565189858906763212654985785650198961212101432010\n54321056876012567875898708783476698763267890303215678321\n87012567988703489874345679692676543294986725456574329478\n96543498589876530365210189501987650187675216987687610569\n01234567651010921234501076401236501010564307678596789876\n10389830532329854376542345321545692323403018789455430965\n21456721013456765289031234980098783410912129670320121054\n92505432565421010109120345671107654567823451061210120123\n87615443478302341018750134543234541050765962552121234984\n34322342189219650129665234789432132021894873443010965673\n45451056077828743234574343276543032134703210523457876532\n51069987456943104545987650167898749865612309610765454101\n32678678345652210698092156756547056764303458779890363232\n43010589232781306787183045876532178965210569888211274321\n56923432101090458989254234923421369878934678898302989430\n87889211078764567876360143010030450767125986567401276589\n96676305669653478985478652102141341458076803456564345676\n45435434734522780340349760123456232349883712678178737894\n80127821821011091211299854354987101016792103549069016323\n92346940910329654304587121267807652345013401232108925412\n81055432101458765643671010871018947654324589543987432101\n76567789023467010782532346965425638945695678654986540012\n05498654110567821891047897212334721032786014345678901098\n12387013223489932346156598101549889821012823216765212387\n03456323016576542345692367210678710701296954907854323456\n12345465437895431016781450123467623654387867878985401501\n21089870124326528701670101874345634565676541045621032012\n32189210065017019632543210965236730120545632456734548743\n43498349876298903545450143050159821321234012349895699654\n34567658389101232123469052101567634489234510106786789985\n99876501276788943016578769872498105672105621215021058876\n87035432365897654107689898763343234321678789334134567655\n70129641034781089898791099854232145690569245493254321567\n63238701123654178718982387763156056781410126787655010498\n54345652321073265001073456012047189872328901098546710327\n34568543434589874132569895145438976987437812361239891210\n21879654898678013203456701236327805456546521450967890123\n30968745467654320112345210987610112345545430567856543234\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_10_questions.txt",
    "content": "--- Day 10: Hoof It ---\n\nYou all arrive at a Lava Production Facility on a floating island in the sky. As the others begin to search the massive industrial complex, you feel a small nose boop your leg and look down to discover a reindeer wearing a hard hat.\n\nThe reindeer is holding a book titled \"Lava Island Hiking Guide\". However, when you open the book, you discover that most of it seems to have been scorched by lava! As you're about to ask how you can help, the reindeer brings you a blank topographic map of the surrounding area (your puzzle input) and looks up at you excitedly.\n\nPerhaps you can help fill in the missing hiking trails?\n\nThe topographic map indicates the height at each position using a scale from 0 (lowest) to 9 (highest). For example:\n\n0123\n1234\n8765\n9876\n\nBased on un-scorched scraps of the book, you determine that a good hiking trail is as long as possible and has an even, gradual, uphill slope. For all practical purposes, this means that a hiking trail is any path that starts at height 0, ends at height 9, and always increases by a height of exactly 1 at each step. Hiking trails never include diagonal steps - only up, down, left, or right (from the perspective of the map).\n\nYou look up from the map and notice that the reindeer has helpfully begun to construct a small pile of pencils, markers, rulers, compasses, stickers, and other equipment you might need to update the map with hiking trails.\n\nA trailhead is any position that starts one or more hiking trails - here, these positions will always have height 0. Assembling more fragments of pages, you establish that a trailhead's score is the number of 9-height positions reachable from that trailhead via a hiking trail. In the above example, the single trailhead in the top left corner has a score of 1 because it can reach a single 9 (the one in the bottom left).\n\nThis trailhead has a score of 2:\n\n...0...\n...1...\n...2...\n6543456\n7.....7\n8.....8\n9.....9\n\n(The positions marked . are impassable tiles to simplify these examples; they do not appear on your actual topographic map.)\n\nThis trailhead has a score of 4 because every 9 is reachable via a hiking trail except the one immediately to the left of the trailhead:\n\n..90..9\n...1.98\n...2..7\n6543456\n765.987\n876....\n987....\n\nThis topographic map contains two trailheads; the trailhead at the top has a score of 1, while the trailhead at the bottom has a score of 2:\n\n10..9..\n2...8..\n3...7..\n4567654\n...8..3\n...9..2\n.....01\n\nHere's a larger example:\n\n89010123\n78121874\n87430965\n96549874\n45678903\n32019012\n01329801\n10456732\n\nThis larger example has 9 trailheads. Considering the trailheads in reading order, they have scores of 5, 6, 5, 3, 1, 3, 5, 3, and 5. Adding these scores together, the sum of the scores of all trailheads is 36.\n\nThe reindeer gleefully carries over a protractor and adds it to the pile. What is the sum of the scores of all trailheads on your topographic map?\n\n--- Part Two ---\n\nThe reindeer spends a few minutes reviewing your hiking trail map before realizing something, disappearing for a few minutes, and finally returning with yet another slightly-charred piece of paper.\n\nThe paper describes a second way to measure a trailhead called its rating. A trailhead's rating is the number of distinct hiking trails which begin at that trailhead. For example:\n\n.....0.\n..4321.\n..5..2.\n..6543.\n..7..4.\n..8765.\n..9....\n\nThe above map has a single trailhead; its rating is 3 because there are exactly three distinct hiking trails which begin at that position:\n\n.....0.   .....0.   .....0.\n..4321.   .....1.   .....1.\n..5....   .....2.   .....2.\n..6....   ..6543.   .....3.\n..7....   ..7....   .....4.\n..8....   ..8....   ..8765.\n..9....   ..9....   ..9....\n\nHere is a map containing a single trailhead with rating 13:\n\n..90..9\n...1.98\n...2..7\n6543456\n765.987\n876....\n987....\n\nThis map contains a single trailhead with rating 227 (because there are 121 distinct hiking trails that lead to the 9 on the right edge and 106 that lead to the 9 on the bottom edge):\n\n012345\n123456\n234567\n345678\n4.6789\n56789.\n\nHere's the larger example from before:\n\n89010123\n78121874\n87430965\n96549874\n45678903\n32019012\n01329801\n10456732\n\nConsidering its trailheads in reading order, they have ratings of 20, 24, 10, 4, 1, 4, 5, 8, and 5. The sum of all trailhead ratings in this larger example topographic map is 81.\n\nYou're not sure how, but the reindeer seems to have crafted some tiny flags out of toothpicks and bits of paper and is using them to mark trailheads on your topographic map. \n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_11.adb",
    "content": "--  Solution to Advent of Code 2024, Day 11\n-------------------------------------------\n--  Plutonian Pebbles\n--\n--  https://adventofcode.com/2024/day/11\n--  Copy of questions in: aoc_2024_11_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_11 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  use Hash_Maps;\n\n  h : Hash_Map_Type;  --  Hash table with stone counts.\n\n  d : constant Data_Type := input;\n\n  verbosity_level : constant := 0;\n\n  procedure Set_Data is\n    procedure Set (i : Integer) is\n      dummy : Integer_64;\n    begin\n      Insert (h, Image (i), 1, True, dummy);\n    end Set;\n  begin\n    Clear (h);\n    --  First example: \"0 1 10 99 999\"\n    --  Second example: \"125 17\"\n    --  Input: \"3028 78 973951 5146801 5 0 23533 857\"\n    case d is\n      when mini =>\n        Set (125);\n        Set (17);\n      when input =>\n        Set (3028);\n        Set (78);\n        Set (973951);\n        Set (5146801);\n        Set (5);\n        Set (0);\n        Set (23533);\n        Set (857);\n    end case;\n  end Set_Data;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Show is\n    total : Integer_64 := 0;\n  begin\n      for i in h'Range loop\n        for j in 1 .. h (i).slots loop\n          if h (i).slot (j).value > 0 then\n            Put (h (i).slot (j).key);\n            if h (i).slot (j).value = 1 then\n              Put (' ');\n            else\n              Put (+\":\" & h (i).slot (j).value'Image & \"x \");\n            end if;\n            total := total + h (i).slot (j).value;\n          end if;\n        end loop;\n      end loop;\n      New_Line;\n      Put_Line (+\"Stones: \" & total'Image);\n  end Show;\n\n  procedure Do_Part (part : Part_Type; rounds : Integer) is\n    h2 : Hash_Map_Type;  --  Hash table with stone counts, after transformation.\n\n    procedure Apply_Rules (s : in out Hash_Slot_Type) is\n      l : Integer;\n      s1, s2 : VString;\n\n      procedure Transform (from, to : VString; remove : Boolean) is\n        old, dummy : Integer_64;\n      begin\n        Find (h2, from, 0, old);\n        if remove then\n          Insert (h2, from, old - s.value, True, dummy);\n          if verbosity_level > 1 then\n            Put_Line (+\"From \" & from & \" stones: \" & old'Image & \" -> \" & Integer_64'Image (old - s.value));\n          end if;\n        else\n          if verbosity_level > 1 then\n            Put_Line (+\"From \" & from & \" stones: \" & old'Image);\n          end if;\n        end if;\n        Find (h2, to, 0, old);\n        Insert (h2, to, old + s.value, True, dummy);\n        if verbosity_level > 1 then\n          Put_Line (+\"  To \" & to & \" stones: \" & old'Image & \" -> \" & Integer_64'Image (old + s.value) & dummy'Image);\n        end if;\n      end Transform;\n\n    begin\n      if s.value > 0 then\n        l := Length (s.key);\n        if s.key = \"0\" then\n          Transform (s.key, +\"1\", True);\n        elsif l mod 2 = 0 then\n          s1 := Slice (s.key, 1, l / 2);\n          s2 := Slice (s.key, l / 2 + 1, l);\n          while Length (s2) > 1 and then Element (s2, 1) = '0' loop\n            Delete (s2, 1, 1);\n          end loop;\n          Transform (s.key, s1, True);\n          Transform (s.key, s2, False);\n        else\n          s1 := +Integer_64'Image (Integer_64'Value (To_String (s.key)) * 2024);\n          Delete (s1, 1, 1);\n          Transform (s.key, s1, True);\n        end if;\n      end if;\n    end Apply_Rules;\n\n  begin\n    if verbosity_level > 0 then\n      Show;\n    end if;\n\n    h2 := h;\n\n    for iter in 1 .. rounds loop\n      --  Traverse the hash table for applying the rules to\n      --  all stones:\n      for i in h'Range loop\n        for j in 1 .. h (i).slots loop\n          Apply_Rules (h (i).slot (j));\n        end loop;\n      end loop;\n      h := h2;\n      if verbosity_level > 0 then\n        Show;\n      end if;\n    end loop;\n\n    --  Traverse the hash table for counting the stones:\n    for i in h'Range loop\n      for j in 1 .. h (i).slots loop\n        r (part) := r (part) + h (i).slot (j).value;\n      end loop;\n    end loop;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Set_Data;\n  Do_Part (part_1, 25);\n  Do_Part (part_2, 50);\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_64'Value (To_String (Argument (1)))  or\n       r (part_2) /= Integer_64'Value (To_String (Argument (2)))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put (+\"Part 1:\"); Put (r (part_1)'Image); New_Line;\n    Put (+\"Part 2:\"); Put (r (part_2)'Image); New_Line;\n    --  Part 1: validated by AoC: 198089\n    --  Part 2: validated by AoC: 236302670835517\n  end if;\nend AoC_2024_11;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_11_questions.txt",
    "content": "--- Day 11: Plutonian Pebbles ---\n\nThe ancient civilization on Pluto was known for its ability to manipulate spacetime, and while the Historians explore their infinite corridors, you've noticed a strange set of physics-defying stones.\n\nAt first glance, they seem like normal stones: they're arranged in a perfectly straight line, and each stone has a number engraved on it.\n\nThe strange part is that every time you blink, the stones change.\n\nSometimes, the number engraved on a stone changes. Other times, a stone might split in two, causing all the other stones to shift over a bit to make room in their perfectly straight line.\n\nAs you observe them for a while, you find that the stones have a consistent behavior. Every time you blink, the stones each simultaneously change according to the first applicable rule in this list:\n\n    If the stone is engraved with the number 0, it is replaced by a stone engraved with the number 1.\n    If the stone is engraved with a number that has an even number of digits, it is replaced by two stones. The left half of the digits are engraved on the new left stone, and the right half of the digits are engraved on the new right stone. (The new numbers don't keep extra leading zeroes: 1000 would become stones 10 and 0.)\n    If none of the other rules apply, the stone is replaced by a new stone; the old stone's number multiplied by 2024 is engraved on the new stone.\n\nNo matter how the stones change, their order is preserved, and they stay on their perfectly straight line.\n\nHow will the stones evolve if you keep blinking at them? You take a note of the number engraved on each stone in the line (your puzzle input).\n\nIf you have an arrangement of five stones engraved with the numbers 0 1 10 99 999 and you blink once, the stones transform as follows:\n\n    The first stone, 0, becomes a stone marked 1.\n    The second stone, 1, is multiplied by 2024 to become 2024.\n    The third stone, 10, is split into a stone marked 1 followed by a stone marked 0.\n    The fourth stone, 99, is split into two stones marked 9.\n    The fifth stone, 999, is replaced by a stone marked 2021976.\n\nSo, after blinking once, your five stones would become an arrangement of seven stones engraved with the numbers 1 2024 1 0 9 9 2021976.\n\nHere is a longer example:\n\nInitial arrangement:\n125 17\n\nAfter 1 blink:\n253000 1 7\n\nAfter 2 blinks:\n253 0 2024 14168\n\nAfter 3 blinks:\n512072 1 20 24 28676032\n\nAfter 4 blinks:\n512 72 2024 2 0 2 4 2867 6032\n\nAfter 5 blinks:\n1036288 7 2 20 24 4048 1 4048 8096 28 67 60 32\n\nAfter 6 blinks:\n2097446912 14168 4048 2 0 2 4 40 48 2024 40 48 80 96 2 8 6 7 6 0 3 2\n\nIn this example, after blinking six times, you would have 22 stones. After blinking 25 times, you would have 55312 stones!\n\nConsider the arrangement of stones in front of you. How many stones will you have after blinking 25 times?\n\n--- Part Two ---\n\nThe Historians sure are taking a long time. To be fair, the infinite corridors are very large.\n\nHow many stones would you have after blinking a total of 75 times?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_12.adb",
    "content": "--  Solution to Advent of Code 2024, Day 12\n-------------------------------------------\n--  Garden Groups\n--\n--  https://adventofcode.com/2024/day/12\n--  Copy of questions in: aoc_2024_12_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_12 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini1\"; n : constant := 4;\n  --  input_name : constant VString := +\"mini2\"; n : constant := 5;\n  --  input_name : constant VString := +\"mini3\"; n : constant := 10;\n  input_name : constant VString := +\"aoc_2024_12\"; n : constant := 140;\n\n  map : array (1 .. n, 1 .. n) of Character;\n\n  type Seen_Type is array (1 .. n, 1 .. n) of Boolean;\n  seen_clear : Seen_Type;  --  Substitute for (others => (others => False))\n\n  --  Borders of each cell (think of spreadsheet cells' styles):\n  --\n  type Cell_Border is array (Direction) of Boolean;\n  type Border_Type is array (1 .. n, 1 .. n) of Cell_Border;\n  border_clear : Border_Type;  --  Substitute for (others => (others => (others => False)))\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data is\n    f : File_Type;\n    cell_border_clear : Cell_Border;\n  begin\n    for d in Direction loop\n      cell_border_clear (d) := False;\n    end loop;\n    Open (f, input_name & \".txt\");\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, map (x, y));\n        seen_clear (x, y) := False;\n        border_clear (x, y) := cell_border_clear;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part (part : Part_Type) is\n    seen : Seen_Type;\n\n    procedure Do_Region (x_start, y_start : Integer; plant : Character) is\n      fence, area : Natural := 0;\n      border : Border_Type;\n      --  Min/Max framing for part 2's search for aligned fences.\n      --  The framing speeds up massively the search.\n      --  In HAC: part 2's total run time goes from 29 seconds to 1.2 second!\n      min_x, max_x : Integer := x_start;\n      min_y, max_y : Integer := y_start;\n\n      procedure Flood_Fill (x, y, orig_x, orig_y : Integer; dir : Direction_or_Nil) is\n      --  Developped from aoc_2023_18.\n      begin\n        if x in 1 .. n and then y in 1 .. n and then map (x, y) = plant then\n          --  We are still inside the region.\n          if not seen (x, y) then\n            seen (x, y) := True;\n            area := area + 1;\n            Flood_Fill (x - 1, y, x, y, west);\n            Flood_Fill (x + 1, y, x, y, east);\n            Flood_Fill (x, y - 1, x, y, south);\n            Flood_Fill (x, y + 1, x, y, north);\n          end if;\n        else\n          --  We have crossed a border: either the map's limits, or to\n          --  a region for another plant type.\n          fence := fence + 1;\n          if part = part_2 then\n            border (orig_x, orig_y)(dir) := True;\n            min_x := Min (orig_x, min_x);\n            max_x := Max (orig_x, max_x);\n            min_y := Min (orig_y, min_y);\n            max_y := Max (orig_y, max_y);\n          end if;\n        end if;\n      end Flood_Fill;\n\n    begin\n      if part = part_2 then\n        border := border_clear;\n      end if;\n\n      Flood_Fill (x_start, y_start, 0, 0, nil);\n\n      if part = part_2 then\n\n        --  Compute rebates for the bulk discount.\n        --  Horizontal fences:\n        for y in min_y .. max_y loop\n          for x in min_x + 1 .. max_x loop\n            if border (x, y)(north) and then border (x - 1, y)(north) then\n              fence := fence - 1;\n            end if;\n            if border (x, y)(south) and then border (x - 1, y)(south) then\n              fence := fence - 1;\n            end if;\n          end loop;\n        end loop;\n\n        --  Vertical fences:\n        for x in min_x .. max_x loop\n          for y in min_y + 1 .. max_y loop\n            if border (x, y)(west) and then border (x, y - 1)(west) then\n              fence := fence - 1;\n            end if;\n            if border (x, y)(east) and then border (x, y - 1)(east) then\n              fence := fence - 1;\n            end if;\n          end loop;\n        end loop;\n      end if;\n\n      r (part) := r (part) + area * fence;\n\n    end Do_Region;\n\n  begin\n    seen := seen_clear;\n\n    for x in 1 .. n loop\n      for y in 1 .. n loop\n        if not seen (x, y) then\n          Do_Region (x, y, map (x, y));\n        end if;\n      end loop;\n    end loop;\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Do_Part (part_1);\n  if not compiler_test_mode then\n    Do_Part (part_2);\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1319878\n    --  Part 2: validated by AoC: 784982\n  end if;\nend AoC_2024_12;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_12.txt",
    "content": "WEEEEEFFFFFFFFFFFTTTTTTTTTTOBBBBQGGGQQQQQQQQQQQQQQQEEGGGGGGGGGGGGGOEMMMMMMMMMMMCMMMIIIIINWWWWWWDDDDDDDDDDDOOOOOOOOOOOOOOOOOXXXXWWWWWWWWWWWWW\nWWEEEEWWFFFFFFFFFFFNNNTTTTOOOBBBQQQGGQQQQQQQQQQQQQEEEEGGGGGGGGGGGGOOOMMMMMMMMMMMMMMIIIINNVNNWWWDDDDDDDDDOOOOOOOOOOOOOOOOOOOXXXXCQWWWWWWWWWWW\nWWWEEEWFFFFFFFFFFFNNNNNNTTOOOOBOQQQQQQQQQQQQQQQQQQEEEEEEGGGGGGGGGXOOOMMMMMMMMMMMMMMMINNNNNNNWWWDDDDDDDDDVQOOOOOOOOOOOOOOOOOXXXXCCCWWWWWWWWWW\nWWWWWWWFFFFFFFFFFFNNNNNNNTOOOOOOUUQQQQQQQQQQQQQQQQEEEEGGGGGGGGGGROOBBMMMMMMMMMMMMMMMINNNNNNNWWDDDDDDDDDDVVVOOOOOOOOOOOOOOOGXXXXCCWWWWWWWWWWW\nWWWWWWWTWFFFFFFFFNNFNNJJNNOOOOOUUUUNNNQQQQQQQQQQEEEEEEEEEGGGGGRGRRRRBMMMMMMMMMMMMMMMNNNNNNNNNNDDDDDDDDVVVVVHOOOOOOOOOOOOOOGGXXXXXWWWWWWWWWWW\nWWWWWWWWWWFFFFGFFFFFFNOOOOOOOOUUUNNNNNQQQQQQQQQQEEEEEEEEGGYGYRRRRRRRBMMMMMMMMMMMMMMNNNNNNNNFFFDDDDDDDDDVUUUUUUUOOOOOOOOOOGGGGXXXXWWWWWWWWWWW\nWWWWWWWWWWWWWGGGFFFFFFOOOOOOOOUNNNNNNNNNQQQQQQQEEEEEEEDGGYYYYRRRRRRRBUUMMMMMMMMMMMMCCNNNNNNFFDDDDDDDDDDDUUUUUUUOOOOOOOORGGGGGGGGGGWWWWWWWWWW\nWWWWWWWWWWWWGGGGGFFFFFOOOOOOONNNNNNNNNNNNNQQQQQEEEEEEEEGGRRRRRRRRRUTUUUUUMMMMMMMMCMCCNNNNNNFFFDDDDDDDDDDUUUUUUUOOOORRORRRRRGGGGGGGGKKKWKWWWW\nWWWWWWWWWWWGGGGGGFFFHFOOOOOONNNNNNNNNNNNNNNNQQQQEEEEEEEEERRRRRRRRRUUUUUUUMMMMMCCMCCCNNNNNNNNNFDDDDDDDDDGUUUUUUURORRRRRRRRGGGGGGGGGGKKKKKWWWW\nWWWWWWWVGGGGGGGGGGGFVFOOOOOOOOONNNNNNNNNNNNNNWWQEEEEUEEERRRCCCCCCCUUUUUUTMIIIMCCCCCCNNNNNNNNNDDDUUDDDRDGUUUUUUURORRRRRRRRRGGGGGGGGGGKKKKKWWW\nWWWWWWWGGGGGGGGGGGHVVBOOOOOOOOOONNNNNNNNNNTTWWHQEEEEUUEERRRCCCCCCCUUUUUUUIIIIMMCCCCNNNNNNNNNHDAANUNNNNNNUUUUUUURRRRRRRRRRRGGGGGGGGGAKKKKKWWW\nWWWWWWWWWGGGGGYYGGVVVBOOOOVVVOOONNNNNNNNNNTWWWTTTEEUUUUURRRCCCCCCCUUUUUUUIIICCCCCCNNNNWWNNNNNNAANUNNNNNNUUUUUUUUUUUUUUUUHGGGGGGGGGGGKKKKKKWW\nWWWWWWWWWGGGGYYYYYVVVBVOOVVVVVNNNNFFNNNNNNTTWWTTTTTUUUUUUURRRRRUUUUUUUUUUIICCCCCCCCCCCCCANNNNNAANNNNNNNNUUUUUUUUUUUUUUUUHGGGGGGGGGGGKKKKKKWW\nWWWWWWWGGGGGGYYYYYVVVVVVQVVVVVNNXXXFFFFNFTTTTTTTTTTUUUUUUURRRRRRUUUUUUUUUIICCCCCCCCCCCCCAAAANNAAANNNNNNGGGGGGRUUUUUUUUUUUUUUUUUGGGGKKKKKKKGG\nWWNWWWWGGGGGGGYYVYVVVVVVVVVVVVVNFFFFFFSFFTTTTTTTTTTUUUUUUURRRRRRWUUUUUUUUUUUCCCCCCCCCCCCAAAAAAAAANNNNNGGGGGRRRUUUUHUUUUUUUUUUUUGGGGKKKKKKKGG\nWWGGGGGGGGGGGGYVVYVVVVVVVVVVVVVVFFFFFFSFFFFTTTTTTFTTUUUUUURRRRRWWUUUUUUUUAAUCCCCCCCCHCCAAAAPPPAAANNNNNVVGRRRRRUUUUHUUUUUUUUUUUUGKKKKKKKKKKKG\nWDDGGGGPGGGGGYYVVVVVVVVVVVVVVVVVVVFFFFFFFTTTTTTTTFFFUUUUUBRRRRRRUUUUUUUUAAAAACCCCTCCMMAAAAPPPPPAANNPPVVVVZRZZZUUUUHUUUUUUUUUUUUKKKKKKKKKKKKG\nDDDGDGGGGGGGGYYYVVVVVVVVVVVVVVVVVVFFFFFFFFTTTTTTTFFFFUBBBBBRRRRRUUUUUUUUUAAAAACCACCCMAAAAPPPPPPAPVVPVVVVVZZZZZUUUUHHHHHHHQUUUUUKKKKKKKKKKKKK\nDDDDDDDGDGWWJYJVVVVVVVVVVVVVVVVVHHHHFFFFFFTTTTTFFFFFFUUBBBRRRRRRUUJRUUCUUAAAAAAAAMPCMMAAAAPPPPPAPJVVVVVVVZZZZZZHHHHHHHHHQQUUUUUKKKKKKKKKKKKK\nDDDDDDDDDDJWJJJVVVVVVVVVVVVVVVVVHHHHFFFTFTTTTTFFFFFFFFBBBBBRRRRRRURRUUUAAAAAAAAMMMMCMMMMAAAPPPPPPJVVVVVVVZZZZRZZRHHHHNHHQQUUUUUZKKKKKKKKKKUK\nDDDDDDDDDDJJJJJJJJJVVVVVVVVVVVVVHHHHFFFFHTTTTHTHFFFFBBBBBBBBRRRRRRRRRUUUUAAAAAAMMMMMMMMMPPPPPPPPPVVVVVVVVVVRZRZZRHHNNNDDQQUUUUUKKKKKKKKKKKUU\nDDDDDDDDDDJJJJJJJJJVVQVVOVVVAAHVVHHHFFFFHHHTTHHHHFFRRRRRRRRBBBRRRRRRRRRUAAAANNNMMMMMMMMMYPPPPPPPPVVVVVVVVVVRRRRRRRRNNNDDDDDDDDDDKKKKKUKUUUUU\nDDDDDDDDDDJJJJJJJJDVVQQVVVVVVVHHHHHHHHHHHHHHHHHHHFFRRRRRRRRBBBBRRRRRRKKNNAAANNNNNMMMMMMMPPPPPPPPVVVVVRRRVVVRRRRNRRRNDDDDDDDDDDDDNFFKKKUUUUUU\nDDDDDDDDDDDDJJJJJJJQQQVVVVVVVVVHHHHHHHHHHHHHHHHHFFFRRRRRRRRBBBBEERRRKKKKNNNNNNNNMMMMMMMPPPPPPPPPPUUVVRRRRRRRRRRRRRRNDDDDDDDDDDDDNKKKNNUUUUUU\nDDDDDDDDDDDJJJJJJJQQQQQVVOVPVHHHHHHHHHHHHHHHHHHHHFFRRRRRRRRGGEEEEERNNKKKNNNNNNNNMMMMMMMPPPPPPPPPPUUUUURRRRRRRRRRRRSDDDDDDDDDDDDDNNNNNUUUUUUU\nDDDDDDDDDDDJJJJJJQQQQQQQOOOPPHHOHHHHHHHIHHHHHHHRRRRRRRRRRRRGGEEENNNNNNNNNNNNNNNMMMMMMMMMPPPPPPPPUUUUUUURRRRRRRRRRRSDDDDDDDDDDDDNNNNSNUUUUUUU\nDDDDDDDDDDJJJJJJJQQQQQQOOOOOOOOOHHHHHHHIIHHHHIFRRRRRRRRRRRRRRGEEEEENNNNNNNNNNNNMMMMMMMMPPPPPPPPPUUUUUUURRRRRRYRRRSSDDDDDDDDDDDDNNNNSISSSUUUU\nDDDDDDDDDDJJJJJJJJFFQQQOOJOOOOOOHHHHHHHIIHHIIIFRRRRRRRRRRRRRRGEEEEENNNNNNNNNNNMMMMMMMMMPPPPPPPPUUTTUUUURRLRPRYYYYYDDDDDNNNNNNNDNNNNSSSSSSUUU\nDDDDDDDDDDJJJJJJJJFFQOOBOOOOOOQQHHHHHIIIIHIIIIFRRRRRRRRRRRRRRGEKKEEENNNNNNNNNNNMMMMMMMMMMPPPPPPTTTUUUUURRYRYYYYYYWDDDDDNNNNNNNNNNNSSSSSSUUUU\nKKDDDDDDDDDJJJJJFJFQQOOOOOOOOOOOOHHIIIIIIIIIIIFRRRRRRRRRRRRRKKKKEEEENNNNNNNNNNNMMMMMQMMMMZPPPPPTTTUUUUUUUYYYYYYYYNNDDDNNNNNNNNNNNSSSSSSSSUUU\nKDDDDDDDDDDDDKFFFFFFHHHHHHHHHOOODIHHIIIIIIIIIIFRRRRRRRRRRRRRRRRRRKENNNNNNNNNNNNMMMMMQXMMMZZPZTTTTTTUUUYUUYYYYYYYYYNNNNNNNNNNNNNNSSSSSSSSSSUU\nKDDKDDKKKDDDKKFFFFFFHHHHHHHHHOOOIIIIIIIIIIIIIIIRRRRRRRRRRRMRRRRRRKKNNNNNNNNNNNNMMMMMQXMMMZZZZZTTTTTTUUYYYYYYYYYYYYNNNNNNNNNNNNNSSSSSSSSSSSUU\nKDDKKKKKKKKKKFFFFFFFHHHHHHHHHOOOZIIIIIIIIIIIIMMEERRRRRRRRRMRRRRRRKKKKNNNNNNNNNNMGQQQQQQZMZZZZZTTTTLILLLYQYYYYYYYYNNNNNNNNNNNNNNNSSSSSSSSSSUU\nKKKKKKKKKKCCFFFFFFFFHHHHHHHHHOOOZZIIIIIIIIIIMMMEERRRRRRRRRKKKKKKKKKKNNNNNNNNNCMMGGQQQQQZZZZZZZTTTLLLLLLYYYYYYYYYYYNNNNNNNNNNSNSSSSSSSSSSSUUU\nNNKKKCCKKKCCFFFFFFOOHHHHHHHHHOOOZZZIZZXIIIIMMMMMMRRRRRRRRRKJKKKKKKKKKNNNCUNNNNNGGQQQQQZZZZZZZZZTTLLLLLLJYYYYYYYYYYNNNNNNNNNSSSSSSSSSHSSSSUUU\nNNNKKCCCKKCFFFFFFFFFHHHHHHHHHOOOZZZZZZZCIICMMMMMMMMMMMMMJJJJJKKKKKKKKKKKCCCNNNNNQQQQQZZZZZZZZZTTTTLLLLLLLHHHYYYYYYYYYNNNNNNNNSSSSSSSSSUUUUUU\nNNNCCCCCKCCCFFFFFFFFHHHHHHHHHOZZZZZZZZZCCCCMMMMMMMMMMMJJJJJJJJKKKKKKKKKKKCCCCNNCCCQCZZZZZZZZZZZZTTTLLLUHHHHHYYYYYYYYYNNNNNNNPPPSSSSSSSUUUUUU\nNNEECCCCCCCCSFFFFFFFHHHHHHHHHOZZZZZZZWZCCCMMMMMMMMMMMJJJJJJJJJJJKKKKKKKKYCCCCCCCCCQCZZZZZZZZZZZZZTTTUUUUHHHHYYYYYYYYYNNUNNNNNGGGSGSSSSUUUUUU\nNNEECCCCCCCCFFFFFGFFGVVOZZZZZZZZZZZZZZCCCCCMMMMMMMMMMMJJJJJJJJJJKKKKKKKKKATTTTCCCCQCCZZZZZZZZZZZZTKKUHUUHHHHHYYYYYYYYNNDZNNGGGGGQGGGGGGUUUUU\nNNCCCCCCCCCPCFFFFGGFGVGZZZZZZZZZZZVZZZZZCCCMMMMMMMMMJJJJJJJJJJJJKKKKKKKKKATTTCCCCCCCCZZZZZZZZZZZTTKKUHHHHHHHHHYYYYYYYYYDZZZGGGGGGGGGGGGUUUUU\nNCCCCCCCCCCCCFFFFGGFGGGZZZZZZZZVVVVVZZVCCCCCMYYYYYYYJJJJJJJJJJJDKKKKKKKKKTTTTTTCTTCCCCCZZZZZZZZZZTKKKKHHHHHHHHHHHYPYYYDDZGGGGGGGGGGGGGGGUUUU\nNCCCCCCCCCCCGGFFGGGFGGZZZZPPZVVVVVVVVCVCCCCCCYYYYYYYGJJJJJJJJJJDKKKKKKKKKTTTTTRTTTCCCCCZCZZZZZZZZZKKKKKHHHHHHHHPPPPPYDUDDGGGGGGGGGGGGGGGUUUU\nNNNCCCCCCCCCGGGGGGGGGGGZZZPPPVVVVVVVVVVVCCCHCCCYYYYYJJJJJJJJJJJJKKKKKKKKGTTTTTTTTCCCCCCCCZZZZZZZKKKKKKKHHHHHHHHHPPDDDDDDTGGGGGGGGGGGGRRGUUUU\nNNNNCCCCCCCGGGGGGGGGGGGZZPPPPSVVVVVVVVVVHHHHCCCYYYYYJJJJJJJJJJJJJKKKDDKKGTTTTTTTTTTTTCCKKUZZZZZZKKKKKKKHHHHHLHHHPPPDDDDTTGGGGGGGGGGGGRRRUUUU\nNNNNNCCCGGGGGGGGGGGGGGGGGPPPPSVVVVVVVVVXHHHHCCCYYYYYADDDJJJJJJJJJJKKDDDTTTTTTTTTTTTTTTTTKKKKKKKKKKKKKKKDDELLHHHHPPPPPDTTTTGGGGGGGGGGGRRRRUUU\nNNNNNNCCGGGGGTTTGGGGGGGGPPPPPSVVVVVVVVVYYYYYYYYYCYEEAAADJJJJJJJZJJJKKKDTTTTTTTTTTTTTTTTKKKKKKKKKKKKKEEKDEEELLHPPPPPNPDTTTTGGTGGRRGGGRRRRUURR\nNNNNNNCCCTTTTTTTTTGGPPPGGPPGGGVVVVVVVVHYYYYYYYYYCCAAAAAAJJJJJJJTTTJKKKTTTTTTTTTTTTTTTTTWKKKKKKKKKKEEEEEEEECELLPPPNNNNNNTTTTTTTGRRRRRRRRRRRRR\nNNNNNNNNCTTTTTTTTGGPPPGGPPPGGVVVVVVVHHHYYYYYYYYYAAAAAAAQQQJJJJJTTTKKKKTTTTTTTTTTTTTTTTTTKKKKKKKKKKKEMEEEEEEEEPPPNNNNNNTTTTTTTGGRRRROORRRRRRR\nNNNNNNNNNTTTTTTTTPPPPPPPPPGGGGVVVHHYYYYYYYYYYYYYAAAAAAAQQQJJJRJTTTTTTTTTTTTTTTTTTTTTTTKKKKKKKKKKKKKKKQEEEEEEEEFFNHNNNNNNNTTTTTOROOOOOOORRRRR\nNNNNNNNNGITTTTTTPPPPPPPPPPGGGGGHHHHYYYYYYYYYYYYYAAAAAEAAQQQQQQTTTTTTTTTTTTTTTTTTTTTFTTKKKFKKFKLKKKKKKQEQQEEKKFFNNNNNNNNNNNNTTOOROOOOOGGORRRR\nNNNNNNNGGTTTTTIPPPPFFFPPFGGGGGGGYYYYYYYYYYHHHAAAAAAAAAAAQQQQQQQTTTTTTTTTTJJJJJJJJTTFFFFFFFFFFKKKWNNQQQQQQGKKFFFNNNNNNNNNNNNTTOOOOOOOOOGORRRR\nNNNNNNNGGGGGGGIIFPFFFFFFFGGGGGGGYYYYYYYYYYHHLAAAAAAAAAALQQQQQQQTTTTTTTTTTJJJJJJJJGTFFFFFFFFFFFFKNNNNQQQQQGGKKFNNNNNNNNNNONNTOOOOOOOOOOOOORRR\nNNNNGNGGGGGGGGIIFFFFFFFFFGGGGGGGYYYYYYYYYYHHAAAAAAALLLLLLYQQQQQTTJJJJJJJJJJJJJJJJGFFFFFFFFFFFFFFNNNNNNQGGGGGGGQGNNNNNNNNNNHHHOOOOOOOOOOOORRR\nNNGGGGGGGGGGGGGIIFFFFFFFFFGGGGGGYYYYYYYYYYGHANAAAAHLLLLLLYQQQQQJJJJJJJJJJJJJJJJJJFFFFFFFFFFFFFFFRNNNNQQQQQQQQQQGNNNNNNNNNHHHHOOOOOOOOOOORRII\nNNNGGGGGGGGGGGGGIFFFFFFFFFCGGGGGYYYYYYYYYHHHANANNAALLLLLLYYQQQQJJJJJJJJJJJJJJJJJJFFFFFFFFFFFFFFFNNNNNQQQQQQQQQQGVNNNNNNNNHHHHOOOOOOOOOIIRRII\nNNGGGGGGGGGGGGQQFFFFFFFFFFGGGGGPPGGHHLTTEHHNNNNNNCALLLLAAYYQAQWJJJJJJJJJJJJJJJJJJWFFFFFFFFFFFFFFFNNNNQQQQQQQQQQGGIINDNNNNNPPPPOOOOOOOOIIIIII\nNNGGGGGGGGGGGGQQKKFFFFFFFFFUGPPPPGGHITTTTTTNNNNNNNKLLLLLAYYYQQWJJJJJJJJJJJJJJJJJJWFFFFFFFFFFFFFFRFFNNQQQQQQQQQQGGIIINNNNNNPPPPFOOOOOOOIIIIII\nNNNGGGGGGGGGGQQKIKFFFFFFFFPPPPPPPPPPIJJJJJNNNNNNNWLLLLLAJJJJJJJJJJJJJJJJJJJJJJJJJWWFZFFFFFFFFFFFFFRRRQQQQQQQQQQQIIIINNNNPPPPPFFOOOOOOOIIIIII\nNNNGGGGGGGGGGGKKKKFFFFFFFFFPPPPPPPPPIJJJTTNNNNNNLLLLLLAAJJJJJJJJJJJJJJJJJJJJJJJJJWWPPPPFFPFFFFFFFRRRRQQQQQQQQQQQIIIINNNPPPPPPPAOOOOODIIIIIII\nNNGGGGGGGGGGGGKKKKKKFFFFFFFPPPPPPPPPPJJJTTTNNNNAAAAAAAAAJJJJJJJJJJJJJJJJJJJJJJJJJWWPPPPPPPFFFFRFFRRRRQQQQQQQQQQQYIYIINNNPPPPPPAOOOOODIIIIIII\nGGGGGGGIGXGKKGKKKKKFFFFFFFUUUUPPPPPPJJJJJJJNNNAAAAAAAAAAJJJJJJJJJJJJJJJJJJJWWWQWWWWPPPPPPKKFFNRRRRRRRQQQQQQQQQQQYYYYYYPPPPPPPPAAAAAIIIIIIIII\nXGGGGGGGGXXKKKKKKKKFFFFFUUUUUPPPPPPPJJJJJJJNNOAAAAAAAAAAJJJJJJJJJJJJJJJJJJJWWWQWWWPPPPPPPKKVVVRRRRRRRRMMMRYYYRYYYYYYYPPPPPPPPAAAAAAIIIIIIIII\nXGXXXXXXXXKKKKKKKKKBBFBBPPPPPPPPPJJJJJJJJJIOOOAAAAAAAAAAJJJJJJJJGVJJJJJJJWEEEQQWWPPPPPPPPPPVVVVVVRRRRMMMMRRYYYYYYYYYYYYPPPPPPAAAAAAIIIIIIIII\nXXXXXXXXXXKKKKKKKKBBBBBBBBBBBBCJJJJJJJJJJJOOOOOOOAAAAAAAJJJJJJJJGVJJEEEEEEEEEQQWWWPPPPPPFPVVVVVVVQVVRRMMRRRRYYYYYYYYYYYTPPPPAAAAAAAAAIIIIIII\nXXXXXXPXKKKKKKKKKKKBBBBBBBBBCBCJJJJJJJJOOOWWOOOOOAAAAAAGJJJJJJJJGJJJEEEEEEEEEEEEEEPPPPPVVVVVVVVVQQVVRRMRRRRRRRYYYYYYYYYYAAAAAAAAAAAAAIIIIIII\nXXSXPPPPPKKKKKKKKBBBBBBBBBBBCBCJJJJJJJJOOOOWOOOOOOOAAGAGJJJJJJJJGJJLEEEEEEEEEEEEEEPPPPPVVVVVVVVVVVVVRRRRRRRRRRYYYYYYYYWWAAAAAAAAAAAAAAIIIEIE\nXXSXPPPPPPKKPPPKBBBBBBBBBBCBCCCJJJJJJJOOOOOOOOOOOOLLLGGGGGGGGGGGGGJLLJFFFJQEEEEEEEPPPPPPVVVVVVVVVVVVVVRRRKRRRYYYYYYYYYWWAAAAAAAAAAAAIIIIEEEE\nXXSSPPPPPPPKPPPPPBBBBBBCCCCCCCCCJJJJJJJOOOOOOOOOOOILLLGWWGGGGGGGGGZMMMMMMZQEEEEEEEPPPPPTTVVVVVVVVVVWKKKKKKKKRRQQQQYYYYYWWWAAAAAAAAAAAAAAAAEE\nXXSMPPPPPPPPPPPPBBBBBBBCCCCCCCCCCJJJDJDDOOOOOOOOOOLLLLOLLLGGGGGGGGMMMMMCCMFEEEEEEETPPPPTXXXVVVVVVVVVKKKKKKKKRRRQQQQQYYYYWWIAAAAAAAAAAAAAAEEE\nXXSSSSSPPPPPPPPPPBBBCCCCCCCCCCCCCJDJDOODDOOOOOOOOLLLLLLLLLGGGGGGGGGMMTMMEEEEEEEEEETTPTTTTVVVVVVVVVVVKKKKKKKKRRQQQQQYYWYWWWIIAAAAAAAAAAAAAAAE\nXXSSSBSPPPPPPPPPPBBBBCCCCCCCCCCCCCDDDDDDDOOOOOOOOLLLLLLLLLQLGGGGGGGRGTMMEEEEEEEEEETTTTTTVVVVVVVVVVVVKKKKKKKKRRQQQQQQQWWWWWIIAIAAAAAAAAAAAAGO\nXXSSXPPPPPPPPPPPPWWWWCCNCUCCCCCCCZDDDDDDDOOOOOOOOQLLLLLLLLLLGGLGGGGGGTMMEEEEEEEEEETTTTTTVVVVVTTHVVVVKKKKKKKKKRQQQQQQWWWWWIIIIIIAAAAAAAAAOOOO\nXXXXXXXPPPPPPPPPPWWWWCINCCCCCCCCCDDDDDDDDOOOOOOWOORLLLLLLLLLLLLGMGMMNMMMEEEEEEEEEETTTTTTVVVTTTTTKKKKKKKKKKKKKKQQQQQQWWIIIIIIIIIAAAAAAAAAAOOO\nXXXXXXXPPPPPTTPPPWWWWWWNNNNBBBBBBDDDDDDDDOOOOOOWOOLKLLLLLLLLLLLQMMMMNMMMEEEEEEEEEETTTTTTTTTTTTTKKKKKKKKKKKKKKQQQQQQQWIIIIIIIIIIIIOOOAAAOOOOO\nJJJXJJXPPPPNTTTWWWWWWWNNNNNBBBBBBUDDDDDDDOOOWWWWWFLLLLLLLLLLLLLLLMMMMMMMEEEEEEEEEETTTTTTTTTTTTTTKKKKKKKKKKKKKQQQQQQQWWWIIIIIIIIIIIQOAAAOOOOO\nJJJJJJJJPPPNTTTTTWWWNNNNNNNBBBBBBDDDDDDDDOOOWWWWWLLLLLLLLLLLLMLLMMMMMMMMMEEEEEEEEETTTTTTTTTTTTTTTKKKKKKKKKKKKQQTQTQQQIIIIIIIIIIIIIIOKAOOOOOO\nJJJJJJJNNNNNNTTTTTWWNNNNNNBBBBBBBDDDDDDDDDOWWWWWWBBLLLLLLLLLMMLLMMMMMMMMMEEEEEEQQQTTTTTTTTTTTTTKKKKKKKKKKKKKFQQTTTKXXIIIIIIIIIIOOHHHHKOOOOOO\nJJJJJJJNNWNNNTTTTNNWNNNNNNBBBBBBBSVDDDDDXXOOOWWWBBBLLLLLLULLMMMMMMMMMMMMWMEEEEBBQQQQQTTKTOTTTTTTKKKKKKKKKKKKKKQQTKKXXXIIIIIIIIIHHHHHHKOOOOOO\nJJJJJJWWWWWNNTTTTNNWNNNNNNBBBBBBBVVVVVEDXXXXWWWWWWBSSLTTLMLMMMMMMMMMMMMMMBEEEEBBQBBQQQQQOOTTTTTTTKKKKKKKKKKKKKKQKKKKKXXIIIIIIIIHHHHHHOOOOOOO\nJJJJJDDWWWWNNNTTTNNNNNNNNNBBBBBBBVVVVVVDXXXXWWWWWBBOOOTTMMMMMMMMMMMMMMMMBBEEEEBBBBQQQQQQOOTTTTTTTTKKKKKKKKKKKKKKKKKKKXXXXXIIIIIHHHOOOOOOOOOO\nJUJJJWWWWWWNNNTTNNNNNNNNNNNBBBBBBVVVVVVDXXXXXWWWWBBBOOMMMMMMMMMMMBBBMBBMBBEEEEBBBQQQQQQQTTTTTTTTTTKKKKKKKKKKKKKKKKKKKXXXXXIIIIIHHHOOOOOOOOOO\nJUWWWWWWWWWWWNNNNNNNNNNNNNNBBBBBBJVVVVVDXXXXXXXXWOOOOOMMMMMMMMMMMBBBBBBBBBEEEEBBQQQQQPQPTTTTTTTTTKKKKKKKKKKKKKKKKKKKKXPPPPIIIIPHHHOOOOOOOOOO\nUUUWWWWWWWWWWWWWWWNNNNGGNNGBBBBBBJVVVJXXXXXXXXOOOOOOOOGGMMMMMMMBBBBBBBBBBBEEEEBMQTTPPPQPPTTTTTTTTTKVVVVVVVVVVVVVKKKKKPPPPPZZIPPHHHOOOOOOOOOO\nUUUWWWWWWWWWWWWWWWNNNGGGGGGGGBBBBJJJJJJXXXXXXOOOOOOOOOOGMVMMMMMBBBBBBBBBBBEEEEBBBTTTTPPPTTTTTTTTTTKVVVVVVVVVVVVVKKKKKNPPPPPPEEEHHHOOOOOOOOMO\nUUUWWWWWWWWWWWWWWNNNNGGGGGGGGBBBBJJJJJJJXXXXXOEOOOOOOOOOOMMMMMMMCCCCBBBBBBBBBBBAAATTTTTPTTTTTTTTTKKVVVVVVVVVVVVVKKKPCPPPPPPPPEEHHHOOOOOOOOMM\nUUUWWWWWWWWWWWXXNNNNGGGGGGGGGBBBBJJJJJJXXXXXXOOOOOOOOOOOMMMMMMCCCICCBBBBBBBBBBBTTTSSSSSSSSSZTTTTTUUVVVVVVVVVVVVVKPPPPPPPPPPPNNEHHHFFOFOOOMMM\nUUUWWWWWWWWWWWXNNNNGGGGGGGGGGJJJJJJJJJJJXXXXXXXOOOOOOOOOMFMMIIIICIIIIBBBBBBBYBLTTTSSSSSSSSSTTUTXUUUVVVVVVVVVVVVVKPPPPPPPPPPNNNNNPPFFFFFOMMMM\nUUUUWWWWWWWWWWXNNNNNGGGGGGGGGJJJJJJJJXXXXXXXXXZQOOOOOOVOFFFMIIIIIIIIIIBBBBBBBBTTTTSSSSSSSSSUUUTUUUUVVVVVVVVVVVVVKPPPPPPPPPPPNNNNNNFFFFFQMMMM\nUUUWWWWWWWWWWXXXXXGGGGGGGGGGGGGJJJJJJJJXXXXXXXZZOOOOOOOIIIMMIIIIIIIIIIBBBBBBWBTTTTSSSSSSSSSUUVVVVVVVVVVVVVVVVVVVKPPPPPPPPPPPNNNNNFFFFFQQQMMM\nUUUUWWWWWWWZWWXNXXXXGGGGGGGGGGJJJJJJJJXXXXXXZZZZDDDOOOOIIIIIIIIIIIIIIIBGFFBBWTTTTTSSSSSSSSSUUVVVVVVVVVVVVVVVVAAKKPPPPPPPPPPNNNNNNNNQQQQQQMMM\nUUWWWWWWWUUWWNNNNXXXGGGGGGGGJJJJJJJJJJJXXZZZZZZZZDDZOOHBIIIIIIIIIIIIIGGGGBBBWTTTTTSSSSSSSSSUUVVVVVVVVVVVVVVVVAAKKPPPPPPPPPPNNNNNNNNNQQQQQMQQ\nUUWWWUUWUUNNWNNNNXXGGGGGGGGGJJJJJJJJJJXXXXZZZZZZZZZZKKHIIIIIIIIIIIIIIGGGGGBBWTTTTTSSSSSSSSSUUVVVVVVVVVVVVVVVVAAAKKKPPPPPPPPPPPNNNNSSSQQQQQQQ\nUUWWUUUUUNNNNNNNRRXXGFGGGGGJJJJJJJJJJJJXXXZZZZZZZZZKKKHHIIIIIPIIIIIIWGGGGGGBBTTTTLSSSSSSSSSSUVVVVVVVVUUUUVAAAAAAAKKPPPPPPPPPPPNNNSSSSQQQQQQK\nUUUWUNNNNNNNNNNRRBRRGFGGGGGJFJJJJJJJJJJXXXZHHZZZKZZKKKHHIIIIPPPPIIIIIGGGGGGGGTTTLLSSSSSSSSSSAVVVVVVVVUUUUVAAAAAKKKKPPBBBBPPPPPSNSSSQQQQQQQQK\nUUUUUNNNNNNNNNNRRRRRFFGGGGGJFFFJJJJJJJJJXOHHZZZKKKKKHHHHHIIIPPPPIGGGGGGGGGGGGGTTTLLAAAAASSSSAAAUUUUUUUUUUUAAAAAAAKKKBBBBBBPPPSSSSSSSSSQKQQQK\nUUUUUUUNNNNNNNNNRRRRFFGGFFGFFFFFFJJJJJOOOOHOCZKKKKKHHHHHHIIIPPPPPGGGGGGGGGGGGGTTTTAAAAAASSSSAAAUUUUUUUUUAAAAAAAAAKKKBBBBBBBBBSBSSSSSSDDKKQQK\nUUUUUUUUNNNNNNNRRRRRFFGFFFFFFFFFFFJJJJOOOOHOOKKKKKKKHHHHHHHHCCPPGGGGGGGGGGGBBBBBBBAAAAAASSSSAAAUUUUUUUUAAAAAAAAAAABBBBBBBBBBBBBSBSSSSDDDKKKK\nUUUUUUUUUUNNNNRRRRRFFFGFFFFFFFFFFFJJJOOOOOOOOKKKKKHHHHHHHHHHCHPPPGGGGGGGGGGBBBBBBBAAAAAAAAAAAAAAUUUUJJUAAAAAAAAAAFFBBBBBBBBBBBBBBBDDDDDKKDDK\nUUUUUUUUUUNNNRRRRRRRRFFFFFFFFFFKJJJJJJOOOOOOOOKKZZHHHHHHHHHHHHYPZGGGGGGGGGGBBBBBBBAAAAAAAAAAAAAUUUUUUUUAAAAAAAAAAABBBBBBBBBBBBWBBBWDDDDKKDDK\nUUUUUUUUUUNBNRRRRRRRRRFRFFFFKKKKKKKOOOOOOOOOOKKKZZHHHHHHHHHHHHYZZYGGGYYGGYGGGGGGAAAAAAAAAAAAQQQUUUUUZAAAAAAAAAAABBBBBBBBBBBBYSWWWBWDDDDKDDKK\nUUUUUUUUUUNBNURRRRRRRRRRKFKKVKKKKKYYOOOOOOOOOOZZZZZZHHHHHHHHHHYYYYYYYYYYYYGGGGGGGAAAAAAAAAQQQQQQQQULZAAAAAAAAAAAABBBBBBBBBBBYSSSWWWWWDDDDDKK\nDDDDUUUUUUNBBBRRRRRRRRRPKKKKKKKKKKYKOOOOOOOOZZZZZZZZZHHZHHHHHHYYXXXYYYYYYYYGGGGGGAAAAAAAAQQQQQQQQQUUZAAAAAAAAAAAABBBBBBBBBBBYYSSSWWWDDDDDDPP\nDDDDDDDUUUBBBBRRRRRRRRKKKKKKKKKKKKKKVOOOOOOOOZZZZZZZZHZZHHHHHYGYXYYYYYYYYWWWWCJCAAAQQQAAQQQQQQQQQUUZZZZZAAAAAAAAABBBBBBBBBBYYSSSSSWZDDDPDDPP\nDDDDDDDDDBBBBBBRRRRRHKKKKKKKKKKKKKKKOOOOOOOOOOZZZZZZZZZZZHHQQYYYYYYYYYYYYYYWCCCCCAAQQWQQQQQQQQQQQZZZZZZZAAAAAAAAHBALLOBBRBBBSSSSZZZZDDDPPPPP\nDDDDDDDDDDBBBBBLLNRRNNNKKKKKKKKKKKKKOOOOOOOOOOZZZZZZZZZZZZZQQQQQQYYYYYYYYYYYCCCCCMQQQQQQQQQQQQQQQZZZZZZZZZZZAAAAAAAALOORRBRRSSSSZZZZZDDDPPPP\nDDDDDDDDDDDBUBBLLNRRNNNKKKKKKKKKKKKKOOOOOOOOOOOZZZZZZZZZZZQQQQQQYYYYYYYYYYYYCCCCCCQQQQQQQQQQQQQQQQQZZZZZZZZZZAAAAOOOOOORRRRRSSSZZZZZZZDPPPPP\nDDDDDDDDDDDFBBQLNNNNNNKKKKKKKKKKKKKFFFOOOOOOOZZZZZZZZZZZZZZQQQQYYYYYYYYYYYYYNYCCCCQJQQQQQQQQQQQQQPZZZZZZZZAZZJAOOOOOOOOZZRRRRSSZZZZZZZZZPPPP\nDDDDDDDDDDDDNLLLNNNNVVKKKKKKKKKKKFFFFAOOOOOOOOZZZZZZZZZZZQQQQQQYYYYYYYYYYYYYYYCCCCCJQQQQQQQQQQQQQQSZZZZEZEAOOOOOOOOOOOARRRRSSSZZZZZZZZZPPPPP\nDDDDDDDDDDDNNNLNNNNNNNKKKKKKKKKKFFFFFOOOOOOOOOZZZZZZZZZZZZZQQQQQYYYYYYYYYYYLYCCCCCPJQQQQQQQQQQQQQJZZEEEEEEAAOOOOOOOOOOOREEESSHHZZZZZZZPPPPPP\nDDDDDDDDDDDNNNNNNNNNNNNKKKKKKKKKKFFFFFFFFOOOOOZZZZZZZZZZUUZQQQQYYJYYJJLYYLLLCCCCCCPPQQQQQQQQQQQQQJJTTREEEEAAAOOOOOOOOOOOEEESSHHZZZZZZZPPPPPP\nDDDDDDDDDDNNNNNNNNNNNNOKKKKKKKKKFFFFFFFFDOOOOOOOHZZZZZZZUUQQQQUYYJJJJJLLLLLLLLLCPPPPPPPQQQQQQQQQQTTTTTTEEEEAAAOOOOOOOOOOOEEYSHHHZZZZZZPPPPPP\nDDDDDDDDDDNNNNNNNNNNNNNKWWKKKKFFFFFFFFFFFFFOOOOOZZZZZZZUUUUUUQUUQJJJJLLLLLLLLCCCCPPPPPPPPQQQQQQQUTTTTTEEEEEAAAAAAOOOOOOOOEEYSXPBZZZZPPPPPPPP\nDDMDDDDDDDNNNNNNNNNNNNNNWKKKKFFFFFFFFFFFFFFFOOOOZZZZZUUUUUUUUUUUQQQJJLLLLLLLLLCCCCPPPPPPPQQPQPGGGTGTTTEEEEEAAAXAAAOOOOOBOEYYPPPPPPPPPPPPPPPP\nDWDDDDDDDDNNNNNNNNNNNNNFUUUQQFFFFFFFFFFFFFFFOOFZZZKKKKKKKUUUUUUUQQQQQCLLLLLLCCCCCPPPPPPPPPPPMGGGGGGGTTGJJJJAAAAAAAAAAGOOOEYYYXPPPPPPPPPPPPPP\nWWDDDDDDDNNNNNNINNNNNNNNUULDQFFFFFFFFFFFFFFFONZZZZKKKKKKKUUUUUUUQQQCQCLCCLCCCCCCCCPPPPPPPPJPMGGGGGGGGGGGGJJJJJAAAAAAAAAZYYYYYYPPPPPPPPEPPPPP\nWWDDDDDDDNNNINIIINNNNNNNUULDDEFFFFFFFFFFFFFFFFOOOONNNKKKKUUUUUUUQQQCCCCCCCCCCCCCCPPPPPPPPPJPMMMGGGGGGGGGGJJJJAAAAAAAAAYZYYYYYPPPPPPPPPEEPPPP\nWYYDDDDDUIIIIIIIIINNNNNUUUDDDFFFDFFFFFFFFFFCFOOONNNNKKKUUUUUUUUUQQQCCCCCCCCCCCCCCCPPPPPPPPPPMMMMMMGGGGGGGJJJAAAAAAAAAAYYYYYYYYYPPPPPPEEEPPPP\nYYYUUDDUUIIIIIIIIINNNNUUUDDDDDDDDFFFFFFFFNNNNMMMMMMMMMKUUUUUUUUQQQQQQCCCCCCCCCCCCPPPPPPPPPPPMMMMMMMGGGGXJJJAAAAAAAAAAAYYYYYYYYYYMMPPEEEEEPPP\nYYUUUUUUUIIIIIIIIIIUNNUUDDDDDDDDFFFFFFFFNNNNNMMMMMMMMMKKKUUUBUQQQQQQQQCCCCCCCCCCCPPPPPPPPPPPMMMMMMMGGGNXMMJJAMAAAAAAAAAYYYYYYYYYYYPPEIEEEPPP\nYYYUUUUUUUIIIIIIIIIUUUUUDDDDDDDDFFFFFFFFNNNNNMMMMMMMMMMKKWKUBUUQQQQQQQQCCCCCCHHCCPPPPPPPPMMMMMMMMMMMXXXXMMMMMMAAAAAADAAYYYYYYYYYYYPYEEEEEPPP\nYYUUUUUUIIIIIIIGUUUUUUUUUUDDFFFFFFFFFFFNNNNNNMMMMMMMMMMKKKKXKKKKQQQQQQQCCCCCHHHCCPPPPPPPNNMMMMMMMMXXXXXXMMMMMMAAAAAAAAYYYYYYYYYYYYYYYYEEEEPP\nYYYYUUUIIIIIIIIIIIUUUUUUUUUUUFFFFFFFFFNNNNNNNMMMMMMMMMMKKKKKKKQQQQQQQQQCCCHHHHHHHPPNNPNNNNMMMMMMMXXXXXXXXMMMMMMMAAGDDAAYYYYYYYYYYYYYYYEEEEPP\nUYUYYUUIIIIIIIUUIUUUUUUUUUUUUUUUFFFFFFNNNNTTTMMMMMMMMMMKKKKKKKLQQQQQQQQCCHHHHHHHHNNNNNNNNNMMMMMMMXXXXXXXXMMMMMMMMAMDDDDDDYYYYYYYYYYYYEEEEEEE\nUYUUUUIIIIIIIIIUUUUUUUUUUUUUUUUUFFFFFFNTTTTTTMMMMMMMMMMKKKKKKKQQQQQGGGQQHHHHHHHHHNNNNNNNNNMMMMMMMXXXXXXXXXMMMMMMMMMDDDDDDDYYYYYYYYYYYEEEEBEA\nUYUUUUUIIIIIIIIUUUUUUUUUUUIUPIUUFFFFNNNTTTTTTMMMMMMMMMMKKKKKWWQQQQQQQGQQTTHHHHHHHNNNNNNNNMMMMMMMXXXXXXXXXXXMMMMMDDDDDDDDJDYYYYYYYYYYYYEEEEEA\nUUUUUUUIIIIIIIUUUUUUUUUUUUIIIIFFFFFFFNNTTTTTTTNNNMMMMMMKKKKKKWQQQQQQQQTTTTHHHHHHHHNNNNNNNMRRRMMMMXXXXXXXXXXMMMMMMMDDDDDDDDDDDYYYYYYYYGEEAAEA\nUUUUPUUIIIIIIIIIUUUUIIIUIIIIIIIFFFFFFNBBNNTTTTNNNMMMMMMKKKKWWWWQQQQQQQQTTHHHHHHHHHHNNNNNNRRRRRMMMMMXXXXXXXMMMMMMMMMDDDDDDDDCYYXYYYYNYGEGGAAA\nUPPUPUPIIDIIIIIIUUUUIIIIIIIITTIFNNFJJJBBBNTTTTNUUMMMMMKKKKKWWWWQQQQQQQQTTTHHHHHHHHHNNNNNNRRRRRRRSSSSSXXXXXMMMMMMMMMDDDDDDDZNNYXNYYNNNGGGGGGG\nPPPUPPPPPIIIIUUUUUUIIIIIIIIIITTNNNNJJAEBBNTTTTUUKKKKKKKKKKWWWWQQRQTQQQTTTHHHHHHHHHHNNNNNCRRRRRRRRLSSSXXXOXMMMMMMMMMMDDVVDDZNNNNNNYNNNGGGGGGI\nPPPPPPPPPPIUUUUUUUUIIIIIIIIINTNNNNREEEENNNNWNUUUUUKKKKKKKKWWWQQRRTTTQQTTTTHHHHHHAAHNNNNNRRRRRRRSSSSSSSXXOOMOOMMMMMMMDDRVVZZZZNNNNNNNRGGGGGGG\nPPPPPPPPPPPPUUUUUUIIIIIIIIIINTTNNNRRREEEEJNNBUUUUUKKKKKKEERRRRRRRTBTTTTTTTTHHAAHAAHNNNNDRRRRRRRSSSSSSSOOOOOOOOMMMMMMMMVVVZZZNNNNNNNNNNGGGGGG\nEEPPPPPPPUUUUUUUIIIIIIIIIINNNNNNNNRRREEYYEINBBBUBBKKKKKKEERRRRRRTTTTTTTTTTHHHHAAAAHNNNNDBRRRRRSSSSSSSSSSOOOOOMMMMMMMMVVVVZNNNNNNNNNNNGGGGGGG\nEGGGGGGPPPUUUUUUUIIIIIIIIINNNNNNNNNRRREEEEIIIBBBBBCKKEEEERRRRRRRTTTJTTTTTTHHTHAAAAANNNDDDDJRRSSSSSSSMMMMOOOOOMMMMMMMVVVVVNNNNNNNNNNNNNGGGGGG\nEGGGGGGGGPPUUUUUUIIIIIIIINNNNNNNNNNEEEEEEEIIBBBBBBBEEEEEEERRRRTTTTTJTTTTTTTTTHAEAANNNNDSSSSRRSSSSSSSSMGMMMGGMMMMMMMMVVVVVNNNNNNNNNNNNGGGGGGG\nEGGGGGGGDPPUUUUUUIIIIIIINNNNNNNNNNNNEEEEEEBBBBBBBBBEEEEEEEEERTTTTTTTTTTTTTTTTEEEEEEUUUUUSSSRSSSSSSSSSGGGGGGGMMMMMVVVVVVVVNNNNNNNNNNNNGGGGGGG\nEGGGGGGGGPPUUUUUUIIIIIIINNNNNNNNNNNNNEEEEGGBBBBBBBBBBEEEEEEEETTTTTTTTTTTTTTTTTEEEEEEUUUUSSSSSSSSSSSGGGGGGGGGGMMMMVVMMVVVMMNNNNNNNNNNNNNGGGGG\nEEGGGGGGGGPUOUUUUFFIIIINNNNNNNNNNNNNEEEEEEBBBBBBBBBBBBBBEEEEETTTTTTTTTTTTTTTTTTEEEEUUUUFFSSSSKKSSSGGGGGGGGGGMMMMMMMMMVVVMMNNNNNNNNNNNNNGGGGG\nGGGGGGGGGGGGOUUUFFFIIIIINNNNNNNNNNNNEEEEEBBBBBBBBBBBBBBBEEEEEEEETTTTTTTTTTTTTTTTEUUUUUUFFSSKKKKSSSSGGGGGGGGGGMMMMMMMMVVVMMMNNNNNNNNNGGGGGGGG\nGGGGGGGGGGOGOOUOOFIIIIFFNNNNNNNNNNNEEEEEEEEEBBBBBBBBBBBBEEEEEEEETTTTTTTTTTTTTTTTEUUUUUUFFFKKKKKKSSSSSGGGGGGGGGMMMMMMMMMMMMNNNNNNNNNNSGGGGFGG\nVGGGGGGGGGOOOOOOOFFFFFFFNNNNNNNNNNNNNEEEEEEEEBBBBBBBBBBBEEEEEEEEEETTTTTTTTTTTTTEEEUUUUUFXXKKKKKKKSSSSGGGNGGGJGMMMMMMMMMMMMNNNNNNNJNNSSGFFFGG\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_12_questions.txt",
    "content": "--- Day 12: Garden Groups ---\n\nWhy not search for the Chief Historian near the gardener and his massive farm? There's plenty of food, so The Historians grab something to eat while they search.\n\nYou're about to settle near a complex arrangement of garden plots when some Elves ask if you can lend a hand. They'd like to set up fences around each region of garden plots, but they can't figure out how much fence they need to order or how much it will cost. They hand you a map (your puzzle input) of the garden plots.\n\nEach garden plot grows only a single type of plant and is indicated by a single letter on your map. When multiple garden plots are growing the same type of plant and are touching (horizontally or vertically), they form a region. For example:\n\nAAAA\nBBCD\nBBCC\nEEEC\n\nThis 4x4 arrangement includes garden plots growing five different types of plants (labeled A, B, C, D, and E), each grouped into their own region.\n\nIn order to accurately calculate the cost of the fence around a single region, you need to know that region's area and perimeter.\n\nThe area of a region is simply the number of garden plots the region contains. The above map's type A, B, and C plants are each in a region of area 4. The type E plants are in a region of area 3; the type D plants are in a region of area 1.\n\nEach garden plot is a square and so has four sides. The perimeter of a region is the number of sides of garden plots in the region that do not touch another garden plot in the same region. The type A and C plants are each in a region with perimeter 10. The type B and E plants are each in a region with perimeter 8. The lone D plot forms its own region with perimeter 4.\n\nVisually indicating the sides of plots in each region that contribute to the perimeter using - and |, the above map's regions' perimeters are measured as follows:\n\n+-+-+-+-+\n|A A A A|\n+-+-+-+-+     +-+\n              |D|\n+-+-+   +-+   +-+\n|B B|   |C|\n+   +   + +-+\n|B B|   |C C|\n+-+-+   +-+ +\n          |C|\n+-+-+-+   +-+\n|E E E|\n+-+-+-+\n\nPlants of the same type can appear in multiple separate regions, and regions can even appear within other regions. For example:\n\nOOOOO\nOXOXO\nOOOOO\nOXOXO\nOOOOO\n\nThe above map contains five regions, one containing all of the O garden plots, and the other four each containing a single X plot.\n\nThe four X regions each have area 1 and perimeter 4. The region containing 21 type O plants is more complicated; in addition to its outer edge contributing a perimeter of 20, its boundary with each X region contributes an additional 4 to its perimeter, for a total perimeter of 36.\n\nDue to \"modern\" business practices, the price of fence required for a region is found by multiplying that region's area by its perimeter. The total price of fencing all regions on a map is found by adding together the price of fence for every region on the map.\n\nIn the first example, region A has price 4 * 10 = 40, region B has price 4 * 8 = 32, region C has price 4 * 10 = 40, region D has price 1 * 4 = 4, and region E has price 3 * 8 = 24. So, the total price for the first example is 140.\n\nIn the second example, the region with all of the O plants has price 21 * 36 = 756, and each of the four smaller X regions has price 1 * 4 = 4, for a total price of 772 (756 + 4 + 4 + 4 + 4).\n\nHere's a larger example:\n\nRRRRIICCFF\nRRRRIICCCF\nVVRRRCCFFF\nVVRCCCJFFF\nVVVVCJJCFE\nVVIVCCJJEE\nVVIIICJJEE\nMIIIIIJJEE\nMIIISIJEEE\nMMMISSJEEE\n\nIt contains:\n\n    A region of R plants with price 12 * 18 = 216.\n    A region of I plants with price 4 * 8 = 32.\n    A region of C plants with price 14 * 28 = 392.\n    A region of F plants with price 10 * 18 = 180.\n    A region of V plants with price 13 * 20 = 260.\n    A region of J plants with price 11 * 20 = 220.\n    A region of C plants with price 1 * 4 = 4.\n    A region of E plants with price 13 * 18 = 234.\n    A region of I plants with price 14 * 22 = 308.\n    A region of M plants with price 5 * 12 = 60.\n    A region of S plants with price 3 * 8 = 24.\n\nSo, it has a total price of 1930.\n\nWhat is the total price of fencing all regions on your map?\n\n--- Part Two ---\n\nFortunately, the Elves are trying to order so much fence that they qualify for a bulk discount!\n\nUnder the bulk discount, instead of using the perimeter to calculate the price, you need to use the number of sides each region has. Each straight section of fence counts as a side, regardless of how long it is.\n\nConsider this example again:\n\nAAAA\nBBCD\nBBCC\nEEEC\n\nThe region containing type A plants has 4 sides, as does each of the regions containing plants of type B, D, and E. However, the more complex region containing the plants of type C has 8 sides!\n\nUsing the new method of calculating the per-region price by multiplying the region's area by its number of sides, regions A through E have prices 16, 16, 32, 4, and 12, respectively, for a total price of 80.\n\nThe second example above (full of type X and O plants) would have a total price of 436.\n\nHere's a map that includes an E-shaped region full of type E plants:\n\nEEEEE\nEXXXX\nEEEEE\nEXXXX\nEEEEE\n\nThe E-shaped region has an area of 17 and 12 sides for a price of 204. Including the two regions full of type X plants, this map has a total price of 236.\n\nThis map has a total price of 368:\n\nAAAAAA\nAAABBA\nAAABBA\nABBAAA\nABBAAA\nAAAAAA\n\nIt includes two regions full of type B plants (each with 4 sides) and a single region full of type A plants (with 4 sides on the outside and 8 more sides on the inside, a total of 12 sides). Be especially careful when counting the fence around regions like the one full of type A plants; in particular, each section of fence has an in-side and an out-side, so the fence does not connect across the middle of the region (where the two B regions touch diagonally). (The Elves would have used the Möbius Fencing Company instead, but their contract terms were too one-sided.)\n\nThe larger example from before now has the following updated prices:\n\n    A region of R plants with price 12 * 10 = 120.\n    A region of I plants with price 4 * 4 = 16.\n    A region of C plants with price 14 * 22 = 308.\n    A region of F plants with price 10 * 12 = 120.\n    A region of V plants with price 13 * 10 = 130.\n    A region of J plants with price 11 * 12 = 132.\n    A region of C plants with price 1 * 4 = 4.\n    A region of E plants with price 13 * 8 = 104.\n    A region of I plants with price 14 * 16 = 224.\n    A region of M plants with price 5 * 6 = 30.\n    A region of S plants with price 3 * 6 = 18.\n\nAdding these together produces its new total price of 1206.\n\nWhat is the new total price of fencing all regions on your map?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_13.adb",
    "content": "--  Solution to Advent of Code 2024, Day 13\n-------------------------------------------\n--  Claw Contraption\n--\n--  https://adventofcode.com/2024/day/13\n--  Copy of questions in: aoc_2024_13_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_13 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  subtype I64 is Integer_64;\n\n  --  The wording is misleading (on purpose of course!),\n  --  with portions such as \"...the cheapest way to win the prize...\"\n  --  or \"...the minimum tokens you would have to spend...\"\n  --  Actually there is at most *one* solution in the real plane (\\IR^2),\n  --  thus also at most one solution in the square lattice (\\ZZ^2).\n  --  So, if there is a solution, we already have the lowest cost.\n  --\n  function Cost (ax, ay, bx, by, px, py : I64) return I64 is\n    det : constant I64 := ax * by - bx * ay;\n    a_times_det, b_times_det, a, b : I64;\n  begin\n\n    --  /    \\       /        \\     /   \\\n    --  | px |       | ax  bx |     | a |\n    --  |    |   =   |        |  *  |   |\n    --  | py |       | ay  by |     | b |\n    --  \\    /       \\        /     \\   /\n\n    --  /   \\       /        \\-1   /    \\\n    --  | a |       | ax  bx |     | px |\n    --  |   |   =   |        |  *  |    |\n    --  | b |       | ay  by |     | py |\n    --  \\   /       \\        /     \\    /\n\n    --             /        \\-1     /          \\\n    --             | ax  bx |       | +by  -bx |\n    --    where:   |        |   =   |          | / (ax by - bx ay)\n    --             | ay  by |       | -ay  +ax |\n    --             \\        /       \\          /\n\n    if px = 0 and py = 0 then\n      --  Case not seen on our input data.\n      Put_Line (\"px = 0, py = 0 ------> solution: a = 0, b = 0\");\n      return 0;\n    end if;\n\n    if det = 0 then\n      --  Case not seen on our input data: a row is a multiple of the other.\n      --     -> Zero or an infinity of solutions in \\IR^2.\n      --     -> Zero or a smaller infinity of solutions in \\ZZ^2.\n      --  We would have to look for the pair\n      --  of natural integers with the smallest cost...\n      Put_Line (\"Determinant 0\");\n      return 0;\n    end if;\n\n    a_times_det := by * px - bx * py;\n    b_times_det := ax * py - ay * px;\n\n    if a_times_det rem det /= 0 or else b_times_det rem det /= 0 then\n      --  There are remainders -> non integer solution\n      --  (solution is in the plane \\IR^2 but not in the square lattice \\ZZ^2).\n      return 0;\n    end if;\n\n    a := a_times_det / det;\n    b := b_times_det / det;\n\n    if a < 0 or b < 0 then\n      --  Case not seen on our input data.\n      Put_Line (\"Negative number of button presses\");\n      return 0;\n    end if;\n\n    if a = 0 or b = 0 then\n      --  Case not seen on our input data.\n      Put_Line (\"Solution with 1 or 2 buttons pressed 0 times\");\n    end if;\n\n    return a * 3 + b;\n\n  end Cost;\n\n  r : array (Part_Type) of I64;\n\n  procedure Read_Data_and_Solve is\n    butax, butbx : String (1 .. 12) := \"Button A: X+\";\n    butay, butby : String (1 .. 4)  := \", Y+\";\n    prix : String (1 .. 9)  := \"Prize: X=\";\n    priy : String (1 .. 4)  := \", Y=\";\n    ax, ay, bx, by, px, py : Integer;\n    f : File_Type;\n    big : constant := 10_000_000_000_000;\n  begin\n    Open (f, \"aoc_2024_13.txt\");\n\n    while not End_Of_File (f) loop\n      Get (f, butax);  Get (f, ax);\n      Get (f, butay);  Get (f, ay);\n      Get (f, butbx);  Get (f, bx);\n      Get (f, butby);  Get (f, by);\n      Get (f, prix);   Get (f, px);\n      Get (f, priy);   Get (f, py);\n\n      r (part_1) :=\n        r (part_1) +\n        Cost (I64 (ax), I64 (ay), I64 (bx), I64 (by), I64 (px),       I64 (py));\n\n      r (part_2) :=\n        r (part_2) +\n        Cost (I64 (ax), I64 (ay), I64 (bx), I64 (by), I64 (px) + big, I64 (py) + big);\n\n    end loop;\n\n    Close (f);\n  end Read_Data_and_Solve;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 2;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data_and_Solve;\n\n  if compiler_test_mode then\n    if +r (part_1)'Image /= +' ' & Argument (1) or\n       +r (part_2)'Image /= +' ' & Argument (2)\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 36954\n    --  Part 2: validated by AoC: 79352015273424\n  end if;\nend AoC_2024_13;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_13.txt",
    "content": "Button A: X+92, Y+24\nButton B: X+13, Y+94\nPrize: X=8901, Y=8574\n\nButton A: X+52, Y+13\nButton B: X+27, Y+72\nPrize: X=18587, Y=299\n\nButton A: X+45, Y+21\nButton B: X+34, Y+56\nPrize: X=12602, Y=14690\n\nButton A: X+78, Y+53\nButton B: X+14, Y+35\nPrize: X=2228, Y=2432\n\nButton A: X+77, Y+16\nButton B: X+13, Y+79\nPrize: X=16314, Y=19562\n\nButton A: X+27, Y+72\nButton B: X+57, Y+11\nPrize: X=16094, Y=14389\n\nButton A: X+43, Y+77\nButton B: X+51, Y+13\nPrize: X=15606, Y=16498\n\nButton A: X+79, Y+45\nButton B: X+41, Y+99\nPrize: X=5535, Y=7389\n\nButton A: X+14, Y+69\nButton B: X+83, Y+25\nPrize: X=15390, Y=13803\n\nButton A: X+18, Y+38\nButton B: X+60, Y+30\nPrize: X=16586, Y=1146\n\nButton A: X+32, Y+65\nButton B: X+40, Y+16\nPrize: X=19544, Y=14414\n\nButton A: X+67, Y+15\nButton B: X+28, Y+79\nPrize: X=9428, Y=13828\n\nButton A: X+51, Y+20\nButton B: X+12, Y+35\nPrize: X=8252, Y=19415\n\nButton A: X+76, Y+52\nButton B: X+12, Y+37\nPrize: X=19492, Y=11639\n\nButton A: X+74, Y+11\nButton B: X+84, Y+80\nPrize: X=6934, Y=2381\n\nButton A: X+20, Y+59\nButton B: X+42, Y+36\nPrize: X=2816, Y=5846\n\nButton A: X+13, Y+39\nButton B: X+67, Y+38\nPrize: X=16077, Y=14664\n\nButton A: X+15, Y+61\nButton B: X+56, Y+23\nPrize: X=9909, Y=18887\n\nButton A: X+71, Y+99\nButton B: X+90, Y+15\nPrize: X=3897, Y=3003\n\nButton A: X+23, Y+49\nButton B: X+35, Y+15\nPrize: X=783, Y=12319\n\nButton A: X+40, Y+74\nButton B: X+73, Y+43\nPrize: X=3809, Y=4009\n\nButton A: X+55, Y+18\nButton B: X+11, Y+61\nPrize: X=1265, Y=1562\n\nButton A: X+80, Y+86\nButton B: X+15, Y+94\nPrize: X=8075, Y=11562\n\nButton A: X+80, Y+26\nButton B: X+15, Y+69\nPrize: X=8175, Y=1263\n\nButton A: X+14, Y+55\nButton B: X+56, Y+18\nPrize: X=16958, Y=1101\n\nButton A: X+20, Y+75\nButton B: X+73, Y+12\nPrize: X=1703, Y=8597\n\nButton A: X+32, Y+84\nButton B: X+89, Y+42\nPrize: X=4212, Y=7224\n\nButton A: X+50, Y+64\nButton B: X+69, Y+14\nPrize: X=8066, Y=5568\n\nButton A: X+22, Y+80\nButton B: X+52, Y+21\nPrize: X=4102, Y=6848\n\nButton A: X+96, Y+40\nButton B: X+34, Y+88\nPrize: X=6838, Y=6024\n\nButton A: X+74, Y+21\nButton B: X+59, Y+77\nPrize: X=11659, Y=8792\n\nButton A: X+17, Y+61\nButton B: X+59, Y+12\nPrize: X=2971, Y=2273\n\nButton A: X+71, Y+37\nButton B: X+14, Y+46\nPrize: X=7100, Y=19268\n\nButton A: X+59, Y+82\nButton B: X+73, Y+27\nPrize: X=2427, Y=2703\n\nButton A: X+92, Y+65\nButton B: X+25, Y+83\nPrize: X=8252, Y=7921\n\nButton A: X+97, Y+49\nButton B: X+60, Y+99\nPrize: X=5570, Y=3638\n\nButton A: X+43, Y+14\nButton B: X+25, Y+43\nPrize: X=16821, Y=13757\n\nButton A: X+79, Y+13\nButton B: X+17, Y+23\nPrize: X=4481, Y=2495\n\nButton A: X+23, Y+58\nButton B: X+66, Y+22\nPrize: X=4056, Y=1562\n\nButton A: X+18, Y+42\nButton B: X+67, Y+40\nPrize: X=4107, Y=2952\n\nButton A: X+17, Y+53\nButton B: X+99, Y+14\nPrize: X=4219, Y=3430\n\nButton A: X+36, Y+13\nButton B: X+40, Y+82\nPrize: X=4508, Y=6019\n\nButton A: X+16, Y+69\nButton B: X+88, Y+56\nPrize: X=2152, Y=1840\n\nButton A: X+34, Y+13\nButton B: X+12, Y+69\nPrize: X=2684, Y=1928\n\nButton A: X+79, Y+21\nButton B: X+31, Y+85\nPrize: X=1675, Y=2441\n\nButton A: X+42, Y+68\nButton B: X+87, Y+30\nPrize: X=8829, Y=7754\n\nButton A: X+76, Y+42\nButton B: X+37, Y+87\nPrize: X=8620, Y=7692\n\nButton A: X+26, Y+45\nButton B: X+96, Y+33\nPrize: X=522, Y=504\n\nButton A: X+22, Y+80\nButton B: X+57, Y+52\nPrize: X=1460, Y=4688\n\nButton A: X+78, Y+61\nButton B: X+24, Y+91\nPrize: X=3108, Y=6620\n\nButton A: X+18, Y+40\nButton B: X+33, Y+16\nPrize: X=10217, Y=10816\n\nButton A: X+99, Y+14\nButton B: X+97, Y+90\nPrize: X=10479, Y=5830\n\nButton A: X+13, Y+57\nButton B: X+91, Y+20\nPrize: X=4095, Y=2037\n\nButton A: X+31, Y+15\nButton B: X+24, Y+37\nPrize: X=3109, Y=1809\n\nButton A: X+12, Y+29\nButton B: X+51, Y+18\nPrize: X=2549, Y=18593\n\nButton A: X+19, Y+93\nButton B: X+90, Y+63\nPrize: X=3706, Y=5304\n\nButton A: X+80, Y+88\nButton B: X+14, Y+81\nPrize: X=4168, Y=5372\n\nButton A: X+39, Y+19\nButton B: X+21, Y+58\nPrize: X=3183, Y=1694\n\nButton A: X+43, Y+21\nButton B: X+31, Y+52\nPrize: X=16089, Y=8718\n\nButton A: X+49, Y+18\nButton B: X+40, Y+58\nPrize: X=965, Y=1134\n\nButton A: X+20, Y+88\nButton B: X+69, Y+58\nPrize: X=1074, Y=3252\n\nButton A: X+21, Y+70\nButton B: X+63, Y+16\nPrize: X=15950, Y=16374\n\nButton A: X+74, Y+35\nButton B: X+14, Y+39\nPrize: X=1672, Y=3064\n\nButton A: X+20, Y+45\nButton B: X+48, Y+23\nPrize: X=5340, Y=9415\n\nButton A: X+62, Y+58\nButton B: X+23, Y+99\nPrize: X=2573, Y=4809\n\nButton A: X+31, Y+63\nButton B: X+54, Y+15\nPrize: X=19014, Y=5888\n\nButton A: X+55, Y+23\nButton B: X+15, Y+37\nPrize: X=8895, Y=2213\n\nButton A: X+15, Y+67\nButton B: X+54, Y+20\nPrize: X=9194, Y=17528\n\nButton A: X+18, Y+75\nButton B: X+68, Y+15\nPrize: X=4586, Y=16760\n\nButton A: X+16, Y+39\nButton B: X+42, Y+26\nPrize: X=6762, Y=12119\n\nButton A: X+47, Y+71\nButton B: X+40, Y+17\nPrize: X=1887, Y=13467\n\nButton A: X+31, Y+16\nButton B: X+37, Y+88\nPrize: X=5502, Y=8352\n\nButton A: X+33, Y+76\nButton B: X+43, Y+14\nPrize: X=16415, Y=12452\n\nButton A: X+71, Y+45\nButton B: X+11, Y+23\nPrize: X=16969, Y=10475\n\nButton A: X+85, Y+17\nButton B: X+41, Y+46\nPrize: X=4525, Y=1472\n\nButton A: X+25, Y+63\nButton B: X+49, Y+23\nPrize: X=9351, Y=16161\n\nButton A: X+15, Y+45\nButton B: X+82, Y+47\nPrize: X=7046, Y=15131\n\nButton A: X+16, Y+48\nButton B: X+22, Y+11\nPrize: X=2828, Y=3534\n\nButton A: X+27, Y+13\nButton B: X+27, Y+61\nPrize: X=8063, Y=7145\n\nButton A: X+39, Y+71\nButton B: X+52, Y+18\nPrize: X=13679, Y=8591\n\nButton A: X+23, Y+60\nButton B: X+49, Y+13\nPrize: X=4680, Y=2419\n\nButton A: X+61, Y+83\nButton B: X+62, Y+17\nPrize: X=8921, Y=7019\n\nButton A: X+66, Y+32\nButton B: X+19, Y+40\nPrize: X=10739, Y=2600\n\nButton A: X+25, Y+93\nButton B: X+98, Y+66\nPrize: X=3314, Y=6954\n\nButton A: X+16, Y+70\nButton B: X+70, Y+68\nPrize: X=3930, Y=7902\n\nButton A: X+67, Y+27\nButton B: X+69, Y+89\nPrize: X=6749, Y=6269\n\nButton A: X+15, Y+54\nButton B: X+57, Y+20\nPrize: X=335, Y=8334\n\nButton A: X+73, Y+16\nButton B: X+18, Y+20\nPrize: X=5917, Y=2212\n\nButton A: X+42, Y+15\nButton B: X+60, Y+86\nPrize: X=3900, Y=3330\n\nButton A: X+62, Y+27\nButton B: X+13, Y+51\nPrize: X=2144, Y=11759\n\nButton A: X+60, Y+21\nButton B: X+11, Y+60\nPrize: X=4782, Y=8672\n\nButton A: X+77, Y+11\nButton B: X+38, Y+78\nPrize: X=6040, Y=7104\n\nButton A: X+19, Y+85\nButton B: X+23, Y+24\nPrize: X=1183, Y=3320\n\nButton A: X+58, Y+74\nButton B: X+56, Y+13\nPrize: X=2040, Y=1200\n\nButton A: X+19, Y+80\nButton B: X+87, Y+33\nPrize: X=1790, Y=4537\n\nButton A: X+19, Y+90\nButton B: X+63, Y+55\nPrize: X=7689, Y=13540\n\nButton A: X+20, Y+73\nButton B: X+66, Y+22\nPrize: X=8268, Y=3896\n\nButton A: X+45, Y+78\nButton B: X+74, Y+12\nPrize: X=7371, Y=6498\n\nButton A: X+83, Y+14\nButton B: X+55, Y+66\nPrize: X=3469, Y=3478\n\nButton A: X+95, Y+32\nButton B: X+32, Y+77\nPrize: X=6871, Y=8473\n\nButton A: X+17, Y+31\nButton B: X+94, Y+50\nPrize: X=3538, Y=3902\n\nButton A: X+16, Y+66\nButton B: X+28, Y+11\nPrize: X=4960, Y=4676\n\nButton A: X+23, Y+73\nButton B: X+54, Y+13\nPrize: X=6634, Y=7542\n\nButton A: X+63, Y+25\nButton B: X+50, Y+77\nPrize: X=7290, Y=5465\n\nButton A: X+83, Y+11\nButton B: X+11, Y+58\nPrize: X=19276, Y=11149\n\nButton A: X+11, Y+88\nButton B: X+83, Y+45\nPrize: X=6666, Y=5665\n\nButton A: X+43, Y+14\nButton B: X+14, Y+67\nPrize: X=11261, Y=14558\n\nButton A: X+62, Y+29\nButton B: X+19, Y+44\nPrize: X=2521, Y=3339\n\nButton A: X+70, Y+15\nButton B: X+59, Y+68\nPrize: X=10614, Y=5928\n\nButton A: X+94, Y+13\nButton B: X+87, Y+96\nPrize: X=8387, Y=8801\n\nButton A: X+87, Y+89\nButton B: X+71, Y+13\nPrize: X=6299, Y=4953\n\nButton A: X+96, Y+24\nButton B: X+49, Y+72\nPrize: X=11557, Y=7968\n\nButton A: X+95, Y+98\nButton B: X+16, Y+85\nPrize: X=6874, Y=8050\n\nButton A: X+71, Y+13\nButton B: X+13, Y+43\nPrize: X=3894, Y=2638\n\nButton A: X+39, Y+87\nButton B: X+23, Y+16\nPrize: X=2003, Y=2950\n\nButton A: X+18, Y+51\nButton B: X+88, Y+42\nPrize: X=7254, Y=3759\n\nButton A: X+11, Y+52\nButton B: X+66, Y+22\nPrize: X=17876, Y=7662\n\nButton A: X+40, Y+21\nButton B: X+15, Y+35\nPrize: X=2195, Y=14382\n\nButton A: X+12, Y+87\nButton B: X+64, Y+21\nPrize: X=5356, Y=2505\n\nButton A: X+13, Y+33\nButton B: X+70, Y+50\nPrize: X=5649, Y=7169\n\nButton A: X+92, Y+16\nButton B: X+42, Y+85\nPrize: X=5178, Y=4863\n\nButton A: X+59, Y+92\nButton B: X+65, Y+25\nPrize: X=5947, Y=4921\n\nButton A: X+53, Y+29\nButton B: X+24, Y+55\nPrize: X=4866, Y=1041\n\nButton A: X+17, Y+66\nButton B: X+67, Y+39\nPrize: X=5699, Y=7974\n\nButton A: X+14, Y+38\nButton B: X+71, Y+33\nPrize: X=4260, Y=4216\n\nButton A: X+58, Y+22\nButton B: X+12, Y+47\nPrize: X=1726, Y=2862\n\nButton A: X+70, Y+33\nButton B: X+48, Y+98\nPrize: X=8822, Y=8229\n\nButton A: X+13, Y+51\nButton B: X+54, Y+16\nPrize: X=4006, Y=5336\n\nButton A: X+69, Y+32\nButton B: X+19, Y+43\nPrize: X=11505, Y=3154\n\nButton A: X+35, Y+14\nButton B: X+16, Y+49\nPrize: X=16262, Y=6269\n\nButton A: X+94, Y+20\nButton B: X+20, Y+57\nPrize: X=7242, Y=2543\n\nButton A: X+22, Y+68\nButton B: X+63, Y+14\nPrize: X=12524, Y=7976\n\nButton A: X+13, Y+59\nButton B: X+63, Y+28\nPrize: X=3729, Y=15618\n\nButton A: X+22, Y+11\nButton B: X+37, Y+67\nPrize: X=3661, Y=1532\n\nButton A: X+98, Y+41\nButton B: X+15, Y+39\nPrize: X=10330, Y=6547\n\nButton A: X+69, Y+16\nButton B: X+23, Y+94\nPrize: X=5451, Y=5786\n\nButton A: X+13, Y+60\nButton B: X+40, Y+15\nPrize: X=8281, Y=9155\n\nButton A: X+41, Y+19\nButton B: X+31, Y+66\nPrize: X=4199, Y=5457\n\nButton A: X+27, Y+70\nButton B: X+59, Y+12\nPrize: X=7391, Y=17342\n\nButton A: X+66, Y+12\nButton B: X+40, Y+77\nPrize: X=5714, Y=3061\n\nButton A: X+66, Y+46\nButton B: X+11, Y+33\nPrize: X=14081, Y=9323\n\nButton A: X+42, Y+20\nButton B: X+34, Y+66\nPrize: X=3960, Y=2334\n\nButton A: X+94, Y+56\nButton B: X+12, Y+41\nPrize: X=6256, Y=4404\n\nButton A: X+14, Y+33\nButton B: X+58, Y+24\nPrize: X=5254, Y=1715\n\nButton A: X+20, Y+63\nButton B: X+81, Y+24\nPrize: X=6982, Y=7662\n\nButton A: X+66, Y+95\nButton B: X+94, Y+41\nPrize: X=5004, Y=3242\n\nButton A: X+66, Y+75\nButton B: X+12, Y+75\nPrize: X=6786, Y=11025\n\nButton A: X+12, Y+33\nButton B: X+71, Y+25\nPrize: X=17784, Y=10819\n\nButton A: X+17, Y+92\nButton B: X+92, Y+49\nPrize: X=2731, Y=5353\n\nButton A: X+93, Y+41\nButton B: X+11, Y+25\nPrize: X=7015, Y=3677\n\nButton A: X+65, Y+13\nButton B: X+13, Y+66\nPrize: X=17722, Y=10475\n\nButton A: X+11, Y+36\nButton B: X+79, Y+41\nPrize: X=7505, Y=10050\n\nButton A: X+12, Y+44\nButton B: X+62, Y+23\nPrize: X=5604, Y=5836\n\nButton A: X+51, Y+27\nButton B: X+19, Y+71\nPrize: X=2344, Y=5324\n\nButton A: X+96, Y+12\nButton B: X+80, Y+85\nPrize: X=10560, Y=4920\n\nButton A: X+36, Y+98\nButton B: X+99, Y+55\nPrize: X=3069, Y=7711\n\nButton A: X+56, Y+25\nButton B: X+20, Y+61\nPrize: X=6116, Y=16247\n\nButton A: X+36, Y+52\nButton B: X+78, Y+30\nPrize: X=5898, Y=5626\n\nButton A: X+31, Y+95\nButton B: X+68, Y+26\nPrize: X=4862, Y=4686\n\nButton A: X+59, Y+13\nButton B: X+14, Y+55\nPrize: X=3090, Y=15871\n\nButton A: X+45, Y+20\nButton B: X+35, Y+55\nPrize: X=4270, Y=4580\n\nButton A: X+96, Y+52\nButton B: X+14, Y+58\nPrize: X=9848, Y=7956\n\nButton A: X+58, Y+25\nButton B: X+11, Y+20\nPrize: X=6199, Y=18370\n\nButton A: X+77, Y+24\nButton B: X+44, Y+81\nPrize: X=4631, Y=5817\n\nButton A: X+11, Y+42\nButton B: X+89, Y+30\nPrize: X=665, Y=990\n\nButton A: X+56, Y+26\nButton B: X+20, Y+60\nPrize: X=1760, Y=2090\n\nButton A: X+73, Y+16\nButton B: X+49, Y+71\nPrize: X=732, Y=522\n\nButton A: X+43, Y+20\nButton B: X+16, Y+37\nPrize: X=16455, Y=11559\n\nButton A: X+62, Y+11\nButton B: X+22, Y+58\nPrize: X=8054, Y=17144\n\nButton A: X+11, Y+56\nButton B: X+91, Y+56\nPrize: X=7989, Y=8904\n\nButton A: X+54, Y+16\nButton B: X+33, Y+86\nPrize: X=4410, Y=8624\n\nButton A: X+23, Y+96\nButton B: X+60, Y+42\nPrize: X=2925, Y=8040\n\nButton A: X+71, Y+39\nButton B: X+19, Y+41\nPrize: X=5533, Y=13797\n\nButton A: X+74, Y+33\nButton B: X+54, Y+77\nPrize: X=7604, Y=5984\n\nButton A: X+28, Y+89\nButton B: X+64, Y+19\nPrize: X=4460, Y=3664\n\nButton A: X+14, Y+39\nButton B: X+68, Y+56\nPrize: X=1442, Y=3083\n\nButton A: X+19, Y+87\nButton B: X+56, Y+60\nPrize: X=3601, Y=7257\n\nButton A: X+59, Y+24\nButton B: X+14, Y+33\nPrize: X=15888, Y=7589\n\nButton A: X+61, Y+19\nButton B: X+59, Y+64\nPrize: X=9413, Y=6673\n\nButton A: X+53, Y+80\nButton B: X+44, Y+16\nPrize: X=14124, Y=16208\n\nButton A: X+31, Y+31\nButton B: X+71, Y+11\nPrize: X=6501, Y=2841\n\nButton A: X+94, Y+20\nButton B: X+49, Y+59\nPrize: X=6254, Y=4828\n\nButton A: X+54, Y+31\nButton B: X+29, Y+52\nPrize: X=2883, Y=9438\n\nButton A: X+58, Y+54\nButton B: X+18, Y+59\nPrize: X=814, Y=1307\n\nButton A: X+20, Y+71\nButton B: X+59, Y+11\nPrize: X=3109, Y=17101\n\nButton A: X+12, Y+34\nButton B: X+37, Y+11\nPrize: X=16103, Y=1699\n\nButton A: X+94, Y+96\nButton B: X+11, Y+62\nPrize: X=4691, Y=7786\n\nButton A: X+95, Y+25\nButton B: X+78, Y+89\nPrize: X=12181, Y=8478\n\nButton A: X+25, Y+65\nButton B: X+79, Y+18\nPrize: X=962, Y=1939\n\nButton A: X+12, Y+63\nButton B: X+42, Y+45\nPrize: X=1872, Y=6318\n\nButton A: X+44, Y+17\nButton B: X+20, Y+58\nPrize: X=6780, Y=19261\n\nButton A: X+34, Y+65\nButton B: X+54, Y+17\nPrize: X=3820, Y=11780\n\nButton A: X+12, Y+75\nButton B: X+71, Y+19\nPrize: X=11722, Y=15270\n\nButton A: X+22, Y+58\nButton B: X+61, Y+46\nPrize: X=3750, Y=5064\n\nButton A: X+26, Y+30\nButton B: X+46, Y+15\nPrize: X=6232, Y=3840\n\nButton A: X+69, Y+79\nButton B: X+79, Y+22\nPrize: X=9421, Y=7227\n\nButton A: X+50, Y+22\nButton B: X+35, Y+60\nPrize: X=17190, Y=12800\n\nButton A: X+20, Y+57\nButton B: X+55, Y+24\nPrize: X=2955, Y=10643\n\nButton A: X+63, Y+17\nButton B: X+16, Y+62\nPrize: X=12674, Y=17090\n\nButton A: X+30, Y+71\nButton B: X+95, Y+50\nPrize: X=8800, Y=5791\n\nButton A: X+46, Y+15\nButton B: X+40, Y+70\nPrize: X=9362, Y=2425\n\nButton A: X+68, Y+72\nButton B: X+66, Y+11\nPrize: X=6626, Y=5897\n\nButton A: X+15, Y+39\nButton B: X+50, Y+35\nPrize: X=13560, Y=6621\n\nButton A: X+63, Y+37\nButton B: X+25, Y+52\nPrize: X=16956, Y=14505\n\nButton A: X+27, Y+84\nButton B: X+93, Y+39\nPrize: X=8091, Y=7899\n\nButton A: X+14, Y+43\nButton B: X+83, Y+49\nPrize: X=8887, Y=1332\n\nButton A: X+26, Y+41\nButton B: X+86, Y+23\nPrize: X=3690, Y=2553\n\nButton A: X+42, Y+15\nButton B: X+19, Y+56\nPrize: X=4755, Y=18862\n\nButton A: X+50, Y+25\nButton B: X+14, Y+66\nPrize: X=4302, Y=7638\n\nButton A: X+59, Y+35\nButton B: X+12, Y+36\nPrize: X=11278, Y=13462\n\nButton A: X+41, Y+77\nButton B: X+45, Y+12\nPrize: X=5703, Y=7665\n\nButton A: X+49, Y+68\nButton B: X+34, Y+12\nPrize: X=3834, Y=2940\n\nButton A: X+24, Y+49\nButton B: X+42, Y+27\nPrize: X=13496, Y=6346\n\nButton A: X+11, Y+52\nButton B: X+43, Y+18\nPrize: X=5977, Y=8740\n\nButton A: X+49, Y+93\nButton B: X+68, Y+37\nPrize: X=6795, Y=4427\n\nButton A: X+57, Y+21\nButton B: X+27, Y+66\nPrize: X=18467, Y=14201\n\nButton A: X+71, Y+13\nButton B: X+50, Y+68\nPrize: X=6377, Y=5581\n\nButton A: X+86, Y+24\nButton B: X+14, Y+95\nPrize: X=1510, Y=6889\n\nButton A: X+24, Y+77\nButton B: X+83, Y+31\nPrize: X=6372, Y=6326\n\nButton A: X+70, Y+35\nButton B: X+23, Y+44\nPrize: X=3744, Y=3107\n\nButton A: X+41, Y+13\nButton B: X+41, Y+65\nPrize: X=8553, Y=10117\n\nButton A: X+31, Y+92\nButton B: X+65, Y+45\nPrize: X=2715, Y=7170\n\nButton A: X+20, Y+93\nButton B: X+39, Y+34\nPrize: X=5098, Y=11623\n\nButton A: X+47, Y+22\nButton B: X+30, Y+50\nPrize: X=10226, Y=6806\n\nButton A: X+47, Y+16\nButton B: X+32, Y+62\nPrize: X=4072, Y=11088\n\nButton A: X+20, Y+95\nButton B: X+69, Y+17\nPrize: X=2893, Y=2244\n\nButton A: X+12, Y+40\nButton B: X+71, Y+25\nPrize: X=19241, Y=5175\n\nButton A: X+13, Y+59\nButton B: X+98, Y+86\nPrize: X=4005, Y=8131\n\nButton A: X+49, Y+15\nButton B: X+17, Y+57\nPrize: X=3550, Y=12584\n\nButton A: X+29, Y+14\nButton B: X+13, Y+49\nPrize: X=369, Y=819\n\nButton A: X+19, Y+72\nButton B: X+62, Y+13\nPrize: X=15652, Y=2141\n\nButton A: X+24, Y+66\nButton B: X+58, Y+20\nPrize: X=16168, Y=12354\n\nButton A: X+12, Y+47\nButton B: X+25, Y+13\nPrize: X=7445, Y=3589\n\nButton A: X+19, Y+60\nButton B: X+77, Y+63\nPrize: X=5950, Y=7980\n\nButton A: X+41, Y+15\nButton B: X+31, Y+52\nPrize: X=14064, Y=12352\n\nButton A: X+24, Y+93\nButton B: X+70, Y+24\nPrize: X=2140, Y=5820\n\nButton A: X+15, Y+69\nButton B: X+86, Y+13\nPrize: X=5919, Y=6567\n\nButton A: X+14, Y+28\nButton B: X+53, Y+11\nPrize: X=18614, Y=18488\n\nButton A: X+98, Y+15\nButton B: X+55, Y+98\nPrize: X=7148, Y=5394\n\nButton A: X+31, Y+11\nButton B: X+11, Y+68\nPrize: X=9045, Y=10249\n\nButton A: X+58, Y+70\nButton B: X+76, Y+16\nPrize: X=12382, Y=7750\n\nButton A: X+93, Y+56\nButton B: X+27, Y+97\nPrize: X=2238, Y=2478\n\nButton A: X+62, Y+30\nButton B: X+16, Y+53\nPrize: X=8124, Y=3852\n\nButton A: X+42, Y+24\nButton B: X+28, Y+54\nPrize: X=13850, Y=6044\n\nButton A: X+55, Y+97\nButton B: X+77, Y+17\nPrize: X=5995, Y=8791\n\nButton A: X+24, Y+49\nButton B: X+40, Y+26\nPrize: X=6432, Y=18253\n\nButton A: X+79, Y+32\nButton B: X+49, Y+68\nPrize: X=11798, Y=8920\n\nButton A: X+72, Y+15\nButton B: X+84, Y+77\nPrize: X=11244, Y=5972\n\nButton A: X+70, Y+45\nButton B: X+27, Y+91\nPrize: X=1990, Y=4225\n\nButton A: X+18, Y+53\nButton B: X+61, Y+50\nPrize: X=5128, Y=6804\n\nButton A: X+96, Y+46\nButton B: X+21, Y+65\nPrize: X=5880, Y=4136\n\nButton A: X+67, Y+21\nButton B: X+21, Y+52\nPrize: X=8162, Y=6010\n\nButton A: X+29, Y+66\nButton B: X+54, Y+20\nPrize: X=4291, Y=12102\n\nButton A: X+53, Y+24\nButton B: X+14, Y+30\nPrize: X=1819, Y=680\n\nButton A: X+52, Y+23\nButton B: X+20, Y+60\nPrize: X=7176, Y=9774\n\nButton A: X+21, Y+54\nButton B: X+45, Y+14\nPrize: X=15716, Y=17168\n\nButton A: X+24, Y+52\nButton B: X+31, Y+11\nPrize: X=14283, Y=16015\n\nButton A: X+12, Y+77\nButton B: X+88, Y+26\nPrize: X=1104, Y=620\n\nButton A: X+13, Y+70\nButton B: X+81, Y+73\nPrize: X=6158, Y=8464\n\nButton A: X+99, Y+38\nButton B: X+20, Y+88\nPrize: X=932, Y=920\n\nButton A: X+45, Y+70\nButton B: X+41, Y+17\nPrize: X=365, Y=16505\n\nButton A: X+16, Y+45\nButton B: X+71, Y+29\nPrize: X=18570, Y=525\n\nButton A: X+92, Y+22\nButton B: X+34, Y+84\nPrize: X=9554, Y=9644\n\nButton A: X+23, Y+52\nButton B: X+46, Y+27\nPrize: X=7897, Y=18630\n\nButton A: X+63, Y+91\nButton B: X+32, Y+15\nPrize: X=2452, Y=1887\n\nButton A: X+11, Y+74\nButton B: X+60, Y+13\nPrize: X=10126, Y=1345\n\nButton A: X+16, Y+47\nButton B: X+37, Y+11\nPrize: X=19201, Y=8796\n\nButton A: X+76, Y+34\nButton B: X+42, Y+97\nPrize: X=5870, Y=5207\n\nButton A: X+66, Y+13\nButton B: X+14, Y+56\nPrize: X=2014, Y=7202\n\nButton A: X+23, Y+62\nButton B: X+74, Y+32\nPrize: X=16271, Y=5174\n\nButton A: X+22, Y+51\nButton B: X+50, Y+28\nPrize: X=644, Y=2445\n\nButton A: X+14, Y+48\nButton B: X+72, Y+27\nPrize: X=7124, Y=4751\n\nButton A: X+64, Y+37\nButton B: X+27, Y+50\nPrize: X=8691, Y=14528\n\nButton A: X+35, Y+94\nButton B: X+60, Y+13\nPrize: X=7870, Y=7063\n\nButton A: X+95, Y+86\nButton B: X+19, Y+98\nPrize: X=8816, Y=10324\n\nButton A: X+92, Y+17\nButton B: X+12, Y+43\nPrize: X=7600, Y=2220\n\nButton A: X+90, Y+36\nButton B: X+35, Y+54\nPrize: X=5245, Y=5418\n\nButton A: X+91, Y+31\nButton B: X+33, Y+54\nPrize: X=3713, Y=1949\n\nButton A: X+36, Y+61\nButton B: X+77, Y+12\nPrize: X=9005, Y=6610\n\nButton A: X+22, Y+48\nButton B: X+52, Y+11\nPrize: X=1826, Y=5756\n\nButton A: X+63, Y+29\nButton B: X+18, Y+58\nPrize: X=15623, Y=6557\n\nButton A: X+36, Y+71\nButton B: X+53, Y+13\nPrize: X=4948, Y=4633\n\nButton A: X+70, Y+29\nButton B: X+14, Y+48\nPrize: X=17364, Y=2186\n\nButton A: X+31, Y+45\nButton B: X+66, Y+29\nPrize: X=2118, Y=1872\n\nButton A: X+39, Y+82\nButton B: X+81, Y+11\nPrize: X=7965, Y=5914\n\nButton A: X+13, Y+73\nButton B: X+67, Y+15\nPrize: X=2161, Y=19093\n\nButton A: X+45, Y+24\nButton B: X+35, Y+80\nPrize: X=5740, Y=7048\n\nButton A: X+37, Y+64\nButton B: X+54, Y+12\nPrize: X=6408, Y=3432\n\nButton A: X+87, Y+11\nButton B: X+11, Y+85\nPrize: X=14470, Y=7034\n\nButton A: X+24, Y+16\nButton B: X+13, Y+39\nPrize: X=10040, Y=18520\n\nButton A: X+23, Y+38\nButton B: X+78, Y+13\nPrize: X=4645, Y=1765\n\nButton A: X+89, Y+63\nButton B: X+13, Y+70\nPrize: X=4343, Y=4655\n\nButton A: X+73, Y+75\nButton B: X+15, Y+89\nPrize: X=5844, Y=6740\n\nButton A: X+14, Y+58\nButton B: X+43, Y+12\nPrize: X=11274, Y=1678\n\nButton A: X+35, Y+66\nButton B: X+54, Y+18\nPrize: X=6095, Y=10178\n\nButton A: X+28, Y+93\nButton B: X+63, Y+28\nPrize: X=4599, Y=8569\n\nButton A: X+28, Y+61\nButton B: X+54, Y+28\nPrize: X=1510, Y=1945\n\nButton A: X+17, Y+55\nButton B: X+39, Y+18\nPrize: X=9257, Y=12020\n\nButton A: X+32, Y+13\nButton B: X+39, Y+61\nPrize: X=8346, Y=11909\n\nButton A: X+25, Y+14\nButton B: X+27, Y+50\nPrize: X=8055, Y=7970\n\nButton A: X+13, Y+39\nButton B: X+47, Y+29\nPrize: X=1065, Y=2299\n\nButton A: X+91, Y+14\nButton B: X+83, Y+90\nPrize: X=10148, Y=5500\n\nButton A: X+88, Y+25\nButton B: X+11, Y+38\nPrize: X=7799, Y=3506\n\nButton A: X+36, Y+95\nButton B: X+48, Y+21\nPrize: X=1824, Y=1749\n\nButton A: X+73, Y+19\nButton B: X+18, Y+78\nPrize: X=521, Y=18131\n\nButton A: X+11, Y+89\nButton B: X+93, Y+39\nPrize: X=3321, Y=9747\n\nButton A: X+46, Y+19\nButton B: X+27, Y+60\nPrize: X=2172, Y=17400\n\nButton A: X+90, Y+18\nButton B: X+23, Y+43\nPrize: X=4461, Y=3081\n\nButton A: X+34, Y+72\nButton B: X+91, Y+26\nPrize: X=2725, Y=3270\n\nButton A: X+25, Y+55\nButton B: X+73, Y+16\nPrize: X=1417, Y=2539\n\nButton A: X+16, Y+30\nButton B: X+30, Y+12\nPrize: X=9614, Y=2156\n\nButton A: X+48, Y+18\nButton B: X+11, Y+54\nPrize: X=15777, Y=14444\n\nButton A: X+20, Y+51\nButton B: X+97, Y+29\nPrize: X=5497, Y=5065\n\nButton A: X+69, Y+28\nButton B: X+13, Y+31\nPrize: X=18098, Y=2226\n\nButton A: X+73, Y+15\nButton B: X+16, Y+17\nPrize: X=3422, Y=1759\n\nButton A: X+32, Y+73\nButton B: X+59, Y+16\nPrize: X=6024, Y=5866\n\nButton A: X+18, Y+50\nButton B: X+62, Y+24\nPrize: X=1178, Y=6386\n\nButton A: X+48, Y+44\nButton B: X+24, Y+85\nPrize: X=2664, Y=4773\n\nButton A: X+27, Y+23\nButton B: X+14, Y+88\nPrize: X=2685, Y=4113\n\nButton A: X+18, Y+44\nButton B: X+67, Y+26\nPrize: X=13034, Y=14972\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_13_questions.txt",
    "content": "--- Day 13: Claw Contraption ---\n\nNext up: the lobby of a resort on a tropical island. The Historians take a moment to admire the hexagonal floor tiles before spreading out.\n\nFortunately, it looks like the resort has a new arcade! Maybe you can win some prizes from the claw machines?\n\nThe claw machines here are a little unusual. Instead of a joystick or directional buttons to control the claw, these machines have two buttons labeled A and B. Worse, you can't just put in a token and play; it costs 3 tokens to push the A button and 1 token to push the B button.\n\nWith a little experimentation, you figure out that each machine's buttons are configured to move the claw a specific amount to the right (along the X axis) and a specific amount forward (along the Y axis) each time that button is pressed.\n\nEach machine contains one prize; to win the prize, the claw must be positioned exactly above the prize on both the X and Y axes.\n\nYou wonder: what is the smallest number of tokens you would have to spend to win as many prizes as possible? You assemble a list of every machine's button behavior and prize location (your puzzle input). For example:\n\nButton A: X+94, Y+34\nButton B: X+22, Y+67\nPrize: X=8400, Y=5400\n\nButton A: X+26, Y+66\nButton B: X+67, Y+21\nPrize: X=12748, Y=12176\n\nButton A: X+17, Y+86\nButton B: X+84, Y+37\nPrize: X=7870, Y=6450\n\nButton A: X+69, Y+23\nButton B: X+27, Y+71\nPrize: X=18641, Y=10279\n\nThis list describes the button configuration and prize location of four different claw machines.\n\nFor now, consider just the first claw machine in the list:\n\n    Pushing the machine's A button would move the claw 94 units along the X axis and 34 units along the Y axis.\n    Pushing the B button would move the claw 22 units along the X axis and 67 units along the Y axis.\n    The prize is located at X=8400, Y=5400; this means that from the claw's initial position, it would need to move exactly 8400 units along the X axis and exactly 5400 units along the Y axis to be perfectly aligned with the prize in this machine.\n\nThe cheapest way to win the prize is by pushing the A button 80 times and the B button 40 times. This would line up the claw along the X axis (because 80*94 + 40*22 = 8400) and along the Y axis (because 80*34 + 40*67 = 5400). Doing this would cost 80*3 tokens for the A presses and 40*1 for the B presses, a total of 280 tokens.\n\nFor the second and fourth claw machines, there is no combination of A and B presses that will ever win a prize.\n\nFor the third claw machine, the cheapest way to win the prize is by pushing the A button 38 times and the B button 86 times. Doing this would cost a total of 200 tokens.\n\nSo, the most prizes you could possibly win is two; the minimum tokens you would have to spend to win all (two) prizes is 480.\n\nYou estimate that each button would need to be pressed no more than 100 times to win a prize. How else would someone be expected to play?\n\nFigure out how to win as many prizes as possible. What is the fewest tokens you would have to spend to win all possible prizes?\n\n--- Part Two ---\n\nAs you go to win the first prize, you discover that the claw is nowhere near where you expected it would be. Due to a unit conversion error in your measurements, the position of every prize is actually 10000000000000 higher on both the X and Y axis!\n\nAdd 10000000000000 to the X and Y position of every prize. After making this change, the example above would now look like this:\n\nButton A: X+94, Y+34\nButton B: X+22, Y+67\nPrize: X=10000000008400, Y=10000000005400\n\nButton A: X+26, Y+66\nButton B: X+67, Y+21\nPrize: X=10000000012748, Y=10000000012176\n\nButton A: X+17, Y+86\nButton B: X+84, Y+37\nPrize: X=10000000007870, Y=10000000006450\n\nButton A: X+69, Y+23\nButton B: X+27, Y+71\nPrize: X=10000000018641, Y=10000000010279\n\nNow, it is only possible to win a prize on the second and fourth claw machines. Unfortunately, it will take many more than 100 presses to do so.\n\nUsing the corrected prize coordinates, figure out how to win as many prizes as possible. What is the fewest tokens you would have to spend to win all possible prizes?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_14.adb",
    "content": "--  Solution to Advent of Code 2024, Day 14\n-------------------------------------------\n--  Restroom Redoubt\n--\n--  https://adventofcode.com/2024/day/14\n--  Copy of questions in: aoc_2024_14_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_14 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; nx : constant := 11; ny : constant := 7; nr : constant := 12;\n  input_name : constant VString := +\"aoc_2024_14\"; nx : constant := 101; ny : constant := 103; nr : constant := 500;\n\n  type Robot is record\n    p, v : Point;\n  end record;\n\n  type Robot_Array is array (1 .. nr) of Robot;\n\n  r0 : Robot_Array;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data is\n    sep1, sep2 : Character;\n    peq : String (1 .. 2);\n    veq : String (1 .. 3);\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in 1 .. nr loop\n      Get (f, peq);\n      Get (f, r0 (i).p.x);\n      Get (f, sep1);\n      Get (f, r0 (i).p.y);\n      Get (f, veq);\n      Get (f, r0 (i).v.x);\n      Get (f, sep2);\n      Get (f, r0 (i).v.y);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show (ro : Robot_Array) is\n    has_robot : Boolean;\n  begin\n    for y in 0 .. ny - 1 loop\n      for x in 0 .. nx - 1 loop\n        has_robot := False;\n        for i in 1 .. nr loop\n          if ro (i).p.x = x and then ro (i).p.y = y then\n            has_robot := True;\n          end if;\n        end loop;\n        if has_robot then\n          Put (\"*\");\n        else\n          Put (\" \");\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  procedure Evolve (ro : in out Robot_Array) is\n  begin\n    for i in 1 .. nr loop\n      ro (i).p.x := (ro (i).p.x + ro (i).v.x) mod nx;\n      ro (i).p.y := (ro (i).p.y + ro (i).v.y) mod ny;\n    end loop;\n  end Evolve;\n\n  function Safety_Factor (ro : in Robot_Array) return Natural is\n    q1, q2, q3, q4 : Natural := 0;\n  begin\n    for i in 1 .. nr loop\n      if    ro (i).p.x in 0 .. nx / 2 - 1 and then ro (i).p.y in 0 .. ny / 2 - 1 then\n        q1 := q1 + 1;\n      elsif ro (i).p.x in nx / 2 + 1 .. nx and then ro (i).p.y in 0 .. ny / 2 - 1 then\n        q2 := q2 + 1;\n      elsif ro (i).p.x in 0 .. nx / 2 - 1 and then ro (i).p.y in ny / 2 + 1 .. ny then\n        q3 := q3 + 1;\n      elsif ro (i).p.x in nx / 2 + 1 .. nx and then ro (i).p.y in ny / 2 + 1 .. ny then\n        q4 := q4 + 1;\n      end if;\n    end loop;\n    return q1 * q2 * q3 * q4;\n  end Safety_Factor;\n\n  procedure Do_Part_1 is\n    ro : Robot_Array := r0;\n  begin\n    for t in 1 .. 100 loop\n      Evolve (ro);\n    end loop;\n    r (part_1) := Safety_Factor (ro);\n  end Do_Part_1;\n\n  --  The threshold is determined heuristically.\n  --  A perfectly uniform setup has 125 robots in\n  --  each quadrant (safety factor 125**4 = 244,140,625).\n  --  If all robots are in a single quadrant, the factor is 0.\n  --  If 497 robots are in a quadrant and the other quadrants\n  --  contain a robot each, the factor is 497.\n  --\n  procedure Do_Part_2 is\n    ro : Robot_Array := r0;\n  begin\n    for t in 1 .. nx * ny + 1 loop\n      Evolve (ro);\n      if Safety_Factor (ro) < 40_000_000 then\n        r (part_2) := t;\n        Show (ro);\n        exit;\n      end if;\n    end loop;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  if not compiler_test_mode then\n    Do_Part_2;\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 226236192\n    --  Part 2: validated by AoC: 8168\n  end if;\nend AoC_2024_14;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_14.txt",
    "content": "p=50,78 v=89,45\np=65,96 v=88,-21\np=23,63 v=61,46\np=61,76 v=25,-67\np=23,90 v=6,91\np=1,47 v=-17,-9\np=84,56 v=-73,-24\np=78,66 v=-20,-76\np=49,59 v=-22,17\np=73,95 v=34,-64\np=99,76 v=67,-40\np=59,77 v=-49,-4\np=15,30 v=24,65\np=89,2 v=-19,-38\np=28,70 v=93,66\np=39,33 v=24,-42\np=14,42 v=-33,-49\np=68,85 v=-37,-47\np=91,0 v=-45,12\np=88,92 v=78,-24\np=19,63 v=-70,-10\np=69,4 v=-40,90\np=61,91 v=64,-11\np=47,95 v=-77,46\np=20,10 v=-23,-63\np=98,82 v=90,96\np=90,30 v=4,74\np=0,28 v=-73,8\np=88,102 v=51,-51\np=66,29 v=26,1\np=19,20 v=-61,-15\np=13,18 v=6,71\np=12,39 v=67,24\np=41,67 v=-24,-23\np=78,10 v=-59,-68\np=30,2 v=-35,85\np=86,47 v=-95,53\np=44,36 v=-69,-89\np=19,20 v=-87,-95\np=65,3 v=73,16\np=95,29 v=43,61\np=66,50 v=49,-69\np=28,92 v=-25,19\np=74,60 v=-6,-98\np=15,80 v=92,-27\np=80,12 v=18,-62\np=72,34 v=19,-65\np=46,75 v=33,-74\np=14,100 v=-79,99\np=94,97 v=74,49\np=46,13 v=-45,-61\np=93,39 v=-9,-64\np=100,45 v=45,-76\np=62,19 v=-76,85\np=18,85 v=30,-71\np=24,68 v=84,-73\np=31,20 v=-86,-35\np=76,46 v=-59,77\np=27,52 v=-95,77\np=52,81 v=1,59\np=43,60 v=-71,-38\np=59,38 v=-6,24\np=70,65 v=26,-23\np=11,40 v=60,-33\np=26,77 v=62,43\np=24,93 v=99,-51\np=46,84 v=24,76\np=48,30 v=58,-87\np=46,100 v=21,98\np=24,39 v=-23,84\np=25,6 v=47,-78\np=89,73 v=-73,23\np=4,49 v=-96,14\np=69,61 v=52,-10\np=96,68 v=-96,99\np=17,12 v=-30,75\np=91,47 v=-98,-87\np=50,38 v=71,67\np=68,58 v=-13,17\np=39,30 v=84,93\np=93,19 v=-66,98\np=31,7 v=-8,75\np=7,81 v=-95,-4\np=38,43 v=8,-89\np=24,21 v=-98,3\np=72,43 v=25,-13\np=4,98 v=-71,78\np=79,65 v=-91,-57\np=49,47 v=-97,23\np=37,7 v=-15,45\np=41,74 v=-15,36\np=58,30 v=-92,71\np=72,92 v=68,-7\np=1,79 v=-4,-75\np=82,99 v=42,6\np=62,51 v=57,63\np=10,43 v=48,-74\np=74,70 v=65,-40\np=25,35 v=-1,-39\np=50,71 v=37,68\np=51,84 v=67,55\np=71,25 v=-45,-98\np=47,14 v=-7,28\np=70,99 v=69,46\np=21,44 v=-94,-16\np=52,40 v=-83,-49\np=76,99 v=-71,63\np=21,92 v=-32,-34\np=78,27 v=-85,-55\np=42,92 v=-76,-61\np=50,29 v=95,77\np=72,10 v=65,58\np=92,48 v=20,-1\np=42,80 v=55,-98\np=69,96 v=41,62\np=68,35 v=-91,-45\np=18,56 v=-33,37\np=52,96 v=1,49\np=22,87 v=53,99\np=84,31 v=19,41\np=87,38 v=58,-13\np=9,13 v=-18,98\np=40,0 v=-94,-31\np=71,16 v=-62,76\np=41,88 v=-46,99\np=27,97 v=-15,-4\np=25,54 v=23,-36\np=61,0 v=-60,-21\np=28,75 v=41,-79\np=64,46 v=-8,34\np=97,26 v=37,74\np=32,67 v=-48,-93\np=18,81 v=53,-2\np=12,101 v=30,-1\np=80,40 v=-90,-16\np=48,16 v=-69,61\np=7,89 v=52,49\np=93,0 v=-35,-61\np=24,52 v=31,53\np=37,67 v=-98,36\np=92,77 v=28,46\np=76,59 v=-74,-21\np=96,63 v=58,57\np=62,2 v=-68,-68\np=39,20 v=-39,-25\np=5,12 v=60,88\np=75,35 v=-37,88\np=77,24 v=-52,-13\np=42,0 v=92,-72\np=33,61 v=-91,-6\np=10,74 v=23,-17\np=6,73 v=37,-54\np=76,99 v=2,-71\np=53,20 v=71,91\np=82,31 v=71,-82\np=20,87 v=-40,26\np=52,47 v=-45,-69\np=32,38 v=43,-55\np=8,85 v=-56,-77\np=11,0 v=68,2\np=40,30 v=-46,-72\np=26,53 v=27,-43\np=5,40 v=98,-90\np=46,4 v=39,-85\np=15,36 v=-95,87\np=0,4 v=-49,42\np=69,11 v=-86,-87\np=47,47 v=86,-17\np=95,88 v=-73,26\np=2,5 v=53,52\np=92,84 v=63,79\np=25,0 v=47,-35\np=83,55 v=-43,-46\np=95,43 v=-3,40\np=30,60 v=-79,-27\np=89,79 v=-39,-80\np=10,19 v=6,-95\np=70,64 v=87,10\np=51,93 v=79,-31\np=30,82 v=85,16\np=66,75 v=-51,40\np=79,70 v=-20,-20\np=59,60 v=25,63\np=86,17 v=75,-62\np=3,62 v=-18,-47\np=43,20 v=24,91\np=23,13 v=56,93\np=32,13 v=71,76\np=12,10 v=53,-28\np=20,86 v=-71,-74\np=91,90 v=-97,-75\np=76,66 v=-67,83\np=54,54 v=-84,64\np=66,70 v=-12,36\np=30,73 v=54,43\np=62,22 v=-21,31\np=11,92 v=-94,76\np=47,101 v=93,-25\np=37,21 v=96,19\np=93,51 v=20,97\np=46,31 v=-54,61\np=26,99 v=-64,-11\np=6,91 v=-55,-90\np=95,7 v=95,33\np=1,89 v=5,19\np=69,24 v=-83,81\np=82,37 v=-66,-92\np=20,66 v=-80,-77\np=45,87 v=-47,-11\np=19,77 v=8,1\np=61,12 v=-70,79\np=59,48 v=14,44\np=68,70 v=48,-37\np=77,94 v=42,-84\np=47,31 v=1,-32\np=22,1 v=-40,95\np=41,98 v=-53,16\np=38,49 v=48,77\np=21,98 v=-71,12\np=67,92 v=-13,69\np=99,99 v=-80,-84\np=50,18 v=-77,-45\np=71,35 v=-36,-22\np=61,65 v=-68,10\np=96,25 v=56,-21\np=77,65 v=-20,-40\np=56,81 v=56,29\np=81,19 v=-97,-15\np=31,12 v=-62,-38\np=92,83 v=51,-4\np=70,23 v=-44,45\np=55,61 v=-27,-33\np=9,48 v=99,40\np=20,36 v=-80,-52\np=83,46 v=-35,-59\np=52,43 v=58,-88\np=2,88 v=-49,-34\np=31,99 v=54,59\np=76,21 v=11,31\np=5,51 v=-27,35\np=57,88 v=2,19\np=86,41 v=-51,60\np=82,58 v=-98,-96\np=100,70 v=-38,-85\np=81,47 v=-10,-30\np=96,88 v=82,6\np=24,28 v=62,98\np=44,71 v=-69,-50\np=75,11 v=-99,-52\np=35,80 v=16,-37\np=2,21 v=-27,84\np=80,14 v=-43,98\np=49,76 v=80,21\np=84,96 v=-82,67\np=32,79 v=-95,74\np=35,81 v=-90,-68\np=47,45 v=-22,-6\np=69,45 v=41,-83\np=63,21 v=1,-92\np=57,1 v=-98,4\np=34,4 v=-93,-81\np=46,63 v=-99,47\np=8,99 v=5,29\np=32,27 v=54,-42\np=27,98 v=17,-98\np=63,22 v=81,98\np=75,36 v=-86,66\np=58,5 v=-67,-58\np=82,20 v=81,-57\np=82,67 v=81,83\np=58,58 v=17,-13\np=18,89 v=14,-21\np=76,63 v=24,65\np=38,48 v=-85,-99\np=17,34 v=45,21\np=77,70 v=3,-50\np=56,82 v=17,76\np=64,97 v=94,-71\np=16,40 v=37,84\np=29,96 v=-61,-7\np=12,79 v=-95,-34\np=1,72 v=63,38\np=0,20 v=60,68\np=43,60 v=-6,40\np=20,22 v=-17,58\np=47,49 v=-70,94\np=12,29 v=-25,-32\np=22,69 v=-44,-22\np=44,78 v=31,33\np=86,50 v=76,-19\np=0,92 v=35,16\np=42,8 v=-39,87\np=30,1 v=14,61\np=41,57 v=18,-84\np=83,82 v=-97,36\np=72,7 v=-78,62\np=17,4 v=-95,12\np=15,15 v=60,73\np=80,79 v=-59,56\np=49,76 v=-22,-47\np=58,82 v=26,62\np=59,101 v=-82,96\np=78,56 v=-97,-56\np=19,62 v=85,-44\np=21,4 v=61,-91\np=80,66 v=-12,-27\np=66,17 v=96,28\np=57,6 v=-45,-38\np=24,70 v=61,-90\np=4,12 v=68,-58\np=27,37 v=15,-59\np=10,66 v=-33,-50\np=22,64 v=95,-38\np=47,44 v=24,-39\np=96,28 v=75,71\np=95,20 v=32,30\np=38,52 v=-89,10\np=88,94 v=96,-6\np=93,31 v=-38,18\np=61,79 v=46,-3\np=22,27 v=-33,5\np=77,62 v=81,-60\np=63,13 v=-94,81\np=39,49 v=93,89\np=7,37 v=-2,-89\np=59,2 v=24,-58\np=82,32 v=-4,-45\np=28,55 v=-70,-13\np=36,49 v=-93,90\np=16,74 v=53,-20\np=56,69 v=-84,93\np=40,25 v=-93,-89\np=73,60 v=-75,90\np=28,82 v=-47,-27\np=35,67 v=-8,-73\np=76,17 v=68,63\np=33,43 v=1,37\np=5,7 v=-52,-34\np=79,49 v=89,60\np=78,59 v=20,57\np=96,31 v=-93,-50\np=24,88 v=78,-24\np=12,39 v=37,-16\np=60,15 v=-21,45\np=25,17 v=-40,-45\np=9,63 v=-42,13\np=46,48 v=8,1\np=16,85 v=18,48\np=36,45 v=-41,95\np=62,88 v=54,6\np=46,57 v=-99,23\np=57,67 v=79,-40\np=88,96 v=4,-51\np=82,19 v=66,-2\np=9,73 v=68,-54\np=66,38 v=9,74\np=40,68 v=-15,83\np=97,24 v=-64,-55\np=52,56 v=-61,7\np=55,15 v=-53,91\np=98,66 v=78,-47\np=27,46 v=-47,4\np=100,19 v=36,-78\np=5,9 v=6,82\np=63,35 v=49,21\np=40,101 v=8,-14\np=98,19 v=-74,-28\np=74,15 v=96,-65\np=53,47 v=-84,34\np=48,14 v=94,-98\np=69,2 v=3,-71\np=38,10 v=78,35\np=74,76 v=-90,-60\np=37,68 v=55,-70\np=52,78 v=-31,48\np=6,24 v=-73,24\np=77,51 v=38,94\np=73,45 v=-42,-72\np=52,57 v=67,-51\np=12,14 v=46,39\np=6,11 v=65,21\np=29,37 v=-54,-95\np=41,24 v=-85,68\np=78,102 v=96,-24\np=13,25 v=-16,66\np=8,53 v=6,90\np=77,6 v=26,-71\np=98,45 v=-95,84\np=56,15 v=-27,-83\np=82,98 v=-35,52\np=24,42 v=-8,-29\np=16,46 v=-78,-53\np=25,15 v=-34,-54\np=27,42 v=-11,-13\np=12,69 v=46,3\np=74,20 v=43,-9\np=25,85 v=9,-93\np=65,99 v=26,-1\np=90,78 v=74,36\np=41,6 v=77,-88\np=85,62 v=-43,93\np=34,61 v=33,2\np=0,65 v=75,53\np=40,30 v=48,-36\np=31,1 v=47,48\np=24,100 v=85,99\np=97,24 v=-76,-67\np=69,59 v=21,28\np=82,72 v=7,96\np=9,10 v=68,25\np=26,91 v=85,49\np=35,86 v=39,-24\np=38,35 v=48,-99\np=99,61 v=35,-61\np=79,86 v=-98,99\np=94,40 v=50,-22\np=47,101 v=16,72\np=53,61 v=41,-3\np=27,101 v=-48,89\np=28,82 v=15,29\np=83,58 v=58,-10\np=40,38 v=-14,-82\np=52,78 v=79,16\np=45,15 v=-47,78\np=72,0 v=81,64\np=72,51 v=-95,-32\np=88,67 v=34,70\np=89,72 v=12,-90\np=61,31 v=25,-92\np=68,53 v=48,70\np=47,53 v=94,10\np=15,53 v=-72,27\np=80,8 v=20,-37\np=28,66 v=-16,-17\np=77,17 v=99,-11\np=46,10 v=-9,-66\np=76,71 v=78,-78\np=26,62 v=-85,56\np=87,9 v=-80,-71\np=67,36 v=-67,18\np=99,32 v=-80,61\np=69,87 v=73,89\np=6,100 v=-72,-48\np=40,38 v=-93,-92\np=89,12 v=81,-92\np=85,97 v=-19,-88\np=22,100 v=37,-4\np=11,45 v=-33,34\np=43,32 v=6,79\np=47,102 v=-84,52\np=89,94 v=-84,65\np=75,14 v=-3,-11\np=11,65 v=2,46\np=76,59 v=65,35\np=65,60 v=-75,40\np=92,36 v=-32,-9\np=69,16 v=11,15\np=62,63 v=32,80\np=47,50 v=-30,60\np=13,98 v=-80,-98\np=32,82 v=23,-74\np=28,6 v=-92,35\np=72,89 v=4,3\np=72,57 v=-3,80\np=6,44 v=89,-1\np=33,19 v=31,-78\np=43,101 v=-39,78\np=46,51 v=-30,-63\np=24,37 v=-79,-82\np=51,46 v=64,44\np=0,36 v=13,-99\np=71,6 v=72,9\np=40,98 v=78,-81\np=36,33 v=96,-14\np=63,100 v=95,12\np=12,42 v=-41,87\np=66,48 v=-52,77\np=5,77 v=36,23\np=94,54 v=80,24\np=77,71 v=-50,1\np=81,20 v=89,-85\np=9,13 v=-95,42\np=13,78 v=71,20\np=36,43 v=-21,88\np=56,94 v=87,69\np=91,53 v=21,57\np=80,84 v=-74,-44\np=19,90 v=-87,96\np=13,83 v=-63,-51\np=14,91 v=5,56\np=23,1 v=-72,-15\np=50,44 v=71,-73\np=6,49 v=45,67\np=4,0 v=-9,-91\np=70,8 v=-98,45\np=30,42 v=-78,61\np=87,74 v=-97,26\np=35,89 v=92,-32\np=23,61 v=94,41\np=87,21 v=-82,28\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_14_questions.txt",
    "content": "--- Day 14: Restroom Redoubt ---\n\nOne of The Historians needs to use the bathroom; fortunately, you know there's a bathroom near an unvisited location on their list, and so you're all quickly teleported directly to the lobby of Easter Bunny Headquarters.\n\nUnfortunately, EBHQ seems to have \"improved\" bathroom security again after your last visit. The area outside the bathroom is swarming with robots!\n\nTo get The Historian safely to the bathroom, you'll need a way to predict where the robots will be in the future. Fortunately, they all seem to be moving on the tile floor in predictable straight lines.\n\nYou make a list (your puzzle input) of all of the robots' current positions (p) and velocities (v), one robot per line. For example:\n\np=0,4 v=3,-3\np=6,3 v=-1,-3\np=10,3 v=-1,2\np=2,0 v=2,-1\np=0,0 v=1,3\np=3,0 v=-2,-2\np=7,6 v=-1,-3\np=3,0 v=-1,-2\np=9,3 v=2,3\np=7,3 v=-1,2\np=2,4 v=2,-3\np=9,5 v=-3,-3\n\nEach robot's position is given as p=x,y where x represents the number of tiles the robot is from the left wall and y represents the number of tiles from the top wall (when viewed from above). So, a position of p=0,0 means the robot is all the way in the top-left corner.\n\nEach robot's velocity is given as v=x,y where x and y are given in tiles per second. Positive x means the robot is moving to the right, and positive y means the robot is moving down. So, a velocity of v=1,-2 means that each second, the robot moves 1 tile to the right and 2 tiles up.\n\nThe robots outside the actual bathroom are in a space which is 101 tiles wide and 103 tiles tall (when viewed from above). However, in this example, the robots are in a space which is only 11 tiles wide and 7 tiles tall.\n\nThe robots are good at navigating over/under each other (due to a combination of springs, extendable legs, and quadcopters), so they can share the same tile and don't interact with each other. Visually, the number of robots on each tile in this example looks like this:\n\n1.12.......\n...........\n...........\n......11.11\n1.1........\n.........1.\n.......1...\n\nThese robots have a unique feature for maximum bathroom security: they can teleport. When a robot would run into an edge of the space they're in, they instead teleport to the other side, effectively wrapping around the edges. Here is what robot p=2,4 v=2,-3 does for the first few seconds:\n\nInitial state:\n...........\n...........\n...........\n...........\n..1........\n...........\n...........\n\nAfter 1 second:\n...........\n....1......\n...........\n...........\n...........\n...........\n...........\n\nAfter 2 seconds:\n...........\n...........\n...........\n...........\n...........\n......1....\n...........\n\nAfter 3 seconds:\n...........\n...........\n........1..\n...........\n...........\n...........\n...........\n\nAfter 4 seconds:\n...........\n...........\n...........\n...........\n...........\n...........\n..........1\n\nAfter 5 seconds:\n...........\n...........\n...........\n.1.........\n...........\n...........\n...........\n\nThe Historian can't wait much longer, so you don't have to simulate the robots for very long. Where will the robots be after 100 seconds?\n\nIn the above example, the number of robots on each tile after 100 seconds has elapsed looks like this:\n\n......2..1.\n...........\n1..........\n.11........\n.....1.....\n...12......\n.1....1....\n\nTo determine the safest area, count the number of robots in each quadrant after 100 seconds. Robots that are exactly in the middle (horizontally or vertically) don't count as being in any quadrant, so the only relevant robots are:\n\n..... 2..1.\n..... .....\n1.... .....\n           \n..... .....\n...12 .....\n.1... 1....\n\nIn this example, the quadrants contain 1, 3, 4, and 1 robot. Multiplying these together gives a total safety factor of 12.\n\nPredict the motion of the robots in your list within a space which is 101 tiles wide and 103 tiles tall. What will the safety factor be after exactly 100 seconds have elapsed?\n\n--- Part Two ---\n\nDuring the bathroom break, someone notices that these robots seem awfully similar to ones built and used at the North Pole. If they're the same type of robots, they should have a hard-coded Easter egg: very rarely, most of the robots should arrange themselves into a picture of a Christmas tree.\n\nWhat is the fewest number of seconds that must elapse for the robots to display the Easter egg?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_15.adb",
    "content": "--  Solution to Advent of Code 2024, Day 15\n-------------------------------------------\n--  Warehouse Woes\n--\n--  https://adventofcode.com/2024/day/15\n--  Copy of questions in: aoc_2024_15_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_15 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"micro\"; n : constant := 6; nx : constant := 12; nm : constant := 1;\n  --  input_name : constant VString := +\"mini0\"; n : constant := 7; nx : constant := 14; nm : constant := 11;\n  --  input_name : constant VString := +\"mini1\"; n : constant := 8; nx : constant := 16; nm : constant := 15;\n  --  input_name : constant VString := +\"mini2\"; n : constant := 10; nx : constant := 20; nm : constant := 700;\n  input_name : constant VString := +\"aoc_2024_15\"; n : constant := 50; nx : constant := 100; nm : constant := 20_000;\n\n  map  : array (1 .. n, 1 .. n) of Character;\n  mapx : array (1 .. nx, 1 .. n) of Character;\n  move : array (1 .. nm) of Direction;\n  p0, p : Point;\n\n  r : array (Part_Type) of Integer;\n\n  procedure Read_Data is\n    new_tile : String (1 .. 2);\n    c : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        if c = '@' then\n          p0.x := x;\n          p0.y := y;\n          c := '.';\n        end if;\n        map (x, y) := c;\n        case c is\n          when '#' => new_tile := \"##\";\n          when 'O' => new_tile := \"[]\";\n          when '.' => new_tile := \"..\";\n          when others => null;\n        end case;\n        mapx ((x - 1) * 2 + 1, y) := new_tile (1);\n        mapx ((x - 1) * 2 + 2, y) := new_tile (2);\n      end loop;\n    end loop;\n    Skip_Line (f);\n    for i in 1 .. nm loop\n      Get (f, c);\n      case c is\n        when '^' => move (i) := north;\n        when 'v' => move (i) := south;\n        when '>' => move (i) := east;\n        when '<' => move (i) := west;\n        when others => null;\n      end case;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show_Map is\n  begin\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        if x = p.x and then y = p.y then\n          Put ('@');\n        else\n          Put (map (x, y));\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n    New_Line;\n  end Show_Map;\n\n  verbose : constant Boolean := False;\n\n  procedure Do_Part_1 is\n  begin\n    p := p0;\n\n    for m in 1 .. nm loop\n      case move (m) is\n        when north =>\n          case map (p.x, p.y + 1) is\n            when '.' =>\n              p.y := p.y + 1;\n            when 'O' =>\n              for y in p.y + 2 .. n loop\n                exit when map (p.x, y) = '#';\n                if map (p.x, y) = '.' then\n                  --  Push boxes North:\n                  for my in reverse p.y + 2 .. y loop\n                    map (p.x, my) := map (p.x, my - 1);\n                  end loop;\n                  map (p.x, p.y + 1) := '.';\n                  p.y := p.y + 1;\n                  exit;\n                end if;\n              end loop;\n            when others => null;\n          end case;\n\n        when south =>\n          case map (p.x, p.y - 1) is\n            when '.' =>\n              p.y := p.y - 1;\n            when 'O' =>\n              for y in reverse 1 .. p.y - 2 loop\n                exit when map (p.x, y) = '#';\n                if map (p.x, y) = '.' then\n                  --  Push boxes South:\n                  for my in y .. p.y - 2 loop\n                    map (p.x, my) := map (p.x, my + 1);\n                  end loop;\n                  map (p.x, p.y - 1) := '.';\n                  p.y := p.y - 1;\n                  exit;\n                end if;\n              end loop;\n            when others => null;\n          end case;\n\n        when east =>\n          case map (p.x + 1, p.y) is\n            when '.' =>\n              p.x := p.x + 1;\n            when 'O' =>\n              for x in p.x + 2 .. n loop\n                exit when map (x, p.y) = '#';\n                if map (x, p.y) = '.' then\n                  --  Push boxes East:\n                  for mx in reverse p.x + 2 .. x loop\n                    map (mx, p.y) := map (mx - 1, p.y);\n                  end loop;\n                  map (p.x + 1, p.y) := '.';\n                  p.x := p.x + 1;\n                  exit;\n                end if;\n              end loop;\n            when others => null;\n          end case;\n\n        when west =>\n          case map (p.x - 1, p.y) is\n            when '.' =>\n              p.x := p.x - 1;\n            when 'O' =>\n              for x in reverse 1 .. p.x - 2 loop\n                exit when map (x, p.y) = '#';\n                if map (x, p.y) = '.' then\n                  --  Push boxes West:\n                  for mx in x .. p.x - 2 loop\n                    map (mx, p.y) := map (mx + 1, p.y);\n                  end loop;\n                  map (p.x - 1, p.y) := '.';\n                  p.x := p.x - 1;\n                  exit;\n                end if;\n              end loop;\n            when others => null;\n          end case;\n      end case;\n    end loop;\n\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        if map (x, y) = 'O' then\n          r (part_1) := r (part_1) + 100 * (n - y) + (x - 1);\n        end if;\n      end loop;\n    end loop;\n\n    if verbose then\n      Show_Map;\n    end if;\n\n  end Do_Part_1;\n\n  procedure Show_Map_X is\n  begin\n    for y in reverse 1 .. n loop\n      for x in 1 .. nx loop\n        if x = p.x and then y = p.y then\n          Put ('@');\n        else\n          Put (mapx (x, y));\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n    New_Line;\n  end Show_Map_X;\n\n  procedure Do_Part_2 is\n\n    function Can_Move_Box (bx, by, dy : Integer) return Boolean is\n      ok : Boolean := True;\n    begin\n      for dx in 0 .. 1 loop\n        case mapx (bx + dx, by + dy) is\n          when '#' => return False;\n          when '[' => ok := ok and then Can_Move_Box (bx + dx,     by + dy, dy); exit when dx = 0;\n          when ']' => ok := ok and then Can_Move_Box (bx + dx - 1, by + dy, dy);\n          when others => null;\n        end case;\n      end loop;\n      return ok;\n    end Can_Move_Box;\n\n    procedure Move_Box (bx, by, dy : Integer) is\n    begin\n      if Can_Move_Box (bx, by, dy) then\n        for dx in 0 .. 1 loop\n          case mapx (bx + dx, by + dy) is\n            when '#' => return;\n            when '[' => Move_Box (bx + dx,     by + dy, dy); exit when dx = 0;\n            when ']' => Move_Box (bx + dx - 1, by + dy, dy);\n            when others => null;\n          end case;\n        end loop;\n        if mapx (bx, by + dy) = '.' and then mapx (bx + 1, by + dy) = '.' then\n          mapx (bx,     by + dy) := '[';\n          mapx (bx + 1, by + dy) := ']';\n          mapx (bx,     by) := '.';\n          mapx (bx + 1, by) := '.';\n        end if;\n      end if;\n    end Move_Box;\n\n  begin\n    p.x := (p0.x - 1) * 2 + 1;\n    p.y := p0.y;\n\n    if verbose then\n      Show_Map_X;\n    end if;\n\n    for m in 1 .. nm loop\n      if verbose then\n        Put_Line (Direction'Image (move (m)));\n      end if;\n\n      case move (m) is\n        when north =>\n          case mapx (p.x, p.y + 1) is\n            when '['    => Move_Box (p.x,     p.y + 1, 1);\n            when ']'    => Move_Box (p.x - 1, p.y + 1, 1);\n            when others => null;\n          end case;\n          if mapx (p.x, p.y + 1) = '.' then\n            p.y := p.y + 1;\n          end if;\n\n        when south =>\n          case mapx (p.x, p.y - 1) is\n            when '['    => Move_Box (p.x,     p.y - 1, -1);\n            when ']'    => Move_Box (p.x - 1, p.y - 1, -1);\n            when others => null;\n          end case;\n          if mapx (p.x, p.y - 1) = '.' then\n            p.y := p.y - 1;\n          end if;\n\n        --  On East-West it is just like Part 1\n\n        when east =>\n          case mapx (p.x + 1, p.y) is\n            when '.' =>\n              p.x := p.x + 1;\n            when '[' =>\n              for x in p.x + 2 .. nx loop\n                exit when mapx (x, p.y) = '#';\n                if mapx (x, p.y) = '.' then\n                  for mx in reverse p.x + 2 .. x loop\n                    mapx (mx, p.y) := mapx (mx - 1, p.y);\n                  end loop;\n                  mapx (p.x + 1, p.y) := '.';\n                  p.x := p.x + 1;\n                  exit;\n                end if;\n              end loop;\n            when others => null;\n          end case;\n\n        when west =>\n          case mapx (p.x - 1, p.y) is\n            when '.' =>\n              p.x := p.x - 1;\n            when ']' =>\n              for x in reverse 1 .. p.x - 2 loop\n                exit when mapx (x, p.y) = '#';\n                if mapx (x, p.y) = '.' then\n                  for mx in x .. p.x - 2 loop\n                    mapx (mx, p.y) := mapx (mx + 1, p.y);\n                  end loop;\n                  mapx (p.x - 1, p.y) := '.';\n                  p.x := p.x - 1;\n                  exit;\n                end if;\n              end loop;\n            when others => null;\n          end case;\n      end case;\n\n      if verbose then\n        Show_Map_X;\n      end if;\n\n    end loop;\n\n    for y in 1 .. n loop\n      for x in 1 .. nx loop\n        if mapx (x, y) = '[' then\n          r (part_2) := r (part_2) + 100 * (n - y) + (x - 1);\n        end if;\n      end loop;\n    end loop;\n\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  r (part_1) := 0;\n  r (part_2) := 0;\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) or\n       r (part_2) /= Integer_Value (Argument (2))\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1515788\n    --  Part 2: validated by AoC: 1516544\n  end if;\nend AoC_2024_15;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_15.txt",
    "content": "##################################################\n#.O#..O#.....##.O.O.OO#..OO..OO.......O....O.O.O.#\n#.....O.#.....O.#..OO#....O#O..#OO#.#..#OO......O#\n#.....OO...#..O.O.........OOO#..O...#O...O.O...OO#\n#..OO....O.#...O.O...O....OO............O.OO..O..#\n#OO.OO...O#.OO....#....O.OO........OO.....#..O.#.#\n#OOO...#....OOO...OOO...O.O.....O..O...O..O.O.#..#\n#......O.#O.....#OO............OOO...OO....O.O...#\n##....O...#.OO.##.O..O..#.#...#.O..#.....O..#....#\n#.O..#.#...O#..OO.OO.O..O..O.O.O...O#..OOOO......#\n#.............O.O...O..OO..#...O.O..O..O....O....#\n#.O#O.OO..O....O......OO.............O....O..O.#.#\n#....O....O.O..........O.##..O.OOO...##O.O.O.O.OO#\n##...O...#......#.#..O..O..OO#O...#...OO..#OO.O.O#\n#.OO..OO.#.##.OO....O.O.#.OO...O.O.......O.#..OOO#\n#.O#OO#.O.O..OO.....O....OO.#O..O.#.....O..#.O...#\n#.OO........O.......O.O...O...O.O#......O.O..O...#\n#....O...O.OO..#...#.O.#..#..O.OOOOO.....O.#.O.#O#\n#.O...#O..#.#.#OO.O...O.##O.O......O.###.O.#O#...#\n#.#O...........O.........O...OO.OO#..O......O.OOO#\n##.....#O..#....O.O...#O.#.O..OOO#......O.O......#\n#O.OO...O..O#....O#O.O....#....O.#.O....O..#.....#\n#........#.#....O.O.OOO......OO.#....#.....O...OO#\n#O...#.#O..O.OO..O...O.#..OOO.OO....#...O.....#..#\n#..O.....OO#O.O....#O..#@...#...#.O....OO....#.#.#\n#O.O.#......#O....OO.OO.OO.#..OO.#OO.........O...#\n#OOOO.##...#..#OO..O...O..O#O....#.OOO...##....O.#\n#.O............O...OO.#........OOO.....O.O..#..OO#\n#......O..OO.....OO.O.O...O....O.O.O.#........#..#\n#............O#.O.O....O.O.O.#OO.O.#....OOO.....O#\n#.O.#..........OOO...O..OOO...#.....O.........O..#\n##OOO.O....#OOO.O...O....O..O...O.O#O.OO.O......##\n#OOO##.......OO...#.........OO..O....O..#......O.#\n#OOO....O.....O.#.O..O.#.......O....O.O..O.O.....#\n#.....O....O.OO....OO.OO..O.OOOO..#..O.O..O.O.O.O#\n#O..OOO#....#.#..OO.O.#..O#OOO.O...O.............#\n#OO......OOO..OO..O.O...##...#..#O..O....O.......#\n#...#..O.#O#.O..O....OO.O.....O#.O.....O..O..O..##\n#O....O..O.OO#.....O#O.#......OOOOOO.O.#OO...#O..#\n#OOO...#O.....OO#O..OOO#...#.........O....O..O...#\n#O.#.O.OOOO....O#O...O.....##.OO....O...O..O#.O..#\n#.OO.OO.......O..O.O.......OO.#OO..#OO..O.O..O.O.#\n##O..............O..#O.....OO.......#O.#.#.O#....#\n##...OO..#.O.......O..#.O...#..OO.O..O...#...O.O.#\n#..OO#....O.....O..O..O#...#.....O#...O...O..O.#.#\n#..O#..OOO.O.O.....OO....O#O...O.O#....OO........#\n#..#..O.O.....#...O#.O........O..O.OO.#O#..OO.O..#\n#...........O..O....OO..O.......O..O#....O...OO.O#\n#.O.O.O...OO......OO....O..OO.....OO#.O.O...OO.OO#\n##################################################\n\n>>v>>^<><<><vv<<v><^v>v^<<>vv<<^<<>v<^<<>><<v>>^><>v<v>>>^^vvv^^<v<<^<^<^<^^>^^>^<^v^<>vv><<>v^<^<v^<v<^vv^^<v^<<v^vv<^>v<^<><v>^<v^v^<>>>><>^<v^<<><>>^v>v>>>vv>v^^^>vvv><^^>^v<v<^<v>vv^^v<^>^v<<v>^>><^<<vv<^>><v<>v>><<<^>>v>^^>>vv><<^>^v^^^<>vvv^<^^>^^>v^vvvv>^>vv>v<vv<v^<^^>>^v>^^<v<^><>>v>>>^>^v>^^^v>vv^v^><^^^>>v<^<>v<^^<<>>v>v>^<<>>v^><<vv<<<^^<>^vvv<^<^>>>^><v>>>>^>><<v>^v<>^>^<^<^><<<>v<<>vv^^v>v><>vv<><^^^vvv>^<>vvv>v^^vv^^<^>v>><<<^<^><^><<^>v<^>><>vv<<v<^^><><>^<<v<^^^v<^v>^>><^^^<<^^<^>^^><^vv>vvvvv<^v>>^vv>vv>^vvv^^v><<<>^vv><>^^<^v<v^^v<^<^>^>>>><v<>v><v<><>vv^<^^v^^vv<<>><>^<v^v<>v^^<^><>^>^^vvvv>>^^>^<<v^v<<>v<v<v><<v>v<>v<<<^<^<>>vv<<<^v<>vv>v><v<^vv^><^><^^^^<<>vv>v^^^>>^>>v>v^v^<>>^<>v<^^v>^^vv^>v^v^<>>>>vv>><<^>^<vv>^^^v<^v>v^v><^>vv<>>><v^>><>>vv<^^<<><^v<<^<v<^<>^>^>^>^v<<^v>v<<><><v<><>v<><<><>^v>^v<><<^v>>^^<^^v^^vv>v>^>v>>v<^vv<>>><^><^^>v>><><>^>^<<v<vv^vv<<vv^^vvv^><v^>vv<<v><><>vvvv>^vv>><>^^v<><>>^v<vv<v<>v^>v><v><<v>>>>>><<>>v<<>vvv^^v>v^>v<>>>><^v>v^><><<<\n>v^^^><^<><>^>><>v<>vvv>v>>>v<><vv>>vv>>^v>>v>^<^^v>>>^v^<><^<^<<>^<<v^<^^>>><v<<>vv<^v>v<><^v>^vv>vv>^>>>v><<<<>vv<^>v<^^^<>^^vv<><<>^<^v<^<<<^>v^v^<^>>>vv^v>><vvvv><^v^>v^<>><>vvv^<<<<>>v^v<vv><v^vv>><vvv><<>>><>v>vvvvvv>^>vv<v<>^vvv<^v><<vvvv<>v<<><^v^^<v<v<^<^v><^v^v^><>v>><^^<>v<>v>><<^>><^v^>>^^>vv>v><><^>>^v<vvvv^^<>>^>v<v^<v><^^<<^<vvvvv>>>^^^v<^^<<v^vv>>^^v<v<<^<<>v<v<>vv>^<>v>^>>v>v><><>>^<>^v^<><^v^v<<v>>v<>>^v>><><<>v<vvv<<^<>^><<>^>v<<v>^<v><><^>^><<v^<^<v>^>v^><v>>v<v^^^vvv^>>v^<^vv<>><v><<<vv<>v^<<^v><><^>v>^vv^><v>v>^v<>>^^<^<>^v>vvvv<^<v>v<v<>^><v^^^>>>vv>v<^^>v<<><^<<<>>v>>^<<^v>^vv>v<^^^vv>^<<^v<<^v^vv^<v<<>v^<v>vv><^<^>^^<vv^^<^^><^><<v>>>v^^v^>>v<^^v>^>^<>^<>^>><>>^^^v<<^^<>vv^^v^<^>vv<><^^<>>>v<<<^<v^vv<^<vvv><^<<v<<>^v>v^^v<v>>>^^><>>^v^^><<v<>vv^^vv<^<^<v>v^^^^>vvvvv^<<>^^^^^v<^<^^<<>>^^<<<<v<v<<v<>^v^>>><>^<>^<>^<><vv<^>v<^^<v^^^<^>vv<v>v><^^>vv<^v^^v>^<<^v^v<<<vv^v>>>^^v>^<v<<v^^><>v>v^vv>v^^v^^v>^v<><v<><<v<<^^>v>>>>^^<<<<v>><v<><^>v^^>^v^v>v<<>v^>v<>>v^<><>v\n^v<<>v^<v>>^<<<^><<v^^^^v^v^<<^v^<<>>>^>v^v<^>><<^<^^^<<^v^vv<^<v<<vv^v><<><>><^v^>v>^v<<<v^<^<^<vvvv^<<^<^<<>^<v^^<^>v<>><>>>vv^>><vv><v>v^>v>^>v^^<^^^<vv>><vv<^^v>^><^<<^><^^^^<<^v<v^>vv>>^v^v^>>^>v<v^<^>v^^vv^<><<v<<<>^>>^^v>>>v><vv<<^>><<^v<^v^><>>^<>vv>>^^^v<v^<v^<v<v^^<<v<vv^<v<^<^vvv>>^v^v<<<^^<<v^<^<^vvv>^>^vv<v^v^<>>>^><<<v^^>^<^>v>^>^v^><v><>v><>>v<><>>^><^><<><>^^>^<<<>><^v^^^>^>^^>^<^>^><<><v<vv^>^^^>^^^v^<v>><<^^v<>^v>>v>v^>^^>^>>v^><^^^^^<<v^v^><<^><v^v^>vv<v<v^v^<^^^>v^>v^^><<<^<<v^^<vv<v^<^<^^<^v^^^>^<>>>v^^^^<>^<vv<vv>v^^>>v^v<<<<<<v^>v^>^^^<<vv^>>vvvv>vv>>v<><>^v>^^vv><<<v^<<v^v>^vv^<<v<v<^><v<vv<^>vvv<<vv^>vv<>>^<<vv>>^^<<>>v^^^^<><v>><v^^>^<>>^<><^<<<vv^<<>^^<^<>^>v<>v<v<<v>^v^>^<^vv>><>^<<><^<<>>^^^><v^v<<^<vvv^<>vv>v^<^><v^v^<>v^v^>^^vv^^^>>^<v>^<<v>^<^<v>v<<v<>v^^<>v<>><^^v<>^v^<>^v<^vv<^vv^<>^v<<<v><vv<^v<v<^v>v>>>^v<<^v^><^>v^v^vv<>v<^>^<^<v^<^^<<>v^<<vv>v<^>v<^>vv^>^><<<<^vv^>>vv^><<>vv<v<vvv<<>v>^v^vv<v<^v^>><v^>^>v<>^<v>vv<<>v<^v>>v^^><>>^<<v^><^>^<<^>vv<<v<\n<><>vv^<<>>v^^<<>><^<>>^^>^>^>v<^^><v<^<v>^v<v>v^<<^>vvv^<v^><v>>vvv^<<^<^^<v>><^v^^>^vvv^v>^<^<<v<^<<><v<<^<v^>vv><^<>><v^^<^^>^>>vv<v^<<<^>vv^>>>v<>^^<v>^vvv<^v><v<<^v>^vvv<>^<^<<v>>v>>v>><v<v^v>v>^<^^><>vv>v^<><v<^>>>^^<<>v^>>^v>^^^vv>^v^>>^v<>>><v>^<^v>><^>v<v<v>^>^v<^v<v^vvvv^^^<v>>>v^^^^v<>>^v<v^^^<^^>vv<^^v^v<^^<<<vv>vv^<><vv><^<v<<>v<><>v><<v^vv<^>>^^v^<v<^<><^<vvvv<vv<^v<^^^vv<><^>vv^><>vv>^>^v^<vv<<v<v><>>>v^<^v>vv<^>^^>v>>^vv>><v<><^^<<>>^><>v<^^^>v<^<v>>^vv<>><v>^^^<^v><><<<<>>v^<>>><^<^^v^<<v<^<^^vvv^<vv>v>><vv^>vv<v<vv^<<v<<<vv<v<>><vv>^<>^<v<<>><^v<<^<>vv><>^^>><><<^>><<<<^^^^v>^^^>v^v<<><<>>v<^^>^^^><^^v>>^^>v>v<^^>^^^<^<^<^^v<vv<^>v>^^<<>>^v<<<<<^<><<<v^>>>^v^^<^<>><vv<<<v^<<vv^^<vvv^v^v^^^^vv^^v><v>v>^><>v<<<<^<v<><^v<>^<>v^^v><<^<<^><v>^vv^<<^^^^<<^><>^v>^<<v^<^v>v<^v^<v^>v<vv^vvv^>^>>^>><v<v<^<^^^<<<>vv><><^^v^><>v<v<<^v>v<^<vvv^>v<^>^v^>v<^<^^^^>^>><<v^^^^>^^><>>v^><<^<><>^v>>^vvv^^v<>^<^<^<<^><vv>^v><<><<<<<>v>v>^><v^v><<v<>>>><^>vv^v>v<>^v>^<v<<^<v<^<v<>>^><<v<><\n^^^<^^>v><>^<<^v^^v>v><><<^^^^^<<^<vv<<^v>>v^>^<v^<<<^>^>^vv>^^><^>v>v><<<vv<<^^>^><^^<v^^^>v>^<<>>^^^v^><vv^>v^>v<<^>^>v<<>^>>>^<v<>>>^<<<>v<<<<<>><^<<^>^^v<^v<><<v>v><v<>^<<^v^^v^<<<^>><v>>v^v>^v>^<>vvvv><^<<v^vv^^<>>v>^>vv<^v<v^^<^^<^>>>vv>^^<vv^v>>vv<^<^>>^^^><v<><<^<^<<>^^^<^vv^^v>^>v<<v>>v^<v^<vvv^v<v^v>>>v>vv>vvv^>^<^vv>^><<^v^><^vv><<<v>^^v^>^><v<v>^v<^v^>>><v^v^^<<>v^v^^^^v><^<<<^^>><<v^><^>v><>vvv^<^>^><>^vv>v^v^v<<^vvvv>v>v<<^vv<v<vv>v<>v^^<^v^v>^v<vv>^v>v<>>vvv<<vv>><vvv>^<>v>><vv<<v^<<v>v<<<v<^>^^>vv>>^>^v><^<<>v>><<^<v><vv<<vvv^^vv<^>>v>^^>v<<<>v<><^v>v<^<<v^^<<^v^<>^v<>>>^vvv>^<>v>v>>^<v<<v<^>^^v<>^<vv^^<>vvv>>vv<<^v>><vv><^^>v<^v<>v><<>v^>^^<<<v<<<<^vv^<>^^>v^v>>v<><^<><^^><^^v^>>v<v<>>><>v<v<v^>v<<v^^^<^v<v<v^>v>>>^>>v<v>v><v<v>^^v>><>>v><>^>>>^<<vvv>v<<v^^<>v><<<>>v<>v^vv><^<>^v<><>v>vvv<><>>>><<<^<^v^v>^^v^<vv<vv^v^>>><<<>^v^><>><<<>^vv>^v>v>>>>^v^>>^^<v>>>>^^>vv^v^<^v<>v>vv<>v><<><vv>^^^^^vvv>>>^v^vv<<<v>>><v>^^vvv^<<^>^^vv^>>v<^>^>><vvv>><v<^v<<<v<>vvv>v<^^vv<>^^><\n<<<<>^^^<>><>^<^<><v<^^^<v<><<<v^^>^^<^><<vv>v<vv>v<v<><>^<><^^^<v^>v^v^^v^>>>^^><^<<^v^v>^v^^<>^<^^v<vv>^>><<>^v<^>vv<><><>><^<>v<v<>^><^<v^v><<v^^><<<^^^v^^^>v^<>vv^^^^^<vvvv<v>>^>>v>vv<>v<^<v>v>vv^>^vv<^<^^<^v>^>>v<<>v<<>v>^<<v>v>>^<vv<>^vv^<^vvvv<v<<v<^^>^v^^<>^^>^v<vvv<v>^v^^<^>^^><<v<<><<<^<><><^^<>^>>>><v<>>><<vv^^v><v>v<^^>><vv^>vv^^<^^v<<<<<><^^<v^v>v^v<<>>v^v^><><>^<^^<^<v<v<vv^^>v^v<<v^><>><<^^^>>^<v^^<<v<<vv^><<^v<vvv>><<vv<<^vv>>^>v>^>v>><v^vv^v<^>^>>^v<<<^^<v><v>>^>vv^<^<><><vv<v^v>><>>>>>>><>^><>v<v>>^><vv><<v^>^^>>v^^>v><>>^vv<>v^<>>v^<><<<<^^vv<>^^^v><<^>>>>>><^>>^<v^^vvvv>v^^<^v>v>v^>v<>^>^>^<^<><v^>>^^v>^>^^<<v<vv>v^^><v>^vv<^>^v<<>>>^^>>>^<^^v^v>^><v>><>^>vv<^>^vv>^vv<^^>^^>vv^vv^^v^^<v<^^<^^^v>v^^^v<^><^>>>v^<^><<^v>v><^<<<><^>^vvv<<<^^>>v^^>><>v>v^v<v>>^v<>v^>^^v^<^>><>v><<v><<<^<>><vv<v<<^<><<>>^<><v^>>vvv>^v><><^><v<v>^^v<^vvvv<>>v<v><>^>v>^<>v<>^><^^v<v>v>>^>^^<<>><^>v^><^^>>>v>>^<^vvv<>^<vv>>vv^>vv<^^><vvvv<^>>^vv^>v^<^<^v>v<>^^<v>v><<^^v^>><>>^^^v^>><<vv<<vv^\n>^><><>v^<^>^<><v^v<v<>vvvv<<^^>>>vv^>^vvvv<^<^v<><^<vvv<v^^<>vvvv>^>v<^^<v>v^v<^<^^>v>v^<^><><<v<<^>^<^><v^vvv>^v<^v>^<^^^<<^<v^>><>>^v<^^<>><^>^<>^^>><v<v<v><^<v><v<vv^<<v<>^v<^<<>><>^<<<v>^v^v<^vv><^v^>v>><<<^v<^^^v<>><<>>v>>^^^^<^^<^^>v^<v>^v<<<v^><^v><^><>>v<>><^<>v^v^^^<v^>^><>^v^vvv<^^<>v<<>^vv>v<^^><<<<>><^><<>^^v^v>^>v<^v>v^v>>v>>^^>v^>><>>^^^^^<^><v^v^>>^>^<<>^v^^v^v<^^v^v<^>>><>^v<^^>^vv>v<>^^v<v>><<^^v^^^<>v<^><vv>^^<v^>><>v<v<><><v>^^<^<<<>v<>v^^^v<^>^<>^^v<>^v^^>^><<v<>^><>^>^^>vv<>v<<^^>>vv>vv^<>>>>><><vvvv<^>v^^>>>>><^>>^v><v>v^>^^^<<^vv^>^vv><v<^<<^v^vv><v<<>^<<<^<v^<<>v<>>^vv<^v>^^^v^^^<v<>vvv>^<^>v>v<<v>v>>><v^<v<^^>><<>^^<>v<^v><^^v^^>^vvv^><^v<^>v><^v^v^v<vv^>^v>>v<v><^v^<^<v<<><v><>><>^^^^v<v>><vvv<<>v<^^v<^>v^v^v^^>v>^<v<^^^v>v>^v^>vvv<>^>>>><v<v>^v><vv<vvv>^<>v^<^<v<v>v>>^>^>>^v<vv<v^<<>v^<vv<vv^^<v>><v>^^<v<vvv<^vv^^v^<^<>v^><v<v^v^^v^><>v^v>>^^>><<>vv>^^^vvv>v>vv<>>^v^<^v<<^>^>vv^^>v<v<v^v><^<^>^^^v^^<^<<^^<v<v><>>v^^vv^v^v<<<<>>v^<v<<v><>><>v<>^>v<>^vv^>v<<v<\n^^>v^><>^v<<<><vv<<<>v>vv^v>>v^>v^^<^^<<v^<>vvv<>^v><^<<<>><<<<v^v<<<>>^vv^<<<>><<v<^<v<<<v<v>>^<<><v><>><v>^^<><v<<<v>v^><v^v>^v^<><^^>v^^<>^<^<^^>vv><^^^v<<<<>^vv^v<v>>vv<<^<^>>^>><><^>><<^<<v^><v^vv<<>>v<>^v^>>v^>vv^<^v>>><>^<^>^^<<<><v<v^v>^^>^v>^vv^<v^<^vv><<>v^>^^v^>^<>v<<<<v^^v>>v^v<<^^v><^>>^<v<>><v<^v^v<>^^<^^v>^v<<^^<v<>>v<v<^<<<^<v^><^>v^^^<^>>^>><v<>^v>vv>^v^^v<<<^>>^><v>>vv^<^<v<v^v<v>^<>^<>v^vv<v<>^v<>^><^v<>v<^<^v<^vv><<<<v<<<^^v<<v<>v>>>v><^v^^vv><vv>vv>>v^<>^>^^><>>^<^>>v><v^>v^><v>>><^^v<v<<^v<>^^^<<<^^v^>>^<v^<>vv^<v>^v<<^v^>vv^vv^><^^vv>><^>^^^<><^>v<>^v<>v^<<>^v>>><>v^v^>^><><<<>vv<^<v>>^^>^^^^^^v^<>>>>v><>v<v^v^v><><vvv<^^<>v<^><<<v>^>^^>^>><>v>v>^^<><v>^^>v^v>v><vvv^<<v>^<<<v>>v>><<<v^v>v>v>v^>^>>><>v^^^vv^v<vvv^>v>v^^vv><><v>>^v^^<>>v<v<v>v>>><>>v^<>><>>^^^^><<^>>^v^v<>>^^v<vv>v^<><^^><v>^v<<vvv^^^<^<^<vv>>^><>v<v^<>^^^^>v<^^vv<v>><<<>v<v<<>v<v>v^^<^<<>>^v^<v^^v><^<<>v><<<<>^v>vv<v<^>v>v>>v<vv>v>v><^>>^^^>^><^><><<><>^>v<v^^>^>>>>><v^^><v^>><^^vv<<<v>v<>^>^<<v<>\n^vv<>v<>^<v>v>^^<^v<<v^^><>>^<<v<>v^<<^v>>^>^<>v<>^v>v>>>^><<^>><v<^^>^>^v^><^vv^v<<v^^^<<^><^<<<>^^><<<>v>^<<v>^<<<>>>><vvv>>>vv^<<^><v><^<v^v<v^v>^>^v<<^vv<^vv^^^vv^<^v^v<>^v><^^^<v<>^^>><<^v<>^<vv>^v>v^>>^^>v>><^v<^<>>><v<v^^<vv>v<<<^<>vv<^><><<>>><^v^<^<vv^>>>>^>v<v<<v>^>^><^^^<^vv<>><<vv<^v>v^v>vvv<^<><v>^v<^^^vv^^^<^v<<<>>>>vv^^^vv><<v^>^>v^^<^<<<^>v<>^<<<<^>><>^><<v<<<v^<<v<vvv<<^^><>^v^<<^^<^<^^v^>><<^>>>vv^vv>>v>>v<<v>vv^<^>v><v>v^>^>>^^v>>v<><>>v><>^vv<^^^>><>v>vv<vv<<vv<vv<<v>v^><v^>^<v<^vv^<vvvv>>>><<^^<^^>v<<<v^vv^<>>>>>^v><><<<><^^v<vv^v^v<>>v^<><<^vv^><vv>v<v>>vvv<^><v>>>^><v>>^^<vv^<^^^<>>>>>v^>vv^<v<>^^^^>^^<<^v>v<<<vvvv<><^<<^<>^><^>><>>><>>>^<^^^vv^>>^<><^vv<<<<v<^>^v>^^v^>^^><v<^v^<^>>v>>>^><<v^v<v^^^^v>>v><^<>>><v^v^v<^^v<<v<<><<^vv<^^<^^^vv><>v^^v>^<v^><<>>vvv^>>^v>><<<>^<>^^<<>v<^><^<vv<<>^>^<<<v><^<<^^vv<vv>vv^^>^^^<>^v<><^v<^>vv>>v>v^^<>v^v^>^^><>^vv>^<v^^<^^<v^^vv>vvv<<>v^^<>vv^v<^v^><<v^<<<>^>>>vv<v>v^><^<^^><^v>^<>v>vv^>vvv<^>v^v>>v^v>^^^<>v^<vv^v^<<>vvv^>^>\n<><>^<v^v>><vv>^v<^vv^>^<<>^^><>v>^v>^>^^<>v<>^<><v<^<><><^v>>v<v>>vv><^<>>^^^>>>>v<vv>^vv<v>^<v<>v^><v><>v<^vvv><^v><<^vv^^>>>v>vv^>v<^v>vv^^v<^<v<<^<^>v<vv<>>v^^vv^v^^^^><v<>v<^>>><v<^>><>^^^v^<^v^^^>v>v>>^v^^<^><^^<vv<^^<<^v<^<<<^vvv<><<v><<v^<>^>v<^v><>><><<>>v<^^<<v<<^v><vvvv><^<v<>vv<><vv^>>^^^>><>>^<<<vv^^<>>v^><v<<>>^<>>>v^^^v>><>vv^><^<^vv<<v<<>>v>^v^v^v<<>v<^v><v><<v^<>^^^v>v^<<><^v<vv^vv>>^^vvv^>>^>v^^vv>^vv^>>>><^>v<<^v><<>^v>v>v>>vvvvv<^<<v>>>vvv>>>^<^<^^^<^<><vv>^>>>vv^<^>>><><^v<>v>><<<<>^<><vv^>v^>>^v^<<<^v^v<^v>>^<>^><<>^v<<v^<v<^<<vv><<>vvv^v><^vvvv<><>>^^>>>v<^>^^v><<vvv^>v<v>><^^^<v<>>v<>^v^><<^^<^<v>^>>>^v<^^^>v>^>v^^<v>v>vv^v><>v^><<<^^v^v>v>>><<vv^v^vv^<^>^<^v<^v<^^^v<<v>>v>^^<<^<<^>>><>>>>>v>v>^^^^>^^>>^><>^<v><vv<<<v><<^<><><<>>^^<v><v><<<^^<vv^v^>>^v^^v<^v^>>>^><^><>v<>v<<<^><><vv<<>v^<<v<>^^^v^vvv>v^<v<^^>>><>>vvv<<<><vvvv^<<<^<^^>vv^>><v>vv<^><^^v<<>v>>v<>v<><^<v^v<<^><><<<v<>>^v>>^^v<^><>><<v<^^vv<>>v^<>>v<<^^<<>^><>vv<^<>^v^<<v<v>v><^<^<>>^<>><vvv><<^^v<<<\n>^<><v<<^vv<>^^>>>^vv^^^v<>^<^^<^<>v^>>>v<v>>>v^^>^^^<><v<vv<^^<><^v^<<v>>v>>^vv^^>>>^^<v<v>^<<^<>>><>^>>^^v^v>>v>>><>^v<>^^^>^^><>v^^vvvvv>>^v<^<<^<><v<v^v^<>^^vvv^^v>v<>^><^^v<v><<<><v<vv^^v^^>^>^^^vv^<^^^vv<>^v<>v>^<><^^<v^<>^<v>>v>vv<v<^^<>v^^^<v>>^^>v<^>^<^><vv>v><><v>v<^vv>^v<vv^^vvv<vv>^<>>>>v<<vv^<^^<<^^><vv^^>v>^<<^>^>><<<v^><<<><<<v<v>v>^>v><v>>^^<<v<<<^^v^><><^<v>v><^v>v<>v<<^><^><vv^vv^<>^v^<^^^v><>v<<<>^^^><<><^^>^>>^>vv<^><^>^^<^^v>vvv^v>^^>>^v^v<vvv^v^<^^vvv<>^>^^^>^^>vv^<<<<v^><v<^><>>^<^><^<v<<vv>>v<^>v><^<>^<>v^v>^<v><^<>v>>vv><>v<>v^^^vv<vv^<v><<^<<<<v^^^v^>>>vv>^>>vv^^v>v<^^><^><>^>^<^^><v<>>^>v<<v><v>v<<><>>^v^vv<^v>v><>vv>^><<>^><vv>>v<>v^><><^^<>>><^<<^>v>^v<v<^^>><v^^<vvv<^^^><v>v>^^v<<v^^^>>>v>>^><>>v>>^<<<^^^<^^>v^^<^>^><>vv>><>^v<<vv^>v><>^v><v<<><<^<v^v^<<v<v<^<^v^<^>^vv<^>^^>^<v>^>^v>>><>^vv<v<v>><<>><v<^^<v>v><>>v><<vv^v<<<>><v^>vv<<<><><vv^^^>^vv^^v<<><^>v^>v<<v^v<vvv^>^^>vv<^vv<^<<^<<v^v><v>>>v>^<<<^>^v>^vv^<v^v<v>vvv^^<v<^><<^^v^>^<^^<>^>^^<v^^^v>>><^^>\nv^^>v<<v<>vvvv<>^>^<<vv^<<>><^^<>v^>^v<^v^>>>>>>^<><<v<<<v^v^>><^^^<><v^>vv^vv>^<<>^^>^v^^v^><>v<<^<>>>v<<^>>>>^<>>><<v>>>><<v<>v<>>v><vv<<v^>^^v><^<><<v^>v^>v<vvv^>v>v<vv>vv>><v>^vv<v>><<<<vv^><<^>^v>^<^>v^v^>^^>^vv^v>vv^^^<<<v<<<<v<vv<<v>v<<v>v><v<>^v<>^v^>^<<>>v<v<vv><>>v>^><<vv<>vvv^v>><v><>^^<<>v^^><<^<>^>>^<>>><v<vv^>^<^>>v^>^^^<v<>v>v^<>><>>><^<vv>vv^v^><^<<^>v^^>^<>>^vv><>^v^^<><>v>v>^v<^<^<vv<v>^v>><>>><v><<<><vv^^>v>>^vv^v<>^<<^^v>v>v<v^v<^>>v>>><vvv<v>>v><>^v<><v^<<^>><v^>v<<<<><<^<>vv^vv<>>vvv<vvvvv^^><v>^>^^vv^v<vvvvv<>>v^<^<>>^<^v><<^<<vvv>>>v><>^v<^<vv^<<<><v<vvv>vv<><^<vv>^<v<^v<^vv<v<<>>>v^>v<<>>v>^<^>vv^>>^vv<>v<^v<<^v<v><<>^^<v^>^^vv^^^v><v><>^v>^><<>>v><v><><>v><>>v^^>>>>>^v>^>^v<>v><^>vvv>>v^>^^>><v><^^v>^vv<^><<>^v><>>><><>^><>^vv<<v<<>>^v^<v><<v<<^^>^^<<><>v><>v^<^^>><<><v^^v>>vv<vv<^>v<v>>^v^>^<^v<^v<<>>^<>vv^>v^<^>><vv>^>^vv<><v<>>>v<v^^<><<^^^<<v>>^<><><<v<<v^vvvv^<<<v<<><v>><>^^v^>>v<^^<<^vv>^<v<^v>^><^^<>^<^^>><<<><v><^><^<<>^v>^<><<^^^>^^<>v^<v><^^>^v<^^>v>\n><>>v<<<^<<vv<^^<<<v<>^v^vv<vv^<<>vvv^<^<>>v^>^>^^v><>v^><<vv^>^^v^v<>><<>v^>v<^<vvv^>vv^<>>><v>v<^^v<^v^v<<^<vv>v><>^>v>>v<^^>>v<^><><<v^>^<<vvvvv^<>^<<<v^<v>^^vv^<^^<<v^^<v<<v^vv^<vv^<v^^^v^v<v^<<>>^<v>>><v^><v^>>^^v<<>^>v^vv^>><>^<><<^<^<v><>v>v^>v^v<^<<<^<<><^v>^<>^>>>v^v>^<<>^>>v>v<v^v<v>>^<^v<>vvv^<<vv>>>>^^vv>^^>^v><<<<^<>^>^>>>>>^^>^<<^v><vv<<^>^<<<^v>><><^>v>>^<<v^v<>^<<vv^>^>>>><^vv>>vv^v^^>>^^^<vv^^>><^<^^^>><<<<>><^<^v^v^vv<<>v><>^^>>><^^v<vvvv>^><^<v<v^v<v<<>v^v^>>^^vv^^vv><>vv>^v><>v^>vv<v^>^>vv>^v<>>^><v><<v>>>^>vvv^<>>^v<^><vv><v<<>^v<vv>v^^v><<>^>v>^^<v><><^>><v^v>^><<v><vv^>v>^^vv<v>^><v>v<<<<<^^>^><><v<v^<>vv><^>>>^>^v><<<>v^<^^<<>><^^<^<^<v^v>>^v>^><><^>^^<v<^<<>^>v<<v<>v<<vv>^^v^v<v^v<v<vv>v<<<<^v>vv>v^<<^>><>>><^>>><^^<>v^^<>>><>vv^>>vvv><><<><^<v<vv^v>^>v>^>v>>^><<^v<^<<><^<^<^v^v<^^<<^<>^<<<^vv><><v^<<<^<<>>^^<^^<v^<^^>^^^vv>>vv^>v><>^v>vv^^>>>v>v^v^^^><>^>v>vv<v>v^>^vv>^v<^^^^>^v<^v<<^><^^^v^v^<v>v^<^><<^<v<>>><>>>>>>v<v<>^>^>vv><^^>^<v<^^>vv>v^^v^<<vv<><^<^<<^\nv<v^>^><<>vv^vv^v<<^^v>^>>^>^>vvvv>>v<^<<><<>><<<<^^^v>v>vvv<^<v><><><^>^v^><^^^^^v><v>>v^^vv^<v<^><v<>^><^<^<<<>>><>^>>^<<v<<v>^^^>^^v^^v^>>^>vv<<><v<^<<<^vv<v<<>^^v>>v<v>^v>>v<>v<^v<<^v<vv^><^>v>v>vv^>^^<<>^^^v<<^>>><<<v>^v<<^^<<<^>v>>v>^^v^^v^^v>^^<<^><<<v>v><<>>vv<^^<^^v^^v^^<<<<<>^^<v<^><v^<v><>>v><>^v<v^v<v<^>v<>v^v^<<<^^>v>vv^v^<<^^^^v><^^^<<>^^<><^^v^^v<^v>v<<<><^<^><v>vv<<<^>vv><^vv<<>^<vv<^^vv><^<<>^vv>v>>^><^v^vv<^v<<<v^^<>^><<v<vv<^<><^^<^<v>^<>>>^^^v<v<^v>v^<v<vvvv><><^^v<^>v^v^><<>^v>^>v^^v^^>vv<vv^<^>vv>v>^v>>^<<v<>><v<^<>^^<>><vv^v<>vv^^<<v<v>v^<^vv^^<^>>^^<v^^<^vv>>vv>^<>v<>vv>v<^^vv^<<v^<<>v>>v<>^><>^v>v<<<<<<^<v^^^>v^^<^><v<>^^<^<v<^<<<v><>v<^^v>^vv^>>>>^v>^<<>vvv>v<^^<><<>vv^><^v^v>^<v<v<<<v^v<^v<^v<vv>^^>v>v<v>v>><><>^v>v<<>^vv<><^^<>v<v^^><^>><vv<>^v>v^v><v>^v^^<>v^^v>^^v^vv<>v<<>>^v<vv<<<v^^>v^>^^v<^<v<^v>^>v<>^^^v<^^<^><><>^>v>v>^<vv>^<^<^vvvv^^v<^^><<<^>^v<<<vv^>v^>^v<v>>><v><v^>v^><^<>><^vv<^>>^>^^<v^<>^^v^^v^vvv>v><v>>^<<>^<<v^<><v^>v><>^>^<^<>>v<>v^^><v><><<\n^^>>v<v^vvv>^v>^^^>^vv<<v><^^^><<>v<<v^v<<^^<<v<><^>>>v>vv><>>^v^v<v<^vv^v>>v<<^<^v<v^^>vv>>v<<^v<><v<>>>vv^<v>v>><>><<v^>>^v>v>^>>^^^^<v>><<><^vvv^>>^>><vvv<vvv><<v>^^<<^<<<>^vvv><v>><<v<v<><v<><<>^><^^>^<>>^>>>>^^v<>>^^^v>>vv<>>>>^<v^>><^v^<^^<v><v^>^vvvvv^v^^><<^v>vvv^^>>>^<<>^<>^^v^^>>^>>v>^>>^^^v<^<>^^vv>>v^v>^^^>v<<^v>^<>v>^>^vvv>v^<^<^<v><>><<v>v^><<<^<^^<v^v>^v^<<^>vv^<<v><^<^>>>^v>>vv<><^>>>>^v<<><v<<<>vv><^v<^v<v^^><>>v>v><^v<^v<><><^v>^><>^^^<^^vv<<<>^>>><v^^>v^<>vvv<>^<v<<v<^<><v^<<^<^>vv>><^<^>^<v>v<^<>v>><^^>>v><<^^>>>>^>^<v<vvv<<<<>^^^<^v^^<<vv>vvv<>v>>^v>>>^>v^v^^>><<><vvv>>^^^vv^^>v>v^v^>>v<<<vv>^v<vv>>v>v>^<<>^vv>^vv<<vv>^vv^^>>><><>>v^^>vv^^<<<><^v>v<^^^<v^>^>>v<^><vv^<v>v<<v>>^>^^vv^v^vv>^^>vv><v^v>>>^^^^>>v>>v>^>^^<^^^<>v<><^v^^v^vv^>v<v^^>^v^><>v>v^v<v><^^v^>v><<^<>v^v>>^^v<>^v>vv^v^>v<><^^>>^<^><^^>^>^>>v^^<<>^><>^<^>><<>^<<>>v^^v<v^v>v>>^^<<<v<<>>^>>>>>^<<><^>v<><>v^><<<><>v<<vv^v^>>v>><>><^<<vv^v>>^^^><^^v^^>^^v>>^^><vvv<^^vv<v<^v>>v<v<>^><^>>^^vv^^<^><v^^v<><^\n>>v>^^<<><^^<>><^<>^v^v<^v<v>>v><>>>^^vv><^vv>v^>^<^^<^<<^vv^v^<<^^<>>^<>^^^>><v><<v><^<>vv^>>>><vv<>v>v^>>>^v^vv><^<v<>^v^v^<^v>>^<><>>^v>v<<^v^vvvvv<v^v<<><vv>v<><<<^>^<<><v<^>^<<<v<>>>v<<<v>><<v^<^<^>v^>v<<<<v^^><vv^<>v<v^^<>v>><^>v<^>v<v>v<v>v<>^<v<^<<v><vv^^>^^>>^vv<v<<^v^^>^vv^v<<<<v<v^v><v>>v^<v>^^^^v>v<^^>^<>>^<vv<>v<v<vv>^v^>v<<<>v^>>v>>^v<v^^vv<>v^^<>>v<<<^v<>^>^<^>v>>^^^^><<v<<><<>v<><<^<v<><>v>vvvv<vvv^^<v>v^><v<<v>>v>>v>v<v>>vv<^v<<^>vv>vv<<v><>v>>>><^><>vv>v^<^>vvv><>>v><<>^>^<v^<<>>>>>>^vv^<^<><>>><vv<>^v^<v^v^>>>v^<<^^^<>v<^>^>>^^<>^^>vv><^^^^><<>v><>vv<^<<v<>^<><^><vv>v^v^>v<>>v>^>v^v^<<^>v<<<>vv^<^<v<><>><^v^^>vv<>>^<>^^^^>>v^<<<><^^v>^^<<>^<>>v>^<vv^^^v^<>^<>v<<<^^^>vv>^<^>v<><<v^^^^<v<<<^vv^^<<v>^>>^<<v>v>v>>>>v>v^><vv>><vv>v<><v>>><^^>^v<><<vv>v><<v>v<>vv^>^<vv>>v<<^^^<<>^><v<>^^v>v<>>v^>><>^<>^>^>v>v<v<v^><><vvv<>>>^><vv>v><<<v<>^^>vvvv>v>^v<><v<v^vv^>><<><^<<<vv><v>><<>^v>><^v^v<v^v^vv^^>vv>^v<v^^>vv^v^v<v^^^v<<<^<<vvvv^vv^^^v>>^vvv<vv>^><^v^v><^>v<^<<^vvv^^><v>^\n^<v<^vv><^^v<><v<^><<v<v>v^>^^<>^^<v^v<^^>>^v><<><<<vvvv<^v^>><^<><^<^<^><^^v<><>^v^^>v<>vv^v<^>^vv^v><^<>v^<<vv>>><v>><v>^>><<<><^^<v<^vv^<^v<v><><v><>^^><<v><^^v>><vv>v<v^>v^>^v><^^<>^v^>>^><^<v<<>v^<vvv^^<^<<><<><<^^v>v<<v>>v<^<>^v^><<<<><^><<vv><<<vv<>v<>^v<<^>^>v>v^><^>>vv>vv<<v<>^^v<<v>>^>><>>>vv^^v^>vv^v>^<<<<^^<vv<>><><^>^<vvv>v>^<v><>^vv>vv^><v<v<^<^^v<^^vv<>^^<v<>v>^^<v^>>^<<^^^^>v^><^<v^>^^>>^<>>>><^<^<v^v><<v>>>v^vv<^<><^^v^<^v<>v<^^^>v^vv^^v>><<vv^v>^<^>v<^>^^^^>vv<vv<>^v<^>^<vv^>vv>^v>>><>><<vv<^<<^>>^<v^><v>v^^vv^>><<>^v^>vv<<>><vv<><<>vv<v<>v<<<<^><<v<>><^v><<v^^^>vv><vv<<v>v<^^><vvvvvv>v^>v^v^v^<>^v<vv^^^<^vvv^>><<>vv^v><v><>vv>v>>v^>vvv>v<vv<^<>v>^^<^v^^v^^<>>>v<><>v>v<vv<>>v^v^><<^>^^^^^><><^>^v^^vv^>^^<<^>vv^^<^<<>^v^v<<^<>^v>^<<<><v<v<v^vvv<<^>v>>^^<>>>^>^^v^v^^<><>><v^>^<<>v>>^^>v>^>^v<^^<>^<v>^<<<^<<>>^^><v>><^^v^vv>>^<v>vvv><^v<<v^>>>^^v>vvv>v>>>v^>^<v<^^<v<^>><<v>vv>vv<<^v<<>v>>>^v^<<v>v>>^vv>^v<vvv<^^v^>>^><^vv<^vv^<^><v^<>^<>^^^v^v<v^<>vv><vv<>vv^^v>>^>vv>v^^\n<><^v^^^><>>vv><><>><<>^^>^<<v>^v^>^>^><^<^vv>>v<^^>v<<<<<<v>^^^<^v>><>^>>>vv^^>v^v^^v>>><<<<>^>>^<<>v<<vv<vv^v^^^>v^v>v^<<<^>><v><^>^<v^^>v><^<<v<>^^<>^<^>><><<^^<^vv<v^^>>^^>><v<vv>>v^<^>>v<^^<>^<>>vvvv><<v<>v>^>^<^<^<<><^^v^>>v><^<^>^v><^>>^<v^v^^>v>^<^>^<vv^<<^^<>>^<<<v^vv^>v>^^<<<>><<^^v>><^><<^v<^><<<vv<<><<>v<>v^^<^^v<v<v>v^><v<^^>^v>^<v>v>>>>^<^<>^<>>>v<^<<^^v><v>><><<^<>^^v>>^>^^>vv<<^>>v<^>><<v^<<<v^<<<<>vv>^^<vv^<<^v^>>v<^^>>^><^v<^v^v<^^v^v^<><><^<<v<>v<><^^<<<>v>^v^<<vv^>v>^v<<^>^^<v<^<v<<>v<v<<<>v>^>>>v<><<>><>>^>v^><<<<vvv>v^>^>vv^<<<v>^>>^<>vv^>^>><<>^^^^<>^^<^>>^^^v^vv<>><>>^^>^vv<v<^<vv><>>><v<^v><v><><>>>^>><v<>vv^v^<v<<<v<vvv<><^>>>v^^v<<v>^vv^<^<^<>^^v>>><vv<>^<><>>>^<>vv^^>^v>>>v>>v>>>v^>>>^<<v<v^<^v^^<<^<<>^^<>>>^>^>>>>>^>>^vv^^^<>>v<>vv>v^^>^v>><<>v^<v>^<v^vv><vvv^<v<>^<><^v^>><v>v<v>^<><>>>v<v^>>>vvvvvv<v<<^^>v^v>>>^^^><v^^v>>^^>>^^>v<vvvv>><<^>v<><<<vv><^^>>v>^vv^^^v<<^^>^>^>^^^^v>><vv<v<><^><<^<v>v<>>>>v<>v<^v<<<>>vv^<v<>>><<><^<^^v<v^>^^>v>^v><<v<v>>v>^<<<^>\n<>^^>>^v>vv^v^<v><><vvvvv<v^>>^>^v>^>v^<>>^<^v><^<>v^>>>^^^><<>v>^<^^<<<vv<v^><>>^<v^<<>^^^>^>^<<v><^^<v<><<^>^<<<^v>>>^^v<>vvv>v>^v><>>>vv^v<>^>^vv^>^^vvvv^v^>>v^<<^v^^><v><<v>^><>>v^v>^^<v>^^^v<>v<<^>vv>^>><<<^^><>>v^vv><><<^>vv^<v^^^<<>v<<^>^>^<<v>^v><vv><>^^<v><<^<^^v<>>^^vv>vv<><^>v>v><vv<<^>v^>v>^>^<v><<><^v^^v<<vv<^><v<<^><v<>v^v<>v^<<^<^<^^v>>><>^v^>^^<>v<<v>^^v><^<v<<v<^<<>vvv><v^v<^v<^vv<^>>v>^v>^^v<>v^v><^<>v<>>v>>v^v<v^>^v<v><<><^<v>>>>>^v^^^vv^v>^<v<^vv<>^<^^>^v>v<v^^vvv^<^>^>v<<>^vvvv<^<^v^v>^^>^v<<>^>^>^^>^>vvv^v>>vv<^<><vv><>>v^^>^v<v<<><<>>v>>><v>vv>><v<><<>v<<^<v<>><v<<<^>>>>v<v><<<v^v^>vv<^vv>^>v<>>^><>v^<^<^^v^^>v^^>><<<>>>^^v>^^^^^^<>v^<>>^<^<v^^<v>v<<v>^<v^v<v<<>>>^v>v^^<><>><><>^<<>^><^^><^^vvv<v<<^<>^^^><^<<<^^>v<<<vvv<>^v<^<^vv^v^><vvv><>>>>^v^vvv<vvvv<v<v<v>v<>v<>^^^v>^^<><<v^<>v>>vv<>v<<^^>vvvv^<<>v^^^^^vv^^vv<>><>v<v^^v^><^v^>>^v>^vv<>v><>vv>v<<v>v>><vvv><^vv^vv>>>^^^<^v>^v<v^^<^v>v^vv^>v<<<v>v<^<v<v^>v>^vv<<vv^<<<>v<v^<v^v<v^vv^vv<>^v><v^^^<^v<^^vv^>^v^<><^\n^^>vv<^^vv>^>^^><><>><><<^vv><<><>>^<>>^^vvv<vvv<^^<<^^>^><v>>>^^vvv^>><<>>^><^<<>^<<^>v<v^<v^>^v>v>><^^>vv>v^><<v^<<>^>>vv>^vv<>v^>>^<>>^<vv<>^>>^><<<^>>v<>^>^>>vv^<<^^v^<v>v^v^<>^^>^><<>>><<^v^v^>><>^v^>v<>>>^v>vv^>><<v^>v>v<>^^^v>><vv<^^>^^>^>><<^<^v<^<<v>v><>>vv><v>^v^^^^>v<>^vv^v>^^v<><<<v>>^<^<<<v<<^^<<<>v><v<><^^><>v^^>v<><<vv^>v>^>v>v>vvv<vv^^v^><><<<^>v<<<<<>>vv>vv^v<<<<<>^>^>^><^v>>^^<<<<<^v^vv><^v^vv<vvv^v<^>>^^vv<<^v>v^^>v^v><^<<>^^^^<>v<v^<^<><vv>^><^>><^^>>^^^>v<>^<v>v>^v>>^v<^>>>^>><<<v>^<v^v<v><^v>>v<vv<^v^<^>^v<>>>^>>^>>^>>>>>^>^><vv>v><<^<<>><<<v^<<>v<>>^^<><<vvv^>v^><^>v<<^<>vv^><<^v<<<>vv><>v>>v<^>^<^^<<^<^vvv^<^<><^>v<^<<>>v<<^>>>>^<<v><vvv<^>>^v^<<^<^v>^><v<><>>>^v>vv^^<v<^^>>><<v^^v<<>><^><<<v^v^v><^>^<>><>vv^><^<>>v<<^>vv>^v><<^^vv<<v<^^^<^<<><>>>v<vv<v<^^v>>v<^>v<<^><<v<^^^><^<v<<>>v><^>v>v>vv<v^^<v<<><^>v>^>v<><v<^<vv^<<v>>><^>vv^>^<v>>><><v<^v<<v^^>^^v>>^>^>vv^<v<v^><<>^^vvv><>><v^<<<^>^>^<>>><v<><^>^^vv<^v>>><^v<>>^>^^^^>^v<>v>>v>v>>vv<>vvv>>v<>v<<vvv<<^v><^\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_15_questions.txt",
    "content": "--- Day 15: Warehouse Woes ---\n\nYou appear back inside your own mini submarine! Each Historian drives their mini submarine in a different direction; maybe the Chief has his own submarine down here somewhere as well?\n\nYou look up to see a vast school of lanternfish swimming past you. On closer inspection, they seem quite anxious, so you drive your mini submarine over to see if you can help.\n\nBecause lanternfish populations grow rapidly, they need a lot of food, and that food needs to be stored somewhere. That's why these lanternfish have built elaborate warehouse complexes operated by robots!\n\nThese lanternfish seem so anxious because they have lost control of the robot that operates one of their most important warehouses! It is currently running amok, pushing around boxes in the warehouse with no regard for lanternfish logistics or lanternfish inventory management strategies.\n\nRight now, none of the lanternfish are brave enough to swim up to an unpredictable robot so they could shut it off. However, if you could anticipate the robot's movements, maybe they could find a safe option.\n\nThe lanternfish already have a map of the warehouse and a list of movements the robot will attempt to make (your puzzle input). The problem is that the movements will sometimes fail as boxes are shifted around, making the actual movements of the robot difficult to predict.\n\nFor example:\n\n##########\n#..O..O.O#\n#......O.#\n#.OO..O.O#\n#..O@..O.#\n#O#..O...#\n#O..O..O.#\n#.OO.O.OO#\n#....O...#\n##########\n\n<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^\nvvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v\n><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<\n<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^\n^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><\n^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^\n>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^\n<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>\n^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>\nv^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^\n\nAs the robot (@) attempts to move, if there are any boxes (O) in the way, the robot will also attempt to push those boxes. However, if this action would cause the robot or a box to move into a wall (#), nothing moves instead, including the robot. The initial positions of these are shown on the map at the top of the document the lanternfish gave you.\n\nThe rest of the document describes the moves (^ for up, v for down, < for left, > for right) that the robot will attempt to make, in order. (The moves form a single giant sequence; they are broken into multiple lines just to make copy-pasting easier. Newlines within the move sequence should be ignored.)\n\nHere is a smaller example to get started:\n\n########\n#..O.O.#\n##@.O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\n<^^>>>vv<v>>v<<\n\nWere the robot to attempt the given sequence of moves, it would push around the boxes as follows:\n\nInitial state:\n########\n#..O.O.#\n##@.O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove <:\n########\n#..O.O.#\n##@.O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove ^:\n########\n#.@O.O.#\n##..O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove ^:\n########\n#.@O.O.#\n##..O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove >:\n########\n#..@OO.#\n##..O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove >:\n########\n#...@OO#\n##..O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove >:\n########\n#...@OO#\n##..O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\nMove v:\n########\n#....OO#\n##..@..#\n#...O..#\n#.#.O..#\n#...O..#\n#...O..#\n########\n\nMove v:\n########\n#....OO#\n##..@..#\n#...O..#\n#.#.O..#\n#...O..#\n#...O..#\n########\n\nMove <:\n########\n#....OO#\n##.@...#\n#...O..#\n#.#.O..#\n#...O..#\n#...O..#\n########\n\nMove v:\n########\n#....OO#\n##.....#\n#..@O..#\n#.#.O..#\n#...O..#\n#...O..#\n########\n\nMove >:\n########\n#....OO#\n##.....#\n#...@O.#\n#.#.O..#\n#...O..#\n#...O..#\n########\n\nMove >:\n########\n#....OO#\n##.....#\n#....@O#\n#.#.O..#\n#...O..#\n#...O..#\n########\n\nMove v:\n########\n#....OO#\n##.....#\n#.....O#\n#.#.O@.#\n#...O..#\n#...O..#\n########\n\nMove <:\n########\n#....OO#\n##.....#\n#.....O#\n#.#O@..#\n#...O..#\n#...O..#\n########\n\nMove <:\n########\n#....OO#\n##.....#\n#.....O#\n#.#O@..#\n#...O..#\n#...O..#\n########\n\nThe larger example has many more moves; after the robot has finished those moves, the warehouse would look like this:\n\n##########\n#.O.O.OOO#\n#........#\n#OO......#\n#OO@.....#\n#O#.....O#\n#O.....OO#\n#O.....OO#\n#OO....OO#\n##########\n\nThe lanternfish use their own custom Goods Positioning System (GPS for short) to track the locations of the boxes. The GPS coordinate of a box is equal to 100 times its distance from the top edge of the map plus its distance from the left edge of the map. (This process does not stop at wall tiles; measure all the way to the edges of the map.)\n\nSo, the box shown below has a distance of 1 from the top edge of the map and 4 from the left edge of the map, resulting in a GPS coordinate of 100 * 1 + 4 = 104.\n\n#######\n#...O..\n#......\n\nThe lanternfish would like to know the sum of all boxes' GPS coordinates after the robot finishes moving. In the larger example, the sum of all boxes' GPS coordinates is 10092. In the smaller example, the sum is 2028.\n\nPredict the motion of the robot and boxes in the warehouse. After the robot is finished moving, what is the sum of all boxes' GPS coordinates?\n\n--- Part Two ---\n\nThe lanternfish use your information to find a safe moment to swim in and turn off the malfunctioning robot! Just as they start preparing a festival in your honor, reports start coming in that a second warehouse's robot is also malfunctioning.\n\nThis warehouse's layout is surprisingly similar to the one you just helped. There is one key difference: everything except the robot is twice as wide! The robot's list of movements doesn't change.\n\nTo get the wider warehouse's map, start with your original map and, for each tile, make the following changes:\n\n    If the tile is #, the new map contains ## instead.\n    If the tile is O, the new map contains [] instead.\n    If the tile is ., the new map contains .. instead.\n    If the tile is @, the new map contains @. instead.\n\nThis will produce a new warehouse map which is twice as wide and with wide boxes that are represented by []. (The robot does not change size.)\n\nThe larger example from before would now look like this:\n\n####################\n##....[]....[]..[]##\n##............[]..##\n##..[][]....[]..[]##\n##....[]@.....[]..##\n##[]##....[]......##\n##[]....[]....[]..##\n##..[][]..[]..[][]##\n##........[]......##\n####################\n\nBecause boxes are now twice as wide but the robot is still the same size and speed, boxes can be aligned such that they directly push two other boxes at once. For example, consider this situation:\n\n#######\n#...#.#\n#.....#\n#..OO@#\n#..O..#\n#.....#\n#######\n\n<vv<<^^<<^^\n\nAfter appropriately resizing this map, the robot would push around these boxes as follows:\n\nInitial state:\n##############\n##......##..##\n##..........##\n##....[][]@.##\n##....[]....##\n##..........##\n##############\n\nMove <:\n##############\n##......##..##\n##..........##\n##...[][]@..##\n##....[]....##\n##..........##\n##############\n\nMove v:\n##############\n##......##..##\n##..........##\n##...[][]...##\n##....[].@..##\n##..........##\n##############\n\nMove v:\n##############\n##......##..##\n##..........##\n##...[][]...##\n##....[]....##\n##.......@..##\n##############\n\nMove <:\n##############\n##......##..##\n##..........##\n##...[][]...##\n##....[]....##\n##......@...##\n##############\n\nMove <:\n##############\n##......##..##\n##..........##\n##...[][]...##\n##....[]....##\n##.....@....##\n##############\n\nMove ^:\n##############\n##......##..##\n##...[][]...##\n##....[]....##\n##.....@....##\n##..........##\n##############\n\nMove ^:\n##############\n##......##..##\n##...[][]...##\n##....[]....##\n##.....@....##\n##..........##\n##############\n\nMove <:\n##############\n##......##..##\n##...[][]...##\n##....[]....##\n##....@.....##\n##..........##\n##############\n\nMove <:\n##############\n##......##..##\n##...[][]...##\n##....[]....##\n##...@......##\n##..........##\n##############\n\nMove ^:\n##############\n##......##..##\n##...[][]...##\n##...@[]....##\n##..........##\n##..........##\n##############\n\nMove ^:\n##############\n##...[].##..##\n##...@.[]...##\n##....[]....##\n##..........##\n##..........##\n##############\n\nThis warehouse also uses GPS to locate the boxes. For these larger boxes, distances are measured from the edge of the map to the closest edge of the box in question. So, the box shown below has a distance of 1 from the top edge of the map and 5 from the left edge of the map, resulting in a GPS coordinate of 100 * 1 + 5 = 105.\n\n##########\n##...[]...\n##........\n\nIn the scaled-up version of the larger example from above, after the robot has finished all of its moves, the warehouse would look like this:\n\n####################\n##[].......[].[][]##\n##[]...........[].##\n##[]........[][][]##\n##[]......[]....[]##\n##..##......[]....##\n##..[]............##\n##..@......[].[][]##\n##......[][]..[]..##\n####################\n\nThe sum of these boxes' GPS coordinates is 9021.\n\nPredict the motion of the robot and boxes in this new, scaled-up warehouse. What is the sum of all boxes' final GPS coordinates?\n\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_16.adb",
    "content": "--  Solution to Advent of Code 2024, Day 16\n-------------------------------------------\n--  Reindeer Maze\n--\n--  https://adventofcode.com/2024/day/16\n--  Copy of questions in: aoc_2024_16_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_16 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini1\"; n : constant := 15;\n  --  input_name : constant VString := +\"mini2\"; n : constant := 17;\n  input_name : constant VString := +\"aoc_2024_16\"; n : constant := 141;\n\n  r : array (Part_Type) of Integer;\n\n  s, e : Point;\n  map : array (1 .. n, 1 .. n) of Character;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        case c is\n          when 'S' =>\n            s.x := x;\n            s.y := y;\n            c := '.';\n          when 'E' =>\n            e.x := x;\n            e.y := y;\n            c := '.';\n          when others =>\n            null;\n        end case;\n        map (x, y) := c;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  --  Dijkstra shortest path algorithm.\n  --  Code adapted from AoC_2023_17.\n  --\n  --  The following definitions belong to the Dijkstra algorithm, but\n  --  we keep them less local because of the path tracking.\n\n  list_length_max : constant := 500_000;\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  type State_Type is record\n    pt  : Point;\n    dir : Direction;\n  end record;\n\n  type Node is record\n    len   : Natural;\n    state : State_Type;\n    pred  : Natural;  --  This is for backtracking the path.\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  best : array (1 .. n, 1 .. n, Direction) of Natural;\n  inf : constant Natural := Integer'Last / 4;\n\n  function Dijkstra_Algorithm (start, finish : Point) return Natural is\n    cur_len : Natural;\n    cur_s   : State_Type;\n    s       : State_Type;  --  Test state derived from current state.\n\n    procedure Visit (dir : Direction) is\n      len_to, ins : Integer;\n      vec : Point;\n      new_node : Node;\n    begin\n      if dir = Opposite (cur_s.dir) then\n        --  Turns must be 90 degrees.\n        return;\n      end if;\n      vec.x := 0;\n      vec.y := 0;\n      --  Move (otherwise, turn without moving):\n      if cur_s.dir = dir then\n        case dir is\n          when north => vec.y := +1;\n          when east  => vec.x := +1;\n          when south => vec.y := -1;\n          when west  => vec.x := -1;\n        end case;\n      end if;\n      s.pt.x := cur_s.pt.x + vec.x;\n      if s.pt.x in 1 .. n then\n        s.pt.y := cur_s.pt.y + vec.y;\n        if s.pt.y in 1 .. n then\n\n          if map (s.pt.x, s.pt.y) /= '.' then\n            return;\n          end if;\n\n          if cur_s.dir = dir then\n            len_to := cur_len + 1;     --  Cost for a move.\n          else\n            len_to := cur_len + 1000;  --  Cost for a turn.\n          end if;\n\n          if len_to < best (s.pt.x, s.pt.y, dir) then\n            s.dir := dir;\n            --  Found a better path to target state s.\n            best (s.pt.x, s.pt.y, dir) := len_to;\n            --\n            --  Insert in a sorted way.\n            --\n            ins := explored + 1;\n            for i in current + 1 .. explored loop\n              if len_to < list (i).len then\n                ins := i;  --  Insert here.\n                --  Optional: remove another node\n                --  with the same state and a larger length.\n                exit;\n              end if;\n            end loop;\n            for i in reverse ins .. explored loop\n              list (i + 1) := list (i);\n            end loop;\n            new_node.len   := len_to;\n            new_node.state := s;\n            new_node.pred  := current;\n            list (ins) := new_node;\n            explored := explored + 1;\n          end if;\n        end if;\n      end if;\n    end Visit;\n\n  begin\n    current  := 0;\n    explored := 0;\n\n    for x in 1 .. n loop\n      for y in 1 .. n loop\n        for d in Direction loop\n          best (x, y, d) := inf;\n        end loop;\n      end loop;\n    end loop;\n\n    cur_s.pt  := start;\n    cur_s.dir := east;\n    cur_len   := 0;\n\n    loop\n      for d in Direction loop\n        Visit (d);\n      end loop;\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        --  Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_s := list (current).state;\n      exit when cur_s.pt.x = finish.x and then cur_s.pt.y = finish.y;\n      cur_len := best (cur_s.pt.x, cur_s.pt.y, cur_s.dir);\n    end loop;\n    return best (cur_s.pt.x, cur_s.pt.y, cur_s.dir);\n  end Dijkstra_Algorithm;\n\n  procedure Do_Part_1 is\n  begin\n    r (part_1) := Dijkstra_Algorithm (s, e);\n  end Do_Part_1;\n\n  procedure Show_Map is\n  begin\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        if x = s.x and then y = s.y then\n          Put ('S');\n        elsif x = e.x and then y = e.y then\n          Put ('E');\n        else\n          Put (map (x, y));\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n    New_Line;\n  end Show_Map;\n\n  seat : array (1 .. n, 1 .. n) of Integer;\n\n  --  PPM picture output, adapted from AoC_2023_10.\n  --\n  procedure Dump_PPM is\n    d : File_Type;\n    f : constant := 50;\n    c : Integer;\n  begin\n    Create (d, input_name & \".ppm\");\n    Put (d, \"P6\" & Chr (10));\n    Put (d, n); Put (d, ' ');\n    Put (d, n); Put (d, Chr (10));\n    Put (d, \"255\" & Chr (10));\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        if x = s.x and then y = s.y then\n          --  Start.\n          Put (d, Chr (255));\n          Put (d, Chr (100));\n          Put (d, Chr (100));\n        elsif x = e.x and then y = e.y then\n          --  End.\n          Put (d, Chr (100));\n          Put (d, Chr (255));\n          Put (d, Chr (100));\n        elsif seat (x, y) >= 0 then\n          --  One of the optimal paths.\n          --  We try to given distinctive colours...\n          c := f * seat (x, y);\n          Put (d, Chr (255 - c));\n          Put (d, Chr (255 - c / 2));\n          Put (d, Chr (c / 2));\n        elsif map (x, y) = '.' then\n          --  Path, not optimal.\n          Put (d, Chr (44));\n          Put (d, Chr (44));\n          Put (d, Chr (44));\n        else\n          --  Wall.\n          Put (d, Chr (1));\n          Put (d, Chr (1));\n          Put (d, Chr (1));\n        end if;\n      end loop;\n    end loop;\n    Close (d);\n  end Dump_PPM;\n\n  verbose : constant Boolean := False;\n\n  --  For part 2 you have to find all optimal paths.\n  --  The method below is certainly far from being the most efficient\n  --  but at least maybe you will understand it ;-) ...\n  --\n  procedure Do_Part_2 is\n    opt : constant Integer := r (part_1);\n    blocks_added : Natural := 0;\n\n    procedure Search_Alternatives is\n      path : array (1 .. 20_000) of Point;\n      last : Natural := 0;\n      block : Point;\n\n      procedure Record_Optimal_Path is\n        --  We record the optimal path found by latest\n        --  run of Dijkstra's algorithm.\n        i : Integer := current;\n      begin\n        last := 0;\n        while i /= 0 loop\n          if i = current\n            or else not\n              (list (i).state.pt.x = path (last).x and then\n               list (i).state.pt.y = path (last).y)\n          then\n            last := last + 1;\n            path (last) := list (i).state.pt;\n            --  Mark the seats:\n            seat (path (last).x, path (last).y) := blocks_added;\n          end if;\n          i := list (i).pred;\n        end loop;\n      end Record_Optimal_Path;\n\n      alternative_found : Boolean;\n\n    begin\n      loop\n        Record_Optimal_Path;\n        alternative_found := False;\n        for i in 2 .. last - 1 loop\n          block := path (i);\n          --  Put a road block on the optimal way, step #i, and see what happens.\n          map (block.x, block.y) := 'B';\n          if Dijkstra_Algorithm (s, e) = opt then\n            --  There is another optimal path despite the road block.\n            alternative_found := True;\n            blocks_added := blocks_added + 1;\n            exit;\n          else\n            --  The road block worsens the optimal path. Remove it.\n            map (block.x, block.y) := '.';\n          end if;\n        end loop;\n        exit when not alternative_found;\n      end loop;\n    end Search_Alternatives;\n\n  begin\n\n    for x in 1 .. n loop\n      for y in 1 .. n loop\n        seat (x, y) := -1;\n      end loop;\n    end loop;\n\n    Search_Alternatives;\n\n    r (part_2) := 0;\n    for x in 1 .. n loop\n      for y in 1 .. n loop\n        if seat (x, y) >= 0 then\n          r (part_2) := r (part_2) + 1;\n        end if;\n      end loop;\n    end loop;\n\n    if verbose then\n      Show_Map;\n      Dump_PPM;\n      Put_Line (+\"Total road blocks added: \" & blocks_added);\n    end if;\n\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n\n  Do_Part_1;\n  if not compiler_test_mode then\n    Do_Part_2;\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Integer_Value (Argument (1)) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 74392\n    --  Part 2: validated by AoC: 426\n  end if;\nend AoC_2024_16;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_16.txt",
    "content": "#############################################################################################################################################\n#.......#.....#.....#.........#...........#.....#.............#.......#.#.....#.......#...#.....#.....#.......#.....#.......#.........#....E#\n#.#.###.###.#.#.###.#####.#.###.#.#.#######.###.#.###.#.#######.#.###.#.#.###.#.#.###.#.#.#.#.#.#.###.#.#.#####.###.#.#.###.#.###.#####.#.###\n#.#...#.....#.....................#.#.....#.#...#.....#.#...........#...#...#...#...#.#.#...#.#.#.....#.#.......#...#.....#.#.#.#.......#...#\n#####.###########.#####.#####.#.#.###.###.#.#.#.###.#.#.#.#########.#######.#######.#.#######.#.#.#.###.#########.#####.#.#.#.#.#.#####.#.#.#\n#.....#.....#...#.....#.#...#.#.#.....#.#.....#.#...#...#.....#...#.......#.#.....#.#.........#...#.#...#.#.......#...#...#.#...#.......#...#\n#.#########.#.#.#.#.###.#.#.#.#.#######.#####.###.###.#######.###.#######.#.#.#.#.#.###########.#.#.#.###.#.###.###.#.#.###.###.#.#.###.#.#.#\n#...#.....#.#.#...#.#...#.#.#.#.......#...#.#.......#.......................#.#.#.#.#.........#...#.#.#...#...#.#...#...#.#...#.....#.....#.#\n#.#.###.#.#.#.#####.#.###.#.#.###.###.#.#.#.#.#######.###.#.###.###.###.#.#.#.#.#.#.#.#######.###.#.#.###.###.#.#.#####.#.#.#####.#.#.#.#.#.#\n#.#...#.#.........#.#.#...#.#.......#...#...#.#.........#...#...#.......#.#.#...#.#.#.#.....#...#.#...#.....#.................#.....#...#...#\n#.###.#.###.###.#.#.#.###.#.###.#.#.#######.#.#.#####.#.###.#.#########.#.#.#.#####.#.#.#######.#.#.###.###.#.#.#######.#.###.#.#.#.###.#.###\n#...#.#...#.#.....#...#...#.....#.........#...#...#...#...#...#...#.....#.#...#.....#...#.......#.....................................#.....#\n###.#.###.###.#.#######.#######.#.###########.###.#.#.###.#####.#.#######.###.#.#######.#.#####.#.#.#####.#.#.#.#.#####.#.#.#.#.#.#.#.#.#.#.#\n#...#...#.........#.........................#...#.#...........#.#.......#.....#...#...#.#.....#.#.#.....#.#.#.#.#...#.#...#.#.#.#...#...#.#.#\n#.#.###.#.#####.#.#######.#.#.###.###.#.#.###.#.#.###.#######.#.#######.#####.###.#.#.#######.#.#.#####.#.#.#.#####.#.#.###.#.#.#.#.###.###.#\n#.#.....#.#.....#.........#.#.....#.#.#.#.......#.........#...#.#.....#.....#...#.#.#...#.....#.#.....#.#.#.#.....#...#.....#...#...#.#.#...#\n#.#.#######.###.#########.#.#######.#.#.#####.#######.###.#.###.#.###.#####.#####.#.###.#.###########.#.#.#.#####.###.#.###.#####.#.#.#.#.#.#\n#.#.#.........#.#.#.......#...#.....#.#.....#.......#...#.#.....#...#.....#.......#.#...#.#.......#...#...#...#.....#.#...#.....#.#...#...#.#\n#.###.#########.#.#.#########.#.#.#.#.#####.#.#####.###.#.#########.#.#.###.#######.#.###.#.#####.#.#####.#####.#####.#.#.###.###.#.#.#.###.#\n#.......#.....#.#...#.......#.#.#.#.#...#...#...#.#...#.#.#...#.....#...#...#.......#.#...#.....#.#.#.#...#.....#.....#.#.#.#.#...#.....#.#.#\n#.#######.###.#.#.###.###.###.###.#####.#.#####.#.###.###.#.###.#.#######.###.#######.###.#####.#.#.#.#.###.#####.#######.#.#.#.#.#.###.#.#.#\n#.#...#...#.#.#.#.#.#...#.#...#...#.....#...#.#.#.........#.....#...........#.......#.#...#...#.#...#.#.#.#.....#.#.....#.#.#.#.#.....#...#.#\n###.#.#.###.#.#.#.#.#.#.#.#.###.#.#.#######.#.#.###.#############################.###.#.###.#.#.#.###.#.#.#####.#.###.#.#.#.#.#.#.#.#.#.#.#.#\n#...............#.#...#.#.#.....#.#.....#...#.#...#.#...#.......#.....#...........#...#.....#...#.....#.#.....#.......#.#.#.#.#...#.#.#...#.#\n#.#.#############.###.#.#######.#######.#.###.###.###.#.#.#####.#.###.#.#######.###.###.#########.###.#.###.###########.#.#.#.###.###.#.###.#\n#...#.......#.......#.#.....#...#.......#.....#.#...#.#.......#.#.#.#...#.....#.....#...#.#.........#...#...#.....#.......#.....#.#...#.#...#\n#.#.#.#####.#######.#.#.#.#.#.###.#####.#####.#.###.#.#########.#.#.#####.#####.#####.###.#.#########.###.#.#.###.#######.#######.#.#####.###\n#.#...#...#.......#.#.#...#.#.#.#.....#.....#.#...#...#.........#.....#.....#...#...#.....#.#...#...#.#...#.#.#.......#...#...#.............#\n#.#.#####.###.###.#.#.###.#.#.#.#####.#####.#.#.#.###.###.#.#########.#####.#.#.#.###.###.#.#.###.#.#.###.###.#######.#.###.#.#.#####.#.#.#.#\n#...#.......#.#...#.#.#.....#.#...#...#...#.#...#.#.....#.#...#...#.........#.#.....#...#.....#...#.#...#...#...#...........#...#.....#.#...#\n###.#.#.###.#.#.###.#.#.###.#.###.#.###.#.###.###.#.###.#.###.#.#.#.#########.#####.###.#######.###.###.#.#.###.###################.###.#.#.#\n#...#.#.#.#...#.#...#.#.#.#.#.....#.....#.......#...#.#.#...#...#...#...#...#...#.....#...#.....#.#...#.#.#...#.......#...#.#.......#...#.#.#\n#.#.#.#.#.###.#.#.#####.#.#.#####.#########.###.###.#.#.###.#########.#.#.#.#.#.#.###.###.#.#####.###.#.###.#.#######.#.#.#.#.#.#####.###.###\n#.#...#.#...#.#.#.......#.#...#...#.......#.#.#.#.......#...#.......#.#...#.#.#.#.#.....#.#.#...#...#.#.....#.#...#...#.#.#.#.#...#...#.....#\n#.#.###.#.#.#.#.#######.#.###.#.###.#####.#.#.#.#.###.#.#.#.###.#####.#####.#.#.#.#.#.###.#.#.#.#.#.#.#########.#.#.###.#.#.#.###.#.###.#.#.#\n#...#...#.#.#.#.#.............#.#.......#.#.#...#.....#...#.....#.....#...#.....#...#.....#...#...#...#.........#.#...#...#.....#...#.......#\n###.#.#####.#.#.#####.#########.#########.#.#.###.#############.#.#####.#.#######.#########.#########.#.#########.#.#.#.#.#######.###.#.#.#.#\n#...#.....#...#.....#...#...#.#.......#...#.#.....#.............#...#.#.#.....#.#.#.......#.........#.#.....#...#.#.#...#.......#.....#...#.#\n#.#.#.#.#.#.#######.#.#.#.#.#.###.###.#.#.#.#######.#########.#.###.#.#.#.###.#.#.#####.#.#######.#.#.#.###.#.###.#.#########.#.#######.#.#.#\n#.....#.#.#...#...#...#...#.....#.......#.#.......#.....#...#.....#.#.#.#.#.#.#.#.......#...#.......#.#...#.#.#...#.#...#...#.#.#...#.......#\n###.#.###.###.#.#.###.#########.#.#########.#.###.#####.#.#.#######.#.#.#.#.#.#.###########.#.#######.#.###.#.#.###.#.###.#.###.#.#.###.#.###\n#.#...#...#...#.#.......#.......#.#.#...........#.......#.#...#.....#...#.#...#.....#...#...#.#.....#.#.#...#.#.#.#...#...#...#.#.#...#.#...#\n#.#.#.#.###.###.#######.#.#######.#.#.###.#####.#####.###.###.#.#####.###.#.#####.#.###.#.###.#.#####.#.#.###.#.#.###.#.###.#.#.#.###.#.#.#.#\n#.#.#...#...#...#...#.....#...#...#.#...#...........#.#...#.#.#.#.......#.#.......#.....#...#.#.#.....#.#.#...#.#.#...#.#.......#.#.#.......#\n#.#.#.#####.#.###.#.#######.#.#.###.###.###.#######.#.#.###.#.#.#######.#.#####.###.#######.#.#.#.#####.#.#.#.#.#.#.###.#.#######.#.#.#.###.#\n#...#.....#.#.....#.........#...#.....#.#.......#...#.#.#.......#...#...#.....#.#.....#...#.#.#.......#.#.#.#.#.#...#...#.#.......#.#...#...#\n#.###.###.#.#####################.###.#.#.#####.#.###.#.#######.#.#.#####.###.###.###.#.#.#.#.#######.###.#.###.#.#.#.#####.#######.###.#####\n#.#.....#.#.#.........#...#.....#.#...#.#.#.....#...#.....#...#.#.#.#...#...#...#...#...#...#.....#.......#...#.#...#...........#.....#.....#\n#.###.#.#.#.#######.#.#.#.#.#.#.#.#.###.#.#########.#####.#.#.###.#.#.#.###.###.###.#########.###.###########.#.#######.#######.#####.#.###.#\n#.....#...#.....#...#...#.#.#.#...#.#.#.#...........#...#...#.....#...#...#...#.#...#.....#...#.#.....#.......#.#.....#.#.....#...........#.#\n#.###.#########.#.#######.###.#.#.#.#.#.#.###########.#.#################.###.#.#.###.###.#.###.#####.###.#.###.#.###.#.#.###.#######.#.###.#\n#.......#.........#.....#...#.#...#...#.#...#...#.....#...................#...#.#.#...#...#.#.......#...#.#.......#...#.#.#.........#.#.....#\n#.#.###.#.#######.#.###.###.#.#########.###.#.###.#.#######################.###.#.#.#######.###.###.###.#.#.#######.#####.#########.#.#.###.#\n#.#.#.#.#.#.....#.#.#.#...#.............#.#.#.#...#.........#.....#.......#.#.#.#.#.......#...#.#.#.#.#.#.....#...#.......#...#...#.........#\n###.#.#.#.#.###.#.#.#.###.###.#.#########.#.#.#.#########.#.#.###.#.###.#.#.#.#.#.#######.###.#.#.#.#.#.#######.#.###.#####.#.#.#.###.#.#.#.#\n#...#.#.#.#.#...#.#.#...#.....#...#.....#.#.#.....#...#.....#...#...#...#.#.#.#.#...#...#.#...#.#.#.#...........#.#...#.....#...#...#...#.#.#\n#.###.#.###.#.#####.#.#######.###.#.###.#.#.#.###.#.#.#.#####.#.#####.#.#.#.#.#.###.#.#.#.#.###.#.#.#.#########.#.#####.###########.#.#.#.#.#\n#.........#.........#.......#...#.....#...#.#...#...#.#...#...#...#.#.#...#...#.....#.#...#...#.#...#...#.#.....#...#...#.........#...#.....#\n#.#######.#.#########.#####.###.#.#.#.###.#.#.#.#####.###.#.#.###.#.#.#######.#######.#######.#.#.###.#.#.#.###.###.#.###.#######.###.#.#####\n#.....#...#.#.#.......#...#...#...#.#...#.#...#.......#...#.#.#...#.#.......#.#...#.#.................#...#.#.#.....#.#...#.........#.#.....#\n#.###.#.###.#.#.#########.#.###########.#.#.#######.###.###.###.###.#######.#.#.#.#.#.#######.#######.#####.#.#####.#.###.#.#######.#.#####.#\n#.#.#.#.#...#.#.#.........#.............#.#.......#...#.#.......#.........#.#.#.#.#.....#...#.#.....#.#.....#.#.....#...#.#...#.....#...#.#.#\n#.#.#.#.###.#.#.#.#####.###########.#.###########.#.###.#.###.#.#.#.#####.#.#.#.#.#.#####.#.###.###.###.#####.#.#####.#.#####.#####.#.#.#.#.#\n#...#.#.#...#...#...#...#.........#.#.#...#...#...#.#...#.#.#...#.#.....#.#...#.#.#.#.....#...#...#.....#.......#...#...#...................#\n###.#.#.#.#.#.#####.#.###.#######.#.###.#.#.#.#.#####.###.#.###.#######.#.#####.#.#.#.#######.#.#.#.#########.###.#.#.###.#.###.#.#####.#.#.#\n#...#.#...#.....#.#.#.....#...#...#.....#...#.#...#...#.#.#.............#.#.....#.#.#.#...#...#.#.....#.....#.....#.#.....#.#...#.......#...#\n#.###.#####.###.#.#.#######.#.#.#.###########.###.#.###.#.#.#########.###.#####.#.#.#.###.#.#######.#.#.###.#######.#####.###.#.#########.###\n#...#.......#.#.#.#...#.....#...#.#.#.....#...#...#...#...#.#.....#.....#.......#...#...#...#.........#.#.#.....#.....#...#...#.#.........#.#\n#####.#####.#.#.#.#.#.#.#########.#.#.###.#.###.#####.#.#.#.#.#####.###.###########.#.#.#.#####.###.###.#.#####.#######.###.###.#.#########.#\n#...#...#...#...#.....#.........#.#...#...#.....#.....#...#.#.#.....#.#.......#.....#.#.......#.#...#...#...#.#...........#.#.....#...#.....#\n#.#.#####.#.#.###.#####.#######.#.#####.###########.#####.#.#.#.#####.#####.###.#####.#.#####.#.###.#.###.#.#.#############.#.#.###.#.#####.#\n#.#.#...#.#.#...#.#...#.....#...#.#...#.............#...#.#.#.#.#.....#...#...#.....#.#.#.....#.......#...#.............#...#.....#.#.......#\n#.#.#.#.#.#.###.###.#.#.#.#.#.###.#.#.#.#########.###.#.#.#.#.#.#####.###.#.#.#####.###.#.#####.#######.#######.#.#######.#####.#.#.#.###.#.#\n#.#...#...#...#.....#.#...#...#.#.#.#.#.#.#...#...#.#.#.....#...#.......#.#.#...........#.....#.#.......#.........#.....#...............#...#\n#.#########.#.#####.#.#.###.#.#.#.#.#.#.#.#.#.#.###.#.#.#####.#.#.###.###.#.#######.#########.#.#####.###.#####.###.###.###.#.#.#####.###.###\n#.#...#.......#.....#...#.#...#...#.#.#.....#...#...#.#.....#.#.#...#.#...#.#.............#.#.#.#...#.#...#...#.#.#.#.#...#.#.....#...#...#.#\n#.#.#.#####.###.#.#######.#####.###.#.#####.#####.#.#.###.#.#.#.#.#.#.#.###.#.#.###.#####.#.#.#.#.#.#.#.###.#.#.#.#.#.###.#.###.#.#.#.#.#.#.#\n#.........#.#...#.............#.#...#.....#...#...#.......#.#.#...#.#.#.#...#.#.........#.#.......#.#.#.#...#.#.#.#.#...#...#...#...#.#...#.#\n#.#.#####.#.#.#####.#########.#.#.#######.###.#.###.#####.###.#.###.#.#.#.###.#.#########.#.#######.#.#.#.###.#.#.#.#.#######.#.#.###.###.#.#\n#...#.#...#.....#...#.......#.#.#...#.....#...#...#.#.#...#...#.#...#.#.#.#...#.................#...#.....#...#...#.#.#...#.......#...#.#...#\n#.###.#.#########.#.###.###.#.#.###.#.#####.#####.#.#.#.###.#####.###.#.###.###.#.#############.###.#.###.#.#######.#.#.#.#.#####.#.#.#.#.#.#\n#.......#.........#...#...#...#...#.#.......#.....#.#.#...#.....#.#...#.....#.#.#.........#...#...#...#...#.#.......#...#...............#...#\n#.#####.#.#.#######.#.###########.#.#########.###.#.#.###.#####.#.#.#########.#.#####.###.###.###.###.#.#.#.#.#######.#.#########.#.#.#.#.###\n#.#.....#.#.......#.#...........#...#...#.......#.#.#...#...#...#.#.#.#.......#...#...#.....#.....#...#.#.#...#.....#...#.........#...#.#.#.#\n#.#.#####.#######.#.###.###.#.#######.#.#.#####.###.#.#.#.#.#.###.#.#.#.#####.###.#.###.###.###.###.###.#.#####.###.###.#.#############.#.#.#\n#.#...#...#.....#...........#.......#.#.#.......#...#.#.#.#.#.....#.#.#.#.#.....#...#.#...#...#.#.....#.#.......#.....#.#.....#.......#.#...#\n#.###.#.#####.#.#####.#######.###.###.#.###.#.#.#.#####.#.###.#.###.#.#.#.#.###.#####.#.#.###.#.#####.#.#########.###.#.#####.#.#####.###.#.#\n#...#.#.....#.#.....#.......#...#.....#...#.#.#.#.#.....#.....#...#.#...#.#.#...#...#...#...#.#.#...#.#...#...#...#.....#...#.#.#...#.....#.#\n###.#.#####.###.#####.#####.###.#########.#.#.###.#.###.#####.###.#.#.#.#.#.#####.#.#.###.#.#.#.#.#.#.###.#.#.#.###.#######.#.#.#.#.#####.#.#\n#...#...#...#...#.....#...#...#.#...#...#...#...#.#.#...#.........#.#.....#.......#.#.....#...#...#.#...#...#.#.....#.....#.#...#.#.#.....#.#\n#.#####.#.###.###.#####.#.###.#.#.#.#.#.###.###.#.#.#.#####.#######.###############.###.#.###.#####.#####.###.#.#####.###.#.#####.#.#.#####.#\n#.....#.#...#.#...#.....#...#.#.#.#.#.#...#...#.....#.......#.....#.................#...#.....#.#...#.........#...#.#...#...#.....#.#.......#\n#####.#.###.#.#.#.#########.#.#.#.#.#.###.###.#############.#.###.#.###############.#.#####.#.#.#.###.###########.#.#.#.###.#####.###.#.#####\n#.#...#.#...#.#.......#.....#.....#.#...#.#...#.#...#.......#...#.............#...#.#.......#.#.#.....#.....#...#.#...#.#.............#...#.#\n#.#.###.#.#.#.#######.#.#####.#######.#.#.###.#.#.#.#####.#.###.#.###########.###.#.#######.#.#.###.#####.###.#.#.#####.#######.###.#.###.#.#\n#.#.#...#.......#.#...#.#...#...........#...#...#.#.....#.#...#.#...#.......#...#.....#.......#...#.......#...#.#.....#...#.....#...#...#.#.#\n#.#.#.#.#######.#.#.###.#.#.###############.#.###.#####.###.#.#.#.###.###.#####.#######.###.###.#.#.###.###.###.#####.#.#.#######.#####.#.#.#\n#...#...#.......#.#.#.#...#...#.....#...........#.....#.....#.#.#.....#...#.....#...............#.#.#...#...#...#...#.#.#.#...#...#...#.#.#.#\n#######.#.#######.#.#.#.###.#.#.###.#####.#####.#.###.#######.#.#.#.###.###.#####.#############.#.#.#.###.###.#.###.#.#.#.#.#.#.#####.#.#.#.#\n#.......#.......#.#.#.#.#...#.#.#...#...#.....#.....#...#...#.#.#.#...#...#...#...#.#...........#.#.#.....#.#.#.....#.#.#...#.#...#.........#\n#.#####.#######.#.#.#.#.#.###.#.#.###.#.###.#.###.#####.###.#.#.#.#.#.###.###.#.###.#.#.#########.#.#######.#.#######.#.#####.###.#.###.#.#.#\n#.....#...........#.#.#.#.#...#.#.....#.....#.#...#...#...#.#...#...#...#...#...#.....#.......#...#.#.....#.#.........#.....#...#.#.....#...#\n#.###.#.###########.#.#.#.#.###.#############.#.###.#.###.#.#####.#####.###.#############.###.#####.#.###.#.###############.#.###.#.#.#####.#\n#...#...#...........#...#.#.#...#...#.....#...#.....#...#.#...#...#...#...#.........#...#.#...#.....#.#...#.#...........#...#.#...#...#.....#\n###.###.#.###########.###.#.#.#.#.#.###.#.#.#########.#.#.#.#.###.#.#.###.#.#####.#.#.#.###.#.#.#####.#.###.#.#######.#.#####.#.#.#####.#####\n#.......#.....#.........#.#.#.#...#...#.#.#.....#...#.#.#...#...#.#.#.....#.#...#.#...#...#.#.#.#.....#.#.........#...#.#.....#.#.#.....#...#\n#.#####.#####.#########.#.#.#########.#.#.#####.#.###.#.#######.#.#.#######.#.#.#.#######.#.###.#.#####.###########.###.#.###.#.#.#.#####.#.#\n#.#...#.....#.......#.#.#.#...........#.#.#.....#...#.#.#...#.#...#.......#.#.#.#.....#.......#.#.....#...#.....#...#.#...#...#.#.#.#.....#.#\n#.#.#.#.#.#########.#.#.#.#############.###.#######.#.#.#.#.#.###########.#.#.#.#####.#.#.###.#.#####.###.#.###.#.###.#.#######.#.#.#.#####.#\n#...#.#...#.......#.#...#...#.......#...............#.#...#.#.#.....#...#.#.#.#...#...#.#.....#.......#.#.#.#.....#.....#...#...#.#.#.....#.#\n#.###.#.#.#.#.###.#.#.#####.###.#.###.###########.#.#.#####.#.#.###.#.#.#.###.###.#.###.#####.#######.#.#.#.#######.#####.#.#.###.#.#######.#\n#...#...#.#...#.#...#.....#...#.#...#.#...#.......#.#.#...#...#.#.#.#.#...#...#.....#.....#...#.#.........#...#...#.#...#.#...#...#.........#\n###.###.#.###.#.#####.#######.#####.#.#.#.#.#####.#.#.#.#.#####.#.#.#.#####.###########.#.#.###.#.###########.#.#.###.#.#.#####.###########.#\n#...#...#...#...#.............#.....#...#.#.#...#.#.#.......#...#.#.#...#...#.........#.#.......#.#.........#...#...#.#...#.....#.....#...#.#\n#####.#.###.#.#.#.###.#########.#####.###.#.#.###.#.#####.#.#.###.#.###.###.#.#######.#.#########.#.#####.#.#######.#.###.#######.#.###.#.#.#\n#.....#.......#.#.#...#.....#.....#...#...#.#...#.#.#...#...#.#...#.....#...#...#...#.#.#.....#...#.#.....#.......#.#...#.#.................#\n#.###.#.###.#.#.#.#.###.###.#.###.#.#.#.###.#.#.#.#.#.#.#.#.#.###.#######.#####.#.#.#.#.#.###.#.#.#.#.###########.#.###.###.#############.#.#\n#.#...#.....#...#.#.#.....#.#...#...#.....#.#.#.#.#.#.#...#.#...#.....#...#.....#.#.#.#.#...#...#.....#.........#...#.....#...#.....#...#...#\n#.#########.#.###.#.#.#.#.###.#####.#######.###.#.###.#####.###.###.#.#.###.#####.###.#####.#####.#####.#######.###.#.###.###.#####.#.#.#####\n#.#.....#...#...#.#...#.#.....#...#...#...#.#...#.....#...#.#.#.....#.#.#...#.....#...#...#.#.....#.#.......#.#...#...#.#.#...#...#...#.....#\n#.#.###.#.#.#.###.###.#.#######.#.###.#.#.#.#.#########.###.#.#######.#.#.###.###.#.###.#.#.###.###.#.#####.#.###.###.#.#.#.###.#.#######.###\n#...#.#...#...#...#...#...#.....#...#.#.#.#.#.................#.....#.#.........#.#.....#.#...#.#...#.....#.#.......#.#.#...#...#.......#...#\n#.###.#####.#.#.###.#####.#.#######.###.#.#.#############.#####.###.#.#####.###.#.#######.###.#.#.#.###.#.#.#########.#.#####.#########.###.#\n#.........#.#...#.#...#.#.#.#.....#.....#...#.....#.....#.#.....#...#.....#...#.#...#...#.....#.#.#...#.#.#.#.........#.......#.......#.#...#\n#.#######.#.#####.###.#.#.#.#.#.#####.#####.#.###.#.###.###.#####.#.#####.###.#.###.#.#########.#####.#.#.#.#.#######.#.#.#######.#####.#.###\n#.....#...#.....#...#.#.#.#.#.#.......#...#.#.#.#...#.#.......#...#.#...#.#.#.#.#.....#.....#...#.....#.#.#...#.....#...#.#.....#...........#\n#####.#.###.###.###.#.#.#.#.#.###.#####.#.###.#.#####.#########.#.###.#.#.#.#.#.#######.#.#.#.#.#.###.#.#.#######.#.#.#.###.###.#.#########.#\n#.....#...........#.#.#...#.#.........#.#.....#...........#.....#.#...#...#.#.#.#.......#.#.....#.#...#...........#.#.#...#.#...#...#.......#\n#.###.#.#.###.###.#.#.#.#.#.#######.###.#######.###.###.###.###.#.#.#######.#.#.#.#######.###.###.#######.#########.#.###.#.#.#####.#.#.###.#\n#.#...#...#.#.#.....#.#...#.....#.#.#...#.....#...#.#.#.#...#...#.#.#...#.....#...#.....#.#.....#.......#.....#...#.#.#...................#.#\n#.###.#####.#.#.#####.#.#######.#.#.#.#.#.#.###.###.#.#.#.###.#.#.#.###.#.#####.###.###.#.###.#.#######.#.#.###.#.#.#.#.#.#.###.#.#.###.#.#.#\n#...#...#.....#.#.....#.......#.#...........#...#...#...#.#...#...#.#...#.#.....#.#.#.#...#...#.........#.#...#.#...#...#...#...#...........#\n#.#.###.#.#####.#.###.#########.#####.#.#####.###.#######.#.#######.#.###.#.#####.#.#.#####.#######.#####.###.#.#####.#####.#.###.###.###.#.#\n#.#...#.#.#.....#.#...#.........#.....#.....#.#...#.......#...#...#.#.....#.#.....#.#.........#...#.#...#...#.#.#...#.#...#.#...#.#...#...#.#\n#.###.#.#.###.###.#.###.#######.#.###.#####.#.#.###.#########.#.###.#.#####.#.###.#.#.#######.###.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#.###.#.###.#\n#.#...#.#...#.#...#.#.#...#.....#.........#...#.#...#...#.#.....#...#.#...#.#.#...#.#.....#.#...#...#.#...#...#.#...............#.....#.....#\n#.#.#######.#.#.###.#.###.#####.#########.###.#.#.#.#.#.#.#.#####.###.#.#.#.#.#####.#####.#.###.#.###.###.#.###.#####.#.#.###.#########.#####\n#.#.....#...............#.#...#.#...#.....#.....#.#.#.#.#.....#...#.#...#.#...#...#...#.#...#...#.#...#...#.....#...#.#.#.....#.....#...#...#\n#.###.#.#.#####.#.#####.#.#.#.###.#.#.#####.#.#.#.###.#.#######.###.#####.#####.#.###.#.###.#.#####.#.###.#####.#.#.###.#######.#.###.###.#.#\n#S....#.........#.......#...#.....#.........#...#.....#.........#...............#.....#.....#.....................#.....#.......#.........#.#\n#############################################################################################################################################\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_16_questions.txt",
    "content": "--- Day 16: Reindeer Maze ---\n\nIt's time again for the Reindeer Olympics! This year, the big event is the Reindeer Maze, where the Reindeer compete for the lowest score.\n\nYou and The Historians arrive to search for the Chief right as the event is about to start. It wouldn't hurt to watch a little, right?\n\nThe Reindeer start on the Start Tile (marked S) facing East and need to reach the End Tile (marked E). They can move forward one tile at a time (increasing their score by 1 point), but never into a wall (#). They can also rotate clockwise or counterclockwise 90 degrees at a time (increasing their score by 1000 points).\n\nTo figure out the best place to sit, you start by grabbing a map (your puzzle input) from a nearby kiosk. For example:\n\n###############\n#.......#....E#\n#.#.###.#.###.#\n#.....#.#...#.#\n#.###.#####.#.#\n#.#.#.......#.#\n#.#.#####.###.#\n#...........#.#\n###.#.#####.#.#\n#...#.....#.#.#\n#.#.#.###.#.#.#\n#.....#...#.#.#\n#.###.#.#.#.#.#\n#S..#.....#...#\n###############\n\nThere are many paths through this maze, but taking any of the best paths would incur a score of only 7036. This can be achieved by taking a total of 36 steps forward and turning 90 degrees a total of 7 times:\n\n\n###############\n#.......#....E#\n#.#.###.#.###^#\n#.....#.#...#^#\n#.###.#####.#^#\n#.#.#.......#^#\n#.#.#####.###^#\n#..>>>>>>>>v#^#\n###^#.#####v#^#\n#>>^#.....#v#^#\n#^#.#.###.#v#^#\n#^....#...#v#^#\n#^###.#.#.#v#^#\n#S..#.....#>>^#\n###############\n\nHere's a second example:\n\n#################\n#...#...#...#..E#\n#.#.#.#.#.#.#.#.#\n#.#.#.#...#...#.#\n#.#.#.#.###.#.#.#\n#...#.#.#.....#.#\n#.#.#.#.#.#####.#\n#.#...#.#.#.....#\n#.#.#####.#.###.#\n#.#.#.......#...#\n#.#.###.#####.###\n#.#.#...#.....#.#\n#.#.#.#####.###.#\n#.#.#.........#.#\n#.#.#.#########.#\n#S#.............#\n#################\n\nIn this maze, the best paths cost 11048 points; following one such path would look like this:\n\n#################\n#...#...#...#..E#\n#.#.#.#.#.#.#.#^#\n#.#.#.#...#...#^#\n#.#.#.#.###.#.#^#\n#>>v#.#.#.....#^#\n#^#v#.#.#.#####^#\n#^#v..#.#.#>>>>^#\n#^#v#####.#^###.#\n#^#v#..>>>>^#...#\n#^#v###^#####.###\n#^#v#>>^#.....#.#\n#^#v#^#####.###.#\n#^#v#^........#.#\n#^#v#^#########.#\n#S#>>^..........#\n#################\n\nNote that the path shown above includes one 90 degree turn as the very first move, rotating the Reindeer from facing East to facing North.\n\nAnalyze your map carefully. What is the lowest score a Reindeer could possibly get?\n\n--- Part Two ---\n\nNow that you know what the best paths look like, you can figure out the best spot to sit.\n\nEvery non-wall tile (S, ., or E) is equipped with places to sit along the edges of the tile. While determining which of these tiles would be the best spot to sit depends on a whole bunch of factors (how comfortable the seats are, how far away the bathrooms are, whether there's a pillar blocking your view, etc.), the most important factor is whether the tile is on one of the best paths through the maze. If you sit somewhere else, you'd miss all the action!\n\nSo, you'll need to determine which tiles are part of any best path through the maze, including the S and E tiles.\n\nIn the first example, there are 45 tiles (marked O) that are part of at least one of the various best paths through the maze:\n\n###############\n#.......#....O#\n#.#.###.#.###O#\n#.....#.#...#O#\n#.###.#####.#O#\n#.#.#.......#O#\n#.#.#####.###O#\n#..OOOOOOOOO#O#\n###O#O#####O#O#\n#OOO#O....#O#O#\n#O#O#O###.#O#O#\n#OOOOO#...#O#O#\n#O###.#.#.#O#O#\n#O..#.....#OOO#\n###############\n\nIn the second example, there are 64 tiles that are part of at least one of the best paths:\n\n#################\n#...#...#...#..O#\n#.#.#.#.#.#.#.#O#\n#.#.#.#...#...#O#\n#.#.#.#.###.#.#O#\n#OOO#.#.#.....#O#\n#O#O#.#.#.#####O#\n#O#O..#.#.#OOOOO#\n#O#O#####.#O###O#\n#O#O#..OOOOO#OOO#\n#O#O###O#####O###\n#O#O#OOO#..OOO#.#\n#O#O#O#####O###.#\n#O#O#OOOOOOO..#.#\n#O#O#O#########.#\n#O#OOO..........#\n#################\n\nAnalyze your map further. How many tiles are part of at least one of the best paths through the maze?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_17.adb",
    "content": "--  Solution to Advent of Code 2024, Day 17\n-------------------------------------------\n--  Chronospatial Computer\n--\n--  https://adventofcode.com/2024/day/17\n--  Copy of questions in: aoc_2024_17_questions.txt\n--\n--  HAC 0.40 \"nice-to-have\"'s detected in this exercise:\n--\n--    *     Modular types (esp. Unsigned_X and bitwise operators)\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  HAC 0.40 \"nice to have\"'s detected in this exercise:\n--    *     Unsigned_X and bitwise operators on it.\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_17 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  subtype UInt is Integer_64;             --  Hack for HAC. \"Full Ada\": type UInt is mod 2 ** 64;\n  subtype Word is Integer range 0 .. 7;   --  Hack for HAC. \"Full Ada\": type Word is mod 2 ** 3;\n\n  r : array (Part_Type) of VString;\n\n  type Instruction is (adv, bxl, bst, jnz, bxc, ovt, bdv, cdv);\n\n  type Word_Array is array (0 .. 20) of Word;\n\n  type Word_Vect is record\n    oct  : Word_Array;\n    last : Integer;\n  end record;\n\n  procedure Convert (prog_s : in VString; prog : out Word_Vect) is\n  begin\n    prog.last := Length (prog_s) - 1;\n    for i in 1 .. prog.last + 1 loop\n      prog.oct (i - 1) := Word (Ord (Element (prog_s, i)) - Ord ('0'));\n    end loop;\n  end Convert;\n\n  procedure Run (A_start : in UInt; prog : in Word_Vect; code : out Word_Vect) is\n    A : UInt := A_start;\n    B : UInt := 0;\n    C : UInt := 0;\n    p : Natural := 0;\n\n    inst : Instruction;\n    oper : Word;\n\n    function Combo return UInt is\n    begin\n      case oper is\n        when 0 .. 3 => return UInt (oper);\n        when 4      => return A;\n        when 5      => return B;\n        when 6      => return C;\n        when 7      => Put (\"Error\"); return 0;  --  \"Full Ada\": raise Program_Error;\n      end case;\n    end Combo;\n\n  begin\n    code.last := -1;\n\n    while p <= prog.last loop\n      inst := Instruction'Val (prog.oct (p));\n      oper := prog.oct (p + 1);\n      p := p + 2;\n      case inst is\n        when adv => A := A / (2 ** Natural (Combo));\n        when bdv => B := A / (2 ** Natural (Combo));\n        when cdv => C := A / (2 ** Natural (Combo));\n        when bxl => B := Sim_XOR (B, UInt (oper));  --  \"Full Ada\" has `xor` of course.\n        when bst => B := Combo mod 8;\n        when jnz => if A /= 0 then p := Natural (oper); end if;\n        when bxc => B := Sim_XOR (B, C);  --  \"Full Ada\" has `xor` of course.\n        when ovt =>\n          code.last := code.last + 1;\n          code.oct (code.last) := Word (Combo mod 8);\n      end case;\n    end loop;\n\n    --  mini  : result is: 4,6,3,5,6,3,5,2,1,0\n    --  input : result is: 5,1,4,0,5,1,0,2,6\n  end Run;\n\n  procedure Run_Hardcoded (A_start : in UInt; code : out Word_Vect) is\n    A : UInt := A_start;\n    B : UInt := 0;\n    C : UInt := 0;\n  begin\n    code.last := -1;\n    loop\n      B := A mod 8;\n      B := Sim_XOR (B, 1);  --  \"Full Ada\" has `xor` of course.\n      C := A / 2 ** Natural (B);\n      B := Sim_XOR (B, 4);  --  \"Full Ada\" has `xor` of course.\n      A := A / 8;\n      B := Sim_XOR (B, C);  --  \"Full Ada\" has `xor` of course.\n      code.last := code.last + 1;\n      code.oct (code.last) := Word (B mod 8);\n      exit when A = 0;\n    end loop;\n  end Run_Hardcoded;\n\n  procedure Do_Part_1 (A_start : UInt; prog_s : VString) is\n    prog, res : Word_Vect;\n  begin\n    r (part_1) := +\"\";\n    Convert (prog_s, prog);\n    Run (A_start, prog, res);\n    for i in 0 .. res.last loop\n      r (part_1) := r (part_1) & Character'Val (res.oct (i) + Character'Pos ('0'));\n    end loop;\n  end Do_Part_1;\n\n  --  Emulate Full Ada's `p1.oct (from .. to) = p2.oct (from .. to)`\n  --\n  function Equal_Slice (p1, p2 : Word_Vect; from, to : Natural) return Boolean is\n  begin\n    if p1.last < to or else p2.last < to then\n      return False;\n    end if;\n    for i in from .. to loop\n      if p1.oct (i) /= p2.oct (i) then\n        return False;\n      end if;\n    end loop;\n    return True;\n  end Equal_Slice;\n\n  procedure Do_Part_2 (prog_s : VString; shortcut : Boolean) is\n\n    prog : Word_Vect;\n    best : UInt := UInt'Last;\n\n    procedure Match (base : UInt; d : Natural) is\n      code : Word_Vect;\n      x : UInt;\n    begin\n      for i in reverse 0 .. 1023 loop\n        x := base + UInt (i) * 8 ** d;\n        if shortcut then\n          Run_Hardcoded (x, code);\n        else\n          Run (x, prog, code);\n        end if;\n        if d <= code.last and then Equal_Slice (code, prog, 0, d) then\n          --  if code.last = 15 then\n          --    Put (+\"Prog: \" & prog_s & \"; A=\" & x'Image & \"; d =\" & d'Image &\n          --         \"; code.last =\" & code.last'Image & \" -> \");\n          --    for p in 0 .. code.last loop\n          --      Put (Character'Val (code.oct (p) + Character'Pos ('0')));\n          --    end loop;\n          --    New_Line;\n          --  end if;\n          if code.last = prog.last\n            and then Equal_Slice (code, prog, d + 1, code.last)\n          then\n            if x < best then\n              --  Put_Line (\"*** \" & x'Image & \"; d =\" & d'Image & \"; code.last =\" & code.last'Image);\n              best := x;\n            end if;\n          elsif code.last < prog.last then\n            Match (x, d + 1);\n          end if;\n        end if;\n      end loop;\n    end Match;\n\n  begin\n    Convert (prog_s, prog);\n    Match (0, 0);\n    r (part_2) := Trim_Left (+best'Image);\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\n  kind : constant Data_Type := mini;\n\n  prog_s : VString;\n\nbegin\n  case kind is\n\n    when mini =>\n      --  Register A: 729\n      --  Register B: 0\n      --  Register C: 0\n      --\n      --  Program: 0,1,5,4,3,0\n\n      Do_Part_1 (729, +\"015430\");\n\n      if not compiler_test_mode then\n        --  Register A: 2024\n        --  Register B: 0\n        --  Register C: 0\n        --\n        --  Program: 0,3,5,4,3,0\n\n        Do_Part_2 (+\"035430\", False);\n\n      end if;\n\n    when input =>\n      --  Register A: 65804993\n      --  Register B: 0\n      --  Register C: 0\n      --\n      --  Program: 2,4,1,1,7,5,1,4,0,3,4,5,5,5,3,0\n\n      prog_s := +\"2411751403455530\";\n      Do_Part_1 (65804993, prog_s);\n      Do_Part_2 (prog_s, True);\n      --  202941412157999\n      --  202391656344111\n      --  202322936867375\n      --  202322936867370 --> OK.\n  end case;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 5,1,4,0,5,1,0,2,6 (mini: 4,6,3,5,6,3,5,2,1,0)\n    --  Part 2: validated by AoC: 202322936867370   (mini: 117440)\n  end if;\nend AoC_2024_17;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_17_questions.txt",
    "content": "--- Day 17: Chronospatial Computer ---\n\nThe Historians push the button on their strange device, but this time, you all just feel like you're falling.\n\n\"Situation critical\", the device announces in a familiar voice. \"Bootstrapping process failed. Initializing debugger....\"\n\nThe small handheld device suddenly unfolds into an entire computer! The Historians look around nervously before one of them tosses it to you.\n\nThis seems to be a 3-bit computer: its program is a list of 3-bit numbers (0 through 7), like 0,1,2,3. The computer also has three registers named A, B, and C, but these registers aren't limited to 3 bits and can instead hold any integer.\n\nThe computer knows eight instructions, each identified by a 3-bit number (called the instruction's opcode). Each instruction also reads the 3-bit number after it as an input; this is called its operand.\n\nA number called the instruction pointer identifies the position in the program from which the next opcode will be read; it starts at 0, pointing at the first 3-bit number in the program. Except for jump instructions, the instruction pointer increases by 2 after each instruction is processed (to move past the instruction's opcode and its operand). If the computer tries to read an opcode past the end of the program, it instead halts.\n\nSo, the program 0,1,2,3 would run the instruction whose opcode is 0 and pass it the operand 1, then run the instruction having opcode 2 and pass it the operand 3, then halt.\n\nThere are two types of operands; each instruction specifies the type of its operand. The value of a literal operand is the operand itself. For example, the value of the literal operand 7 is the number 7. The value of a combo operand can be found as follows:\n\n    Combo operands 0 through 3 represent literal values 0 through 3.\n    Combo operand 4 represents the value of register A.\n    Combo operand 5 represents the value of register B.\n    Combo operand 6 represents the value of register C.\n    Combo operand 7 is reserved and will not appear in valid programs.\n\nThe eight instructions are as follows:\n\nThe adv instruction (opcode 0) performs division. The numerator is the value in the A register. The denominator is found by raising 2 to the power of the instruction's combo operand. (So, an operand of 2 would divide A by 4 (2^2); an operand of 5 would divide A by 2^B.) The result of the division operation is truncated to an integer and then written to the A register.\n\nThe bxl instruction (opcode 1) calculates the bitwise XOR of register B and the instruction's literal operand, then stores the result in register B.\n\nThe bst instruction (opcode 2) calculates the value of its combo operand modulo 8 (thereby keeping only its lowest 3 bits), then writes that value to the B register.\n\nThe jnz instruction (opcode 3) does nothing if the A register is 0. However, if the A register is not zero, it jumps by setting the instruction pointer to the value of its literal operand; if this instruction jumps, the instruction pointer is not increased by 2 after this instruction.\n\nThe bxc instruction (opcode 4) calculates the bitwise XOR of register B and register C, then stores the result in register B. (For legacy reasons, this instruction reads an operand but ignores it.)\n\nThe out instruction (opcode 5) calculates the value of its combo operand modulo 8, then outputs that value. (If a program outputs multiple values, they are separated by commas.)\n\nThe bdv instruction (opcode 6) works exactly like the adv instruction except that the result is stored in the B register. (The numerator is still read from the A register.)\n\nThe cdv instruction (opcode 7) works exactly like the adv instruction except that the result is stored in the C register. (The numerator is still read from the A register.)\n\nHere are some examples of instruction operation:\n\n    If register C contains 9, the program 2,6 would set register B to 1.\n    If register A contains 10, the program 5,0,5,1,5,4 would output 0,1,2.\n    If register A contains 2024, the program 0,1,5,4,3,0 would output 4,2,5,6,7,7,7,7,3,1,0 and leave 0 in register A.\n    If register B contains 29, the program 1,7 would set register B to 26.\n    If register B contains 2024 and register C contains 43690, the program 4,0 would set register B to 44354.\n\nThe Historians' strange device has finished initializing its debugger and is displaying some information about the program it is trying to run (your puzzle input). For example:\n\nRegister A: 729\nRegister B: 0\nRegister C: 0\n\nProgram: 0,1,5,4,3,0\n\nYour first task is to determine what the program is trying to output. To do this, initialize the registers to the given values, then run the given program, collecting any output produced by out instructions. (Always join the values produced by out instructions with commas.) After the above program halts, its final output will be 4,6,3,5,6,3,5,2,1,0.\n\nUsing the information provided by the debugger, initialize the registers to the given values, then run the program. Once it halts, what do you get if you use commas to join the values it output into a single string?\n\n--- Part Two ---\n\nDigging deeper in the device's manual, you discover the problem: this program is supposed to output another copy of the program! Unfortunately, the value in register A seems to have been corrupted. You'll need to find a new value to which you can initialize register A so that the program's output instructions produce an exact copy of the program itself.\n\nFor example:\n\nRegister A: 2024\nRegister B: 0\nRegister C: 0\n\nProgram: 0,3,5,4,3,0\n\nThis program outputs a copy of itself if register A is instead initialized to 117440. (The original initial value of register A, 2024, is ignored.)\n\nWhat is the lowest positive initial value for register A that causes the program to output a copy of itself?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_18.adb",
    "content": "--  Solution to Advent of Code 2024, Day 18\n-------------------------------------------\n--  RAM Run\n--\n--  https://adventofcode.com/2024/day/18\n--  Copy of questions in: aoc_2024_18_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_18 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 6; stop : constant := 12;\n  input_name : constant VString := +\"aoc_2024_18\"; n : constant := 70; stop : constant := 1024;\n\n  type Map_Type is array (0 .. n, 0 .. n) of Character;\n\n  map, map_clear : Map_Type;  --  map_clear : emulate Full Ada's `(others => others => '.'))`\n\n  --  Dijkstra shortest path algorithm.\n  --  Code simplified from AoC_2024_16.\n  --\n  --  The following definitions belong to the Dijkstra algorithm, but\n  --  we keep them less local because of the path tracking.\n\n  list_length_max : constant := 500_000;\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  type State_Type is record\n    pt  : Point;\n  end record;\n\n  type Node is record\n    len   : Natural;\n    state : State_Type;\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  type Score_Type is array (0 .. n, 0 .. n) of Natural;\n  best, best_clear : Score_Type;\n  inf : constant Natural := Integer'Last / 4;\n\n  start, finish : Point;\n\n  function Dijkstra_Algorithm return Natural is\n    cur_len : Natural;\n    cur_s   : State_Type;\n    s       : State_Type;  --  Test state derived from current state.\n\n    procedure Visit (dir : Direction) is\n      len_to, ins : Integer;\n      new_node : Node;\n    begin\n      case dir is\n        when north => s.pt.x := cur_s.pt.x;     s.pt.y := cur_s.pt.y - 1;\n        when east  => s.pt.x := cur_s.pt.x + 1; s.pt.y := cur_s.pt.y;\n        when south => s.pt.x := cur_s.pt.x;     s.pt.y := cur_s.pt.y + 1;\n        when west  => s.pt.x := cur_s.pt.x - 1; s.pt.y := cur_s.pt.y;\n      end case;\n      if s.pt.x in 0 .. n and then s.pt.y in 0 .. n and then map (s.pt.x, s.pt.y) = '.' then\n        len_to := cur_len + 1;  --  Cost for a move.\n        if len_to < best (s.pt.x, s.pt.y) then\n          --  Found a better path to target state s.\n          best (s.pt.x, s.pt.y) := len_to;\n          --\n          --  Insert in a sorted way.\n          --\n          ins := explored + 1;\n          for i in current + 1 .. explored loop\n            if len_to < list (i).len then\n              ins := i;  --  Insert here.\n              --  Optional: remove another node\n              --  with the same state and a larger length.\n              exit;\n            end if;\n          end loop;\n          for i in reverse ins .. explored loop\n            list (i + 1) := list (i);\n          end loop;\n          new_node.len   := len_to;\n          new_node.state := s;\n          list (ins) := new_node;\n          explored := explored + 1;\n        end if;\n      end if;\n    end Visit;\n\n  begin\n    current  := 0;\n    explored := 0;\n    best     := best_clear;\n\n    cur_s.pt := start;\n    cur_len  := 0;\n\n    loop\n      for d in Direction loop\n        Visit (d);\n      end loop;\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        --  Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_s := list (current).state;\n      exit when cur_s.pt.x = finish.x and then cur_s.pt.y = finish.y;\n      cur_len := best (cur_s.pt.x, cur_s.pt.y);\n    end loop;\n    return best (cur_s.pt.x, cur_s.pt.y);\n  end Dijkstra_Algorithm;\n\n  block : array (1 .. 5000) of Point;\n  last_block : Natural := 0;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    dummy_separator : Character;\n    f : File_Type;\n  begin\n\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      last_block := last_block + 1;\n      Get (f, block (last_block).x);\n      Get (f, dummy_separator);\n      Get (f, block (last_block).y);\n    end loop;\n    Close (f);\n\n    start.x := 0;\n    start.y := 0;\n    finish.x := n;\n    finish.y := n;\n\n    for y in 0 .. n loop\n      for x in 0 .. n loop\n        map_clear (x, y) := '.';\n        best_clear (x, y) := inf;\n      end loop;\n    end loop;\n\n  end Read_Data;\n\n  procedure Byte_Fall (to : Natural) is\n  begin\n    map := map_clear;\n    for step in 1 .. to loop\n      map (block (step).x, block (step).y) := '#';\n    end loop;\n  end Byte_Fall;\n\n  procedure Do_Part_1 is\n  begin\n    Byte_Fall (stop);\n    r (part_1) := +\"\" & Dijkstra_Algorithm;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    a, b, mid  : Integer;\n  begin\n    a := stop;\n    b := last_block;\n    loop\n      mid := (a + b) / 2;\n      Byte_Fall (mid);\n      if Dijkstra_Algorithm = inf then\n        b := mid;\n      else\n        a := mid;\n      end if;\n      exit when abs (a - b) <= 1;\n    end loop;\n    r (part_2) := +\"\" & block (b).x & ',' & block (b).y;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n\n  Do_Part_1;\n  Do_Part_2;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 298 (mini: 22)\n    --  Part 2: validated by AoC: 52,32 (mini: 6,1)\n  end if;\nend AoC_2024_18;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_18.txt",
    "content": "7,22\n63,47\n4,45\n5,6\n26,3\n1,27\n3,59\n14,7\n37,54\n25,65\n7,17\n69,47\n9,16\n51,61\n61,52\n39,68\n43,62\n47,51\n41,57\n49,60\n12,23\n8,31\n59,58\n67,34\n26,5\n53,65\n16,7\n15,60\n23,31\n3,57\n49,47\n23,67\n57,63\n29,60\n61,43\n41,69\n69,50\n66,49\n29,1\n61,51\n22,3\n6,51\n32,69\n21,9\n46,53\n51,50\n9,32\n22,67\n60,63\n9,22\n15,31\n13,11\n38,61\n18,7\n7,46\n61,53\n21,3\n13,15\n51,65\n1,22\n28,57\n1,3\n65,53\n68,59\n58,61\n51,53\n11,60\n13,23\n61,65\n14,9\n8,37\n3,34\n68,45\n5,25\n41,64\n37,58\n65,45\n67,54\n33,57\n19,7\n56,67\n46,59\n11,34\n11,51\n51,52\n17,23\n21,61\n40,51\n26,67\n13,50\n53,53\n51,47\n65,55\n5,13\n19,9\n47,61\n10,17\n40,61\n57,55\n13,49\n5,63\n2,41\n55,33\n37,57\n69,57\n66,41\n26,65\n33,49\n9,20\n31,65\n27,69\n5,3\n1,19\n15,68\n27,10\n39,66\n48,51\n33,4\n63,65\n13,19\n15,62\n34,59\n67,59\n67,43\n11,25\n15,64\n66,63\n11,61\n14,39\n24,1\n8,7\n31,9\n63,60\n37,53\n65,69\n28,69\n59,61\n2,19\n4,27\n64,41\n55,45\n13,12\n19,15\n23,64\n49,45\n7,41\n29,69\n7,4\n29,58\n12,7\n67,42\n3,50\n41,55\n45,53\n7,31\n55,47\n67,39\n10,31\n9,23\n63,59\n33,66\n7,53\n9,15\n7,7\n70,43\n5,45\n19,2\n21,46\n33,1\n31,57\n7,45\n11,33\n9,31\n55,51\n47,59\n3,26\n52,63\n59,47\n19,67\n27,55\n3,61\n41,61\n32,59\n1,18\n50,63\n7,47\n15,38\n45,54\n48,55\n19,68\n11,5\n57,57\n7,52\n4,41\n11,37\n11,35\n43,61\n63,56\n21,65\n17,5\n62,69\n19,20\n11,8\n69,61\n6,7\n13,62\n63,54\n60,67\n3,12\n29,57\n8,29\n65,58\n49,61\n2,29\n33,52\n57,37\n4,19\n19,11\n9,35\n37,63\n55,34\n11,1\n47,48\n11,28\n56,61\n4,37\n48,59\n31,63\n39,69\n6,25\n4,61\n12,13\n6,59\n69,43\n65,46\n2,61\n69,55\n29,55\n15,22\n9,9\n61,42\n3,43\n4,17\n5,23\n27,63\n63,53\n27,57\n68,47\n14,65\n17,67\n43,66\n59,56\n67,47\n7,25\n27,61\n1,2\n61,57\n63,63\n58,65\n7,56\n37,70\n12,51\n15,45\n0,27\n27,1\n47,66\n5,11\n2,15\n15,2\n5,1\n15,41\n9,50\n1,7\n49,67\n55,55\n2,17\n21,64\n35,57\n12,19\n33,67\n22,13\n9,52\n28,67\n54,45\n18,47\n32,61\n35,50\n10,49\n30,67\n8,19\n3,37\n21,63\n35,69\n1,35\n12,37\n7,1\n5,14\n11,9\n53,45\n67,65\n4,25\n25,7\n11,49\n19,19\n29,3\n51,59\n4,43\n26,9\n13,3\n49,62\n31,52\n59,63\n13,7\n4,51\n13,1\n2,3\n31,1\n15,17\n37,56\n63,55\n61,45\n13,21\n63,43\n2,53\n67,61\n53,61\n31,3\n5,41\n9,17\n13,42\n5,46\n16,47\n17,15\n9,40\n43,69\n5,15\n61,35\n32,55\n11,65\n15,3\n42,49\n57,45\n68,61\n31,54\n1,45\n49,51\n5,57\n28,5\n11,48\n57,64\n38,51\n9,29\n30,61\n13,32\n33,69\n68,41\n35,6\n65,67\n47,49\n45,69\n36,63\n3,5\n7,35\n5,7\n57,61\n38,65\n0,21\n10,47\n33,7\n11,7\n45,43\n17,6\n3,31\n11,47\n41,68\n59,43\n51,55\n69,48\n40,63\n19,69\n67,53\n61,63\n2,25\n52,55\n13,35\n1,41\n13,34\n57,46\n24,5\n21,67\n9,54\n49,49\n3,14\n17,32\n1,47\n49,48\n1,6\n1,23\n65,49\n10,7\n5,37\n31,10\n20,65\n69,66\n52,45\n39,65\n47,53\n69,59\n7,20\n50,49\n10,3\n64,51\n16,3\n29,59\n34,57\n7,40\n3,47\n57,62\n5,19\n3,48\n45,51\n9,42\n8,47\n58,51\n5,30\n4,5\n7,29\n1,29\n0,13\n34,7\n27,5\n21,4\n43,57\n67,38\n23,3\n7,33\n3,39\n61,55\n29,5\n47,43\n69,54\n17,14\n35,61\n58,55\n3,49\n64,57\n59,48\n47,39\n5,33\n7,18\n15,5\n55,67\n45,59\n19,63\n54,51\n67,41\n62,51\n42,63\n33,55\n19,13\n22,17\n34,55\n5,12\n24,65\n17,65\n69,67\n5,27\n23,6\n23,5\n59,57\n30,69\n32,65\n11,27\n59,53\n7,42\n65,51\n9,0\n9,45\n66,69\n51,48\n41,51\n3,35\n6,53\n10,27\n3,33\n19,4\n33,68\n3,10\n51,63\n1,15\n9,53\n14,3\n66,51\n21,1\n3,58\n13,24\n7,19\n31,64\n31,5\n11,11\n20,15\n41,1\n39,57\n5,43\n19,62\n7,13\n61,68\n27,67\n69,52\n47,63\n22,1\n30,55\n3,30\n37,51\n9,27\n7,9\n15,23\n8,55\n29,63\n3,63\n2,39\n17,70\n63,46\n5,40\n15,11\n3,27\n44,51\n53,55\n7,15\n49,59\n41,63\n69,65\n8,27\n13,26\n3,3\n29,64\n64,61\n30,9\n53,62\n7,61\n25,59\n67,69\n3,17\n28,53\n60,55\n53,63\n5,16\n59,67\n55,56\n4,21\n15,67\n41,60\n4,59\n70,45\n3,55\n9,13\n43,63\n45,65\n8,59\n23,8\n63,48\n55,64\n3,1\n32,7\n39,63\n69,49\n3,24\n54,57\n9,37\n25,66\n48,69\n59,49\n4,1\n47,56\n62,59\n21,8\n1,54\n14,23\n56,45\n56,49\n63,49\n19,25\n27,2\n29,62\n41,65\n10,39\n6,43\n61,54\n65,39\n61,46\n51,39\n65,65\n35,55\n22,61\n16,9\n63,51\n1,46\n5,51\n11,26\n13,22\n3,54\n62,49\n13,5\n11,46\n20,67\n63,57\n25,55\n9,44\n19,30\n23,69\n13,31\n53,47\n17,63\n28,7\n16,65\n23,62\n6,9\n5,31\n69,33\n35,60\n68,69\n61,49\n21,19\n29,61\n13,25\n2,49\n7,5\n43,68\n63,41\n3,45\n8,11\n69,69\n32,57\n25,5\n10,25\n5,21\n55,66\n47,57\n3,7\n21,18\n23,65\n13,9\n29,8\n58,45\n61,44\n5,61\n63,44\n33,61\n2,45\n21,6\n5,17\n7,21\n55,48\n39,59\n52,65\n14,51\n5,35\n19,33\n5,39\n8,15\n11,23\n15,63\n47,64\n54,55\n42,55\n59,41\n49,66\n37,55\n8,5\n7,37\n26,57\n58,67\n9,5\n9,24\n28,11\n14,41\n17,17\n15,7\n1,8\n65,62\n46,61\n69,62\n15,30\n62,57\n49,55\n51,54\n1,9\n2,37\n60,59\n11,44\n21,10\n3,15\n55,65\n7,2\n70,37\n55,61\n1,5\n0,49\n29,65\n9,11\n67,44\n29,6\n3,11\n53,58\n53,41\n1,38\n5,47\n21,5\n17,69\n7,39\n54,47\n67,55\n61,66\n53,52\n11,31\n7,27\n9,3\n18,15\n45,58\n10,53\n7,24\n7,55\n37,65\n11,17\n49,68\n58,43\n55,63\n33,59\n59,65\n65,61\n63,64\n6,49\n19,64\n31,61\n3,13\n1,4\n1,49\n23,12\n5,29\n5,49\n54,65\n13,10\n25,69\n3,21\n43,47\n43,65\n41,53\n19,1\n24,3\n32,5\n60,49\n9,57\n39,54\n30,3\n67,63\n5,32\n3,32\n58,47\n65,59\n16,1\n55,53\n39,61\n5,36\n31,69\n20,69\n63,67\n65,47\n17,1\n1,43\n51,51\n14,29\n13,33\n67,45\n17,66\n64,49\n57,41\n25,0\n19,65\n61,64\n57,47\n31,67\n5,54\n68,51\n5,53\n69,53\n1,11\n9,7\n49,65\n66,39\n35,59\n19,18\n56,43\n44,57\n27,7\n24,69\n2,9\n38,63\n13,29\n32,3\n7,36\n57,49\n33,63\n19,10\n57,67\n51,46\n2,11\n11,4\n3,41\n37,60\n68,57\n66,47\n13,6\n26,69\n21,11\n14,31\n57,50\n56,57\n43,59\n65,41\n2,33\n33,12\n2,21\n49,53\n11,41\n35,52\n1,13\n41,59\n29,67\n64,67\n3,23\n62,61\n9,47\n7,38\n25,1\n5,62\n35,51\n65,43\n49,69\n27,3\n6,33\n33,3\n25,67\n17,3\n69,37\n63,70\n7,11\n45,63\n19,5\n11,29\n5,55\n9,51\n49,57\n23,1\n20,61\n65,44\n69,45\n42,59\n1,56\n22,21\n15,48\n47,67\n63,45\n15,61\n47,69\n60,61\n58,59\n1,37\n1,39\n3,51\n11,2\n6,1\n55,59\n7,57\n3,29\n9,49\n7,23\n25,3\n31,55\n17,61\n1,1\n31,0\n57,65\n17,21\n6,29\n12,5\n7,49\n5,10\n15,34\n5,28\n3,6\n12,29\n9,14\n34,63\n51,57\n69,64\n19,39\n32,63\n63,69\n11,45\n9,34\n45,68\n37,61\n13,46\n18,17\n14,17\n7,60\n27,62\n13,47\n13,61\n5,9\n1,36\n59,51\n29,4\n43,70\n7,51\n44,59\n15,15\n57,43\n27,59\n6,17\n13,48\n20,7\n55,69\n7,3\n15,1\n5,4\n57,51\n56,59\n60,51\n21,69\n5,48\n29,56\n61,61\n18,3\n13,45\n48,63\n47,65\n37,59\n55,43\n50,57\n3,53\n5,56\n23,68\n13,41\n66,53\n2,43\n69,63\n18,9\n64,53\n45,62\n8,1\n13,36\n19,61\n27,65\n18,67\n28,65\n45,64\n65,57\n46,69\n36,55\n70,59\n67,49\n54,61\n67,51\n65,68\n20,1\n44,61\n5,59\n7,44\n13,39\n49,52\n18,63\n29,13\n45,66\n29,2\n66,59\n10,37\n26,59\n9,33\n3,56\n1,28\n25,13\n45,67\n9,25\n69,68\n12,53\n12,61\n9,43\n25,12\n15,4\n50,55\n31,58\n7,58\n50,65\n33,15\n11,15\n8,35\n5,34\n31,59\n69,41\n33,9\n61,59\n3,2\n35,62\n1,25\n5,22\n1,44\n47,50\n9,19\n10,21\n62,63\n9,1\n12,41\n63,42\n45,55\n25,14\n3,9\n12,1\n7,8\n15,29\n0,41\n11,18\n15,65\n21,13\n63,39\n9,41\n23,35\n37,66\n61,15\n6,67\n4,67\n23,44\n29,27\n68,27\n21,30\n51,4\n41,47\n63,19\n45,21\n37,43\n23,59\n57,40\n35,44\n23,55\n65,64\n31,31\n57,3\n63,7\n25,17\n18,31\n27,17\n67,22\n39,56\n65,66\n23,23\n52,17\n41,39\n61,12\n17,49\n29,29\n60,29\n29,7\n53,19\n17,36\n15,33\n47,29\n30,39\n11,57\n25,36\n55,54\n38,17\n37,9\n49,4\n13,44\n29,15\n36,13\n16,37\n65,11\n57,5\n21,15\n17,7\n38,19\n13,55\n57,38\n49,10\n23,13\n30,35\n34,69\n27,27\n1,61\n11,21\n1,66\n41,37\n21,49\n37,25\n51,45\n29,39\n33,47\n49,7\n29,42\n31,45\n42,19\n35,9\n41,2\n26,33\n31,41\n16,25\n67,37\n41,18\n40,21\n63,20\n39,47\n59,36\n20,57\n1,65\n5,65\n37,41\n41,40\n26,63\n41,50\n31,39\n46,27\n59,22\n61,17\n29,11\n21,39\n20,33\n52,11\n57,39\n51,15\n59,3\n61,28\n51,37\n59,13\n23,10\n58,7\n53,11\n37,39\n23,41\n35,8\n21,7\n22,23\n67,5\n67,1\n48,35\n29,43\n67,7\n59,2\n23,37\n51,26\n9,12\n13,65\n20,43\n34,33\n11,19\n51,67\n49,5\n63,5\n48,25\n43,33\n35,42\n30,19\n32,27\n46,35\n31,49\n48,39\n11,63\n34,41\n40,37\n7,63\n63,17\n47,23\n11,40\n53,44\n33,36\n35,63\n68,31\n35,25\n65,25\n15,9\n20,25\n36,19\n63,13\n39,7\n62,39\n19,38\n25,51\n49,23\n33,42\n61,47\n65,37\n51,27\n44,31\n27,47\n45,23\n67,57\n67,56\n28,13\n25,28\n70,33\n43,19\n25,15\n47,10\n25,23\n42,43\n52,61\n1,68\n48,19\n9,21\n67,24\n15,59\n3,64\n27,23\n9,69\n28,35\n55,5\n47,45\n28,31\n29,41\n21,29\n37,33\n42,21\n3,19\n27,29\n15,21\n64,11\n63,61\n25,8\n60,43\n66,11\n27,45\n3,69\n5,67\n50,23\n41,32\n45,61\n39,53\n65,26\n15,39\n55,8\n21,47\n6,13\n66,25\n15,50\n51,11\n25,9\n43,28\n35,36\n37,23\n18,23\n44,49\n43,1\n31,53\n51,6\n63,30\n53,37\n69,2\n48,31\n52,23\n15,52\n67,33\n17,33\n50,19\n52,35\n47,17\n57,15\n43,5\n59,59\n21,59\n37,24\n51,5\n33,24\n55,11\n39,6\n15,51\n62,19\n56,29\n67,3\n7,67\n53,30\n43,39\n22,25\n51,33\n62,35\n26,23\n65,63\n51,23\n15,53\n15,26\n47,19\n21,35\n57,28\n1,60\n69,18\n11,53\n35,34\n32,49\n18,21\n1,67\n67,25\n57,10\n55,37\n25,18\n0,59\n59,17\n41,21\n63,4\n39,24\n55,16\n61,67\n55,14\n17,53\n15,37\n62,23\n38,41\n50,27\n70,13\n32,31\n45,29\n61,19\n55,2\n39,38\n43,24\n47,20\n50,11\n25,41\n47,18\n42,7\n24,55\n38,49\n53,24\n63,23\n24,29\n23,29\n19,53\n45,1\n29,19\n17,29\n28,41\n43,43\n31,7\n69,15\n61,27\n38,33\n57,7\n57,35\n23,21\n37,31\n57,13\n37,30\n39,4\n63,11\n67,13\n41,23\n50,39\n55,9\n1,21\n23,7\n45,28\n14,15\n26,41\n29,47\n43,15\n51,28\n31,43\n31,17\n29,37\n39,11\n49,8\n23,9\n55,25\n41,17\n60,9\n37,49\n19,41\n53,23\n34,13\n35,3\n21,56\n41,35\n17,57\n33,21\n35,23\n23,26\n35,11\n48,41\n49,2\n59,4\n45,9\n37,37\n59,15\n19,58\n35,27\n67,66\n11,43\n63,31\n49,24\n59,16\n29,49\n35,21\n67,19\n17,13\n18,53\n39,26\n20,13\n37,15\n17,59\n3,25\n60,31\n35,19\n26,39\n59,38\n25,63\n69,11\n53,57\n43,49\n11,59\n17,45\n65,29\n20,21\n57,17\n53,68\n1,57\n35,26\n26,47\n68,37\n31,40\n13,17\n53,31\n36,37\n65,5\n40,19\n55,57\n4,69\n15,47\n5,5\n66,55\n36,5\n59,23\n64,19\n69,51\n36,53\n56,37\n47,1\n42,15\n67,12\n9,60\n45,3\n19,26\n17,19\n24,23\n9,61\n57,4\n18,43\n24,53\n43,36\n21,55\n52,37\n35,31\n57,27\n63,37\n55,39\n38,1\n32,37\n40,5\n45,42\n69,23\n31,35\n65,1\n35,47\n55,15\n13,20\n41,49\n29,16\n53,43\n26,55\n67,17\n44,33\n56,13\n21,51\n36,17\n23,20\n29,18\n34,27\n51,18\n33,65\n38,9\n48,15\n58,35\n16,29\n35,39\n43,46\n49,33\n19,40\n65,15\n36,11\n47,0\n39,32\n47,22\n36,31\n23,34\n45,17\n45,39\n63,38\n53,7\n46,5\n27,53\n59,55\n69,5\n45,5\n55,29\n47,37\n51,69\n47,25\n67,21\n33,27\n43,17\n69,7\n35,24\n37,7\n49,3\n27,11\n59,12\n46,3\n53,67\n31,26\n48,29\n29,25\n37,44\n51,17\n29,48\n36,21\n13,13\n51,29\n9,39\n57,29\n43,55\n31,13\n59,5\n34,1\n41,43\n31,27\n67,27\n55,21\n25,57\n1,55\n38,11\n67,31\n50,7\n31,33\n19,23\n39,44\n43,30\n52,7\n42,37\n31,25\n23,57\n20,37\n31,29\n39,46\n23,11\n66,7\n55,6\n61,26\n13,63\n7,43\n46,33\n32,17\n35,46\n43,22\n41,7\n53,12\n45,20\n13,57\n61,29\n17,24\n64,23\n7,64\n57,1\n21,37\n30,31\n53,29\n47,2\n49,30\n56,69\n51,35\n55,20\n19,21\n19,29\n61,14\n55,31\n39,16\n53,9\n47,3\n44,13\n21,38\n33,8\n33,31\n33,29\n59,26\n50,15\n19,31\n21,60\n35,7\n29,51\n52,15\n46,47\n67,30\n15,27\n65,20\n45,37\n27,15\n31,21\n49,46\n17,54\n59,69\n19,35\n23,45\n55,27\n27,37\n59,27\n49,38\n17,47\n29,46\n25,45\n21,21\n59,33\n61,33\n61,39\n25,37\n65,18\n22,39\n55,32\n43,4\n43,26\n45,35\n67,29\n41,41\n16,21\n25,22\n2,69\n25,44\n55,18\n32,29\n63,14\n40,15\n69,24\n43,31\n53,50\n61,41\n51,3\n59,18\n39,39\n23,15\n33,17\n26,49\n21,17\n41,66\n35,43\n27,43\n35,18\n37,19\n33,11\n44,1\n24,31\n47,8\n48,45\n68,39\n65,3\n61,2\n27,24\n62,37\n37,5\n33,25\n49,35\n69,3\n27,52\n8,67\n41,67\n37,69\n65,17\n63,24\n41,46\n37,29\n69,8\n10,11\n63,35\n25,21\n55,3\n49,13\n20,47\n17,25\n63,16\n22,57\n57,59\n47,35\n37,47\n34,39\n47,11\n41,25\n37,3\n49,29\n53,32\n37,1\n43,45\n59,20\n16,11\n31,51\n45,25\n15,54\n38,13\n28,21\n69,1\n38,29\n51,31\n9,59\n39,43\n16,57\n0,31\n11,13\n26,35\n7,69\n43,67\n25,29\n35,15\n23,46\n31,44\n68,35\n17,27\n9,64\n18,39\n45,19\n37,8\n42,1\n13,43\n32,47\n51,36\n17,56\n2,65\n57,23\n61,13\n35,41\n57,30\n30,13\n55,0\n46,41\n35,35\n37,45\n18,55\n58,11\n45,26\n51,13\n37,13\n21,43\n31,47\n55,17\n34,15\n61,10\n55,40\n27,31\n25,39\n61,21\n28,27\n41,26\n52,9\n25,33\n44,9\n69,6\n41,34\n19,49\n38,21\n35,66\n56,23\n49,9\n36,49\n28,37\n53,38\n47,44\n67,11\n33,5\n47,31\n6,69\n51,60\n17,39\n14,59\n55,41\n39,51\n39,5\n15,35\n13,59\n67,0\n39,33\n56,33\n23,58\n51,42\n47,55\n63,25\n37,21\n45,57\n61,7\n46,17\n20,23\n62,5\n21,31\n63,3\n62,1\n69,13\n9,65\n25,53\n66,3\n65,27\n45,41\n39,21\n38,5\n45,14\n21,42\n5,66\n47,47\n61,1\n11,68\n61,3\n27,41\n19,37\n65,21\n35,48\n19,17\n27,54\n43,6\n37,17\n1,52\n18,35\n24,43\n61,18\n53,27\n35,22\n38,35\n13,69\n21,23\n47,14\n66,17\n23,39\n67,23\n44,37\n39,19\n27,60\n29,50\n43,27\n56,1\n15,43\n49,19\n42,53\n61,9\n25,35\n57,20\n49,16\n43,7\n27,19\n27,42\n18,49\n23,49\n59,29\n30,51\n1,51\n43,16\n45,27\n1,69\n37,42\n59,14\n53,66\n59,1\n57,69\n34,3\n19,51\n33,33\n24,25\n53,13\n53,28\n43,25\n15,58\n55,42\n15,25\n25,19\n43,42\n43,53\n53,49\n40,13\n23,56\n46,55\n43,41\n15,44\n31,28\n54,69\n39,3\n13,53\n29,31\n65,13\n57,53\n67,15\n21,33\n33,41\n27,38\n43,3\n29,24\n47,12\n14,55\n52,41\n19,32\n62,9\n64,33\n26,11\n53,3\n26,15\n13,51\n11,58\n35,33\n31,22\n34,51\n3,67\n39,17\n16,41\n51,25\n13,67\n41,31\n23,48\n65,7\n32,41\n19,57\n33,18\n39,67\n67,35\n11,14\n45,49\n25,31\n43,35\n64,29\n39,27\n49,21\n9,66\n63,33\n58,33\n62,31\n60,17\n19,52\n34,47\n29,9\n41,29\n34,29\n25,52\n51,20\n19,3\n21,53\n62,7\n55,24\n35,49\n37,67\n19,47\n37,11\n57,33\n51,68\n36,1\n61,37\n46,39\n16,43\n16,51\n54,5\n45,11\n51,58\n60,33\n51,49\n65,32\n11,64\n37,35\n59,19\n39,15\n22,31\n7,59\n16,19\n23,19\n24,49\n57,19\n68,21\n21,45\n55,36\n25,25\n54,35\n62,27\n32,1\n40,29\n11,70\n33,37\n23,63\n54,9\n43,34\n23,43\n67,4\n25,20\n32,33\n13,37\n16,45\n42,13\n49,25\n23,51\n65,9\n17,60\n21,36\n53,2\n63,32\n65,31\n32,15\n25,47\n11,55\n55,22\n53,33\n23,61\n42,39\n26,17\n57,22\n52,31\n45,16\n49,31\n1,17\n41,8\n44,53\n49,1\n18,59\n35,67\n43,9\n9,10\n39,45\n55,19\n61,69\n57,42\n53,15\n45,45\n67,32\n54,41\n20,51\n38,37\n14,37\n63,21\n51,70\n39,48\n22,41\n68,15\n39,23\n15,69\n11,3\n19,55\n25,49\n45,47\n29,32\n39,9\n29,23\n21,27\n39,25\n53,69\n43,13\n69,10\n45,7\n17,55\n33,51\n53,5\n59,8\n51,7\n58,25\n41,3\n55,26\n41,27\n30,25\n59,37\n53,17\n29,17\n53,59\n34,21\n51,21\n41,9\n1,63\n66,29\n32,45\n17,51\n11,56\n31,23\n19,46\n68,13\n45,24\n35,17\n55,1\n28,15\n53,51\n53,4\n39,37\n17,43\n63,29\n59,25\n40,9\n70,17\n70,25\n49,17\n24,33\n19,45\n36,27\n25,61\n67,67\n38,23\n35,13\n17,9\n33,19\n22,33\n27,49\n56,53\n26,27\n21,54\n27,44\n29,22\n9,62\n59,35\n30,43\n33,45\n69,20\n18,27\n41,11\n49,11\n0,63\n21,41\n41,44\n23,47\n30,15\n37,46\n43,21\n24,59\n24,17\n21,57\n11,32\n65,22\n1,33\n39,41\n25,27\n1,53\n43,56\n49,34\n21,28\n58,3\n34,31\n27,26\n52,1\n13,16\n17,41\n69,39\n69,29\n40,57\n15,12\n59,40\n66,9\n29,34\n69,21\n7,65\n43,51\n41,5\n49,27\n23,53\n55,12\n53,22\n27,50\n68,5\n55,7\n45,8\n61,22\n27,9\n53,39\n35,37\n65,19\n45,22\n53,35\n19,27\n69,28\n57,26\n53,1\n65,2\n46,31\n27,39\n60,35\n41,13\n19,43\n27,21\n58,53\n61,0\n51,19\n23,33\n40,59\n44,19\n12,57\n27,18\n45,31\n13,66\n9,68\n45,15\n29,35\n33,35\n17,37\n36,35\n65,35\n39,30\n57,18\n24,41\n19,50\n13,27\n47,13\n35,68\n61,25\n6,63\n47,27\n46,37\n47,9\n49,32\n64,3\n47,21\n9,63\n43,23\n54,29\n33,13\n39,31\n59,70\n27,33\n39,55\n29,45\n19,59\n59,24\n37,27\n68,1\n25,43\n58,31\n31,12\n40,35\n22,53\n57,31\n65,33\n1,31\n57,25\n53,26\n40,23\n39,1\n39,49\n43,2\n28,47\n64,27\n15,14\n35,1\n63,27\n33,39\n16,33\n63,10\n15,13\n31,11\n31,15\n44,45\n15,55\n39,29\n49,39\n49,36\n27,13\n59,9\n42,31\n33,38\n69,17\n55,35\n39,35\n59,39\n26,31\n44,5\n39,13\n36,3\n23,17\n29,21\n55,23\n24,39\n69,9\n10,63\n47,15\n65,23\n48,5\n53,20\n38,27\n65,36\n44,47\n55,13\n4,63\n61,23\n63,15\n10,57\n33,20\n31,20\n11,39\n33,53\n41,45\n67,18\n22,35\n51,9\n1,59\n27,25\n67,9\n49,43\n49,37\n50,3\n15,57\n59,31\n27,35\n69,35\n24,37\n23,25\n45,40\n67,64\n27,51\n53,21\n64,5\n17,40\n66,35\n17,35\n45,50\n54,17\n31,37\n66,13\n17,12\n49,12\n35,53\n41,28\n33,23\n27,20\n13,68\n28,29\n49,22\n47,41\n56,5\n39,2\n64,15\n40,53\n59,11\n62,15\n17,28\n51,41\n11,67\n67,16\n41,48\n37,68\n31,34\n61,5\n43,37\n21,44\n66,27\n47,7\n51,34\n30,37\n3,65\n53,48\n12,65\n5,69\n15,19\n22,51\n57,9\n21,25\n45,33\n36,39\n44,39\n22,15\n47,33\n35,10\n29,33\n23,50\n59,7\n50,41\n49,15\n63,9\n47,5\n57,21\n11,69\n69,19\n37,40\n29,53\n17,31\n35,29\n60,5\n14,69\n65,8\n57,11\n25,11\n23,27\n55,49\n15,18\n69,25\n40,41\n51,43\n64,7\n21,48\n30,49\n48,43\n53,25\n61,11\n33,10\n35,65\n58,15\n43,11\n51,1\n45,44\n24,15\n43,29\n12,55\n19,12\n51,14\n35,5\n45,13\n40,11\n41,15\n45,12\n25,62\n9,67\n31,19\n63,40\n27,30\n37,14\n49,63\n43,10\n46,7\n41,33\n17,11\n69,27\n60,39\n59,21\n19,16\n12,11\n61,31\n50,29\n68,9\n15,49\n49,41\n20,27\n35,45\n47,26\n39,52\n42,11\n59,45\n54,11\n33,43\n32,23\n56,9\n63,1\n35,16\n27,46\n9,55\n63,34\n41,19\n69,31\n2,68\n31,32\n50,67\n19,44\n25,64\n64,22\n14,12\n19,48\n54,36\n21,58\n30,2\n50,22\n67,58\n22,56\n2,46\n63,8\n2,55\n58,10\n41,62\n62,2\n62,17\n4,29\n30,58\n4,49\n56,62\n42,70\n42,0\n70,57\n46,64\n48,37\n18,57\n41,10\n41,16\n22,64\n20,30\n6,23\n40,24\n53,16\n64,65\n12,44\n5,8\n58,29\n23,60\n36,69\n40,22\n32,2\n46,65\n28,30\n19,24\n26,20\n28,48\n27,58\n4,46\n31,62\n15,28\n29,28\n8,32\n33,28\n58,68\n1,24\n44,17\n58,60\n66,16\n4,62\n4,30\n40,33\n16,59\n38,48\n6,27\n36,14\n35,32\n20,24\n30,62\n18,52\n55,10\n32,62\n64,54\n62,25\n4,53\n36,28\n52,4\n31,70\n62,38\n11,52\n20,0\n18,2\n23,70\n60,66\n16,56\n31,60\n46,12\n6,64\n38,10\n4,50\n8,62\n50,45\n58,13\n44,67\n35,30\n29,12\n68,33\n19,56\n29,38\n6,50\n38,46\n20,68\n57,68\n66,31\n29,54\n37,2\n49,40\n20,44\n32,58\n6,61\n6,19\n50,20\n32,8\n62,20\n64,16\n6,66\n14,49\n56,19\n56,64\n26,66\n17,46\n38,22\n56,41\n11,50\n32,52\n42,25\n29,30\n31,66\n64,25\n10,45\n69,4\n28,66\n24,67\n12,16\n14,60\n31,68\n36,46\n14,32\n34,44\n54,10\n48,9\n54,37\n68,16\n19,42\n16,0\n42,33\n30,60\n41,22\n60,2\n44,32\n65,6\n16,14\n26,61\n52,69\n62,24\n47,38\n45,10\n44,4\n42,36\n28,59\n30,10\n26,68\n17,10\n50,5\n41,52\n36,44\n36,9\n17,50\n8,53\n30,32\n44,35\n33,2\n15,0\n22,28\n60,69\n42,14\n26,25\n10,48\n46,9\n16,18\n67,70\n20,35\n4,20\n7,30\n30,45\n4,66\n26,62\n21,32\n20,28\n46,6\n61,16\n20,39\n66,20\n6,22\n70,22\n64,36\n26,24\n70,14\n24,28\n0,68\n40,28\n51,62\n22,26\n19,60\n47,68\n3,60\n54,64\n0,70\n66,67\n51,8\n4,26\n20,32\n52,64\n22,55\n48,14\n56,6\n70,34\n62,29\n52,18\n68,24\n63,0\n17,34\n18,68\n53,6\n26,64\n70,31\n50,66\n16,64\n4,58\n40,32\n48,65\n32,39\n58,63\n14,68\n60,14\n60,22\n8,50\n16,42\n2,31\n60,15\n52,70\n2,18\n50,16\n26,12\n12,34\n62,12\n34,46\n1,42\n62,4\n30,66\n35,14\n29,36\n50,0\n60,21\n54,24\n50,47\n34,52\n38,8\n54,22\n51,2\n6,45\n38,59\n46,40\n58,22\n63,6\n54,70\n16,30\n19,34\n66,66\n0,69\n39,36\n6,21\n37,22\n54,56\n64,26\n49,44\n50,12\n70,19\n38,15\n21,0\n27,32\n3,40\n0,44\n2,52\n16,54\n34,38\n48,24\n16,39\n26,53\n2,27\n68,36\n10,26\n6,24\n24,13\n35,70\n30,0\n52,13\n64,69\n54,19\n28,24\n64,28\n34,49\n6,55\n44,60\n2,54\n5,64\n14,22\n28,40\n34,62\n28,58\n30,47\n20,38\n10,62\n60,68\n8,0\n22,34\n24,30\n13,52\n22,70\n27,48\n3,20\n40,8\n67,28\n12,60\n36,56\n22,27\n20,26\n22,43\n24,44\n58,4\n33,62\n44,66\n20,48\n48,67\n28,55\n24,62\n30,40\n18,48\n17,42\n41,12\n28,54\n4,56\n6,58\n48,34\n60,24\n46,8\n8,21\n50,38\n70,27\n33,32\n17,48\n8,43\n50,18\n47,70\n12,62\n17,68\n35,56\n33,30\n66,15\n25,30\n10,12\n16,35\n46,4\n54,6\n11,12\n22,60\n32,9\n60,6\n42,67\n67,6\n26,6\n14,56\n18,26\n32,43\n70,10\n47,6\n12,32\n18,1\n15,42\n32,48\n2,51\n45,70\n10,33\n26,42\n31,42\n4,42\n32,53\n59,64\n18,36\n59,62\n68,14\n28,60\n20,31\n54,62\n10,35\n64,38\n28,63\n62,67\n64,0\n10,58\n46,36\n5,0\n36,15\n10,68\n32,44\n12,12\n20,34\n33,44\n39,42\n19,36\n58,62\n1,62\n15,32\n14,35\n50,36\n54,68\n14,38\n47,24\n56,60\n64,18\n60,16\n69,0\n53,70\n28,50\n34,5\n66,6\n32,54\n42,69\n6,60\n57,66\n4,22\n0,20\n14,46\n17,18\n37,16\n34,66\n33,6\n41,0\n60,30\n33,64\n41,30\n43,50\n50,61\n8,63\n52,32\n44,69\n23,0\n6,6\n46,46\n3,46\n31,18\n58,40\n14,20\n8,51\n40,64\n20,10\n66,70\n63,12\n41,4\n49,18\n43,8\n60,18\n36,33\n42,51\n50,25\n62,21\n57,24\n10,32\n45,6\n2,42\n52,26\n46,19\n32,64\n38,43\n38,64\n19,14\n28,9\n0,7\n70,49\n36,57\n14,24\n14,40\n63,18\n0,18\n54,26\n18,69\n56,31\n52,50\n12,50\n66,28\n20,63\n4,39\n12,21\n60,44\n34,70\n69,14\n64,50\n4,12\n32,6\n48,68\n6,41\n14,14\n52,59\n40,20\n1,10\n2,2\n34,30\n65,34\n9,70\n24,4\n54,60\n18,16\n19,70\n35,12\n39,8\n14,5\n30,20\n48,36\n52,40\n24,22\n36,2\n64,37\n53,46\n60,28\n17,52\n32,10\n56,47\n9,58\n8,46\n53,0\n20,22\n37,48\n17,58\n60,38\n62,55\n6,16\n0,66\n66,58\n20,4\n60,62\n42,48\n46,60\n43,54\n42,17\n24,70\n0,1\n40,58\n24,2\n26,18\n30,59\n18,38\n38,62\n5,70\n23,42\n24,8\n4,48\n55,52\n70,0\n7,28\n25,26\n66,43\n40,69\n21,2\n58,70\n6,4\n47,4\n56,38\n10,46\n58,23\n47,30\n41,42\n39,14\n44,8\n25,58\n29,44\n36,38\n22,32\n8,26\n47,42\n16,58\n47,36\n50,14\n35,2\n13,30\n31,46\n60,10\n55,60\n54,46\n46,18\n28,68\n28,32\n54,32\n16,32\n40,44\n32,30\n10,59\n44,30\n58,18\n24,27\n12,25\n56,42\n11,6\n1,14\n30,18\n0,10\n12,0\n36,34\n22,38\n64,8\n7,10\n4,57\n39,18\n51,44\n5,50\n53,18\n43,44\n66,60\n60,8\n32,14\n14,70\n62,60\n36,43\n64,1\n0,56\n48,49\n2,26\n14,47\n2,20\n42,3\n12,43\n57,48\n15,36\n61,40\n40,42\n29,20\n70,63\n42,35\n51,16\n54,44\n46,63\n66,30\n56,46\n0,42\n38,47\n19,66\n16,15\n44,18\n28,1\n49,58\n16,49\n30,5\n56,50\n18,60\n64,35\n2,66\n48,38\n34,6\n58,16\n56,26\n28,38\n6,20\n65,40\n16,38\n6,39\n40,52\n38,36\n0,55\n52,27\n30,54\n62,34\n61,58\n65,10\n50,53\n50,28\n10,70\n4,38\n63,66\n25,50\n60,58\n46,15\n41,36\n26,8\n7,34\n53,14\n52,60\n50,35\n5,44\n16,34\n16,46\n70,8\n56,39\n14,44\n39,64\n70,38\n0,4\n22,52\n20,29\n66,12\n31,8\n30,44\n60,25\n36,67\n50,24\n17,30\n54,50\n56,0\n25,42\n24,18\n14,66\n53,8\n62,3\n39,28\n9,30\n2,67\n12,31\n0,38\n56,3\n56,55\n12,49\n68,28\n64,21\n38,20\n70,9\n21,24\n60,41\n6,57\n65,28\n54,14\n51,0\n0,67\n64,24\n44,43\n25,38\n20,45\n2,7\n44,12\n50,13\n13,58\n43,38\n54,25\n7,48\n48,3\n56,17\n1,34\n31,48\n10,64\n56,27\n38,39\n38,32\n42,58\n68,52\n68,34\n60,56\n36,64\n2,6\n18,61\n64,48\n34,58\n48,1\n70,3\n62,6\n64,43\n6,47\n7,68\n51,66\n36,59\n70,11\n49,28\n2,44\n45,56\n55,44\n57,70\n56,52\n27,28\n16,40\n52,5\n56,34\n69,26\n6,36\n69,60\n52,52\n34,14\n15,24\n24,47\n44,58\n44,64\n54,27\n70,7\n8,57\n33,14\n63,22\n60,7\n44,23\n53,60\n28,39\n30,22\n9,28\n67,20\n1,50\n38,30\n40,36\n3,42\n59,68\n57,8\n56,63\n44,56\n58,5\n18,20\n68,19\n62,56\n40,60\n52,57\n60,57\n44,63\n44,29\n58,41\n60,0\n60,70\n24,34\n56,12\n63,36\n46,34\n4,47\n63,58\n16,36\n58,27\n8,4\n28,17\n48,53\n42,34\n66,19\n70,56\n16,22\n18,65\n25,56\n58,32\n12,54\n64,59\n13,56\n58,26\n50,2\n31,38\n66,8\n41,70\n42,18\n6,8\n18,19\n64,32\n28,51\n24,68\n40,65\n60,23\n48,23\n24,9\n7,62\n47,52\n11,16\n22,22\n30,53\n26,21\n31,30\n66,54\n46,14\n38,38\n24,54\n3,44\n60,50\n4,64\n23,4\n24,10\n19,22\n55,70\n49,26\n36,45\n70,30\n48,42\n4,34\n48,62\n23,40\n59,0\n0,62\n30,63\n24,14\n21,34\n28,33\n18,8\n24,6\n14,62\n59,54\n1,30\n40,26\n45,32\n55,46\n64,46\n61,50\n37,12\n10,14\n62,47\n10,10\n30,7\n48,18\n56,58\n20,42\n13,8\n7,6\n12,3\n61,24\n8,61\n45,46\n16,31\n2,36\n68,67\n26,13\n38,28\n46,67\n27,16\n48,27\n56,54\n11,22\n68,43\n10,42\n45,30\n8,48\n56,48\n48,46\n39,70\n8,44\n32,21\n0,14\n3,4\n48,58\n35,0\n14,53\n14,8\n64,47\n22,54\n27,0\n4,31\n61,8\n5,52\n64,64\n28,4\n48,56\n54,3\n45,18\n59,28\n42,62\n11,62\n28,26\n40,17\n62,18\n6,14\n62,30\n62,16\n28,64\n55,50\n24,26\n26,60\n30,8\n30,16\n57,0\n40,0\n62,40\n48,44\n19,0\n66,18\n38,54\n56,24\n24,46\n26,0\n6,44\n28,6\n36,66\n44,6\n10,40\n18,37\n44,7\n59,34\n8,64\n59,30\n65,54\n50,42\n22,65\n4,23\n22,58\n52,10\n33,46\n30,30\n61,30\n38,58\n20,40\n22,66\n68,25\n4,6\n70,41\n22,37\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_18_questions.txt",
    "content": "--- Day 18: RAM Run ---\n\nYou and The Historians look a lot more pixelated than you remember. You're inside a computer at the North Pole!\n\nJust as you're about to check out your surroundings, a program runs up to you. \"This region of memory isn't safe! The User misunderstood what a pushdown automaton is and their algorithm is pushing whole bytes down on top of us! Run!\"\n\nThe algorithm is fast - it's going to cause a byte to fall into your memory space once every nanosecond! Fortunately, you're faster, and by quickly scanning the algorithm, you create a list of which bytes will fall (your puzzle input) in the order they'll land in your memory space.\n\nYour memory space is a two-dimensional grid with coordinates that range from 0 to 70 both horizontally and vertically. However, for the sake of example, suppose you're on a smaller grid with coordinates that range from 0 to 6 and the following list of incoming byte positions:\n\n5,4\n4,2\n4,5\n3,0\n2,1\n6,3\n2,4\n1,5\n0,6\n3,3\n2,6\n5,1\n1,2\n5,5\n2,5\n6,5\n1,4\n0,4\n6,4\n1,1\n6,1\n1,0\n0,5\n1,6\n2,0\n\nEach byte position is given as an X,Y coordinate, where X is the distance from the left edge of your memory space and Y is the distance from the top edge of your memory space.\n\nYou and The Historians are currently in the top left corner of the memory space (at 0,0) and need to reach the exit in the bottom right corner (at 70,70 in your memory space, but at 6,6 in this example). You'll need to simulate the falling bytes to plan out where it will be safe to run; for now, simulate just the first few bytes falling into your memory space.\n\nAs bytes fall into your memory space, they make that coordinate corrupted. Corrupted memory coordinates cannot be entered by you or The Historians, so you'll need to plan your route carefully. You also cannot leave the boundaries of the memory space; your only hope is to reach the exit.\n\nIn the above example, if you were to draw the memory space after the first 12 bytes have fallen (using . for safe and # for corrupted), it would look like this:\n\n...#...\n..#..#.\n....#..\n...#..#\n..#..#.\n.#..#..\n#.#....\n\nYou can take steps up, down, left, or right. After just 12 bytes have corrupted locations in your memory space, the shortest path from the top left corner to the exit would take 22 steps. Here (marked with O) is one such path:\n\nOO.#OOO\n.O#OO#O\n.OOO#OO\n...#OO#\n..#OO#.\n.#.O#..\n#.#OOOO\n\nSimulate the first kilobyte (1024 bytes) falling onto your memory space. Afterward, what is the minimum number of steps needed to reach the exit?\n\n--- Part Two ---\n\nThe Historians aren't as used to moving around in this pixelated universe as you are. You're afraid they're not going to be fast enough to make it to the exit before the path is completely blocked.\n\nTo determine how fast everyone needs to go, you need to determine the first byte that will cut off the path to the exit.\n\nIn the above example, after the byte at 1,1 falls, there is still a path to the exit:\n\nO..#OOO\nO##OO#O\nO#OO#OO\nOOO#OO#\n###OO##\n.##O###\n#.#OOOO\n\nHowever, after adding the very next byte (at 6,1), there is no longer a path to the exit:\n\n...#...\n.##..##\n.#..#..\n...#..#\n###..##\n.##.###\n#.#....\n\nSo, in this example, the coordinates of the first byte that prevents the exit from being reachable are 6,1.\n\nSimulate more of the bytes that are about to corrupt your memory space. What are the coordinates of the first byte that will prevent the exit from being reachable from your starting position? (Provide the answer as two integers separated by a comma with no other characters.)\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_19.adb",
    "content": "--  Solution to Advent of Code 2024, Day 19\n-------------------------------------------\n--  Linen Layout\n--\n--  https://adventofcode.com/2024/day/19\n--  Copy of questions in: aoc_2024_19_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_19 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  input_name : constant VString := +\"mini\"; nt : constant := 8; nd : constant := 8;\n  input_name : constant VString := +\"aoc_2024_19\"; nt : constant := 447; nd : constant := 400;\n\n  towel  : array (1 .. nt) of VString;\n  design : array (1 .. nd) of VString;\n\n  max_len_design : constant := 60;\n  type Memo_Type is array (1 .. max_len_design) of Integer_64;\n  memo_clear : Memo_Type;  --  memo_clear: emulate `others =>`.\n\n  unknown : constant := -1;\n\n  r : array (Part_Type) of Integer_64;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n    s : VString;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in 1 .. nt loop\n      s := +\"\";\n      loop\n        Get (f, c);\n        exit when c = ',';\n        s := s & c;\n        exit when End_Of_Line (f);\n      end loop;\n      if c = ',' then\n        Get (f, c);  --  Consume ' ' after the ','.\n      end if;\n      towel (i) := s;\n    end loop;\n    Skip_Line (f, 2);\n    for i in 1 .. nd loop\n      Get_Line (f, design (i));\n    end loop;\n    Close (f);\n\n    for i in memo_clear'Range loop\n      memo_clear (i) := unknown;\n    end loop;\n\n  end Read_Data;\n\n  procedure Solve_Method_Memoization_by_Index is\n    memo : Memo_Type;\n\n    function Count_Options (design : VString; first, length_design : Positive) return Integer_64 is\n      last : Natural;\n      options : Integer_64;\n    begin\n\n      if memo (first) >= 0 then\n        return memo (first);\n      end if;\n\n      --  Number is unknown -> we have to compute it...\n\n      options := 0;\n      for i in 1 .. nt loop\n        last := first + Length (towel (i)) - 1;\n        if last <= length_design and then Slice (design, first, last) = towel (i) then  --  Match\n          if last = length_design then\n            options := options + 1;\n          else\n            options := options + Count_Options (design, last + 1, length_design);\n          end if;\n        end if;\n      end loop;\n\n      memo (first) := options;\n      return options;\n\n    end Count_Options;\n\n    opt : Integer_64;\n\n  begin\n    r (part_1) := 0;\n    r (part_2) := 0;\n\n    for i in 1 .. nd loop\n      memo := memo_clear;\n      opt := Count_Options (design (i), 1, Length (design (i)));\n      if opt > 0 then\n        r (part_1) := r (part_1) + 1;\n        r (part_2) := r (part_2) + opt;\n      end if;\n    end loop;\n\n  end Solve_Method_Memoization_by_Index;\n\n  procedure Solve_Method_Triage_by_Initial is\n    --  Lists of towels, bucketed by their initial:\n    towel_after_initial : array (Character, 1 .. nt) of VString;\n    --  Number of towels starting by the character in question:\n    towels_with_initial : array (Character) of Natural;\n\n    memo : Memo_Type;  --  memo_clear: emulate `others =>`.\n\n    function Count_Options (design : VString; first, length_design : Positive) return Integer_64 is\n      length_towel, last : Natural;\n      options : Integer_64;\n      c : Character;\n    begin\n\n      if memo (first) >= 0 then\n        return memo (first);\n      end if;\n\n      --  Number is unknown -> we have to compute it...\n\n      options := 0;\n      c := Element (design, first);\n\n      for i in 1 .. towels_with_initial (c) loop\n        length_towel := Length (towel_after_initial (c, i)) + 1;\n        last := first + length_towel - 1;\n        if last <= length_design and then Slice (design, first + 1, last) = towel_after_initial (c, i) then  --  Match\n          if last = length_design then\n            options := options + 1;\n          else\n            options := options + Count_Options (design, last + 1, length_design);\n          end if;\n        end if;\n      end loop;\n\n      memo (first) := options;\n      return options;\n\n    end Count_Options;\n\n    opt : Integer_64;\n    c : Character;\n    s : VString;\n\n  begin\n\n    for ini in Character loop\n      towels_with_initial (ini) := 0;\n    end loop;\n\n    --  Prepare hashing by the towel's first character.\n    for i in 1 .. nt loop\n      s := towel (i);\n      c := Element (s, 1);\n      towels_with_initial (c) := towels_with_initial (c) + 1;\n      towel_after_initial (c, towels_with_initial (c)) := Slice (s, 2, Length (s));\n    end loop;\n\n    r (part_1) := 0;\n    r (part_2) := 0;\n\n    for i in 1 .. nd loop\n      memo := memo_clear;\n      opt := Count_Options (design (i), 1, Length (design (i)));\n      if opt > 0 then\n        r (part_1) := r (part_1) + 1;\n        r (part_2) := r (part_2) + opt;\n      end if;\n    end loop;\n\n  end Solve_Method_Triage_by_Initial;\n\n  procedure Solve_Method_Full_Hashing is\n    use Hash_Maps;\n    memo : Hash_Map_Type;\n\n    function Count_Options (design : VString) return Integer_64 is\n      length_design, length_towel : Natural;\n      options : Integer_64;\n    begin\n\n      Find (memo, design, unknown, options);\n      if options /= unknown then\n        return options;\n      end if;\n\n      --  Number is unknown -> we have to compute it...\n\n      options := 0;\n      length_design := Length (design);\n\n      for i in 1 .. nt loop\n        length_towel := Length (towel (i));\n        if length_towel <= length_design and then Slice (design, 1, length_towel) = towel (i) then  --  Match\n          if length_towel = length_design then\n            options := options + 1;\n          else\n            options := options + Count_Options (Slice (design, length_towel + 1, length_design));\n          end if;\n        end if;\n      end loop;\n\n      Insert (memo, design, options, False, options);\n      return options;\n\n    end Count_Options;\n\n    opt : Integer_64;\n\n  begin\n    Clear (memo);\n    r (part_1) := 0;\n    r (part_2) := 0;\n\n    for i in 1 .. nd loop\n      opt := Count_Options (design (i));\n      if opt > 0 then\n        r (part_1) := r (part_1) + 1;\n        r (part_2) := r (part_2) + opt;\n      end if;\n    end loop;\n\n  end Solve_Method_Full_Hashing;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\n  type Method is (m1, m2, m3);\n  choice : constant Method := m2;\n\nbegin\n  Read_Data;\n\n  case choice is\n    when m1 =>\n      --  Simple method with memoization (used for sending the answer to AoC).\n      --  Time HAC: 13.4 seconds; time GNAT (mode: Fast_Unchecked): 0.84 seconds.\n      Solve_Method_Memoization_by_Index;\n\n    when m2 =>\n      --  Method with memoization and bucket triage by the towel's initial.\n      --  Time HAC:  3.8 seconds; time GNAT (mode: Fast_Unchecked): 0.17 seconds.\n      Solve_Method_Triage_by_Initial;\n\n    when m3 =>\n      --  Method with memoization and hashing of the design string (idea: J.C. Moyer,\n      --  https://github.com/jcmoyer/puzzles/blob/master/AdventOfCode2024/src/day19.adb).\n      --  Adapted to our HAC-compatible Hash Maps (slower).\n      --  Time HAC: 14.5 seconds; time GNAT (mode: Fast_Unchecked): 0.89 seconds.\n      --  J.C. Moyer's code, GNAT & Release mode: 0.09 seconds.\n      Solve_Method_Full_Hashing;\n\n  end case;\n\n  if compiler_test_mode then\n    if Trim_Left (+r (part_1)'Image) /= Argument (1) or\n       Trim_Left (+r (part_2)'Image) /= Argument (2)\n    then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1:\" & r (part_1)'Image);\n    Put_Line (+\"Part 2:\" & r (part_2)'Image);\n    --  Part 1: validated by AoC: 260\n    --  Part 2: validated by AoC: 639963796864990\n  end if;\nend AoC_2024_19;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_19.txt",
    "content": "buu, ubg, gub, wbwu, rrgrgg, urrwr, grwb, ubw, ubrbr, ubgb, gbw, rbrwgw, wbrr, brg, urugggr, wgbb, uwwu, urgg, wwwr, wrub, rbr, brgwb, gruwwb, rrwuwbu, rub, urwwgu, bbbw, wrr, uwr, grr, ggwrb, wbrwwbur, brbg, rubrg, urwbbru, brwww, bu, gugwww, rbww, buw, rurwgrug, rugwr, ruubww, bgbu, bgbw, wuu, burw, uuwb, rug, grw, bbrugwr, wurwbg, uurwu, bgu, ruu, bgrg, uguub, bgug, burubb, ubuugb, bbww, grbrr, gubbww, gwbgrwu, ggu, bubgurub, wguu, gww, wuuu, wbgb, bgrw, gug, rwwbw, uru, rwr, ubwr, uwb, bubwbwbw, gggwr, brr, gbrrg, rrww, gwg, uurubb, ruwwgrw, brgrru, gbgrwb, wbbwgg, wuwr, ruwuwbw, ggwrr, gbu, gwr, uur, wbgu, gbwgbgr, bbb, bubu, rwwggw, ruw, rbwuw, ugbbrwu, uurrgrg, bwwubwwg, gruu, ubgwu, rww, bur, ubwrg, wgb, gurbbr, rgbr, wuw, gbwuwru, rgwbrg, wbbr, wr, bgrrgb, wwb, urgwubww, bwurw, ur, rgbu, rrurw, ubbu, ubur, wrbwwr, uugww, grg, rwb, rgb, gguggu, rwgr, gurbubg, guwwr, wwbgb, grbgwruw, wug, bgb, rb, ruuubggr, www, wbgg, gguu, bbur, gbub, bwg, uuugbw, brb, brrrggu, buwu, rbrg, bg, bwgrbw, bwb, u, guw, gwrwur, brgb, wrru, ruugu, wrgrg, wbrb, rg, buwrr, ugr, uwru, bub, wbb, ubr, brrwr, wgbuu, bguu, bubw, ug, ugwg, wurbww, bwrbuwu, wwuwb, brbubg, wwub, g, brw, bbrwrgb, bgr, rbuwb, gwur, bggg, gbuu, wbu, rubw, bguug, bbw, wuguw, uwbwrgb, wwwub, wwbugg, gwubbb, rugwg, rgwwbru, ugbbubr, wrrgr, bubg, wwbwu, wbw, bbr, wbggugw, wurw, wwgwgr, burgr, wbgbu, wwwuuw, buguu, gwrugg, wwgugg, bburg, urwbu, rrug, ggb, ggbg, rguwbu, guru, wwr, ggurrw, brbbbubg, bbguuwgw, rru, ugwu, wbggr, rgrbww, rrubw, ubwurwg, gbr, rwrgw, wwguwbu, wggrr, wru, wrgbb, bgburwg, wruwwg, uuu, rugr, rwbw, bwwbr, bbbrgwu, br, ubb, bbu, urg, brbuggb, uw, rbug, wbbrgugb, rgu, uubgrrgw, bru, rwgbu, wrgw, gwb, bwbr, bgw, wgwg, wbgrwwg, wwwwgr, gg, gwgggu, ugwuu, gugur, gggbw, bwbwguu, uwbr, gw, wrgg, rugwbgg, uwg, urb, uwggb, urgggb, bbg, gwbr, uub, gbg, gwuu, buwrrw, rbu, wbbu, ru, rbbw, rgugrbwg, ggbgrw, ugrwwww, uwgbwu, wwbw, wurr, wrwrrr, rrw, rbb, rwrgr, bbwwg, rbg, bbbgrbrw, ruubwb, ubbg, gr, gwwbuuuw, bwgr, rrwwggu, bbuugb, guwwbg, rguw, rur, gwbbbbr, rbwr, wb, uuwrbb, uruwbrrr, bb, bbubu, gruguu, urr, bwbrb, rbru, ugu, ugg, rwbgu, rbbuug, uguw, grwbg, bbgrrr, gur, urw, gguwbb, rburuug, w, wg, ggw, wur, ubwuw, bwggugb, gwbu, wbrg, gbrgw, wrugur, rbgb, uwbrrubg, bbugugw, rwbgwur, ubwu, rw, wurwggr, gru, brur, gwbuw, uwu, gurbb, rgbgr, bgg, rggg, rrg, wbbg, wwu, wbr, uww, ggr, wbwgu, rrgu, rgw, rrwugrg, wgug, wrw, rbw, bug, bruuubrb, rubwurr, rwub, bbbru, rr, gwu, ubbgwg, gbww, wwrgrgg, wbg, rwu, ugurw, bubwg, wbubw, urwur, wgu, ubuuug, wubu, rrb, rrru, bwr, rbbubbru, gbwb, ggrruw, bww, uu, wu, wwuww, gwguwbb, ubu, uug, gubgr, rwggb, ubwug, wrg, r, wbwgwu, ww, gggw, rubrw, ugw, wgg, buguurwr, grb, bwur, wgr, uubb, wuwbwrb, urbwr, bw, ggg, bgrgr, buguwr, rbgbg, rrr, wgwbrr, rgg, rububg, bwu, ub, gbb, wub, uuw, wgw, bbub, wbggbb, wwwbgg, rgr, rbbbu, wuwb, grubu, rruwu, gubu, urwu, wrurg\n\nwuuwwuwubwggbgggggwgurgwubwwrbwubgrbuubrwwgwgbbwugw\ngwbwwrurbbgwuubwwugbrgrrwrgurgwgggubbugb\nbugwwguwrbbgrbguguurbrrbwubbbrrwrgbguwrurbgwbg\nbugwgguwrwbrggwugwgguwrwrwubrgwgwrububwrgugb\nruurguwurrwbgrrgwwbrrwgbrrbrbwwurwruuuuwbbbuwgggbugb\nbgrurbguuurrgbgggrggrbgwbbwwguuggrwbwrgbgrrbugbgguwr\nguggrwuugwrbbrwrubbbgwrrwruururgwubwwrbguugb\ngrugwgrgwrbuwwruurgwwwbrbrbwrurbbwrrubuwugb\ngbwrgrgbubugggrwuwbugrrrrgurbbwbbgbggguwruwuubrurwrg\nwuwbbgbrbruuubrbwwwugwbbwrugrwruwggwbbwbbuurbgr\nrgbrbwugwrrgggbruuubruuubggrrrrgrbrgrwwrgrrgg\nguwuggggurwbwugwgruwubwrubbuwbrwurwubugrburwuwbw\nbrbgwugbgggruwwugbwbguuugubwgrrrrruguwugubu\nuggrbbbuwrggbgwbrbwggugwbrgrbwwwbrrbrbrwguwbbuugug\nwurububrurruguubggbubbgwgwgguwbguubbwbwwwbrrubuuruuubbwgur\nrrbbrbrwbbrrgrbbrugwggrwbwgwrrwwggugrbugwbugbbwrwub\nggwubrwrbwrubuwwrbguubwrrbbbbbrruuuruwbbrrbubgr\nbrgubwrbbbrrrbbggwuggrugrggwbbuuwwwubwbggwwubbrgw\nwbbwurbrbgbrruugbbgrbubuuguwuruubbbgurugwbrubr\nbwbbuwwurbwgrubuurwwbrurwrbwggrrgwgrwggubruburbgrrg\ngurbuggubwrggugggbwuurbgbgugwguwrbwbgwgrgrgb\nrgwbuwrgurwbgubwurruugwgwrbuwrgrbrurrurguwwwrugb\nwrrugbguruuwwrbrrwbrggwrwrgwwuwrwbgwgrbwguggwbwugb\nrgbubguwbrwuuuwrbgruuwgrrrugugbbwrrwrrgruuubruggwrbrgubrw\nuguwgwwbubgwwwrugbururbbugugrwgbbbgwubwggbburwubwuuubgu\nbbwrgwbggwuwggwggurrrrbgbbgwurrwrgwuwbuggbgrgwwuguubrguuugb\nwbbrbguggurrbuuwbbugrwrbgwuguubuguwbrgrurgbbrbgruwuwwrugb\nuwgrbwuuwrugubggubgubrgrgrrwgrgbrbbwuwruwgbbgwubwww\nbuwbgggwwrwbuuugwwbbugrgugurrrrbwrugbruuuwbwrruw\nugrurwbgbwrbbgrwwgrwbugwbwgwrbugwgggugugugwrgugb\nwuwwwwbubgwwrwwuuguggrggrbggbwbwrbwuwubrgrr\ngugbwbuuwugwuwbrbwuguggbuurruwgugbbwbbwbrurgrrbbwrgurwgg\nugurugrubrrbgwrubgwrrwgubbwgurgwwugrwbuwrbwrubbuwrggugg\nbubuwuggrbugburbwwbbwgwbbbwwgubgugugbrurbuubbgbrgbbgb\nwugbgwubugbbrrbgbrrwgbwuuububwuwgrugububrburbuu\nubrubuurwgbrrrbgubbgwwrbgwwbgbububbbruwwwwgguguggrgggugb\nwubbwubgbwrrrggrubwbbwwggguugrgwgrwbgurgurgbuwuurbrbgwu\ngbwbwggrwgrurbbwwrbruwrguwgggrbuwrbbururrwrwrrrwwwwwburbwu\nubgbrubbbgwbguburuwuggggbgrwbbguruwrrwbruggugwwuwbb\nbbbbgrbbbbbgbwrurbwbwruubrbrgwrbgwwrgbruwwgwururguggbb\nuguwbubguwrgrbgwgwbuurbuwrrgbuwbuurruwuggububu\nuwurbbuguwbwwgwurwwbgwuwggbwrwbgrrrrbuwruwbrbgguuubwggrugb\nubbrwrbrrbgbrgrrwuwgrrwurwrbwubwbwggguwbwww\nbrrrggwrgwruwgwwuwwwwwwbwbwguwbwwurbwbuggubbrgrugurugu\nurwbuuwgrurwgrgurrgbbwguwrgugurrwbwrwrrbugbwguugb\nwbrubrwubgruurwwwgugwwwbwbwbgbuguwgbubbwgrgbrgbrbguwugwbrb\ngbguugwwgggwbbbbbbwbguugrbrguuwuwwrgbwbgggw\nrbbrrrbbwwbugwbbgbubbrugwbbrwwbruuwubwrgwbuwrrbwu\nggubwggwbbuwbwbwuwgrwbwrbugugbwuwrrugruwuurubbbw\nubururrguubuugggubgggrgrwwwwgbgbuwrbggrwugrgbguu\nruugbuwwbbrrbwurgguburrbgruugugbguwwrubrwuwrrwuuugb\nugbgbbrrbrrggbwwgwwubuwwuggrugurbrbwgrgwburrrurgggwbugb\nguruwbrrrrrrbbwwwruwwubrurbgggwugwruuurwugwwwrgbuwgwwwugb\nurrbbrbrgwwrbgbbbbgbwgruuwuwgwwbwwwuguuggbg\nubggggbbuurrrbruuwwbrwugrbbwrbbrubwwruggrrwwuuuggw\nggbggbwguurugggwgwwgurrrgubgwrruguburgurwbwuurubbgrgwbbrww\nguurbugwuubgugrwurbuuwuwwuruwwrgwwwubbbbuubgbb\nggugwggurgguurwgwwrburwrwwbgwgwbwgwugwubrbuuwubugb\nbwuwbwgwrwububgrbgrgwbwbwrrubuwrbgwgurbrwuwubwugb\nubgbgggrrggrgrrwbrubrguuwbwurrrbbuuurguwubbuwguurw\ngruurubrugrgggurwgbguwwrbwwrrwwrwbgrrugwrrgrggrurggb\nrbwwgbwrwbbgrbuggrubgurggwbrrguuurbgrbgrrrwwbugb\nruwugwubgwwgwruwwwwuurrgbbwbwwwrbbbggwubgbwuubrwbuubrggbw\nbwbrrrrwurrrbgggburgubwubrruwwwrrgwruugb\nurwwwbggugrrgwuwubbbburbugrguwubrbwbwwugb\nbbwrrwugugbgbbgbrrrrrbuwwuuuwrgubgwbwubrburwubwrrgwwurwbr\nbruubrrrwbruruurgrwbrbguwuwwrgrbbgbrbugggbguuwgbbub\nrgrburrwuruwrrgruruuubgrrrrwrubwwbwbbwbgwubuugwbgbww\nrwwgrrbbwbguurwggrurgwgwwgbbubrwgrurggbggurbbugbbrubwruub\nrugbguwubggwwrugbbuwbrwwwuuwbgrugrrrgruruwuuurwugwgrgubruugb\nbbwgbwwruuguuuggrgwrrwrugbggrbbgwrggrrgbgbguurrg\nwggbrguwbbrbbgwugbbgubrwgbbwgurbgwwrguruubbrbuwguwrrwgrugb\nrwgrrgwwwwwugbwuwgurguuwubwbuwrgggbrrruwbwugb\ngwrwbubuwurrubrrbrgbbggrrbugurrwwwruwubwubwuubwrgr\nwwrbwggwguwwbuwuwbrgrbwuuwgruurwrgbgwrubbgubwbrrgwrgugb\nwwwwugwwuwurrrrbwuuuguuwuwuwuurrrgwrwrrwwgbbbrwrrrubgu\nguuguwggwruwgwbuwrrwbbwrbbbbburrbuwbbrgbuuug\nuwuwurwwgwbgwrgrgugwgrbwwbwbbbuggugrbuuwggwwbguuwgw\nrwrrbwbgubbbwbrgwubwgbwuwwrrrwbugggwwwrbrg\nbgbbwurrrruwguuwwwgubwrwwgurrwwguwrwgrgubgubururrrrugb\nbwugruwgwbwbrrbbuwuuwwurwbrrgugbbubguwggggwwurrwb\nrrwuuwurrwwgwwwbuubgrruugrgurwuuwbggrbbwwug\nwgugrwuruwwgrbugbwbgbrrruuubggrbrwubwwgugrwbbrrbugb\nwrwgwwubuwbgwbgwgbubuwuwwwrubwuuwwwwwrwugb\nbrggbuwgwrgguwgwgbrwwuwuuugwgbwwwrgugwbwwwguwuuubwu\nrrwuwburwgwbburbrwrgrbrbgbgrrrrrwgrggwwggrrwuwrr\ngwrrrgrwuruwrbrbbbubgrbgrugrrbbrwgrgbbuugbbbugb\nguwuuwrgbbgrrubwwuwbgwrwwbguwrguguubbuugrrubwwbruwrbw\nwbrrbuwruuuurggurrbgwburwwgurwbrwrbwuuuwwrrrwwgubwgruwrbwr\nrrwgrugbbgwgrwgrburugubuwrububuuugbugugbbgbrurwgrugbu\nwrgwbwbggruugbrrruggwbwwugrguruubgwwgwwwubbwwwwuruurwuru\nbwbrrrbwugubwggrgbuwrbubgubrbbbgwwrgwbrrbu\nugbrrrgbbgrwrbwbwwuwbuuuwbuwuubbgwwurrrubwugggugbbgwrg\nrwgrwwbgwugbwrbuwrwwwgwwbrwrugurwgwbbguwbgruwrggbuubgrwuugb\nurugurwbrrwrruwwrbuubruugurwbrbrbbruururbwubuuugwgggwgugb\nugggugwrwwwuubuubggbbuugbgguwrguubgrrgwurrwwuwubguurrrgugb\nrubrgrrbuwuruwgggbuuwbwubwugggbgguwbwubbbruwwgwwbbbbu\nuwbwgubrbbwgbugwggurbugrbwwwgrwubuuubwubwrw\ngggrggwbwgbbwuuugwbwwubguububggruwububgwwgbwbrrwbbbwu\nguuurwwbbuwgguuwwruubuurgbgwggrrbwwuurwbgwwbubbbgu\nbbgbbrurwrwbrwwbuguggwwwguwuubrrgruuwgururugububurrrb\nbuwbrrubgubwbubgbrrwwwbrrggwrwwgwbruuugb\ngrrbggubwggbbbuwggrubrrbbbggrbuuugbrrrurbbwbb\nwugggrrubwruruggbrbwrgwwugbwwbwbuuwwrbubggbggw\nrggugrbuggrwubrwuugrrugrrrrugwubguwbwwugb\ngrbrgbwrwuugrrbugrugbwruwrwbbggbrwurbuubbwubrgbbgugb\nruurubgrbgrwwgrwrwgwbwuggwwbbrgbgrbbgrugb\ngwbwgubgggbgrrbgwuwrrwwgbrbbbwwgubugrrbwgbgbrwgw\ngbrubwggubwruwwrrwbwrrrwuurwrgbubrrubbbugrbbwu\ngwgrrbwwgrubwrrrrwwrgwrgwgbbugrbrrgrubwgruruugbwugwuuubugb\nrrrwwubbuwuurrruubwbwugrwbwwgurbwwrwrruuguubbbbubbggwugb\ngrwrwburgurbrwuuubgrrgwubwrbuwwwrbbwrgrrrubrwwgrrburwbbw\nububgwuurwruwbwuburbuurwrgwrrguurbwgwwggrwbbugggr\nrgwugbgbbbbbrrbbwwgwguuwurbwbubwwgwwbbgwgbrbgbrwuuuw\nbgbbwugbrwuubuwrgggruuwubbbbgbruguugwrwrbu\nwugbrbrbbwubgbrrugubwugbugrwgubbugbwggugwug\ngbbbwguuwrruubrbgrgbwgubbbgggbbuwwbruugb\nbwgbrbwbbburubbbwwggrwbuwbruguurwruurgbgbrgww\nrbgrggruugbbgwbwuggbruuuurgwbbgubbrbbubgruwbuwgwr\nwgwugguuwubggguubbruugggrrbrrbrwburwrrggrgubrwbbbb\ngbbgwuuubwbrwwburuwwruubuwgwuuwuwgwgurbgrrgbb\nubwgbgwggwwbuwwwbbggbbbwuubwrwggrbbgrrugwr\ngwugwgurgugguwubgbrgwgwbbwbwbuwwwbwugrbwugwgrrg\nrgbbbwruubuurruwbgugggwubwwuwgbbugbbrrrbrwgrrgbr\nuwbggrgrbuwbgwbrurwgbrbbbubgrwburrggwbrbuwugrbwrggub\ngwuuwgwrggbwrrbwwuruguwbrwbgwuggwrgwbuubuugbbrggw\nugbwbrrbbwugggrwwbwubbwrbgrwrrwgbgrgurrurrwbg\ngggwbrggubgwgwrgrrgurubbguwrbwwurgbwrurubbwbrbgrbwrbw\nruwwgurbbbguurgrbwwwgugbbrbguggbrwuurwgwbrr\ngrgugrbwgbbrrugbuwubrgrgbwururggwrbrbgugb\nbrurggwbgwrbbugwbgggwwbwruwbgbgbubgrgbwbwgwbgugw\ngrrggguugwuguugrrrwwugbguugrbbubbrugrubgbgbwururbwbrguurwugb\nwuubwubwgrgurwurrwbbwgbwbgugbwbbbwggruwubgrgbgubb\ngburuuwwwwrubrwwurwgwbbrbuuuwgrrgurgwwwgwgugbwgug\nuruuwbwbbrwwrwruwrgruwuurwrgrguwwggggbuubbbbrrgrruugb\nwrrrbubruuwggbguurubrbuguwurwbgbrrbuwurwbwggbwgrwrbwwuuggugb\nggwwrbgrgrgggbgwuwbgbgwwrrwburuwwgwbggrwgruuwwbwgrugubrru\nubbbbgbugbwuuggubbwrugrbgwwrruwuwggwwuggbwguruw\nrgurwrbwuuuubwggrbuubwwubwwgbubgwugbgrgrurwuwbrwrbbgurgugb\nbgrgrrgrurbwrbrbruububwuwgububwgbwwwrugrgwr\nubbggubwrgwgwwbbbwbbrgguubrbwguggrrguguwgbgg\nruubwgbgugubbrrrbgrbwwuwwwwbgrbwwugrruwwrgbruwwrbugb\nbururubguggubwrurgbrurbubbuwgbwggrguwgggbbubugb\ngrgrguuurwuwgubgrwbbwrwggggbguburrwbububrgb\nwubbwugruwbgbwbrubrrwggwwwubbgurwurwubuggbrruuurrrugb\nwubgbwguwbugbwgwwgrrbubgubgwrgrbgwruwgbwubbggwgwr\nbwwruugwruuruurgbwwrwgrwruguugruruggrrbgugrwrrrrbbgwururugb\ngurruwbwubrurwbuwruggurrgbubwwggwbubgwbbuw\nbwbggubwbbwbwgwrbwbrrgurugbrbrbrbwwrurugrwbggugu\nbwgwgrgwwguuwrwgbuurubwgbgbrwwwgbugwrbwrrggug\nubugrwguuuwrrgbgbggwgbbbubgbgbwubwggwggrururgwr\nwgwwbguwwrburrrwrwwuruugugurbrbgubbgwrrrbbrrugrbbubbb\nwbgurwrbrgwburwrguurrggugurugrbrguwwrrbgruwgbwgrgwwuwgg\nbrrrggwugbbgrwrwrgbbrgbuubwguuwwrwrrrugurugw\ngbubbgrgggbwuuwwgugbgrwbrgbbwwbgbuurwgurwbgbub\nggrugwugrwuburugruruwwwrurbgwbwrbwgbuggwggrwwwrburguurgugb\nwwrrwrruwwwwrurwurrbbrgrbbuuurbwwbguwwwbgrwggbwr\nubrbuurbrwbgrbrwbgubbbrrbrburggburbwwbggrguwg\nugwrbwuwrbgrrubugwbbbbrbrbwuuruuwuwbrwbgguwrwgr\nurwgwwrubrrwrrwwbbrubggrbwrbwgrrbwgrgggbbubwrwwwwguguugb\nubbugwgbwwruwruubwugburwurgbrgwwgbgubbgburrbuuwrbrwurggugb\nrwbgwbruwbguwbrwwburrrrgggbgwgbggrwuwuwbrwgwbggugb\nguggbuuggrgrwwrgrwguwggrbwrbggwwrbgrwbuwrwrgbrwww\nbgwugwubgggwwbuuuwgwubuugggbgbwurwbrgbuurbbb\nwggrrrgrbwruugrgbbguuwgwgwgrugrbgubwggbugwwrgwrgrugb\nuwguuwurgrbwggwbwrubbwgbwrwurwrwuwbwguuuguwuuug\ngrwuwrgwbwbrwrbgggrbbwburbgbuwggrrrrrgbbwgu\nugwrwbwgwrggwwgrrgubgwgrgwurgrwrrbururbuurrwgwgugugb\nwgwggrbrrwbubwurwgubguwrubgwbbrgbbugugguruwbbggruwuwgwwugb\nugwbgbrgrurrurbgbgbruwrbgbugggrwwgrubugggwubbwu\nbbwugrggrwggrwwrugwuwbbgbbwurbgbgrrguwubwbrbrguwrruugb\nbbwggrwwbrrubwgbubguruburwbubbrwwruwrbbbgrburubruruwurwwugb\nwwgurbbwrwrwrubuuwuwgwrrbbwgururbrurbwwggwuuwrbbgrwrgrbg\nwbwbgwgrbrwrugbgwbwgbbgbgrubrrrbwruguugwrb\nwbburwwbggbbgrrbbwwrruuwrrbuguwugwwugbwgb\nuwwbwbuwrwrwggbwrbbwgwrgwwubbwbugbwuggrwrbugb\ngurwgrwwwgwggbubbubrgwwbbwgbwuwbbgwwbrrgbbu\ngbgburbwbburbrbrubwwubwwguubwguwguuburubrbbrrbruggg\nubrbwggrbwururguwubggurbbbrwwrgurwwururuugwrrbbgwburrwrugb\ngrbuurwbrbruugubrbwggbbggbuwruubgwubbrwgbwbwwwgwugbwgrgrb\ngbuugbbwggrurbwrbuwugwuwuuwbwrugbgrbubrbubrwuw\nwrwggugbgurrwbwrgbwubrurbwwgggbwgggwgbgubggrbuwwugb\nwgugbggggbrgrbbrwbruubrrrrggbuwgrwbrbrgwrrwbgbgwuuugb\nggburgwguwggwrbugwgwurgrbggwwwubwrgrugbrugb\nwgubururrugrbbubbrbwwubwuruwwugrubuguwburgubrrwwbbbgbbgwg\ngwurwgwugbugurgubgubuguurwurrbburrbubwwbrwgub\nbwguuugwgugwbuwrwrrwrrubrggrwbbrgugbbgwrguwuwruwwugb\nurrrubrwbwgrgruuwwgbubrbubugguwwgrbwrwuwbu\ngruubbbubwrrrgrbwwbuwbwbrwrubgrrrurgwugbbbbbwggubwug\nugbuwrruwrbbwggbrrgurwggwwgrubbwgwuwwrwugb\nrbrrwuwrrbrguuwuggwbrrubggwgrgwrrwrgbwgbgb\nrbggwgwgubrwbbrgwrwwbubuwgugwrwrgrrgbugb\nwwuwurrbrubbbubgggubwuwbrrrbrgbrwwgrbwurugbugb\nuuubuugggbwwgwrguruwuubbrrguwwuubwwubbbubggubugb\nwbgwbubwbwbwwbrrrwbwrwwgugurrgbbubuuwgrrgbbwuggubgug\ngrwbbrwuwgggbuwgwugrubwubggrgbwbbugruwugrugu\ngbrbwggbbgbwwrwgruwwbwrbbuwburrwbugbbrbubgguugb\nbrbwggbgbwgurwubwguuuugurwbgbwgggubwrubggurgugrbwggrub\nugguuwgubgubrubbbbgwgbuguuubrgrbrbrruggbugb\nbwwbgwruwrrbruuurwugwwbbrurguwrguwrgwbugwguuugbugg\nbbwuwrrwgbgbbwrwwrgwrggubggubuwurugugugwrrwbrgwwguuw\nugwubuguurwrbguruwurrrrgrggrugwguuggwgruwwbbwuu\ngwgwgwbwwrrrbburbugubbubuugugbwuggugwuubrwrggbrbgurgu\nrrrubgggbgwwwbbrrrgubuggbgwrrubgbubuwrggwruuwbuuuwurrw\ngwgrgbrgugbgguwbwubugwrgbrrrgrruggwgwbwbwwurbubgrbgwuw\nuuuubuuwgrwbwbrgwrwwuubwwgrbwrugugwwrwwgrurb\nwugrrgrgbuwggwuuwwbrrbrwbbwbgwuruuwurggugwrwwwug\nbguuwubgrrbwrrbgrubgwburwbwguggwrbbrurgbgrguwuwbbbgrurrbrugb\nrwurgubuwwggrwrrrbgrbgruwgbrwwuubwurgwrwbb\nwrbubrrugbgggburubruubgrugrwgbgwguugwwgrubwbrrguwgrug\nuwugwbuburwgrgbrgggrrrgbbggruubbuurgwuubwwgwbrbruwgg\nwbubuwgbwbwwbwbbgbbguuwgwugrruurbwbbrbggwuburgruugwwrb\ngrgruggwgwbbrwrwuwwwuurrwurwwwwrgbrugbuurruwr\nurbgbbguuwgrwbrgrggwuwurbugbgugrurbrrrrrwrrgrgubw\ngwwrwwwbburgwggburruwugubwwwguuruubugubrwb\nwggggguwguwrrrbugbbgrbwbugbgurrbgugubuubgwuwwburwugb\nbguwgrwuubuwgwurgbrgugrwbrwbuwgurggbgbugb\nwbuubbwruguwuburwuwwrbgrgrrgbbgggrbrbwuwrgguu\nugwwbuuuwwwwburuggubbrbubrurbrrrbwgbgugb\nubggurbruuwgubgbrggugbbbbrbugbuubrrrbuugbrgwurgw\nuugbgugrbruugugwggwwrrbugbgrwbwrggrwwrbuuwgb\ngwgugwbugugwgrgbrbuuuwwbbbbrurrrurwwgwuuugb\nguwrbggbbwgrrwwwbgrgbgburwwbuggwggugguwbrugb\nguubbgubwurbbrbbruwrwbugruwuwuguubugugrruuggbgwgwwuggwugb\nbguwbrrgrrrggurwrrwurwrrrbrbuwrurbwrgrrrubug\nggbgwrrbgbrgwubrbrgrwgrurwbgwbuwbrgbrugrwwwgrbbuwwurubbgw\nbbuurugwggurgwubwbbwgwgrbwuuwgbggurgwwbrbwuwuwbwb\nugbbuurubuubggubwruubbgwubggbrggubgwwbuugwuwbrwgbwug\nbrrggwbrburrwbwrgrwwubbwbbrwuguubugwrgugwugggugb\nwuwrbggbrrrbrgrggbgburrwggwgwgubgrrgbubrggbgbbgbwugb\nbwbwbgbugbgwguwwwbwwwugbggwwguwrbggruwgbwguwguugb\nrbgwwggbwrwggugurbgrbgrgrgbgrrbugrggrwwugb\nuugurugggugwwgrrwbuggbwgruwrbbwwrguwbbbrwrrgwruurbbuwugrwu\nrgggwgbbwguwwwugurwbuugrwbrururwburburbrurrwuwgugrurwwurrg\nugrwwubgrwugwburbwruwgrbrgrgwwbubrbbgwwrgugbwurubggguugb\nubbwubbbrggugrbbrrrgwuruugbuggubgrbwwbbbwbggwrugb\nbuwgbbbbwugbwbruwuwgrwubbuwwbgggwguuwbbugwuugb\nuugrgrwgugwbwwgbwrrbuwwuuguwurggggrwugwuwbbuugb\nurguugrwuwwuurubuurbbwugrbggrgrgwwguubwwwrbbugb\nbwbwrbbggwrggggrgruwwuwwbuwrrbggrgrrurwggrgbbb\nbwbrwwrwwgrwggubwguubrgwbburwgurwbgrruugb\nbgggubwubwbwwbuurbrgbwbuurbrbgwwgrgbwwwrwwrbrrbbrggb\nurugbruwbrbgbbwbguuurruggwruuurrwrubbrrubbrwwwrggwwg\ngwwuggwbuwbbrubgbwgburruwgbwbgbbrgbwrugbbbwugbbuuwbrubrbr\nwbgbuuguuwwbuggwrruggbwurwrrrubbwrruurburrwbbbuurwu\nbgrgbruruuuugwrwuggwuwrbwgrwrbwbwbbuwbbbgggwwuwwgugb\nuwggubrrwuruwwuwwuuwubwbbgbbuuubgwbwgbwburrbrbuugbgguur\ngrgbubwurbuwbbrgugbwuwwuwwrwbrugbrwbuugubbr\nguuwbuwrwwurubrggwurubbuwgrrurgwwugbwgruuguuugb\nwbbwwurwwwwggrrwbrbuwbbrguwgwwrubwrgggruruuugwuwbru\ngwggururwruuuubgrrrgggbguwbrrruguuwbbgguggurr\nggbrruwgggwrrwggurbbubrbbbbgbgwwgggbuugrbrwwburggb\nwbubwgurwwgrgwuruurgwbrrugruwbugrrbbgwrguruwgurrwuwb\nrgrgbgwrrrgrbgbbwubgrggwwruugbbuurrubrbwbgbwuurruurugrugbr\nbuwubbrwgbwbwruwrbrbgrrwrugbggbrbbbwbbgrwwruuuuugwgrgruww\ngggrbrbuugwgwgruwuurwuuggwwbwbuwgwggrgrrburuwguwbbrbwwub\nbgwwuwgbruuuwwgwwugwrbwurrgwubgwwrggbrggwuubgbrwugrbg\nrugwrurrggwwwbggwrrubrburbwrbubuwbrwrwwbuwugwuburubwugb\nugguuwrwgrbuugbrbwbugbbgwbwwuurgruguuugurwuggwwugbwwb\nrbwrbbwrwuwrwgwuuwwrubbgrrwrbwuwwuurugwrugb\nbguwgwgbuguurwrbgrgrbwgwwgugwwwwwuuwbrbrgrugb\nrwgwwuuuwuuuuwwrubugbwuuubrurgbbbgrbbwguwbrrubgugwg\nbwbugruruuwbgrgbgwwbbrrguubuubgugwwwwuwrgrbuugb\ngrgrgrwrbwuwwbwrrbgburubrgubrruurbbbgrrgrwubr\nurburrrbrrgrguubugrwgrwbbgwwwbbruuubgwguburrwu\nrwggbgwguuugubbbbrgggbuurgrugrbburbbwruwwuuwwbwbwwugb\nrubgbrguggrwwwubrbrwburrwgwurrbubwrwwgrrwbbbwgr\nuwwbwbwuwgrbrbbrwbwwgruburggbrgwwgrbrrrburgrbbbub\nwrgwrrwwwbgubrbrwbwbwuwuurwubggbgubrwrrbbwwbgbgrrbwwgrugw\ngrrgwgbggbgbggrwgwurggurrggwgbwuwrbgwrubrg\nwuwgrrbbbrwwubrubwrurrrggrbgwbgrurgwgubuwubrgbbbuguugb\nrwgrgbgggbuwurwrbrrubbrrbrbwgbrgrwwguwgurrgggurbuuwgu\nbbwbbguwugrbbbbgrbrwbrggbuuurbgwgwgugbuwgwug\nrrrurububrburggurugurrubwgugwguwrbgbbggbwgw\nbgubrruugrwuugggwwbuwrwwugrwggbgwwwwwggrrgbubbgrgbgr\nbbuwburbgggruuwbuuwwbwuurwbuugugrgrgruwwwwb\ngubbruurbggbwuubruubugwurgwwbbgubrbwgrwwrggrguugb\nbwwgrrurwggugrguuwgrbwuwbuuwwgrrwggbuububgggugggbubbbgur\nrugrubwwbguwuwwwurwbbuubwwwuguwgurbubrggwrrubrrrrbwrbggb\ngwbuuwgrrgguuwbgrbgwruwugburbrruurgrurbwbuwrrugb\ngbwgwgrrgwrwwrbbwwbggbrbgwrwwrwrgwggrrrbgrwbubgurg\nwuubrguwbwuwugwurgbgbwgubwggbbrrurbwguurbw\nbugwwbrgwguwruuwgbguuwbbwgbgbburbwburbrbrrrbgrbw\ngrwbwggwrbbbrgwbrwrruwubwbgbrwbgbbwwrwggwgwwuurgwurwgggrgugb\nuubgrwggrbubruuubrbrrrbggbgbbruugwwuwgrugurwuwwrwguggbugb\nruwgugrggwuugrugbrwrbggugguggrggrbwuburbbbgrr\nwrububurgbbrgwrgbuguguwwbrbgbwwwwgrbbrwbugb\nwuuwurwbrwrgwrgrrwububrggwgbrrrbgburwgugb\nrgrrguwgwguubwrbruwugrwurbgurbbggbrwgubwbu\nugwbgrbbbgwwrgggggrrbwurrbbwwgguwrwgwbbugb\nbgwrwrgwbwbwrggwuwbggrwwguwurbrggrguuubggwwwrurbuwwuugb\nbbgwwbbuwguggggwbbugbuuururbrwrrububbbbruugbgrrrbururrwrugb\nwbrwbrwgrgwrwuurguubrwguuwuubwrwwgugbrbrbbwbruwgrwwuuwuggw\nwbgwuurbwggurrrbugrbrugbguruwbwgubgbguurrbrwguwrrwgrbw\nrubrrbubgbuuugbbgggrgrgggrruruuwwurbgrugbwrrbgubugrwgwrbrb\nwugwrwwrbuwrggbugbwruugwgwbbgggwuruwwrgurbbrgrr\nbrrubrwbbbrgbuwwguwgrgwbguuwrwrbruwwbrgrgwbugb\nggwrrbgbwgrbrwbbrrwggugwuurrgurgrbgurwrbbubwwuwrwwugb\nrwrrbgrrwbbuubburbbwugwugwgbbwwbuwubuwguwgggrwbuugb\nwuuuwuruwbrrruwrrbwwwbbwrwwugurbbwgrwrguubg\nuwwgbbrgurbwggwbwwuuwuuuwbgwwwrwgwrguggrgwgrgrwwgbbrurrrgg\nbrgwbbrgrrrrrwbwgbwwgruuubbbbwrugubggwgwrwruggugbgw\nrubgwrgbrwrwbwwbrrwrbrrwbwuurugrgwbrgrgubuubbubg\nrwrbwwwubgbwbubguurgbwwbbwggrgggbrrurwgbbbwwbrubbggrbg\nwuubgrrbrrgrburuggbbwruwbbrrwbwgrwwbwbggbbubbbugb\ngbuwbrruuwwwwwbrgguruubrbuuuubgwrrgugrguwwuwwg\nuurburbrugwurruwbrbgggwwubgwuwuwggrwwbbrrrbwbrwggbrg\nuwruguwwgwwbuwugurrbwguwurugrwrugrugrrgwuwugrb\ngrwrbrbgwgwwrbwubbwurwrbwgrurbwgurubrgwbgruuubguuur\ngbugrwrgrbrrrrbbuuwubrugbgbgwrrbbuwgwwuwruggwgwwwgguurwguugb\nbbrbgrgrbguurgwuurrgwuurbrgwrugwbrgwbbuwgbubrwugbggb\nbrwwwgruggguuwbwgbrbgwbrwbbbuggbubwrbwwruwbgrwgbrruw\ngwrgubwgwugrruwwrrugggbugurbubuurbwurgbbwgggwggwrub\nuwbuubrugwubbbbrgurbrrugwrbbrbubrwgbbbrurwbuugrbgwwgugb\ngubgbwrbruwwgrwggrrbgwwbgurgbwubgbrwbuwrgrrgg\nwwgbrgbubrwrguggrugwuwwwwwburgwrbgggguubwwurwbgggwru\ngubruugrgrggbgbbgbubgugwbrrguwbgurrrwrgbgggwbrubbubbwggbgugb\nrgubguuurugruggrguuuubggrwbgbwgbrbrburugwbwuwwuwgbw\nruwbuurburwwgububgrbrwbbbrggrwrgrrrgugrubgrgwwgbgw\nuwurrrbbuwbgrwugbwgbwbrrwrwwuggwbbuuwubgwbwwugb\ngubguruubbrrugburbgrguurwrrurwbbuwgrrrruuugrwgrwrugb\ngrurrwwbbuwwrwwrrrugbwgbrgbrugrrwrgwggrwbuwurgb\nuwrrgubrbbbwbggurrgbbrggwuubgrbgrguugugbwrgbwgbbugw\nwgurrguubuugburrwbggbrrbbbwbgwbrwbwgurgrgururgbbbruwuwb\nwwbbrgrgbubruuuwuurugrruwbuubwrgrrrbggurwurgurrr\nbrbwwbguuugurruwguwgugbbgrbrgguwruuuuwwruugb\nrrbgwwwwwwbrguwbrgwwguwrurrwbgugggbggbwgubrgbubugb\ngrgrgwbrruugwgbwguwwwbwwgrwugbgrbbwrrwgrrbwrbwwgwwbbw\nbgbugrgugugrugrgruuurwwrggbggwrrwurbbgggbwwwuwggwrgrgrb\nuwwrrgrbbwuuruwgwgggrwwrgwrwrruruwbggugrguuugbrrwrbrrgwb\ngburgwwgbwbwurbugurrgrruwubbububwgrrgwwgbuugb\nrguuwbururbwgwubbgrgbgrrwrwbuwwwwuggrbwrguub\nbbugwgugrrbugbgruwrugwwwbbwurrrurrgrgwrbwuuugb\nwbubbrggwwubruuurwrubrggbrgrugurwwugrbuwwgugb\nwggrwrwwburrgbwgbruuggbuwugwruugbwggrwrbbburwwbbugb\nubwubuurrruugrbwggbgugrbgbbubbruwugbburgwugb\nuugwubbbubwrguugggrgugrgrwbwrwrgbbbgbggburrrbggbrwwbgg\nrwuubwwurruuwrwbwbbgrwbbgbbwurrggwugguwburgwwbuwrbu\nugwbgbrwwrguubgwuwrbgurwggbggrurbuwruwgrbrgbbgb\ngrugwbgwbubgurubbrwbrwgbrrbbwubuuwurbrgruwu\nwuwbbbwwwrbrgugwrwrwbwrrbubuwwgbbgurgwbbbuubugugwuggruggw\nrrrwwgrbburwrgbwrwbwuwuuguggubrurrrgrruruggwbwgwubuwu\nrrrgrrrrwwrbwugbwwgurwruwbgugwrggbbgwbugbugb\nrrwgruwgbrwurrrrguuubbwuuuruurruwgbrgbwubgbbggrwbbwww\nrgbugugurwgurrwuuuguggwggrbrbubgwrwuwbbwgbbgwuuugbggb\nurwruwbgrwgwgrrbuwurwwugrbggwwugrgbrggbrbbbguwugb\nurwruwurrgurrbrrgwwrbgbbbgrbrwggubguwggburggbwgrurrbubgrugb\nwgrubgrrwgubrgurubggrgrrrgrggbgbbuwwurburgrrr\nuwrruggugruruurugugbgwguruuruburwugwbugwgbbu\nwuugubwwuugubrwgwurrrrbruguwbwuwwwrrwbwbgbgwg\nurrggrrrbgubrrbwwrbwwrggbuwrrwgugrbwburrgrrbugrrbgbwub\nwgruwrrrgbubwbbuubuwbbgwgwrbwguwugrwuwgrbrwguwb\nurgwbbggugrwwuubrwrgwuugrgwrruwgwrbbwrwurrbguwwuwwggggrrg\nbrwrwrrrrbubbgubwuuwbwuggruggbubbwbwugrgurubbbwrwgr\nbrrruguggbwgurbwburrwrrbugubrrrwrubugggbugb\nwwguwbuuwrbwgrwwwwwrggbuwruuwgurwuugwuurggwgbwu\nrububwbrguuuuwrrbwbguwgrwgwuggugwgbgugrrguwru\nrgrwbuubwrwrwwbwgrugguwgbrwubwruwwbbgggurbwgwrugb\nurrbbubbrubwbwuggrurbbgbgurgbbrgbwbubgrwgrwb\nwrrwwbbwubrwuurbwuurbugrrgrrwurbubrwgrrgggguwr\ngrguwbburbrurubggwwwgrwbgbbugrwrgbrggrugb\ngbwrruuurrwbgrgrwgrburbwwgwwuwbubburgrubgwrwgrbb\nwwwggwrwwubrggwrgrwgwrbggbbbggubwwwbruguwbwbrrruwgrg\nbbwwgwwurwgrgrrgubguggwbugrbuwuwgwgbruwgurgugb\ngwgwgwgbgrruwbruwgbguuuwwrubbgrrwgrruwbbbgww\nrwwwbggwggbbwggubgubwwrwgrbbubwbwbwbbugb\nwgwwgwrbuwbuwgbggwggrguwubggbrwugbbwrrurbrbgru\nrrrbgbwurrrbbbrbwgrugrrrrggbgbrgbbruguwwwbu\nugbugwbuuuruggggrubrrugrrrrugbubwugbbwuuwbrrbugurwbrgwg\ngbbwuwwbbgwurgwguuwrbgbbgbguruuurrrgbwugwwbrgrgwgrwugbbgb\nrwbwggwuuwruuwgburgrubrrwugrwrgggugbgrwgwu\nwwwrrugrgrrrugbwgugrwuwrwuguruwuurugbbbwubbgbubr\nbwgrwrugrbrrurwgwrbgbbrrwrubbbgwwggugwgwrgruggrggbuwbuugb\nggbgurbbgwbrwbuurrgrrwwurwgrwruwwwuguugubb\nwurwgbrgwguubuguugurrwbbrugrgwugruggbgbgbguugb\ngrrbwbuubwbruggwbubwbwgbrugrrwbrrwgwrbugggbggwwgrugb\nuubwrgrrwggubggbwwgugwbrgbgbruwgwuwgrrurrwurbg\ngwgurrrwgrguguuuwugwurgrgrrurbwrwgbggggbgbrbwrwurgugbu\nrrwbwgugruwuubgbwrwbbbbbbbugwgbwrgggwwrurr\nwrrgbwrrbrgrbwuwrwbrrwgubwbgbugburugwgrugruwbgrugb\ngrbbgrwggrggbrrbgwwguubbrbbbgburgrbwgurggru\nbwuwuwbwbugrurgrwbbburwwbrwbuubgggbwwubwwrwwuw\nwwwrwbbuubwrguruwwurwwubbgwbbgbrrurbgwwbuggurbwrugw\nwuuwwruuguuwbrbugubwrurwrggwuguwwgwwbbbugb\nbburuguugrgurugrbwgggbbugrurwgwrrguguuguwubbbbrrwgwurubrugb\nwbwgrbbwbrrubwurrgbwbugbrwgwwgwbuubggggguubwgwbbw\nbwrwurbwgrgrurbrwrbubrbugrbugubbrbbgrgbuwguguuuuu\ngrbuuwbrugrbugurrwwwbwrubuwgwwubrbwwwgurrrbubbrubbwuggugg\nrurbwrrbwuguuwrurwgruguwrgggrbgbgubwgrwbbbwugb\nbbggbwwbwbururuwrgrgrbwggburwwgrrbwuwwwgwgbwgrwwugbg\nbwbbbbbwwgwwrgubrrguurwugwwbguugrbrwubgrwgrugbbgwrrwwubgg\nrrgwuuuwgwuubbrbwuuubggrrgbrubgbgrrrbbgugbgbguugb\nggburbrwwbgbgwwgrubggggguuwwwrrbubrrgwububbruubggwrgggrbuw\nggrugwrgbubrrrwbbwguuruuwgwrbggguwbgguwwggwbugwruubrugb\nbuubwgrbbgwurububwgwbgbrrbrbbrwwbbrbbrwggwbbbuwuug\nwgwruubwbrwgbwugbwwbgruwuwbbgwrbwrrrurbrgrgwbgwrb\nrrrugrgbrrrrgggrbbbgubuwwurwrrrruwbwgwwruwubgwrbwgrbgw\nrwggrgrbgwgwgwrwwwrggwbwwrwgrguuugrrguwggruwb\ngggrbgwgruwwbbugggwrgurbwwwuugrwbburrrgwgwgrwguwwwgrwgbggr\nwwwuwrwggrrrrwuruwwbugbrbrguwuuuuwrrwrbugb\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_19_questions.txt",
    "content": "--- Day 19: Linen Layout ---\n\nToday, The Historians take you up to the hot springs on Gear Island! Very suspiciously, absolutely nothing goes wrong as they begin their careful search of the vast field of helixes.\n\nCould this finally be your chance to visit the onsen next door? Only one way to find out.\n\nAfter a brief conversation with the reception staff at the onsen front desk, you discover that you don't have the right kind of money to pay the admission fee. However, before you can leave, the staff get your attention. Apparently, they've heard about how you helped at the hot springs, and they're willing to make a deal: if you can simply help them arrange their towels, they'll let you in for free!\n\nEvery towel at this onsen is marked with a pattern of colored stripes. There are only a few patterns, but for any particular pattern, the staff can get you as many towels with that pattern as you need. Each stripe can be white (w), blue (u), black (b), red (r), or green (g). So, a towel with the pattern ggr would have a green stripe, a green stripe, and then a red stripe, in that order. (You can't reverse a pattern by flipping a towel upside-down, as that would cause the onsen logo to face the wrong way.)\n\nThe Official Onsen Branding Expert has produced a list of designs - each a long sequence of stripe colors - that they would like to be able to display. You can use any towels you want, but all of the towels' stripes must exactly match the desired design. So, to display the design rgrgr, you could use two rg towels and then an r towel, an rgr towel and then a gr towel, or even a single massive rgrgr towel (assuming such towel patterns were actually available).\n\nTo start, collect together all of the available towel patterns and the list of desired designs (your puzzle input). For example:\n\nr, wr, b, g, bwu, rb, gb, br\n\nbrwrr\nbggr\ngbbr\nrrbgbr\nubwu\nbwurrg\nbrgr\nbbrgwb\n\nThe first line indicates the available towel patterns; in this example, the onsen has unlimited towels with a single red stripe (r), unlimited towels with a white stripe and then a red stripe (wr), and so on.\n\nAfter the blank line, the remaining lines each describe a design the onsen would like to be able to display. In this example, the first design (brwrr) indicates that the onsen would like to be able to display a black stripe, a red stripe, a white stripe, and then two red stripes, in that order.\n\nNot all designs will be possible with the available towels. In the above example, the designs are possible or impossible as follows:\n\n    brwrr can be made with a br towel, then a wr towel, and then finally an r towel.\n    bggr can be made with a b towel, two g towels, and then an r towel.\n    gbbr can be made with a gb towel and then a br towel.\n    rrbgbr can be made with r, rb, g, and br.\n    ubwu is impossible.\n    bwurrg can be made with bwu, r, r, and g.\n    brgr can be made with br, g, and r.\n    bbrgwb is impossible.\n\nIn this example, 6 of the eight designs are possible with the available towel patterns.\n\nTo get into the onsen as soon as possible, consult your list of towel patterns and desired designs carefully. How many designs are possible?\n\n--- Part Two ---\n\nThe staff don't really like some of the towel arrangements you came up with. To avoid an endless cycle of towel rearrangement, maybe you should just give them every possible option.\n\nHere are all of the different ways the above example's designs can be made:\n\nbrwrr can be made in two different ways: b, r, wr, r or br, wr, r.\n\nbggr can only be made with b, g, g, and r.\n\ngbbr can be made 4 different ways:\n\n    g, b, b, r\n    g, b, br\n    gb, b, r\n    gb, br\n\nrrbgbr can be made 6 different ways:\n\n    r, r, b, g, b, r\n    r, r, b, g, br\n    r, r, b, gb, r\n    r, rb, g, b, r\n    r, rb, g, br\n    r, rb, gb, r\n\nbwurrg can only be made with bwu, r, r, and g.\n\nbrgr can be made in two different ways: b, r, g, r or br, g, r.\n\nubwu and bbrgwb are still impossible.\n\nAdding up all of the ways the towels in this example could be arranged into the desired designs yields 16 (2 + 1 + 4 + 6 + 1 + 2).\n\nThey'll let you into the onsen as soon as you have the list. What do you get if you add up the number of different ways you could make each design?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_20.adb",
    "content": "--  Solution to Advent of Code 2024, Day 20\n-------------------------------------------\n--  Race Condition\n--\n--  https://adventofcode.com/2024/day/20\n--  Copy of questions in: aoc_2024_18_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_20 is\n\n  use AoC_Toolbox, HAT;\n\n  input_name : constant VString := +\"aoc_2024_20_mini\"; n : constant := 15;\n  --  input_name : constant VString := +\"aoc_2024_20\"; n : constant := 141;\n\n  verbose : constant Boolean := False;\n\n  map : array (1 .. n, 1 .. n) of Character;\n\n  --  Dijkstra shortest path algorithm.\n  --  Code adapted from AoC_2024_18.\n  --\n  --  The following definitions belong to the Dijkstra algorithm, but\n  --  we keep them less local because of the path tracking.\n\n  list_length_max : constant := 500_000;\n  subtype List_Range is Integer range 1 .. list_length_max;\n\n  type State_Type is record\n    pt : Point;\n  end record;\n\n  type Node is record\n    len   : Natural;\n    state : State_Type;\n    pred  : Natural;  --  This is for backtracking the path.\n  end record;\n\n  list : array (List_Range) of Node;\n  current, explored : Natural;  --  0 <= current <= explored\n\n  type Score_Type is array (1 .. n, 1 .. n) of Natural;  --  , 0 .. path_max, Direction\n  best, best_clear : Score_Type;\n  inf : constant Natural := Integer'Last / 4;\n\n  start, finish, cheat_start, cheat_end : Point;\n\n  function Dijkstra_Algorithm (cheat_start_step : Natural; cheat_dir : Direction_or_Nil) return Natural is\n    cur_len : Natural;\n    cur_s   : State_Type;\n    s       : State_Type;  --  Test state derived from current state.\n\n    procedure Visit (dir : Direction) is\n      len_to, ins : Integer;\n      new_node : Node;\n    begin\n      s := cur_s;\n      case dir is\n        when north => s.pt.y := cur_s.pt.y - 1;\n        when east  => s.pt.x := cur_s.pt.x + 1;\n        when south => s.pt.y := cur_s.pt.y + 1;\n        when west  => s.pt.x := cur_s.pt.x - 1;\n      end case;\n      len_to := cur_len + 1;\n      if s.pt.x in 2 .. n - 1\n        and then s.pt.y in 2 .. n - 1\n        and then len_to < best (s.pt.x, s.pt.y)\n      then\n        if map (s.pt.x, s.pt.y) = '.'\n          or else (len_to = cheat_start_step and then dir = cheat_dir)\n        then\n          --  Found a better path to target state s.\n          best (s.pt.x, s.pt.y) := len_to;\n          --\n          --  Insert in a sorted way.\n          --\n          ins := explored + 1;\n          for i in current + 1 .. explored loop\n            if len_to < list (i).len then\n              ins := i;  --  Insert here.\n              --  Optional: remove another node\n              --  with the same state and a larger length.\n              exit;\n            end if;\n          end loop;\n          for i in reverse ins .. explored loop\n            list (i + 1) := list (i);\n          end loop;\n          new_node.len   := len_to;\n          new_node.state := s;\n          new_node.pred  := current;\n          list (ins) := new_node;\n          explored := explored + 1;\n        end if;\n      end if;\n    end Visit;\n\n  begin\n    current  := 0;\n    explored := 0;\n    best     := best_clear;\n    cheat_end.x := -1;\n    cheat_end.y := -1;\n\n    cur_s.pt := start;\n    cur_len  := 0;\n\n    loop\n      for d in Direction loop\n        Visit (d);\n      end loop;\n      --\n      --  Switch to the next best explored point.\n      --\n      current := current + 1;\n      if current > explored then\n        Put_Line (\"No way found.\");\n        return inf;\n      end if;\n      cur_s := list (current).state;\n      exit when cur_s.pt.x = finish.x and then cur_s.pt.y = finish.y;\n      cur_len := best (cur_s.pt.x, cur_s.pt.y);  --  , cur_s.cheat, cur_s.cheat_dir\n    end loop;\n    return best (cur_s.pt.x, cur_s.pt.y);\n  end Dijkstra_Algorithm;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    c : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        Get (f, c);\n        case c is\n          when 'S' =>\n            start.x := x;\n            start.y := y;\n            c := '.';\n          when 'E' =>\n            finish.x := x;\n            finish.y := y;\n            c := '.';\n          when others =>\n            null;\n        end case;\n        map (x, y) := c;\n        best_clear (x, y) := inf;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Show_Map is\n  begin\n    for y in reverse 1 .. n loop\n      for x in 1 .. n loop\n        if x = start.x and then y = start.y then\n          Put ('S');\n        elsif x = finish.x and then y = finish.y then\n          Put ('E');\n        elsif x = cheat_start.x and then y = cheat_start.y then\n          Put ('C');\n        elsif x = cheat_end.x and then y = cheat_end.y then\n          Put ('c');\n        else\n          Put (map (x, y));\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n    New_Line;\n  end Show_Map;\n\n  stat : array (1 .. 10_000) of Natural;\n  compute_stats : constant Boolean := verbose;\n\n  function Do_Part_1_Explicit_Cheat_Point return VString is\n    len, count, save : Integer;\n\n    procedure Find_Cheat_Points (cheat_step : Integer) is\n      --  We record the optimal path found by latest\n      --  run of Dijkstra's algorithm.\n      i : Integer := current;\n      step : Integer := len;\n    begin\n      while i /= 0 loop\n        i := list (i).pred;\n        step := step - 1;\n        if step = cheat_step + 1 then\n          cheat_end := list (i).state.pt;\n        elsif step = cheat_step then\n          cheat_start := list (i).state.pt;\n          exit;\n        end if;\n      end loop;\n    end Find_Cheat_Points;\n\n    use Interfaces;\n\n    cheats : Hash_Maps.Hash_Map_Type;\n    value : Integer_64;\n    key : VString;\n    unknown : constant := -1;\n    path_max : constant Natural := Dijkstra_Algorithm (0, nil);\n\n  begin\n    count := 0;\n\n    if compute_stats then\n      for i in 1 .. path_max loop\n        stat (i) := 0;\n      end loop;\n    end if;\n\n    Hash_Maps.Clear (cheats);\n\n    for cheat_step in 1 .. path_max loop\n      for cheat_dir in Direction loop\n        len := Dijkstra_Algorithm (cheat_step, cheat_dir);\n        save := path_max - len;\n        if save > 0 then\n          Find_Cheat_Points (cheat_step);\n          key :=\n            Image (cheat_start.x) & \",\" & Image (cheat_start.y) & \"x\" &\n            Image (cheat_end.x) & \",\" & Image (cheat_end.y);\n\n          Hash_Maps.Find (cheats, key, unknown, value);\n          if value = unknown then\n            Hash_Maps.Insert (cheats, key, 1, True, value);\n            if verbose then\n              Put_Line (+\"Saved: \" & save);\n              Show_Map;\n            end if;\n            if compute_stats then\n              stat (save) := stat (save) + 1;\n            end if;\n            if save >= 100 then\n              count := count + 1;\n            end if;\n          else\n            if verbose then\n              Put_Line (+\"Duplicate for saved: \" & save);\n              Show_Map;\n            end if;\n          end if;\n        end if;\n      end loop;\n    end loop;\n\n    --  Finds 1361 cheats with save > 0 including 2 start/end point duplicates -> 1359 unique.\n    --  1360 is the correct value...\n    if compute_stats and verbose then\n      for i in 1 .. path_max loop\n        if stat (i) > 0 then\n          Put_Line (+\"There are \" & stat (i) & \" cheats that save \" & i & \" picoseconds.\");\n        end if;\n      end loop;\n    end if;\n\n    return +\"\" & count;\n\n  end Do_Part_1_Explicit_Cheat_Point;\n\n  --  The following is adapted from the very smart solution @\n  --  https://github.com/jcmoyer/puzzles/blob/master/AdventOfCode2024/src/day20.adb\n  --\n  function Do_as_JC_Moyer (max_cheats : Positive; threshold : Natural) return VString is\n    distance : Score_Type;\n\n    --  No need for a shortest path algorithm:\n    --  we know there is only one path.\n    --\n    procedure Build_Distance_Map is\n      c    : Node;\n      n    : Point;\n      last : Natural;\n    begin\n      distance := best_clear;\n\n      list (1).len := 0;\n      list (1).state.pt := start;\n      last := 1;\n\n      while last > 0 loop\n        c := list (last);\n        last := last - 1;\n\n        distance (c.state.pt.x, c.state.pt.y) := c.len;\n\n        for d in Direction loop\n          n := c.state.pt;\n          case d is\n            when north => n.y := c.state.pt.y - 1;\n            when east  => n.x := c.state.pt.x + 1;\n            when south => n.y := c.state.pt.y + 1;\n            when west  => n.x := c.state.pt.x - 1;\n          end case;\n\n          if distance (n.x, n.y) = inf and then map (n.x, n.y) = '.' then\n            last := last + 1;\n            list (last).len := c.len + 1;\n            list (last).state.pt := n;\n          end if;\n        end loop;\n      end loop;\n    end Build_Distance_Map;\n\n    count : Integer;\n    c, n : Point;\n\n    use Interfaces;\n\n    cheats : Hash_Maps.Hash_Map_Type;\n    value : Integer_64;\n    key : VString;\n    save : Integer;\n\n  begin\n    Build_Distance_Map;\n    Hash_Maps.Clear (cheats);\n\n    for x in map'Range (1) loop\n      for y in map'Range (2) loop\n        if distance (x, y) < inf then\n          for dx in -max_cheats .. +max_cheats loop\n            for dy in -max_cheats .. +max_cheats loop\n              c.x := x;\n              c.y := y;\n              n.x := c.x + dx;\n              n.y := c.y + dy;\n              if n.x in map'Range (1) and then n.y in map'Range (2)\n                and then Dist_L1 (n, c) <= max_cheats\n                and then distance (c.x, c.y) > distance (n.x, n.y)\n                --  Implied pathable; walls are = inf\n              then\n                --  Simulate all walls being removed horizontally from (say) c to (n.x, c.y),\n                --  then vertically from (n.x, c.y) to n, or even on the whole rectangle with\n                --  points c and n as opposite corners. The exact path doesn't matter: all\n                --  lengths are the same (L1 / Manhattan distance) since there is no obstacle!\n\n                --  Compute the gain obtained by having the \"cheat\" path:\n\n                value :=\n                  Integer_64 ((distance (c.x, c.y) - distance (n.x, n.y)) - Dist_L1 (n, c));\n\n                if compute_stats or else value >= Integer_64 (threshold) then\n                  key :=\n                    Image (c.x) & \",\" & Image (c.y) & \"x\" &\n                    Image (n.x) & \",\" & Image (n.y);\n\n                  Hash_Maps.Insert (cheats, key, value, True, value);\n                end if;\n              end if;\n            end loop;\n          end loop;\n        end if;\n      end loop;\n    end loop;\n\n    count := 0;\n\n    if compute_stats then\n      for i in stat'Range loop\n        stat (i) := 0;\n      end loop;\n    end if;\n\n    --  Traverse the hash table for counting the stones:\n    for i in cheats'Range loop\n      for j in 1 .. cheats (i).slots loop\n        save := Integer (cheats (i).slot (j).value);\n        if save > 0 then\n          if compute_stats then\n            stat (save) := stat (save) + 1;\n          end if;\n          if save >= threshold then\n            count := count + 1;\n          end if;\n        end if;\n      end loop;\n    end loop;\n\n    if compute_stats and verbose then\n      Put_Line (+\"Max cheat length: \" & max_cheats);\n      for i in stat'Range loop\n        if stat (i) > 0 then\n          Put_Line (+\"There are \" & stat (i) & \" cheats that save \" & i & \" picoseconds.\");\n        end if;\n      end loop;\n    end if;\n\n    return +\"\" & count;\n\n  end Do_as_JC_Moyer;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\n  threshold_part_1, threshold_part_2 : Natural;\n\n  type Method is (m1, m2);\n  choice : constant Method := m2;\n\nbegin\n  Read_Data;\n\n  if Index (input_name, \"mini\") > 0 then\n    threshold_part_1 := 1;\n    threshold_part_2 := 50;\n  else\n    threshold_part_1 := 100;\n    threshold_part_2 := 100;\n  end if;\n\n  case choice is\n    when m1 =>\n      r (part_1) := Do_Part_1_Explicit_Cheat_Point;\n      r (part_2) := +\"\";\n    when m2 =>\n      r (part_1) := Do_as_JC_Moyer (2,  threshold_part_1);\n      r (part_2) := Do_as_JC_Moyer (20, threshold_part_2);\n  end case;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1360    (mini: 44  with threshold 1)\n    --  Part 2: validated by AoC: 1005476 (mini: 285 with threshold 50)\n  end if;\nend AoC_2024_20;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_20.txt",
    "content": "#############################################################################################################################################\n#.....#.......#...#...#...#.....#.......###...###.......#.......###.....#.....#.....#...###.....#...#...###.........#.......#...#...###.....#\n#.###.#.#####.#.#.#.#.#.#.#.###.#.#####.###.#.###.#####.#.#####.###.###.#.###.#.###.#.#.###.###.#.#.#.#.###.#######.#.#####.#.#.#.#.###.###.#\n#.#...#...#...#.#.#.#...#.#...#.#...#...#...#.....#...#.#.....#...#...#...#...#...#...#.#...#...#.#.#.#.#...#.......#.....#...#...#...#.#...#\n#.#.#####.#.###.#.#.#####.###.#.###.#.###.#########.#.#.#####.###.###.#####.#####.#####.#.###.###.#.#.#.#.###.###########.###########.#.#.###\n#.#...#...#.#...#.#.....#.....#.#...#...#...#.......#...#...#.#...###...#...#####.....#.#.#...#...#.#.#.#...#.....#.....#...#.........#.#...#\n#.###.#.###.#.###.#####.#######.#.#####.###.#.###########.#.#.#.#######.#.###########.#.#.#.###.###.#.#.###.#####.#.###.###.#.#########.###.#\n#...#.#.#...#...#...#...#.....#.#.....#.....#.....#...###.#.#.#.#...#...#.#...#...#...#.#.#...#...#.#.#.###.#.....#.#...#...#...###.....#...#\n###.#.#.#.#####.###.#.###.###.#.#####.###########.#.#.###.#.#.#.#.#.#.###.#.#.#.#.#.###.#.###.###.#.#.#.###.#.#####.#.###.#####.###.#####.###\n#...#.#.#.#...#...#.#...#...#...#...#...#...#...#.#.#.#...#.#.#.#.#.#...#.#.#.#.#.#...#.#...#.###.#.#.#.....#...#...#.....#...#...#.#.....###\n#.###.#.#.#.#.###.#.###.###.#####.#.###.#.#.#.#.#.#.#.#.###.#.#.#.#.###.#.#.#.#.#.###.#.###.#.###.#.#.#########.#.#########.#.###.#.#.#######\n#...#...#...#...#.#.###...#...#...#...#.#.#.#.#...#.#...#...#.#.#.#.#...#...#.#.#...#.#.###.#...#.#.#.....#.....#.#.....#...#.....#.#.......#\n###.###########.#.#.#####.###.#.#####.#.#.#.#.#####.#####.###.#.#.#.#.#######.#.###.#.#.###.###.#.#.#####.#.#####.#.###.#.#########.#######.#\n#...#.....#...#...#.....#.#...#...#...#...#.#...#...#...#.#...#.#.#.#.....#...#...#...#.....#...#.#.###...#.###...#...#.#.#...#...#.#.......#\n#.###.###.#.#.#########.#.#.#####.#.#######.###.#.###.#.#.#.###.#.#.#####.#.#####.###########.###.#.###.###.###.#####.#.#.#.#.#.#.#.#.#######\n#...#...#.#.#.........#...#.#.....#...#...#.#...#.....#.#.#...#.#.#...###.#.#...#.....#.......#...#...#...#...#...#...#...#.#.#.#.#.#...#...#\n###.###.#.#.#########.#####.#.#######.#.#.#.#.#########.#.###.#.#.###.###.#.#.#.#####.#.#######.#####.###.###.###.#.#######.#.#.#.#.###.#.#.#\n#...#...#...###...###...#...#...#.....#.#.#.#.#...###...#.#...#.#.#...#...#...#.#.....#.......#.#...#...#...#.#...#.....#...#...#...#...#.#.#\n#.###.#########.#.#####.#.#####.#.#####.#.#.#.#.#.###.###.#.###.#.#.###.#######.#.###########.#.#.#.###.###.#.#.#######.#.###########.###.#.#\n#.....#...#.....#...###.#.#####.#.#.....#.#.#.#.#.#...#...#.#...#.#...#.#.....#.#.....#.......#...#.#...#...#.#.#.......#.#...........#...#.#\n#######.#.#.#######.###.#.#####.#.#.#####.#.#.#.#.#.###.###.#.###.###.#.#.###.#.#####.#.###########.#.###.###.#.#.#######.#.###########.###.#\n###.....#.#.....#...#...#...#...#.#.....#.#.#.#.#.#...#.###.#...#...#.#...#...#.....#.#...#...###...#...#.#...#.#...#...#.#.#...###.....#...#\n###.#####.#####.#.###.#####.#.###.#####.#.#.#.#.#.###.#.###.###.###.#.#####.#######.#.###.#.#.###.#####.#.#.###.###.#.#.#.#.#.#.###.#####.###\n#...#...#...#...#...#...#...#...#...#...#...#.#.#...#.#...#.#...#...#.....#...#...#...#...#.#...#.....#.#.#.###.#...#.#...#...#...#.#.....###\n#.###.#.###.#.#####.###.#.#####.###.#.#######.#.###.#.###.#.#.###.#######.###.#.#.#####.###.###.#####.#.#.#.###.#.###.###########.#.#.#######\n#...#.#...#...#...#...#.#...#...#...#.#.....#.#.#...#...#.#.#...#.#.......###...#.....#...#.#...#...#.#.#.#.#...#.....#.........#...#.....###\n###.#.###.#####.#.###.#.###.#.###.###.#.###.#.#.#.#####.#.#.###.#.#.#################.###.#.#.###.#.#.#.#.#.#.#########.#######.#########.###\n###...###...#...#...#...#...#.#...###...#...#.#.#...#...#.#.#...#.#.......#...#...###.#...#.#.#...#.#.#.#.#...#...#...#.......#.....#...#...#\n###########.#.#####.#####.###.#.#########.###.#.###.#.###.#.#.###.#######.#.#.#.#.###.#.###.#.#.###.#.#.#.#####.#.#.#.#######.#####.#.#.###.#\n#.....###...#.#...#.#...#.....#.#...#...#...#.#.#...#...#.#.#.#...#.......#.#.#.#.....#.###.#.#...#...#.#.#.....#...#.#.....#.....#...#.#...#\n#.###.###.###.#.#.#.#.#.#######.#.#.#.#.###.#.#.#.#####.#.#.#.#.###.#######.#.#.#######.###.#.###.#####.#.#.#########.#.###.#####.#####.#.###\n#...#...#.....#.#.#...#...#...#.#.#.#.#.#...#...#.#.....#...#.#...#.#...#...#.#.....#...#...#...#.....#.#.#.#.....#...#...#.#...#.#...#.#...#\n###.###.#######.#.#######.#.#.#.#.#.#.#.#.#######.#.#########.###.#.#.#.#.###.#####.#.###.#####.#####.#.#.#.#.###.#.#####.#.#.#.#.#.#.#.###.#\n###...#.........#.###...#...#.#.#.#.#.#.#.......#.#...#.......###.#.#.#.#.#...#...#.#.###.#.....#...#.#.#.#...#...#.......#...#.#...#.#.....#\n#####.###########.###.#.#####.#.#.#.#.#.#######.#.###.#.#########.#.#.#.#.#.###.#.#.#.###.#.#####.#.#.#.#.#####.###############.#####.#######\n#...#...........#.#...#.......#...#...#...#...#.#.#...#.#.....#...#.#.#.#.#.#...#.#.#...#.#.....#.#.#.#...#...#...#...........#.......#.....#\n#.#.###########.#.#.#####################.#.#.#.#.#.###.#.###.#.###.#.#.#.#.#.###.#.###.#.#####.#.#.#.#####.#.###.#.#########.#########.###.#\n#.#.............#...#.....#.............#...#.#.#.#...#.#.#...#.#...#.#...#.#.###.#.#...#...###.#.#...#.....#.#...#.#...#.....#...#...#.#...#\n#.###################.###.#.###########.#####.#.#.###.#.#.#.###.#.###.#####.#.###.#.#.#####.###.#.#####.#####.#.###.#.#.#.#####.#.#.#.#.#.###\n#.....................###...#...###...#...#...#.#.....#.#.#...#.#...#...#...#...#.#.#.....#...#.#.....#.....#...###.#.#...#.....#...#...#...#\n#############################.#.###.#.###.#.###.#######.#.###.#.###.###.#.#####.#.#.#####.###.#.#####.#####.#######.#.#####.###############.#\n#.............................#.....#.....#...#.......#.#.###...###...#.#.#.....#...###...#...#.#.....###...###...#.#.#...#...#.............#\n#.###########################################.#######.#.#.###########.#.#.#.###########.###.###.#.#######.#####.#.#.#.#.#.###.#.#############\n#.#...................#...#...#.....###...###.....#...#.#.....#.......#.#.#.#.....#.....#...###.#.#.......#...#.#.#.#...#...#.#.............#\n#.#.#################.#.#.#.#.#.###.###.#.#######.#.###.#####.#.#######.#.#.#.###.#.#####.#####.#.#.#######.#.#.#.#.#######.#.#############.#\n#...#...###...#.......#.#.#.#...###.....#.......#.#.###.......#...#...#.#.#.#...#...#...#.###...#.#.........#...#...#.......#.#...........#.#\n#####.#.###.#.#.#######.#.#.###################.#.#.#############.#.#.#.#.#.###.#####.#.#.###.###.###################.#######.#.#########.#.#\n#.....#.....#.#.........#...###...........#.....#...#.....#.....#.#.#.#.#...###...#...#.#...#.....###.........#.....#.#...###.#.#...#...#...#\n#.###########.#################.#########.#.#########.###.#.###.#.#.#.#.#########.#.###.###.#########.#######.#.###.#.#.#.###.#.#.#.#.#.#####\n#...#...#...#...#...#...###...#.........#.#.#...#...#...#.#.#...#.#.#...#...###...#...#...#.#...#...#.......#.#...#.#...#.....#...#...#.....#\n###.#.#.#.#.###.#.#.#.#.###.#.#########.#.#.#.#.#.#.###.#.#.#.###.#.#####.#.###.#####.###.#.#.#.#.#.#######.#.###.#.#######################.#\n#...#.#...#...#.#.#...#...#.#...........#.#...#...#.....#...#.###.#.#.....#.....#...#.#...#.#.#...#.#.......#.....#...#.....#...#...#.......#\n#.###.#######.#.#.#######.#.#############.###################.###.#.#.###########.#.#.#.###.#.#####.#.###############.#.###.#.#.#.#.#.#######\n#.....#...###.#...#.....#.#.........#...#...........#...#...#...#.#.#.#.......#...#...#.....#.....#.#...........#...#.#.###.#.#.#.#...#...###\n#######.#.###.#####.###.#.#########.#.#.###########.#.#.#.#.###.#.#.#.#.#####.#.#################.#.###########.#.#.#.#.###.#.#.#.#####.#.###\n#.....#.#.#...#...#.###.#.#...#...#...#...........#.#.#.#.#.#...#.#.#.#.#.....#.#...###...#...#...#.........#...#.#.#.#...#...#...###...#...#\n#.###.#.#.#.###.#.#.###.#.#.#.#.#.###############.#.#.#.#.#.#.###.#.#.#.#.#####.#.#.###.#.#.#.#.###########.#.###.#.#.###.###########.#####.#\n#...#.#.#.#.....#...#...#...#...#.................#.#.#...#.#.###...#.#.#...#...#.#.....#...#...#...#.....#.#.....#.#...#.....###...#.#.....#\n###.#.#.#.###########.#############################.#.#####.#.#######.#.###.#.###.###############.#.#.###.#.#######.###.#####.###.#.#.#.#####\n###.#...#.#...#.....#.............................#.#...#...#.......#...###...###.........#...#...#.#...#.#.........###.....#.....#...#.....#\n###.#####.#.#.#.###.#############################.#.###.#.#########.#####################.#.#.#.###.###.#.#################.###############.#\n#...#...#.#.#.#...#...............#.....#.........#.....#...#...#...###...................#.#...###.....#.....###.........#...#...#...#.....#\n#.###.#.#.#.#.###.###############.#.###.#.#################.#.#.#.#####.###################.#################.###.#######.###.#.#.#.#.#.#####\n#...#.#.#...#.....#.............#.#.###...#...###...#.....#.#.#...#.....#...#.....#...#...#.#.........###...#.....#.......###...#.#.#.#.....#\n###.#.#.###########.###########.#.#.#######.#.###.#.#.###.#.#.#####.#####.#.#.###.#.#.#.#.#.#.#######.###.#.#######.#############.#.#.#####.#\n###...#.............###...#.....#.#.........#...#.#.#.#...#.#.....#.....#.#.#.#...#.#...#.#.#.......#.....#.........#...........#...#.......#\n#######################.#.#.#####.#############.#.#.#.#.###.#####.#####.#.#.#.#.###.#####.#.#######.#################.#########.#############\n#.......................#...#...#.....#.......#...#...#...#.#.....#.....#.#...#.....###...#.#.......#.................#.........#...#.....###\n#.###########################.#.#####.#.#####.###########.#.#.#####.#####.#############.###.#.#######.#################.#########.#.#.###.###\n#...................#...#...#.#.#...#...#...#.....#.......#...#...#.......#...#.........#...#...#...#.#.......#...#.....#...#.....#.#...#...#\n###################.#.#.#.#.#.#.#.#.#####.#.#####.#.###########.#.#########.#.#.#########.#####.#.#.#.#.#####.#.#.#.#####.#.#.#####.###.###.#\n#.....#...........#.#.#.#.#.#.#...#.......#.....#.#.........#...#.#.....#...#.#.....#.....#####.#.#...#.....#...#...###...#...#.....###.#...#\n#.###.#.#########.#.#.#.#.#.#.#################.#.#########.#.###.#.###.#.###.#####.#.#########.#.#########.###########.#######.#######.#.###\n#...#.#.........#...#.#...#...#.................#.....#...#.#...#.#...#.#...#.......#.#...###...#.#.........#...###.....#.......#.......#...#\n###.#.#########.#####.#########.#####################.#.#.#.###.#.###.#.###.#########.#.#.###.###.#.#########.#.###.#####.#######.#########.#\n#...#.......###.......#.......#.......#.........#...#.#.#.#.....#...#.#...#.....#...#.#.#.....#...#...........#.....#.....###...#.#.......#.#\n#.#########.###########.#####.#######.#.#######.#.#.#.#.#.#########.#.###.#####.#.#.#.#.#######.#####################.#######.#.#.#.#####.#.#\n#.#...#...#.............#...#.........#.#.......#.#.#...#.#...#.....#.#...#.....#.#.#.#...#...#.#...........#...#...#.........#...#...###...#\n#.#.#.#.#.###############.#.###########.#.#######.#.#####.#.#.#.#####.#.###.#####.#.#.###.#.#.#.#.#########.#.#.#.#.#################.#######\n#.#.#...#...#...#.....#...#.............#.......#.#.....#.#.#.#.#.....#...#.......#...###...#...#.....#...#.#.#...#.#.....#.....#...#.......#\n#.#.#######.#.#.#.###.#.#######################.#.#####.#.#.#.#.#.#######.###########################.#.#.#.#.#####.#.###.#.###.#.#.#######.#\n#.#...#...#...#...###...#.......................#.#.....#.#.#...#.....#...###.....#...........#...###...#.#.#...#...#...#...###.#.#.......#.#\n#.###.#.#.###############.#######################.#.#####.#.#########.#.#####.###.#.#########.#.#.#######.#.###.#.#####.#######.#.#######.#.#\n#...#.#.#.............###...................#...#.#.#...#...#.....#...#...#...#...#.........#.#.#.#...#...#.....#...#...#...#...#.......#.#.#\n###.#.#.#############.#####################.#.#.#.#.#.#.#####.###.#.#####.#.###.###########.#.#.#.#.#.#.###########.#.###.#.#.#########.#.#.#\n###...#.............#.......................#.#...#...#...#...#...#.#.....#...#.....#.......#...#...#.#...........#.#.....#.#...#.......#.#.#\n###################.#########################.###########.#.###.###.#.#######.#####.#.###############.###########.#.#######.###.#.#######.#.#\n#...#...#...........#...#...#.......#...#...#.#...........#...#...#.#...#...#.#.....#.....#.........#.............#.#.......###.#.......#.#.#\n#.#.#.#.#.###########.#.#.#.#.#####.#.#.#.#.#.#.#############.###.#.###.#.#.#.#.#########.#.#######.###############.#.#########.#######.#.#.#\n#.#...#...#.......#...#...#...#.....#.#.#.#.#.#.###....S#...#...#.#.#...#.#...#.#.....###...#...#...#.............#.#.........#.#...#...#...#\n#.#########.#####.#.###########.#####.#.#.#.#.#.###.#####.#.###.#.#.#.###.#####.#.###.#######.#.#.###.###########.#.#########.#.#.#.#.#######\n#...#...#...#.....#.###...#...#.......#...#...#...#.#####.#...#.#...#.###.#.....#.#...#...#...#.#.#...###.........#.......#...#.#.#.#.......#\n###.#.#.#.###.#####.###.#.#.#.###################.#.#####.###.#.#####.###.#.#####.#.###.#.#.###.#.#.#####.###############.#.###.#.#.#######.#\n#...#.#.#.#...#...#.#...#...#.....................#.#####...#.#...#...#...#...#...#...#.#.#...#.#...#...#.....#.......###...###...#...#.....#\n#.###.#.#.#.###.#.#.#.#############################.#######.#.###.#.###.#####.#.#####.#.#.###.#.#####.#.#####.#.#####.###############.#.#####\n#.....#...#.....#...#.......................#.......#####...#...#.#...#.#.....#.#.....#.#.#...#.#...#.#.....#...#.....#...........###.#.....#\n###########################################.#.###########.#####.#.###.#.#.#####.#.#####.#.#.###.#.#.#.#####.#####.#####.#########.###.#####.#\n#.........###...........#...................#.###########.....#.#.#...#.#...#...#...#...#.#...#.#.#.#.....#.......#...#.#.........#...#...#.#\n#.#######.###.#########.#.###################.###############.#.#.#.###.###.#.#####.#.###.###.#.#.#.#####.#########.#.#.#.#########.###.#.#.#\n#.......#.....#...#...#.#...............#...#.#####.....#...#.#.#.#.###.#...#.#.....#...#.#...#...#.#...#.........#.#...#.........#.#...#.#.#\n#######.#######.#.#.#.#.###############.#.#.#.#####.###.#.#.#.#.#.#.###.#.###.#.#######.#.#.#######.#.#.#########.#.#############.#.#.###.#.#\n###...#.........#...#.#.#...............#.#...#####...#.#.#...#.#.#...#.#.#...#...#...#.#.#.#...#...#.#...........#.#...........#.#...###.#.#\n###.#.###############.#.#.###############.###########.#.#.#####.#.###.#.#.#.#####.#.#.#.#.#.#.#.#.###.#############.#.#########.#.#######.#.#\n#...#...........#.....#...#...#.....#...#.....#######.#.#...#...#.#...#.#.#...#...#.#.#.#.#...#.#.###...............#.........#.#.......#...#\n#.#############.#.#########.#.#.###.#.#.#####.#######.#.###.#.###.#.###.#.###.#.###.#.#.#.#####.#.###########################.#.#######.#####\n#.#.....#.....#...#.....#...#...###...#...#...#######.#...#.#...#.#...#.#.#...#.#...#.#.#.#...#.#.#...#...#...#...#...#...#...#.#.....#.#...#\n#.#.###.#.###.#####.###.#.###############.#.#########.###.#.###.#.###.#.#.#.###.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#.###.#.#.#.#\n#...###...###.......###...###...#...#.....#...#######...#.#.#...#.#...#.#.#...#.#.###...#.#.#.#.#.#.#...#.#.#...#.#.#...#...###...#...#...#.#\n#############################.#.#.#.#.#######.#########.#.#.#.###.#.###.#.###.#.#.#######.#.#.#.#.#.#####.#.#####.#.###############.#######.#\n#.......#...#.........#...#...#...#...#...#...#######...#.#.#...#.#...#.#.#...#.#...###...#.#.#.#.#.....#.#.....#.#...............#.....#...#\n#.#####.#.#.#.#######.#.#.#.###########.#.#.#########.###.#.###.#.###.#.#.#.###.###.###.###.#.#.#.#####.#.#####.#.###############.#####.#.###\n#.....#.#.#...#.....#.#.#...#...#.....#.#.#...#..E###...#.#.#...#.#...#.#...###...#...#...#.#.#.#.#...#.#.#...#.#.#...#...........#...#...###\n#####.#.#.#####.###.#.#.#####.#.#.###.#.#.###.#.#######.#.#.#.###.#.###.#########.###.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###########.#.#######\n#.....#...#...#.#...#...#...#.#.#.#...#.#.#...#.#...#...#...#.....#...#.###.......#...###.#.#.#.#...#.#.#...#.#.#.#.#.#.............#.......#\n#.#########.#.#.#.#######.#.#.#.#.#.###.#.#.###.#.#.#.###############.#.###.#######.#####.#.#.#.#####.#.#####.#.#.#.#.#####################.#\n#.#.........#...#...#...#.#.#.#.#.#...#.#...###...#.#...........#.....#...#.....#...#.....#.#.#...###.#.....#.#.#.#.#...#...................#\n#.#.###############.#.#.#.#.#.#.#.###.#.###########.###########.#.#######.#####.#.###.#####.#.###.###.#####.#.#.#.#.###.#.###################\n#...#.......#.......#.#.#.#...#.#.#...#...#.....#...#.....#...#.#.#.....#...###.#.###...#...#...#...#.#...#.#.#.#...###.#.........#.........#\n#####.#####.#.#######.#.#.#####.#.#.#####.#.###.#.###.###.#.#.#.#.#.###.###.###.#.#####.#.#####.###.#.#.#.#.#.#.#######.#########.#.#######.#\n###...#...#.#.........#.#...#...#.#.#...#.#...#.#.#...###...#.#.#.#.#...#...#...#.....#...#.....#...#...#.#.#.#.......#...#...#...#.#.......#\n###.###.#.#.###########.###.#.###.#.#.#.#.###.#.#.#.#########.#.#.#.#.###.###.#######.#####.#####.#######.#.#.#######.###.#.#.#.###.#.#######\n#...#...#.#.............#...#...#.#.#.#...#...#...#.........#.#.#...#...#...#...#.....#.....#...#.#.....#.#.#.#...#...###.#.#...###.#.....###\n#.###.###.###############.#####.#.#.#.#####.###############.#.#.#######.###.###.#.#####.#####.#.#.#.###.#.#.#.#.#.#.#####.#.#######.#####.###\n#...#...#.#.............#.#.....#.#.#.#.....#...#.....#.....#.#...#####...#.#...#.#.....#...#.#.#...#...#.#.#.#.#.#.#...#.#.........#...#...#\n###.###.#.#.###########.#.#.#####.#.#.#.#####.#.#.###.#.#####.###.#######.#.#.###.#.#####.#.#.#.#####.###.#.#.#.#.#.#.#.#.###########.#.###.#\n#...#...#...###.........#.#.#...#.#.#.#...#...#.#...#.#.....#...#...#.....#.#.....#.#.....#.#.#...#...###...#.#.#.#...#.#...#.........#...#.#\n#.###.#########.#########.#.#.#.#.#.#.###.#.###.###.#.#####.###.###.#.#####.#######.#.#####.#.###.#.#########.#.#.#####.###.#.###########.#.#\n#.#...###.......#.....#...#.#.#.#.#.#.#...#...#.#...#.#.....#...#...#...#...###.....#.#.....#...#.#.........#.#.#.#...#.#...#.......#...#...#\n#.#.#####.#######.###.#.###.#.#.#.#.#.#.#####.#.#.###.#.#####.###.#####.#.#####.#####.#.#######.#.#########.#.#.#.#.#.#.#.#########.#.#.#####\n#...#...#.....#...#...#.###.#.#...#...#...#...#.#...#.#.....#...#.###...#.#.....#...#.#.#...#...#.#.........#.#.#.#.#.#.#.#...#...#...#.....#\n#####.#.#####.#.###.###.###.#.###########.#.###.###.#.#####.###.#.###.###.#.#####.#.#.#.#.#.#.###.#.#########.#.#.#.#.#.#.#.#.#.#.#########.#\n###...#.......#...#...#.#...#...#...#...#.#.###.#...#.....#...#.#...#...#.#.....#.#.#.#...#.#.#...#.........#...#.#.#...#...#.#.#.......#...#\n###.#############.###.#.#.#####.#.#.#.#.#.#.###.#.#######.###.#.###.###.#.#####.#.#.#.#####.#.#.###########.#####.#.#########.#.#######.#.###\n#...#.....#...#...#...#.#...#...#.#...#...#...#.#.###...#.....#.#...#...#.#.....#.#.#...###...#.#...#.....#.....#.#...#...###.#.......#.#...#\n#.###.###.#.#.#.###.###.###.#.###.###########.#.#.###.#.#######.#.###.###.#.#####.#.###.#######.#.#.#.###.#####.#.###.#.#.###.#######.#.###.#\n#...#.###...#.#...#...#.###.#.###.........#...#.#.....#.....###.#.###.....#...#...#...#.#.......#.#.#...#.#.....#.#...#.#...#...#.....#.....#\n###.#.#######.###.###.#.###.#.###########.#.###.###########.###.#.###########.#.#####.#.#.#######.#.###.#.#.#####.#.###.###.###.#.###########\n#...#.#.......#...#...#.#...#...#.........#...#.#.....#...#...#.#.......#.....#.#.....#.#...#...#.#.#...#.#...#...#.....#...#...#...........#\n#.###.#.#######.###.###.#.#####.#.###########.#.#.###.#.#.###.#.#######.#.#####.#.#####.###.#.#.#.#.#.###.###.#.#########.###.#############.#\n#.....#.........###.....#.......#.............#...###...#.....#.........#.......#.......###...#...#...###.....#...........###...............#\n#############################################################################################################################################\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_20_mini.txt",
    "content": "###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..E#...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_20_questions.txt",
    "content": "--- Day 20: Race Condition ---\n\nThe Historians are quite pixelated again. This time, a massive, black building looms over you - you're right outside the CPU!\n\nWhile The Historians get to work, a nearby program sees that you're idle and challenges you to a race. Apparently, you've arrived just in time for the frequently-held race condition festival!\n\nThe race takes place on a particularly long and twisting code path; programs compete to see who can finish in the fewest picoseconds. The winner even gets their very own mutex!\n\nThey hand you a map of the racetrack (your puzzle input). For example:\n\n###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..E#...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nThe map consists of track (.) - including the start (S) and end (E) positions (both of which also count as track) - and walls (#).\n\nWhen a program runs through the racetrack, it starts at the start position. Then, it is allowed to move up, down, left, or right; each such move takes 1 picosecond. The goal is to reach the end position as quickly as possible. In this example racetrack, the fastest time is 84 picoseconds.\n\nBecause there is only a single path from the start to the end and the programs all go the same speed, the races used to be pretty boring. To make things more interesting, they introduced a new rule to the races: programs are allowed to cheat.\n\nThe rules for cheating are very strict. Exactly once during a race, a program may disable collision for up to 2 picoseconds. This allows the program to pass through walls as if they were regular track. At the end of the cheat, the program must be back on normal track again; otherwise, it will receive a segmentation fault and get disqualified.\n\nSo, a program could complete the course in 72 picoseconds (saving 12 picoseconds) by cheating for the two moves marked 1 and 2:\n\n###############\n#...#...12....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..E#...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nOr, a program could complete the course in 64 picoseconds (saving 20 picoseconds) by cheating for the two moves marked 1 and 2:\n\n###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..E#...12..#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nThis cheat saves 38 picoseconds:\n\n###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..E#...#...#\n###.####1##.###\n#...###.2.#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nThis cheat saves 64 picoseconds and takes the program directly to the end:\n\n###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..21...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nEach cheat has a distinct start position (the position where the cheat is activated, just before the first move that is allowed to go through walls) and end position; cheats are uniquely identified by their start position and end position.\n\nIn this example, the total number of cheats (grouped by the amount of time they save) are as follows:\n\n    There are 14 cheats that save 2 picoseconds.\n    There are 14 cheats that save 4 picoseconds.\n    There are 2 cheats that save 6 picoseconds.\n    There are 4 cheats that save 8 picoseconds.\n    There are 2 cheats that save 10 picoseconds.\n    There are 3 cheats that save 12 picoseconds.\n    There is one cheat that saves 20 picoseconds.\n    There is one cheat that saves 36 picoseconds.\n    There is one cheat that saves 38 picoseconds.\n    There is one cheat that saves 40 picoseconds.\n    There is one cheat that saves 64 picoseconds.\n\nYou aren't sure what the conditions of the racetrack will be like, so to give yourself as many options as possible, you'll need a list of the best cheats. How many cheats would save you at least 100 picoseconds?\n\n--- Part Two ---\n\nThe programs seem perplexed by your list of cheats. Apparently, the two-picosecond cheating rule was deprecated several milliseconds ago! The latest version of the cheating rule permits a single cheat that instead lasts at most 20 picoseconds.\n\nNow, in addition to all the cheats that were possible in just two picoseconds, many more cheats are possible. This six-picosecond cheat saves 76 picoseconds:\n\n###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#1#####.#.#.###\n#2#####.#.#...#\n#3#####.#.###.#\n#456.E#...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nBecause this cheat has the same start and end positions as the one above, it's the same cheat, even though the path taken during the cheat is different:\n\n###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S12..#.#.#...#\n###3###.#.#.###\n###4###.#.#...#\n###5###.#.###.#\n###6.E#...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n\nCheats don't need to use all 20 picoseconds; cheats can last any amount of time up to and including 20 picoseconds (but can still only end when the program is on normal track). Any cheat time not used is lost; it can't be saved for another cheat later.\n\nYou'll still need a list of the best cheats, but now there are even more to choose between. Here are the quantities of cheats in this example that save 50 picoseconds or more:\n\n    There are 32 cheats that save 50 picoseconds.\n    There are 31 cheats that save 52 picoseconds.\n    There are 29 cheats that save 54 picoseconds.\n    There are 39 cheats that save 56 picoseconds.\n    There are 25 cheats that save 58 picoseconds.\n    There are 23 cheats that save 60 picoseconds.\n    There are 20 cheats that save 62 picoseconds.\n    There are 19 cheats that save 64 picoseconds.\n    There are 12 cheats that save 66 picoseconds.\n    There are 14 cheats that save 68 picoseconds.\n    There are 12 cheats that save 70 picoseconds.\n    There are 22 cheats that save 72 picoseconds.\n    There are 4 cheats that save 74 picoseconds.\n    There are 3 cheats that save 76 picoseconds.\n\nFind the best cheats using the updated cheating rules. How many cheats would save you at least 100 picoseconds?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_21.adb",
    "content": "--  Solution to Advent of Code 2024, Day 21\n-------------------------------------------\n--  Keypad Conundrum\n--\n--  https://adventofcode.com/2024/day/21\n--  Copy of questions in: aoc_2024_21_questions.txt\n--\n--  HAC 0.40 \"nice-to-have\"'s detected in this exercise:\n--\n--    *     pass string literals directly! - Solved in HAC 0.41\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox, Interfaces;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_21 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  The following algorithm is adapted for HAC subset from J.C. Moyer's solution:\n  --  https://github.com/jcmoyer/puzzles/blob/master/AdventOfCode2024/src/day21.adb\n  --\n  --  Differences from J.C.M.'s implementation:\n  --     - Breadth First Search (BFS) algo for getting paths in keypads is\n  --         replaced by a systematic search, \"Manhattan-style\" (there is\n  --         no obstacle except one gap).\n  --     - Memoization (cache-ing) is done via an array instead of a hash map.\n\n  ----------------\n  --  Commands  --\n  ----------------\n\n  --  A command is abstractly a single instruction for a robot to perform.\n  --  Commands can be \"lowered\" in the code-gen sense to a sequence of\n  --  commands for a robot controlling another robot.\n  type Command is (c_west, c_east, c_north, c_south, c_press);\n\n  ----------------------\n  --  Numeric keypad  --\n  ----------------------\n\n  type Number_Pad_Key is (np_A, np_0, np_1, np_2, np_3, np_4, np_5, np_6, np_7, np_8, np_9);\n\n  function Parse_Np_Key (c : Character) return Number_Pad_Key is\n  begin\n    case c is\n      when '0' .. '9' =>\n        return\n          Number_Pad_Key'Val (Number_Pad_Key'Pos (np_0) + Character'Pos (c) - Character'Pos ('0'));\n      when others =>\n        return np_A;\n    end case;\n  end Parse_Np_Key;\n\n  --  +---+---+---+\n  --  | 7 | 8 | 9 |\n  --  +---+---+---+\n  --  | 4 | 5 | 6 |\n  --  +---+---+---+\n  --  | 1 | 2 | 3 |\n  --  +---+---+---+\n  --      | 0 | A |\n  --      +---+---+\n\n  procedure Position_Num (k : Number_Pad_Key; p : out Point) is\n  begin\n    case k is\n      when np_7 => p.y := 1; p.x := 1;\n      when np_8 => p.y := 1; p.x := 2;\n      when np_9 => p.y := 1; p.x := 3;\n      when np_4 => p.y := 2; p.x := 1;\n      when np_5 => p.y := 2; p.x := 2;\n      when np_6 => p.y := 2; p.x := 3;\n      when np_1 => p.y := 3; p.x := 1;\n      when np_2 => p.y := 3; p.x := 2;\n      when np_3 => p.y := 3; p.x := 3;\n      when np_0 => p.y := 4; p.x := 2;\n      when np_A => p.y := 4; p.x := 3;\n    end case;\n  end Position_Num;\n\n  --------------------------\n  --  Directional keypad  --\n  --------------------------\n\n  type Directional_Pad_Key is (dp_left, dp_up, dp_down, dp_right, dp_A);\n\n  function Command_To_Key (c : Command) return Directional_Pad_Key is\n  begin\n    case c is\n      when c_east =>  return dp_right;\n      when c_south => return dp_down;\n      when c_west =>  return dp_left;\n      when c_north => return dp_up;\n      when c_press => return dp_A;\n    end case;\n  end Command_To_Key;\n\n  --      +---+---+\n  --      | ^ | A |\n  --  +---+---+---+\n  --  | < | v | > |\n  --  +---+---+---+\n\n  procedure Position_Dir (k : Directional_Pad_Key; p : out Point) is\n  begin\n    case k is\n      when dp_up    => p.y := 1; p.x := 2;\n      when dp_A     => p.y := 1; p.x := 3;\n      when dp_left  => p.y := 2; p.x := 1;\n      when dp_down  => p.y := 2; p.x := 2;\n      when dp_right => p.y := 2; p.x := 3;\n    end case;\n  end Position_Dir;\n\n  subtype Pad_Range_X     is Integer range 1 .. 3;\n  subtype Max_Pad_Range_Y is Integer range 1 .. 4;\n\n  gap_numpad, gap_dirpad : Point;\n\n  max_robot_level : constant := 25;\n\n  type Cache_Type is\n    array\n      (Pad_Range_X,           --  Memoization by location from.x\n       Max_Pad_Range_Y,       --  Memoization by location from.y\n       Pad_Range_X,           --  Memoization by location to.x\n       Max_Pad_Range_Y,       --  Memoization by location to.y\n       0 .. max_robot_level)  --  Memoization by recursion depth\n    of Integer_64;\n\n  cache, cache_clear : Cache_Type;\n\n  verbose : constant Boolean := False;\n\n  inf : constant Integer_64 := Integer_64'Last;  --  Approximation of infinity.\n\n  function Lower_Commands\n    (from, to, gap : Point;\n     robot_count   : Integer;\n     depth         : Integer)\n  return Integer_64\n  is\n    --  Directional pad controlling us, which we will lower commands to.\n    dpad_key, next_key : Directional_Pad_Key;\n\n    sum : Integer_64 := 0;\n\n    procedure Single_Press (new_cmd : Command) is\n      p1, p2 : Point;\n    begin\n      Position_Dir (dpad_key, p1);\n      next_key := Command_To_Key (new_cmd);\n      Position_Dir (next_key, p2);\n      sum := sum + Lower_Commands (p1, p2, gap_dirpad, robot_count, depth + 1);\n      dpad_key := next_key;\n    end Single_Press;\n\n    cmd : Command;\n    valid : Boolean;\n    cur_pos : Point;\n    min : Integer_64;\n    dx, dy, len_x, len_y, length, n, horizontal_steps : Integer;\n\n    cached_val : Integer_64;\n\n  begin\n    if depth = robot_count then\n      --  Direct command.\n      return 1;\n    else\n      cached_val := cache (from.x, from.y, to.x, to.y, depth);\n      if cached_val >= 0 then\n        return cached_val;\n      end if;\n\n      min := inf;\n\n      dx := Sgn (to.x - from.x);\n      dy := Sgn (to.y - from.y);\n      len_x := abs (to.x - from.x);\n      len_y := abs (to.y - from.y);\n      length := len_x + len_y;\n\n      All_Paths :\n      for comb in 0 .. 2 ** length - 1 loop\n        n := comb;\n        horizontal_steps := 0;\n        for count in 1 .. length loop\n          if n mod 2 = 1 then\n            --  Binary representation of `comb` has 1's for\n            --  horizontal moves and 0's for vertical moves.\n            horizontal_steps := horizontal_steps + 1;\n          end if;\n          n := n / 2;\n        end loop;\n        if horizontal_steps = len_x then\n          --  The numer of 1's in the code `comb` matches the number of\n          --  horizontal moves. Then the number of vertical moves is also correct.\n          sum  := 0;\n          dpad_key := dp_A;\n          n := comb;\n          cur_pos := from;\n          valid := True;\n\n          Path :\n          for count in 1 .. length loop\n\n            if n mod 2 = 1 then\n              --  Horizontal move.\n              if dx = 1 then\n                cmd := c_east;\n              else\n                cmd := c_west;\n              end if;\n              cur_pos.x := cur_pos.x + dx;\n            else\n              --  Vertical move.\n              if dy = 1 then\n                cmd := c_south;\n              else\n                cmd := c_north;\n              end if;\n              cur_pos.y := cur_pos.y + dy;\n            end if;\n\n            --  \"If a robot arm is ever aimed at a gap where no button is\n            --   present on the keypad, even for an instant, the robot will\n            --   panic unrecoverably. So, don't do that.\"\n            --\n            valid := Dist_L1 (cur_pos, gap) > 0;\n\n            exit Path when not valid;\n            Single_Press (cmd);\n            n := n / 2;\n          end loop Path;\n\n          if valid then\n            --  Do \"Press\"!\n            Single_Press (c_press);\n            --  Take the minimum length of all lowered command sequences.\n            if sum < min then\n              if verbose and then min < inf then\n                Put_Line\n                  (+\"Depth: \" & depth &\n                   \", from \" & from.x & \",\" & from.y & \" to \" & to.x & \",\" & to.y &\n                   \": better length, from\" & min'Image & \" to\" & sum'Image);\n              end if;\n              min := sum;\n            end if;\n          end if;\n\n        end if;\n      end loop All_Paths;\n    end if;\n\n    cache (from.x, from.y, to.x, to.y, depth) := min;\n\n    return min;\n  end Lower_Commands;\n\n  subtype Digicode is String (1 .. 4);\n\n  function Do_Code (s : Digicode; robot_count : Integer) return Integer_64 is\n    npad_key, next_key : Number_Pad_Key := np_A;\n    sum  : Integer_64 := 0;\n    p1, p2 : Point;\n    numeric_part : String (1 .. 3);\n  begin\n    for i in s'Range loop\n      --  We start the search with numpad parameters, and it will recurse\n      --  with dirpad parameters.\n      Position_Num (npad_key, p1);\n      next_key := Parse_Np_Key (s (i));\n      Position_Num (next_key, p2);\n      sum := sum + Lower_Commands (p1, p2, gap_numpad, robot_count, 0);\n      npad_key := next_key;\n    end loop;\n\n    for i in numeric_part'Range loop\n      numeric_part (i) := s (i);\n    end loop;\n\n    return Integer_64'Value (numeric_part) * sum;\n  end Do_Code;\n\n  r : array (Part_Type) of VString;\n\n  data : constant Data_Type := input;\n\n  procedure Do_Part (part : Part_Type) is\n    score : Integer_64 := 0;\n    robots : Positive;\n\n    procedure Cumulate_Complexity (d : Digicode) is\n    begin\n      score := score + Do_Code (d, robots);\n    end Cumulate_Complexity;\n\n  begin\n    case part is\n      when part_1 => robots := 3;\n      when part_2 => robots := max_robot_level + 1;\n    end case;\n\n    case data is\n      when mini =>\n        Cumulate_Complexity (\"029A\");\n        Cumulate_Complexity (\"980A\");\n        Cumulate_Complexity (\"179A\");\n        Cumulate_Complexity (\"456A\");\n        Cumulate_Complexity (\"379A\");\n\n      when input =>\n        Cumulate_Complexity (\"965A\");\n        Cumulate_Complexity (\"143A\");\n        Cumulate_Complexity (\"528A\");\n        Cumulate_Complexity (\"670A\");\n        Cumulate_Complexity (\"973A\");\n    end case;\n\n    r (part) := +\"\" & Trim_Left (+score'Image);\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  gap_numpad.y := 4;\n  gap_numpad.x := 1;\n\n  gap_dirpad.y := 1;\n  gap_dirpad.x := 1;\n\n  --  \"Full Ada 2012+\" does the following in a single loop (for ... of).\n  for i1 in Cache_Type'Range (1) loop\n    for i2 in Cache_Type'Range (2) loop\n      for i3 in Cache_Type'Range (3) loop\n        for i4 in Cache_Type'Range (4) loop\n          for i5 in Cache_Type'Range (5) loop\n            cache_clear (i1, i2, i3, i4, i5) := -1;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n  end loop;\n\n  for part in Part_Type loop\n    cache := cache_clear;\n    Do_Part (part);\n  end loop;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 222670\n    --  Part 2: validated by AoC: 271397390297138\n  end if;\nend AoC_2024_21;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_21_questions.txt",
    "content": "--- Day 21: Keypad Conundrum ---\n\nAs you teleport onto Santa's Reindeer-class starship, The Historians begin to panic: someone from their search party is missing. A quick life-form scan by the ship's computer reveals that when the missing Historian teleported, he arrived in another part of the ship.\n\nThe door to that area is locked, but the computer can't open it; it can only be opened by physically typing the door codes (your puzzle input) on the numeric keypad on the door.\n\nThe numeric keypad has four rows of buttons: 789, 456, 123, and finally an empty gap followed by 0A. Visually, they are arranged like this:\n\n+---+---+---+\n| 7 | 8 | 9 |\n+---+---+---+\n| 4 | 5 | 6 |\n+---+---+---+\n| 1 | 2 | 3 |\n+---+---+---+\n    | 0 | A |\n    +---+---+\n\nUnfortunately, the area outside the door is currently depressurized and nobody can go near the door. A robot needs to be sent instead.\n\nThe robot has no problem navigating the ship and finding the numeric keypad, but it's not designed for button pushing: it can't be told to push a specific button directly. Instead, it has a robotic arm that can be controlled remotely via a directional keypad.\n\nThe directional keypad has two rows of buttons: a gap / ^ (up) / A (activate) on the first row and < (left) / v (down) / > (right) on the second row. Visually, they are arranged like this:\n\n    +---+---+\n    | ^ | A |\n+---+---+---+\n| < | v | > |\n+---+---+---+\n\nWhen the robot arrives at the numeric keypad, its robotic arm is pointed at the A button in the bottom right corner. After that, this directional keypad remote control must be used to maneuver the robotic arm: the up / down / left / right buttons cause it to move its arm one button in that direction, and the A button causes the robot to briefly move forward, pressing the button being aimed at by the robotic arm.\n\nFor example, to make the robot type 029A on the numeric keypad, one sequence of inputs on the directional keypad you could use is:\n\n    < to move the arm from A (its initial position) to 0.\n    A to push the 0 button.\n    ^A to move the arm to the 2 button and push it.\n    >^^A to move the arm to the 9 button and push it.\n    vvvA to move the arm to the A button and push it.\n\nIn total, there are three shortest possible sequences of button presses on this directional keypad that would cause the robot to type 029A: <A^A>^^AvvvA, <A^A^>^AvvvA, and <A^A^^>AvvvA.\n\nUnfortunately, the area containing this directional keypad remote control is currently experiencing high levels of radiation and nobody can go near it. A robot needs to be sent instead.\n\nWhen the robot arrives at the directional keypad, its robot arm is pointed at the A button in the upper right corner. After that, a second, different directional keypad remote control is used to control this robot (in the same way as the first robot, except that this one is typing on a directional keypad instead of a numeric keypad).\n\nThere are multiple shortest possible sequences of directional keypad button presses that would cause this robot to tell the first robot to type 029A on the door. One such sequence is v<<A>>^A<A>AvA<^AA>A<vAAA>^A.\n\nUnfortunately, the area containing this second directional keypad remote control is currently -40 degrees! Another robot will need to be sent to type on that directional keypad, too.\n\nThere are many shortest possible sequences of directional keypad button presses that would cause this robot to tell the second robot to tell the first robot to eventually type 029A on the door. One such sequence is <vA<AA>>^AvAA<^A>A<v<A>>^AvA^A<vA>^A<v<A>^A>AAvA^A<v<A>A>^AAAvA<^A>A.\n\nUnfortunately, the area containing this third directional keypad remote control is currently full of Historians, so no robots can find a clear path there. Instead, you will have to type this sequence yourself.\n\nWere you to choose this sequence of button presses, here are all of the buttons that would be pressed on your directional keypad, the two robots' directional keypads, and the numeric keypad:\n\n<vA<AA>>^AvAA<^A>A<v<A>>^AvA^A<vA>^A<v<A>^A>AAvA^A<v<A>A>^AAAvA<^A>A\nv<<A>>^A<A>AvA<^AA>A<vAAA>^A\n<A^A>^^AvvvA\n029A\n\nIn summary, there are the following keypads:\n\n    One directional keypad that you are using.\n    Two directional keypads that robots are using.\n    One numeric keypad (on a door) that a robot is using.\n\nIt is important to remember that these robots are not designed for button pushing. In particular, if a robot arm is ever aimed at a gap where no button is present on the keypad, even for an instant, the robot will panic unrecoverably. So, don't do that. All robots will initially aim at the keypad's A key, wherever it is.\n\nTo unlock the door, five codes will need to be typed on its numeric keypad. For example:\n\n029A\n980A\n179A\n456A\n379A\n\nFor each of these, here is a shortest sequence of button presses you could type to cause the desired code to be typed on the numeric keypad:\n\n029A: <vA<AA>>^AvAA<^A>A<v<A>>^AvA^A<vA>^A<v<A>^A>AAvA^A<v<A>A>^AAAvA<^A>A\n980A: <v<A>>^AAAvA^A<vA<AA>>^AvAA<^A>A<v<A>A>^AAAvA<^A>A<vA>^A<A>A\n179A: <v<A>>^A<vA<A>>^AAvAA<^A>A<v<A>>^AAvA^A<vA>^AA<A>A<v<A>A>^AAAvA<^A>A\n456A: <v<A>>^AA<vA<A>>^AAvAA<^A>A<vA>^A<A>A<vA>^A<A>A<v<A>A>^AAvA<^A>A\n379A: <v<A>>^AvA^A<vA<AA>>^AAvA<^A>AAvA^A<vA>^AA<A>A<v<A>A>^AAAvA<^A>A\n\nThe Historians are getting nervous; the ship computer doesn't remember whether the missing Historian is trapped in the area containing a giant electromagnet or molten lava. You'll need to make sure that for each of the five codes, you find the shortest sequence of button presses necessary.\n\nThe complexity of a single code (like 029A) is equal to the result of multiplying these two values:\n\n    The length of the shortest sequence of button presses you need to type on your directional keypad in order to cause the code to be typed on the numeric keypad; for 029A, this would be 68.\n    The numeric part of the code (ignoring leading zeroes); for 029A, this would be 29.\n\nIn the above example, complexity of the five codes can be found by calculating 68 * 29, 60 * 980, 68 * 179, 64 * 456, and 64 * 379. Adding these together produces 126384.\n\nFind the fewest number of button presses you'll need to perform in order to cause the robot in front of the door to type each code. What is the sum of the complexities of the five codes on your list?\n\n--- Part Two ---\n\nJust as the missing Historian is released, The Historians realize that a second member of their search party has also been missing this entire time!\n\nA quick life-form scan reveals the Historian is also trapped in a locked area of the ship. Due to a variety of hazards, robots are once again dispatched, forming another chain of remote control keypads managing robotic-arm-wielding robots.\n\nThis time, many more robots are involved. In summary, there are the following keypads:\n\n    One directional keypad that you are using.\n    25 directional keypads that robots are using.\n    One numeric keypad (on a door) that a robot is using.\n\nThe keypads form a chain, just like before: your directional keypad controls a robot which is typing on a directional keypad which controls a robot which is typing on a directional keypad... and so on, ending with the robot which is typing on the numeric keypad.\n\nThe door codes are the same this time around; only the number of robots and directional keypads has changed.\n\nFind the fewest number of button presses you'll need to perform in order to cause the robot in front of the door to type each code. What is the sum of the complexities of the five codes on your list?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_22.adb",
    "content": "--  Solution to Advent of Code 2024, Day 22\n-------------------------------------------\n--  Monkey Market\n--\n--  https://adventofcode.com/2024/day/22\n--  Copy of questions in: aoc_2024_22_questions.txt\n--\n--  HAC 0.40 \"nice-to-have\"'s detected in this exercise:\n--\n--    *     Modular types (esp. Unsigned_X and bitwise operators)\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_22 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  input_name : constant VString := +\"aoc_2024_22_mini\";\n  --  input_name : constant VString := +\"aoc_2024_22\";\n\n  r : array (Part_Type) of VString;\n\n  subtype U64 is Integer_64;  --  Hack for HAC. \"Full Ada\": type U64 is mod 2 ** 64;\n\n  total : U64 := 0;\n\n  subtype Diff_Range is Integer range -9 .. +9;\n\n  type Price_for_Diffs is array (Diff_Range, Diff_Range, Diff_Range, Diff_Range) of Integer;\n\n  total_first_price : Price_for_Diffs;\n\n  procedure Generate_2000 (seed : U64) is\n    x : U64 := seed;\n    x10, x10_old, d0, d1, d2, d3 : Integer := 0;\n    unseen : constant := -1;\n    first_price : Price_for_Diffs;\n  begin\n    --  \"Full Ada\" does it in a single expression (see AoC_2024_22_Full_Ada).\n    for a in Diff_Range loop\n      for b in Diff_Range loop\n        for c in Diff_Range loop\n          for d in Diff_Range loop\n            first_price (a, b, c, d) := unseen;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n\n    for count in 1 .. 2000 loop\n      --  NB: a \"Full Ada\" compiler has the `xor` operator of course.\n      x := Sim_XOR (x, x * 64)   mod 16777216;\n      x := Sim_XOR (x, x / 32)   mod 16777216;\n      x := Sim_XOR (x, x * 2048) mod 16777216;\n\n      x10_old := x10;\n      x10 := Integer (x mod 10);\n\n      d3 := d2;\n      d2 := d1;\n      d1 := d0;\n      d0 := x10 - x10_old;\n      if count > 4 and then first_price (d3, d2, d1, d0) = unseen then\n        --  First occurrence of the price difference sequence d3, d2, d1, d0.\n        --  We record the price for that sequence.\n        first_price (d3, d2, d1, d0) := x10;\n      end if;\n    end loop;\n    total := total + x;\n\n    for a in Diff_Range loop\n      for b in Diff_Range loop\n        for c in Diff_Range loop\n          for d in Diff_Range loop\n            if first_price (a, b, c, d) /= unseen then\n              total_first_price (a, b, c, d) :=\n                total_first_price (a, b, c, d) + first_price (a, b, c, d);\n            end if;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n  end Generate_2000;\n\n  procedure Read_Data is\n    i : Integer;\n    f : File_Type;\n  begin\n    --  \"Full Ada\" does it in a single instruction.\n    for a in Diff_Range loop\n      for b in Diff_Range loop\n        for c in Diff_Range loop\n          for d in Diff_Range loop\n            total_first_price (a, b, c, d) := 0;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get (f, i);\n      Generate_2000 (U64 (i));\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n  begin\n    r (part_1) := Trim_Left (+total'Image);\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    max_price : Integer := 0;\n    p : Integer;\n  begin\n    --  \"Full Ada 2012+\" does the following in a single loop (for ... of).\n    for a in Diff_Range loop\n      for b in Diff_Range loop\n        for c in Diff_Range loop\n          for d in Diff_Range loop\n            p := total_first_price (a, b, c, d);\n            if p > max_price then\n              max_price := p;\n            end if;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    r (part_2) := Trim_Left (+max_price'Image);\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 16619522798 (mini 1: 37327623, mini 2: 37990510)\n    --  Part 2: validated by AoC: 1854 (mini 2: 23)\n  end if;\nend AoC_2024_22;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_22.txt",
    "content": "4080909\n2254738\n8155901\n7477951\n16431099\n5408639\n5157077\n6843017\n7343391\n2516192\n12286948\n6805409\n3330250\n10938366\n14374017\n10957655\n168758\n5016772\n2875289\n9954275\n8573337\n12925507\n12561359\n14243976\n2884223\n428102\n3248277\n860940\n15841288\n13887317\n6901633\n7623423\n3284294\n14627437\n16250818\n13250706\n6157588\n6419581\n1357452\n6810417\n11905247\n163700\n7127512\n13449599\n2282345\n5558515\n14163958\n2136577\n6713087\n10042179\n9873822\n6425428\n13878989\n3967264\n11792741\n15545765\n16340909\n956959\n6561178\n2718465\n12238209\n7445788\n9852068\n191993\n3991138\n5605377\n6714142\n1594412\n936933\n6242706\n6318558\n7668085\n13409399\n3949685\n8789051\n12664487\n16300624\n4197308\n9822144\n13052208\n11233910\n4598392\n4786565\n3568973\n4955243\n14152345\n8138308\n7110676\n1601907\n8881468\n11011123\n7849771\n1747179\n16722201\n4131945\n10264257\n4447491\n918586\n5398680\n6629665\n5507085\n4038232\n12977280\n13355820\n7312882\n6013577\n7531615\n7216104\n1457831\n7662244\n14501470\n7696532\n7533897\n3204827\n3108760\n1595310\n12073783\n6429038\n4981285\n14916035\n7042772\n14590737\n4422416\n11176998\n3594679\n8657371\n10924514\n14998838\n4895148\n9948114\n5083618\n13799758\n16413359\n5679393\n12305338\n15077436\n3773683\n6906383\n11599823\n2695871\n10008897\n14041931\n7934436\n3550081\n5901912\n1456614\n1892687\n13642949\n12798887\n14553261\n8945970\n8327474\n4249469\n10644421\n3016151\n7589921\n16115949\n5431198\n15989333\n10181155\n10039007\n2059840\n15689810\n11636392\n10763850\n16122788\n6208936\n16512293\n14268500\n3840143\n6290763\n3707040\n5418480\n9727184\n10341561\n13383930\n8562892\n3759880\n6326721\n4825118\n2445499\n2192227\n15519815\n14946053\n6797403\n3333274\n4528417\n5461290\n6079366\n14003569\n687350\n5247557\n12852533\n12791205\n2718818\n11598594\n594069\n8695211\n1246324\n15655825\n4983230\n2671139\n3080133\n5174342\n11416810\n14337025\n6069327\n4032953\n3919672\n1973901\n15284264\n3264844\n1138906\n2736706\n12947242\n13138318\n10149432\n2196573\n2255991\n6154617\n3154633\n13721704\n10004644\n6149978\n1336702\n5352627\n5223212\n11015649\n11348575\n12789180\n8132497\n1550554\n8406854\n12001508\n4022109\n3746041\n4145696\n4765058\n8265183\n13632577\n4555951\n13160073\n7457882\n8580276\n5799086\n15468368\n12718282\n10079829\n10688092\n12465616\n1768014\n7785918\n8217254\n10316998\n16205732\n11030315\n13201628\n11797149\n8831456\n7333953\n9448804\n12013514\n5415671\n7522972\n1944330\n11076183\n6269017\n4319203\n5163674\n9653758\n6574379\n2842344\n4154343\n1653194\n2986309\n5773917\n11895808\n15974291\n15098232\n14004649\n12328227\n5464084\n15314432\n8270187\n6796821\n14799142\n2593119\n10381468\n13747934\n12858628\n14950215\n5406309\n3670064\n10691033\n8817761\n12849470\n11317453\n16321239\n5095465\n13365075\n772052\n16404559\n5935409\n14348256\n11467856\n10054845\n9143658\n9618106\n13420692\n5900989\n1252135\n8860717\n12386972\n8457497\n8961996\n15975681\n12761455\n5509037\n9357853\n16664243\n4778395\n14227423\n14836540\n9500578\n12374006\n10688177\n4869766\n804988\n14277010\n5154562\n3749977\n10731533\n12261658\n15323564\n14981871\n16413511\n3206448\n8087647\n8229212\n14690677\n6045444\n10494167\n10225571\n6278749\n8326437\n5998088\n10534608\n9724509\n746187\n14822703\n16675006\n15180198\n6647761\n11309929\n10032169\n8350763\n4796528\n6776456\n6857306\n14956025\n2518327\n5022503\n5164951\n8122521\n9126630\n6118357\n9019931\n4769584\n3915459\n310053\n12627001\n9199164\n1789342\n15601133\n9474259\n16716320\n399878\n10657198\n3819781\n6277888\n1986650\n15906402\n6290044\n10984939\n5004543\n610320\n4252287\n11512028\n7821751\n8848813\n8353347\n5621188\n10369557\n6416557\n10494119\n2823816\n6491192\n8361278\n9073630\n4955571\n1538388\n1507310\n12250664\n10978188\n13580607\n2274235\n16711406\n14684756\n15170574\n11837675\n225594\n10583137\n5665986\n707333\n10165409\n13703484\n3716994\n12765273\n8344120\n12173575\n3703841\n16083252\n9122650\n7498986\n2052761\n7823750\n16154467\n1459655\n5503475\n1011515\n2336661\n16721138\n6617687\n4604645\n5804244\n813951\n1388591\n4067674\n15303870\n6258775\n8411182\n10743066\n13226772\n6920756\n7020925\n7810829\n4695112\n1863082\n9198769\n9093335\n16699984\n1275456\n9921055\n1315236\n5197992\n7586302\n8702174\n1180051\n1049526\n5580261\n1419325\n15718959\n11984262\n8693038\n13764491\n16010362\n7658984\n11111063\n4649724\n12243177\n4463064\n7438227\n5275669\n16657537\n10507524\n15920825\n10776369\n8610258\n8379413\n8235685\n4395766\n16197132\n13386304\n7960105\n16562197\n13818784\n1389659\n11094950\n7432271\n6026775\n12173978\n695652\n1114582\n9371570\n8391587\n4920524\n6889487\n250433\n5376908\n12009609\n3218265\n3545914\n9446102\n8269581\n3328717\n12859576\n1939528\n9371909\n14877711\n9681723\n8421364\n1590283\n3987950\n7557214\n16311677\n8220222\n5968441\n9311893\n4612876\n14058792\n224573\n10877727\n7353617\n7017219\n8410486\n6947525\n3004481\n5284450\n16518021\n8556009\n9373407\n2782987\n14549238\n15643010\n10151834\n14280944\n12970839\n369436\n5379814\n7422290\n16136238\n13471466\n7552723\n5977903\n16021636\n6532603\n1295600\n9696672\n13015149\n14770535\n6356209\n7477492\n1325694\n13227760\n12766496\n476423\n2181417\n6964726\n262869\n14431432\n4466472\n342559\n3288180\n562844\n2636893\n12209405\n12834690\n7092247\n10536262\n11330357\n15134630\n281415\n12818406\n12080487\n16304734\n16426477\n1526028\n2937550\n13991543\n4672740\n1310750\n3820827\n12552482\n4673845\n8064264\n16710512\n4307154\n11974285\n15444907\n7419792\n15653555\n4448540\n356588\n15103361\n3141328\n1298775\n6539219\n12076194\n6921130\n15631258\n12140380\n469796\n14704655\n2375240\n12502063\n5823308\n15692990\n2353070\n6898528\n7794274\n11895387\n15987674\n13081627\n7062913\n12652237\n310869\n13348241\n10374549\n3855147\n13677265\n7480261\n10724297\n1754053\n2709206\n15552662\n3902342\n551651\n4506551\n14073388\n8026314\n15005477\n6647900\n10261539\n5825040\n8842339\n14232509\n3584248\n4945522\n15162448\n7016568\n11289850\n4892627\n10731217\n11146589\n1804918\n16203750\n12745848\n2560912\n1581089\n4985555\n15909673\n190078\n3390886\n15961321\n6867277\n13582799\n9182941\n11281259\n14740102\n10251114\n5158830\n16483550\n11302201\n2357396\n14426255\n4441232\n16659869\n301924\n15286665\n6177053\n14361958\n1764857\n13342482\n7233468\n10860917\n9226526\n5111902\n6598587\n7888186\n13580668\n2904507\n1508480\n12667074\n6590196\n10049092\n6785402\n8601242\n15376974\n14445187\n16766239\n11949301\n13333528\n6669543\n16725763\n16508317\n735578\n4567188\n4041496\n818538\n7546263\n8143579\n2382632\n10240511\n2783893\n16036539\n10278939\n11671236\n6040433\n439290\n3293508\n1825784\n16553624\n14337006\n16615754\n9156570\n5062556\n16377009\n9873521\n13331914\n7543572\n719728\n10265648\n232780\n3004977\n657294\n4345284\n11183795\n6420021\n5130693\n12777063\n7460902\n336796\n2802675\n340272\n7849862\n9225840\n1196796\n148039\n5738393\n8866582\n1074247\n15784512\n15864992\n10915284\n12531319\n7083162\n3711300\n4734253\n3055998\n15850335\n13718660\n16594282\n12489682\n10051765\n8306438\n9823161\n10545500\n818115\n8895941\n14078628\n5272561\n11903472\n9178329\n2586097\n6016066\n5032383\n9884299\n4085367\n1860845\n8434389\n11031722\n5958919\n1408753\n16277658\n11973479\n4207393\n16535260\n1027078\n8497595\n13463292\n3279892\n4056725\n12349107\n2464554\n10776371\n15003195\n6723700\n8220436\n7401706\n10858845\n14466369\n2507180\n16449468\n6290502\n8659761\n6119573\n8482815\n12064893\n9926787\n9501045\n14493140\n5569412\n16310275\n12330564\n12772404\n3065617\n4776450\n2176507\n9125383\n11506364\n11964129\n3073608\n6475277\n12900185\n3313474\n6571723\n8028060\n15954099\n12743482\n16029650\n10826891\n2468959\n8812787\n14363491\n9390908\n11273610\n11837312\n3177815\n12927618\n16537430\n14370689\n5051156\n9060162\n7269168\n14496899\n379809\n15059123\n7528423\n4555492\n5439990\n8020963\n7150315\n14703158\n2882434\n12942486\n14417930\n3262171\n567667\n5400748\n7888730\n4352719\n16429434\n9923370\n1232298\n2000965\n13584508\n5112982\n816086\n12020920\n1557536\n861858\n13395370\n1463281\n351474\n11997484\n2880436\n15829844\n6666125\n15578454\n3143050\n15972989\n4396359\n12316917\n14720307\n13877787\n13566365\n14694343\n883283\n7100573\n10077945\n7092405\n11304359\n1335541\n10262616\n12294948\n7550181\n13014648\n11547605\n12020378\n8412587\n9991268\n14068033\n12811535\n14232949\n8901720\n3939751\n4053511\n13579742\n15822703\n7005666\n7054630\n7809348\n968302\n13995349\n15566334\n12359182\n11122889\n16027483\n10692609\n8793935\n9813215\n5720058\n3530712\n11188793\n5435446\n7297096\n13002532\n11477542\n1212639\n4207103\n527198\n6195799\n11789482\n13980093\n766128\n5639810\n8735500\n13293013\n7548137\n5763928\n9586448\n1009071\n16204073\n4954081\n13902540\n6875458\n10604946\n4712765\n2304332\n351892\n14866757\n5334463\n2863592\n2523615\n14968099\n5043136\n7687264\n14690688\n8321283\n13606301\n7488288\n11513550\n6750428\n3369065\n12526654\n14605717\n10494204\n7229326\n10698227\n1008434\n5154207\n878227\n10898229\n14754055\n1522240\n8012898\n1244506\n2884213\n11086772\n5262133\n7398019\n6537606\n15299737\n11851308\n3431082\n9860332\n4053420\n1811433\n4657411\n14336864\n12683935\n10380613\n14070121\n11038946\n7383945\n6072854\n7828585\n14993431\n2910811\n4625789\n2784317\n5347731\n14801612\n7143605\n1109277\n13269704\n8110333\n10274981\n6551236\n7027499\n14823286\n774282\n15642652\n2207263\n9426781\n6571291\n8285059\n6668366\n15272361\n13332557\n15269352\n3999034\n3902648\n2105481\n14024883\n7177015\n6875895\n13469611\n7946489\n3169830\n5311612\n15425661\n3732001\n545276\n12750339\n14552452\n15968702\n14140012\n5249926\n11521039\n6697436\n3924735\n479888\n6071129\n4104587\n5136205\n7047336\n14394163\n13788402\n232480\n256915\n13345115\n6660499\n10679585\n4746191\n15325685\n15801593\n11195562\n12309615\n8431604\n12918346\n8604297\n1535670\n13471546\n2689689\n4648870\n12786153\n11517265\n12471111\n11042258\n14309742\n13254717\n3584213\n446841\n15891201\n1040057\n4685580\n9473090\n9473189\n9220973\n10476633\n10381694\n3132734\n5537602\n3731899\n1316019\n9564926\n14728930\n7785846\n7048590\n4188042\n1093292\n7042357\n12466230\n2179680\n2746374\n10788636\n416529\n10231367\n14849254\n6789270\n15173899\n2631055\n7496621\n13435010\n8337045\n16749223\n7901218\n11496600\n6960584\n6428145\n3356479\n10474167\n4073613\n15089395\n9213153\n7852488\n15404007\n13978841\n12526878\n7710432\n11148081\n11321554\n422115\n14277910\n6982299\n3556146\n16164868\n16545119\n10515212\n15493678\n4866929\n8876732\n6491174\n1160682\n756332\n11940237\n8429909\n13310172\n777949\n3259115\n11602313\n15668468\n16031942\n16193889\n5088395\n5880978\n4184241\n16025421\n11839960\n6136388\n775837\n5491623\n1372521\n15157850\n5361524\n6497219\n12463089\n10179995\n14293080\n3230474\n2421699\n2368530\n7003761\n11755630\n2836219\n4708735\n14920893\n10035127\n4668490\n766483\n5462380\n5826166\n12868445\n7185724\n12602101\n5227717\n4294100\n7410855\n9681840\n15670407\n4275086\n11097939\n14590754\n7567916\n6619684\n8153692\n7223143\n5833609\n10383745\n12583714\n8595790\n3239803\n14209994\n12464098\n11961248\n10520461\n5583609\n12723244\n6798285\n2295571\n9781281\n14529909\n14838010\n3392609\n15578259\n3299549\n5846974\n6335774\n11729399\n8031627\n5971535\n13283541\n10565841\n13559333\n1652713\n7956737\n15657712\n14757845\n11651169\n6588202\n595445\n12014782\n1381259\n14674812\n10164010\n7918375\n9068768\n9442457\n13236977\n2504841\n14269527\n12674880\n4234283\n2472056\n11266755\n6348163\n8321343\n13394380\n11424835\n8518966\n9134522\n15452288\n6630237\n5420857\n7751405\n284608\n5717337\n10875173\n13228169\n16743710\n5251347\n8002517\n7883167\n461622\n458548\n4863747\n7215211\n13408032\n8004135\n8851505\n11421919\n9646017\n4695893\n12858537\n9950449\n5183618\n4386693\n1111908\n1909640\n11376952\n15614714\n11128606\n11007274\n13591241\n6822131\n205517\n758149\n14047981\n6601387\n13370939\n1908836\n7614606\n8376736\n16404772\n12900554\n4207994\n307488\n9141486\n14436258\n6449373\n7259500\n13410958\n14182846\n7741297\n16519339\n4544446\n4135097\n3375744\n9412837\n6671155\n13014256\n14116071\n13609953\n6936300\n9461159\n4805833\n15650656\n14451017\n13400410\n11008276\n7585689\n6225102\n1413178\n1297167\n5993486\n8406811\n15558659\n16131327\n4668925\n289979\n10313597\n13760349\n906385\n3523840\n15091529\n11844996\n3118034\n7633456\n14453267\n6715522\n7556324\n13101763\n1310113\n2849431\n10162853\n6364024\n10962417\n12652321\n14448149\n4785011\n10000665\n12577048\n12342278\n1449606\n357272\n3445953\n14641840\n13290014\n6145639\n8175645\n15647618\n3054152\n16060494\n5853093\n15336785\n11362664\n6305745\n14492171\n3147397\n12591662\n4374632\n9557340\n13408066\n10146699\n1497532\n12157265\n7549648\n11320598\n6807598\n3560901\n15787665\n7435175\n5644327\n10780722\n16231854\n11471975\n1986406\n3620752\n10830993\n6626546\n2315756\n15676012\n14296984\n12610447\n6955287\n14333667\n1195820\n10215350\n7316484\n12298016\n13136237\n5184418\n6454917\n5000763\n7917808\n14299036\n9077922\n11964622\n5825014\n13552211\n2187774\n2087200\n15140173\n12261960\n7177069\n1654991\n3648466\n4976399\n5722999\n13305811\n12175330\n6320312\n10455473\n2226970\n7593350\n8295519\n2950806\n14140038\n4982607\n8331621\n11829945\n14935737\n3460810\n5320552\n12492582\n15659591\n11629946\n2835620\n11067968\n7048909\n7043036\n9183920\n12285570\n8555820\n9961642\n12161094\n9667621\n5179243\n9672929\n14185708\n16089618\n8278759\n3318372\n13175526\n2980421\n12802381\n307486\n4333594\n13955155\n11841112\n12735109\n6023924\n10922685\n11523727\n2789158\n11806867\n11745152\n16295994\n6868595\n12816611\n3513949\n12806769\n15121579\n4482910\n435817\n10403469\n11302360\n3112849\n6720674\n13489518\n4665893\n2399871\n4099456\n16698317\n14598103\n4069703\n3117049\n7542398\n16619497\n12716401\n14568359\n15397022\n6798627\n7453542\n916128\n2621934\n9626616\n11151263\n2420690\n6334976\n179425\n13866540\n4129253\n15480222\n6380824\n4520446\n16365054\n12314031\n6323143\n9785756\n6316834\n8862212\n9631089\n16144530\n12544920\n11664836\n12207715\n2700276\n2507559\n437969\n13338706\n9789472\n6536400\n10226740\n10954990\n12194236\n939645\n6283675\n5623896\n8799158\n1413613\n7536211\n305320\n12505823\n1793588\n8395859\n12248207\n9701718\n10156336\n10237923\n13210641\n11848662\n10564243\n9853182\n1225930\n14345338\n13999946\n16084195\n7682308\n3181906\n2945663\n11851640\n9328339\n14744745\n10784245\n16490661\n15712527\n11542640\n5274572\n13193643\n12386214\n7895523\n10669507\n11792465\n3249657\n13494500\n1052258\n12663303\n6176099\n11840530\n12754339\n849527\n3768805\n12360228\n977256\n4100011\n14250008\n15404620\n12597289\n12004540\n12173305\n4509710\n7458647\n9659143\n6658336\n5358097\n13997109\n2865227\n8479735\n14544629\n11971370\n15738206\n352824\n10480215\n15086576\n3900706\n9396411\n12972713\n3477138\n7425286\n2602740\n14748033\n8841911\n1473495\n1640181\n6866786\n4189788\n9156536\n488650\n4534559\n15042557\n12317935\n10295085\n14396181\n2351088\n13796311\n11439957\n12217757\n11242167\n14701672\n422740\n12183853\n2893861\n2808064\n7639046\n16147358\n3630663\n1044361\n14425592\n15074846\n796986\n11028426\n10064355\n4427850\n9795479\n5572259\n14911074\n11346907\n13380418\n3344388\n1557385\n9177414\n12357194\n3519437\n11805348\n14158744\n5117896\n6319196\n12849950\n259210\n3138477\n8861509\n8391156\n4578538\n16682761\n11887040\n11071828\n9845726\n5340766\n786827\n15639371\n13755824\n4766323\n5161051\n13242934\n10369841\n2119492\n15286995\n11177382\n7510469\n6778322\n1282949\n11516899\n1266827\n13965788\n892658\n6334697\n9503998\n3442149\n4869511\n11898089\n12021711\n5836651\n2813004\n235447\n16278888\n6684845\n13704079\n7187810\n13727765\n15378973\n12360704\n8729670\n14737220\n5572929\n9911721\n8918921\n16573390\n12728996\n9539787\n9978752\n13529025\n4988533\n16082462\n3673587\n868459\n9281622\n8045022\n12596085\n9070314\n10000669\n8237854\n8384268\n14980562\n15546729\n13635109\n11592569\n8111305\n8201276\n3986683\n11886355\n11616592\n2555461\n13114424\n16602599\n6019381\n276192\n1794789\n4275002\n13607751\n16418952\n5835388\n1293539\n5536082\n8998156\n16400254\n13365776\n6661715\n14928827\n5638804\n13997344\n5636399\n8354407\n5455384\n4306676\n10601003\n2521941\n11651791\n9663230\n10169233\n7470852\n11008265\n3706782\n4106219\n6651646\n4900756\n8767483\n1805647\n16368659\n15988964\n2520208\n278801\n10120124\n7685757\n14694367\n14497116\n10294213\n3206137\n2074235\n11277789\n16170493\n10933305\n5379723\n1611217\n14646564\n6798586\n15397969\n13929307\n9405982\n13542850\n11688156\n1535522\n3449409\n10606357\n2160438\n2864332\n941669\n12268830\n2598032\n1700301\n5614702\n8312180\n803567\n9809834\n12572436\n12441899\n14564495\n7264926\n14831581\n14826345\n10564357\n9940234\n10619526\n16707496\n9390219\n3897599\n13739371\n5153332\n15881794\n11921035\n12697854\n6977541\n354413\n11151418\n4370152\n6686891\n6456248\n5752989\n10973462\n14136620\n5219680\n6672463\n15996832\n1286332\n8740348\n2398036\n14385013\n4625344\n12559362\n9589298\n5943411\n2004485\n10121921\n10731134\n12740038\n993812\n4226201\n13098765\n11158616\n9230460\n7880320\n8706373\n5103241\n14724686\n10670005\n15355500\n700278\n2553190\n2696535\n11028748\n15194295\n374518\n4099898\n232159\n893121\n6584471\n12643278\n15331025\n3328994\n9666931\n6128941\n13312004\n4332371\n14102336\n9528237\n4867518\n10816190\n15946147\n4121399\n15390837\n9415252\n7140648\n7395978\n16300338\n7464884\n6931738\n13768527\n6630812\n6047670\n4551878\n14573895\n12360707\n1959047\n11807797\n14664562\n3018470\n6239135\n15167985\n10304793\n13017633\n6601610\n16622226\n1116111\n8993105\n419776\n5625505\n9944159\n5187945\n1234572\n14596106\n1265763\n2030543\n257892\n1820816\n5128916\n15727064\n1948906\n2818767\n5474396\n8837245\n7879316\n16420373\n6138474\n16281831\n8136679\n5499584\n10155849\n9369129\n11567114\n13498401\n8130393\n11224893\n8569297\n11232669\n10231140\n2476321\n421694\n3827367\n15779759\n11357047\n8526328\n6435623\n10528254\n8175055\n14471538\n10112097\n10330094\n13404241\n11209996\n3895249\n8321133\n13959950\n2835942\n16012857\n11173883\n7165906\n14468840\n3083301\n8393053\n13948360\n15860507\n854596\n5592319\n1106128\n2005086\n11132519\n2433035\n7070406\n11367526\n13160860\n9995879\n9987956\n16261376\n826271\n8905790\n12875583\n4499613\n520193\n2905524\n1357066\n15581832\n16714916\n11991917\n15158291\n8442933\n5958552\n14766652\n1222351\n5634263\n14437191\n7482642\n3586872\n10331783\n16078494\n8618908\n14266104\n14681893\n11647787\n11294585\n3023445\n6676392\n14470262\n2037483\n1359546\n225377\n12896633\n11067409\n8198397\n1012099\n11027177\n1848439\n12692353\n16246366\n7030277\n10320785\n11269264\n9602190\n13406193\n11545887\n14724376\n3588295\n11362298\n11846655\n5887807\n12908006\n15610866\n13658126\n4263425\n3121782\n325549\n11166687\n5782308\n13783583\n661426\n6906599\n11113138\n5617959\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_22_full_ada.adb",
    "content": "--  Solution to Advent of Code 2024, Day 22\n-------------------------------------------\n--  Monkey Market\n--\n--  https://adventofcode.com/2024/day/22\n--  Copy of questions in: aoc_2024_22_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_22_Full_Ada is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_22\";\n\n  r : array (Part_Type) of VString;\n\n  type U64 is mod 2 ** 64;\n\n  total : U64 := 0;\n\n  subtype Diff_Range is Integer range -9 .. +9;\n\n  type Price_for_Diffs is array (Diff_Range, Diff_Range, Diff_Range, Diff_Range) of Integer;\n\n  total_first_price : Price_for_Diffs := (others => (others => (others => (others => 0))));\n\n  procedure Generate_2000 (seed : U64) is\n    x : U64 := seed;\n    x10, x10_old, d0, d1, d2, d3 : Integer := 0;\n    unseen : constant := -1;\n    first_price : Price_for_Diffs := (others => (others => (others => (others => unseen))));\n  begin\n\n    for count in 1 .. 2000 loop\n      x := (x xor (x * 64))   mod 16777216;\n      x := (x xor (x / 32))   mod 16777216;\n      x := (x xor (x * 2048)) mod 16777216;\n\n      x10_old := x10;\n      x10 := Integer (x mod 10);\n\n      d3 := d2;\n      d2 := d1;\n      d1 := d0;\n      d0 := x10 - x10_old;\n      if count > 4 and then first_price (d3, d2, d1, d0) = unseen then\n        --  First occurrence of the price difference sequence d3, d2, d1, d0.\n        --  We record the price for that sequence.\n        first_price (d3, d2, d1, d0) := x10;\n      end if;\n    end loop;\n\n    total := total + x;\n\n    for a in Diff_Range loop\n      for b in Diff_Range loop\n        for c in Diff_Range loop\n          for d in Diff_Range loop\n            if first_price (a, b, c, d) /= unseen then\n              total_first_price (a, b, c, d) :=\n                total_first_price (a, b, c, d) + first_price (a, b, c, d);\n            end if;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n\n  end Generate_2000;\n\n  procedure Read_Data is\n    i : Integer;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get (f, i);\n      Generate_2000 (U64 (i));\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n  begin\n    r (part_1) := Trim_Left (+total'Image);\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    max_price : Integer := 0;\n  begin\n    --  Traverse the 4-dimensional array total_first_price:\n    for total_price of total_first_price loop\n      max_price := Integer'Max (max_price, total_price);\n    end loop;\n    r (part_2) := Trim_Left (+max_price'Image);\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 16619522798 (mini 1: 37327623, mini 2: 37990510)\n    --  Part 2: validated by AoC: 1854 (mini 2: 23)\n  end if;\nend AoC_2024_22_Full_Ada;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_22_mini.txt",
    "content": "1\n2\n3\n2024\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_22_questions.txt",
    "content": "--- Day 22: Monkey Market ---\n\nAs you're all teleported deep into the jungle, a monkey steals The Historians' device! You'll need get it back while The Historians are looking for the Chief.\n\nThe monkey that stole the device seems willing to trade it, but only in exchange for an absurd number of bananas. Your only option is to buy bananas on the Monkey Exchange Market.\n\nYou aren't sure how the Monkey Exchange Market works, but one of The Historians senses trouble and comes over to help. Apparently, they've been studying these monkeys for a while and have deciphered their secrets.\n\nToday, the Market is full of monkeys buying good hiding spots. Fortunately, because of the time you recently spent in this jungle, you know lots of good hiding spots you can sell! If you sell enough hiding spots, you should be able to get enough bananas to buy the device back.\n\nOn the Market, the buyers seem to use random prices, but their prices are actually only pseudorandom! If you know the secret of how they pick their prices, you can wait for the perfect time to sell.\n\nThe part about secrets is literal, the Historian explains. Each buyer produces a pseudorandom sequence of secret numbers where each secret is derived from the previous.\n\nIn particular, each buyer's secret number evolves into the next secret number in the sequence via the following process:\n\n    Calculate the result of multiplying the secret number by 64. Then, mix this result into the secret number. Finally, prune the secret number.\n    Calculate the result of dividing the secret number by 32. Round the result down to the nearest integer. Then, mix this result into the secret number. Finally, prune the secret number.\n    Calculate the result of multiplying the secret number by 2048. Then, mix this result into the secret number. Finally, prune the secret number.\n\nEach step of the above process involves mixing and pruning:\n\n    To mix a value into the secret number, calculate the bitwise XOR of the given value and the secret number. Then, the secret number becomes the result of that operation. (If the secret number is 42 and you were to mix 15 into the secret number, the secret number would become 37.)\n    To prune the secret number, calculate the value of the secret number modulo 16777216. Then, the secret number becomes the result of that operation. (If the secret number is 100000000 and you were to prune the secret number, the secret number would become 16113920.)\n\nAfter this process completes, the buyer is left with the next secret number in the sequence. The buyer can repeat this process as many times as necessary to produce more secret numbers.\n\nSo, if a buyer had a secret number of 123, that buyer's next ten secret numbers would be:\n\n15887950\n16495136\n527345\n704524\n1553684\n12683156\n11100544\n12249484\n7753432\n5908254\n\nEach buyer uses their own secret number when choosing their price, so it's important to be able to predict the sequence of secret numbers for each buyer. Fortunately, the Historian's research has uncovered the initial secret number of each buyer (your puzzle input). For example:\n\n1\n10\n100\n2024\n\nThis list describes the initial secret number of four different secret-hiding-spot-buyers on the Monkey Exchange Market. If you can simulate secret numbers from each buyer, you'll be able to predict all of their future prices.\n\nIn a single day, buyers each have time to generate 2000 new secret numbers. In this example, for each buyer, their initial secret number and the 2000th new secret number they would generate are:\n\n1: 8685429\n10: 4700978\n100: 15273692\n2024: 8667524\n\nAdding up the 2000th new secret number for each buyer produces 37327623.\n\nFor each buyer, simulate the creation of 2000 new secret numbers. What is the sum of the 2000th secret number generated by each buyer?\n\n--- Part Two ---\n\nOf course, the secret numbers aren't the prices each buyer is offering! That would be ridiculous. Instead, the prices the buyer offers are just the ones digit of each of their secret numbers.\n\nSo, if a buyer starts with a secret number of 123, that buyer's first ten prices would be:\n\n3 (from 123)\n0 (from 15887950)\n6 (from 16495136)\n5 (etc.)\n4\n4\n6\n4\n4\n2\n\nThis price is the number of bananas that buyer is offering in exchange for your information about a new hiding spot. However, you still don't speak monkey, so you can't negotiate with the buyers directly. The Historian speaks a little, but not enough to negotiate; instead, he can ask another monkey to negotiate on your behalf.\n\nUnfortunately, the monkey only knows how to decide when to sell by looking at the changes in price. Specifically, the monkey will only look for a specific sequence of four consecutive changes in price, then immediately sell when it sees that sequence.\n\nSo, if a buyer starts with a secret number of 123, that buyer's first ten secret numbers, prices, and the associated changes would be:\n\n     123: 3 \n15887950: 0 (-3)\n16495136: 6 (6)\n  527345: 5 (-1)\n  704524: 4 (-1)\n 1553684: 4 (0)\n12683156: 6 (2)\n11100544: 4 (-2)\n12249484: 4 (0)\n 7753432: 2 (-2)\n\nNote that the first price has no associated change because there was no previous price to compare it with.\n\nIn this short example, within just these first few prices, the highest price will be 6, so it would be nice to give the monkey instructions that would make it sell at that time. The first 6 occurs after only two changes, so there's no way to instruct the monkey to sell then, but the second 6 occurs after the changes -1,-1,0,2. So, if you gave the monkey that sequence of changes, it would wait until the first time it sees that sequence and then immediately sell your hiding spot information at the current price, winning you 6 bananas.\n\nEach buyer only wants to buy one hiding spot, so after the hiding spot is sold, the monkey will move on to the next buyer. If the monkey never hears that sequence of price changes from a buyer, the monkey will never sell, and will instead just move on to the next buyer.\n\nWorse, you can only give the monkey a single sequence of four price changes to look for. You can't change the sequence between buyers.\n\nYou're going to need as many bananas as possible, so you'll need to determine which sequence of four price changes will cause the monkey to get you the most bananas overall. Each buyer is going to generate 2000 secret numbers after their initial secret number, so, for each buyer, you'll have 2000 price changes in which your sequence can occur.\n\nSuppose the initial secret number of each buyer is:\n\n1\n2\n3\n2024\n\nThere are many sequences of four price changes you could tell the monkey, but for these four buyers, the sequence that will get you the most bananas is -2,1,-1,3. Using that sequence, the monkey will make the following sales:\n\n    For the buyer with an initial secret number of 1, changes -2,1,-1,3 first occur when the price is 7.\n    For the buyer with initial secret 2, changes -2,1,-1,3 first occur when the price is 7.\n    For the buyer with initial secret 3, the change sequence -2,1,-1,3 does not occur in the first 2000 changes.\n    For the buyer starting with 2024, changes -2,1,-1,3 first occur when the price is 9.\n\nSo, by asking the monkey to sell the first time each buyer's prices go down 2, then up 1, then down 1, then up 3, you would get 23 (7 + 7 + 9) bananas!\n\nFigure out the best sequence to tell the monkey so that by looking for that same sequence of changes in every buyer's future prices, you get the most bananas in total. What is the most bananas you can get?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_23.adb",
    "content": "--  Solution to Advent of Code 2024, Day 23\n-------------------------------------------\n--  LAN Party\n--\n--  https://adventofcode.com/2024/day/23\n--  Copy of questions in: aoc_2024_23_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_23 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_23\";\n\n  r : array (Part_Type) of VString;\n\n  dic : Hash_Maps.Hash_Map_Type;\n\n  subtype Id_Range is Integer range 1 .. 1000;\n  subtype Computer_Name is String (1 .. 2);\n\n  historian : array (Id_Range) of Boolean;\n  connected : array (Id_Range, Id_Range) of Boolean;\n  name_of   : array (Id_Range) of Computer_Name;\n\n  last : Id_Range;\n\n  procedure Read_Data is\n    use Hash_Maps;\n    dummy_separator : Character;\n    name : Computer_Name;\n    f : File_Type;\n    last_64, v1, v2 : Integer_64;\n\n    procedure Register (val : out Integer_64) is\n      dummy : Integer_64;\n      unknown : constant := 0;\n    begin\n      Find (dic, +name, unknown, val);\n      if val = unknown then\n        last_64 := last_64 + 1;\n        Insert (dic, +name, last_64, False, dummy);\n        val := last_64;\n        if name (1) = 't' then\n          historian (Id_Range (last_64)) := True;\n        end if;\n        name_of (Id_Range (last_64)) := name;\n      end if;\n    end Register;\n\n  begin\n\n    for i in Id_Range loop\n      historian (i) := False;\n      for j in Id_Range loop\n        connected (i, j) := False;\n      end loop;\n    end loop;\n    Clear (dic);\n    last_64 := 0;\n\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get (f, name);\n      Register (v1);\n      Get (f, dummy_separator);\n      Get (f, name);\n      Register (v2);\n      connected (Id_Range (v1), Id_Range (v2)) := True;\n      connected (Id_Range (v2), Id_Range (v1)) := True;\n    end loop;\n    Close (f);\n\n    last := Id_Range (last_64);\n  end Read_Data;\n\n  verbosity_level : constant := 0;\n\n  procedure Do_Part_1 is\n    count_with_historian : Natural := 0;\n  begin\n    for i in 1 .. last loop\n      for j in i + 1 .. last loop\n        if connected (i, j) then\n          if verbosity_level > 1 then\n            Put_Line (+\"Connected: \" & name_of (i) & ',' & name_of (j));\n          end if;\n          for k in j + 1 .. last loop\n            --  \"[...] each computer in the set is connected to the other two computers.\"\n            if connected (j, k)\n              and then connected (i, k)\n              and then (historian (i) or else historian (j) or else historian (k))\n            then\n              if verbosity_level > 0 then\n                Put_Line (+\"Historian in triplet: \" & name_of (i) & ',' & name_of (j) & ',' & name_of (k));\n              end if;\n              count_with_historian := count_with_historian + 1;\n            end if;\n          end loop;\n        end if;\n      end loop;\n    end loop;\n    r (part_1) := +\"\" & count_with_historian;\n  end Do_Part_1;\n\n  --  Sorting is copy-pasted-adapted from the BWT example for HAC.\n  --  Note the Ada standard has a generic sorting in its library.\n\n  type Table is array (Id_Range) of Computer_Name;\n\n  procedure Shell_Sort (b : in out Table; n : Natural) is\n    i, j, step : Integer;\n    step_size : array (1 .. 4) of Integer;\n    stop : Boolean;\n    temp : Computer_Name;\n  begin\n    --  'steps' contains decreasing increments for each\n    --  pass. The last pass has increment 1.\n    step_size (4) := 1;\n    for pass in reverse 1 .. 3 loop\n      step_size (pass) := 2 * step_size (pass + 1);\n    end loop;\n  Passes :\n    for pass in 1 .. 4 loop\n      step := step_size (pass);\n      --  Do a straight insertion sort with 'step' as\n      --  an increment instead of 1.\n      i := step + 1;\n      while i <= n loop\n        temp := b (i);\n        j := i;\n        stop := False;\n        while j > step and not stop loop\n          j := j - step;\n          if b (j) > temp then\n            b (j + step) := b (j);\n          else\n            b (j + step) := temp;\n            stop := True;\n          end if;\n        end loop;\n        if not stop then\n          b (1) := temp;\n        end if;\n        i := i + step;\n      end loop;\n    end loop Passes;\n  end Shell_Sort;\n\n  procedure Do_Part_2 is\n    elem_set : array (Id_Range) of Natural;\n    set_size, set_last, best, name_count : Natural;\n    valid : Boolean;\n    t : Table;\n    type Pass_Type is (find_largest_set_size, pick_largest_set);\n  begin\n    best := 0;\n\n    Passes :\n    for pass in Pass_Type loop\n      Main_Vertex_Loop :\n      for i in 1 .. last loop\n        if verbosity_level > 1 then\n          Put (+\"From \" & name_of (i) & \": \");\n        end if;\n\n        --  Create a group around computer i:\n        set_last := 1;\n        elem_set (set_last) := i;\n\n        --  We gather all computers connected to i:\n        for j in 1 .. last loop\n          if connected (i, j) then\n            set_last := set_last + 1;\n            elem_set (set_last) := j;\n            if verbosity_level > 1 then\n              Put (name_of (j) & ' ');\n            end if;\n          end if;\n        end loop;\n        if verbosity_level > 1 then\n          New_Line;\n        end if;\n\n        --  Now we have *the* set of all computers connected to i.\n\n        --  Check mutual connections in the set:\n        set_size := set_last;\n        Check_Connections :\n        for elem_i in 1 .. set_last loop\n          valid := True;\n          for elem_j in elem_i + 1 .. set_last loop\n            valid := valid and then connected (elem_set (elem_i), elem_set (elem_j));\n            if not valid then\n              if verbosity_level > 1 then\n                Put_Line\n                  (+\"  Eliminated: \" & name_of (elem_set (elem_i)) &\n                    \" not connected to \" & name_of (elem_set (elem_j)));\n              end if;\n              exit;\n            end if;\n          end loop;\n          if not valid then\n            set_size := set_size - 1;\n            elem_set (elem_i) := 0;  --  Cancel the element (no packing)\n          end if;\n        end loop Check_Connections;\n\n        --  Now we have *a* set of computers connected to i, where computers\n        --  are directly connected to each others.\n        --  Note that vertex i can belong to multiple such sets.\n\n        if verbosity_level > 0 then\n          Put (+\"Set size: \" & set_size & \": \");\n          for elem_i in 1 .. set_last loop\n            if elem_set (elem_i) > 0 then\n              Put (name_of (elem_set (elem_i)) & ' ');\n            end if;\n          end loop;\n          New_Line;\n        end if;\n\n        case pass is\n\n          when find_largest_set_size =>\n            best := Max (best, set_size);\n\n          when pick_largest_set =>\n\n            if set_size = best then\n              --  We found a set with the maximum size (hope this is the expected one!):\n              name_count := 0;\n              for elem_i in 1 .. set_last loop\n                if elem_set (elem_i) > 0 then\n                  name_count := name_count + 1;\n                  t (name_count) := name_of (elem_set (elem_i));\n                end if;\n              end loop;\n              Shell_Sort  (t, name_count);\n              r (part_2) := +\"\";\n              for i in 1 .. name_count loop\n                r (part_2) := r (part_2) & t (i);\n                if i < name_count then\n                  r (part_2) := r (part_2) & ',';\n                end if;\n              end loop;\n              exit Main_Vertex_Loop;\n            end if;\n\n        end case;\n      end loop Main_Vertex_Loop;\n    end loop Passes;\n\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1227\n    --  Part 2: validated by AoC: cl,df,ft,ir,iy,ny,qp,rb,sh,sl,sw,wm,wy\n  end if;\nend AoC_2024_23;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_23.txt",
    "content": "jm-oz\nel-mn\naa-jt\nag-mt\nfg-bt\ntm-xh\nag-si\ntx-mk\nig-zj\nfd-tp\nsj-ln\nrp-zo\nnp-mr\nqq-ny\ntf-ku\nfp-fo\nlp-pu\nht-zn\nsf-pw\nln-aw\nmt-tg\nft-ny\nsw-rb\nfh-vq\nec-xk\nfo-ko\nif-ka\nuv-bl\nmv-ph\nua-vq\nyw-tj\nlb-pp\nyr-nv\nrm-km\nyf-ww\ntx-ij\ndz-oq\nwn-qv\nyw-ow\nay-cp\nps-hv\nke-lj\ndq-xi\nna-pu\nux-cn\npb-vb\nth-pg\nva-ut\nem-mc\nmi-un\njk-bg\nfc-bo\nke-ei\nyf-fp\nec-yc\nom-ip\nss-gd\nlp-mk\njj-sj\nru-je\nfp-sd\nwg-gj\ndj-cm\nth-ue\nzf-cz\nwg-gb\nxv-ss\nuw-ms\nup-hc\npp-sp\nmy-bh\nmp-hj\nyy-ko\ndm-ru\nax-ja\nup-vh\ndr-sp\nfg-fy\nwh-or\nbl-mb\nic-wn\nws-sg\nmm-nk\ndq-ti\nkv-yh\ncc-ev\njg-vr\nga-fj\nkp-jb\nme-nf\nad-jd\nwy-qp\nfj-uz\nmy-tw\nfu-zc\nxq-cx\nhs-wk\nah-zv\nsn-kb\nay-ch\nla-hr\nqj-jn\nae-gt\nmb-eu\nmu-yg\nei-fd\nrh-gp\nrd-ua\nvg-ou\njd-on\nfo-ww\nue-sb\nrz-so\nfa-cp\nwl-jo\nko-ww\nsi-nx\nrz-jf\npb-zi\ngd-kc\nli-wo\nmw-xf\nmj-dv\nvl-rh\nrk-bp\new-in\ndn-xd\nka-ip\nws-jt\neb-ho\nez-ow\nwa-hw\naa-vy\ncb-fq\nll-xv\nlb-qs\ndz-zm\nfk-ss\nqs-xw\nyd-wo\ntk-zg\nkv-kn\nwg-ld\nnk-av\nry-fm\ntd-km\nbu-fa\nlo-mz\nxw-pp\nzj-ew\nhe-nx\nbo-ya\nwv-oy\nyu-pd\nmj-na\nhc-qt\nmv-ej\nbp-yg\nwl-hc\nya-fg\nkr-wn\nyt-ij\nxm-sp\nkn-yk\nuz-qj\nhv-uu\nnt-wq\nin-jx\nge-up\nte-uv\nbs-ku\ngd-sa\ncj-xo\nyx-nd\nds-pp\nba-nu\ntg-xe\nfo-mg\nbn-bk\nfw-nj\nmh-jj\nvy-tp\nua-ic\naz-il\nee-yi\nrs-ju\nrw-wf\nqh-js\nso-dz\nes-xo\nha-zv\nya-wh\nln-jj\nkq-nu\nya-vk\ngz-bf\nbl-ra\nwz-jl\nfd-hj\nyb-pj\nfb-fv\ndf-ir\nxm-qs\nrs-fq\nau-sh\nah-oj\nax-ds\ncb-wy\nzn-xx\ndv-tx\nbj-mb\nph-uk\nid-yi\nsh-rb\nhi-yn\nyq-bp\npu-tx\nqc-fh\nho-zj\nlh-xx\ntk-js\nrj-we\nml-we\nqx-yc\nax-af\npl-sg\nur-ho\npu-pi\nxw-ds\nio-te\nyi-tl\nts-lt\nzn-fz\nsw-ft\npr-uz\nmh-qw\nyn-bz\nwk-rw\nve-ti\nha-fc\noh-ib\nlw-mw\nys-pi\ntm-sa\nqb-yw\ndu-sx\njm-ha\ndw-mk\nqm-dn\npm-wx\nwn-ip\nrc-jd\njn-ql\ngl-us\nen-bn\nub-ch\noz-ha\ncq-dj\nkh-ty\nyx-xv\npj-ww\nhz-zv\nxk-pm\nwn-bu\nzz-dz\ndz-jp\nyr-az\nna-yt\nnf-zx\nln-vr\nlq-zz\nsg-ju\nmg-gv\njh-bs\nwm-cl\nsm-wo\nfa-ub\ncp-ch\nqq-se\nlj-gl\nfw-wo\nnt-co\nya-be\npr-df\nva-ok\nml-nz\nmb-yp\nrs-hf\nhz-eu\nvk-be\nwu-mi\njs-gi\nib-jf\nfo-eb\nln-nt\ncm-ns\nwn-za\nad-ru\nlg-zi\nbd-vl\nem-mo\nqt-up\nkp-sm\nvg-gu\nfv-jh\nqh-zg\nik-pu\nse-vk\nss-im\npj-zp\nfy-mx\ngl-ti\nro-zn\nxt-en\nku-jh\nfu-lc\nai-sv\nkp-kq\nla-xq\nxh-oe\nvy-yc\ntx-mj\nuk-zo\nrc-zc\nad-on\nrc-gv\naa-sg\nzz-yr\naz-en\nzv-nz\nhx-az\nmd-kd\nwg-fa\nru-ms\nfv-jz\nch-tr\nsg-cb\nef-rd\nkv-xx\nth-fc\ncf-wb\nid-vw\nlq-bc\nnx-mt\ncv-ok\nez-ip\nmn-nz\nky-ht\nwi-tq\nxo-su\nid-tl\nqj-pr\nzr-mm\nuz-re\noo-cx\nyy-yh\nth-kd\nxv-do\nke-gl\nyr-il\npz-jh\nzf-nu\niq-pt\nvg-lg\ngq-jm\non-dm\nhl-ao\nid-er\nur-ew\nfj-tc\nxd-bu\noo-ao\npi-yt\nfx-bz\nno-uz\nym-ea\ngx-qo\nli-zf\nuw-rc\npw-yy\nvw-wu\nmg-eb\nxf-of\nfj-no\nrq-tp\nur-in\nit-zt\nrd-bg\nsm-nj\nki-te\nvv-kz\ncf-aw\nmv-rp\nko-ar\nwc-yz\nof-rm\nsv-mn\nuy-oa\ntz-ax\npm-mn\noy-sq\nlq-if\njz-hv\njh-zg\nnl-ci\nbi-wn\nup-wc\ngu-xo\nze-ky\ngq-jv\nyj-fv\njp-so\ncz-jb\nti-zb\nfa-iz\nuk-ej\nae-hv\noe-fk\ncq-oy\nom-bi\nph-rg\net-bc\nwz-st\ncj-zi\nmz-nl\nbn-ub\nar-uj\nku-yg\nfp-ko\nkm-ux\nag-mz\nds-dr\nvr-cf\nbi-ow\nwv-dj\nwq-sj\nsn-rp\nwy-df\nff-qy\ntr-ld\nvy-sv\nfm-gz\nhz-pe\nbt-yc\neq-ne\nsi-lk\nkt-hv\nui-ka\net-gb\nyr-hx\ngn-is\nlv-qt\ndf-cl\nkn-vn\nnf-km\nki-bl\npt-ff\nxf-um\ntd-yq\nzx-oa\nti-ev\njw-gh\nen-pa\noz-jv\nkw-hj\nwz-cc\nok-yy\nnn-kj\ncp-wg\nsl-qp\nwf-nn\nxu-ts\nrs-cb\nse-ya\nlb-ja\nba-sm\nes-gr\nlp-ij\nhm-id\ncm-sq\nut-yy\nxd-ay\nwv-aj\nbg-uy\nfl-vn\nhn-rj\nqy-ek\nex-ww\nbi-tj\nlj-zt\nfy-wh\nvy-rq\ndj-gz\nkb-rp\nbh-tw\nlg-av\nne-qo\nxi-st\nfc-mm\nua-qa\nch-et\npz-ku\nei-gl\nkn-ze\nst-ti\nee-wt\nhc-xt\nlq-qe\nec-hk\ncb-hf\nsw-cl\nxv-iz\nnv-pa\nvh-hc\nzm-gd\nci-be\nyt-ys\nnf-gk\nld-gb\nkz-lm\nxf-in\nsj-co\nzc-jd\nwe-hz\nvj-gt\nkp-li\ngo-nc\nno-lx\nlp-tx\nns-wu\nwg-ef\nen-ce\nxq-rs\nlm-ab\nmh-xu\nmi-ac\nch-xd\nui-rh\nxp-er\nko-yf\nom-kr\nqy-lr\nea-va\nth-bo\npg-au\ngo-oh\nth-mm\nxk-yc\nrh-fh\nwi-je\nqy-kh\nio-md\nmr-wc\nbd-qc\nci-or\nys-pu\nut-fe\nho-ig\nyu-im\nwy-ir\nqe-ib\nvu-fi\nqz-vd\nmx-be\nfl-ht\nfq-ju\nyw-zh\nnx-nl\nwq-aw\nss-pd\nay-fa\nce-pf\njj-co\npx-la\nfx-yn\nvq-qc\nfw-li\nml-jv\nmd-eu\nag-tg\nki-eu\njv-ah\nns-vw\nic-oa\ngk-qa\nci-mx\nzz-qe\nyu-kc\ngs-oe\nfe-ct\nlk-xe\nhw-tw\nir-qp\nxu-wa\nav-th\noe-zm\nll-ph\nfh-ui\nvv-vd\nwv-jr\niq-lr\nhs-wf\nzk-pf\nbm-gh\nzg-gi\nog-bk\nsu-zi\npc-rs\npa-yr\niy-wy\ntk-gi\nzp-eb\nyz-xt\nwu-hm\nrs-ws\nkm-yq\ncb-uz\nnu-wo\nze-fz\nmd-bl\nms-cp\nij-on\nzc-lc\nrd-gk\nvt-vu\nir-sl\ntr-xd\nra-ki\nft-sl\nni-xf\nrg-hd\ncl-zl\nph-rp\njg-wq\nfd-vp\nwl-np\nhb-zd\nea-ct\njx-ig\nwb-qw\nzy-ue\net-ub\nke-vp\nkh-hi\nbp-rm\nlw-ig\ndm-uw\npt-hi\nkb-mv\nbi-za\nur-jx\nwl-mr\njg-jj\nhn-rs\nve-xi\ntf-tk\nhv-fv\nvy-mn\nlo-yd\nst-cc\nek-fx\nqb-ez\ntt-dz\nxl-ay\nyw-bi\nuz-ql\nqy-ty\nvd-rt\nvj-bh\nfz-ky\nap-tk\ncp-xd\nmu-km\nit-pg\nou-zi\non-ms\nxu-cw\ngi-pz\nmv-sn\njw-jn\nbn-pf\nll-ww\nzj-lw\njd-rz\nom-qe\nkt-ps\nhx-pf\nvr-ik\nla-iv\nae-yj\nmn-qx\njv-nz\nsi-xe\nvm-ke\nhz-jv\nfw-hc\ntf-jh\nss-zm\nir-hj\nec-sv\nsh-df\nad-tm\nrq-xk\nlp-dw\nej-zo\nev-zb\nwe-gq\nmj-mk\neb-ww\nxv-go\npc-ju\niq-ty\nmm-zt\nfm-aj\npm-rq\ntd-gd\nab-hs\nkz-rt\nva-yh\npi-dv\nfm-cm\nkv-ze\nua-gk\nro-ze\nzd-xo\nqo-jg\nmb-uv\nml-ha\nhx-og\npj-fo\nur-ni\nxf-zj\nsp-tz\ngb-fa\nqv-yw\nyu-ss\nro-lh\nha-pe\nqh-jh\ndz-jf\nln-co\num-ur\nni-jy\npb-su\nne-ae\noy-vx\nvy-qx\nvu-vq\nba-li\naj-sq\nkh-lr\nnf-ic\nea-yy\niy-hk\nxm-xw\nfj-jn\nqa-rd\nfc-nk\nmq-pr\nyd-ge\nyx-kj\ngs-xh\niq-hy\nhz-ah\nmb-ra\nhi-rd\nps-fb\noe-ss\niv-ao\njz-yj\nui-lu\nhl-bm\ntc-pr\nve-ev\ndz-ib\nne-ps\npg-ue\nge-nx\nai-hk\ntj-zh\nwb-sj\nfu-dm\nlj-mp\nec-rq\nvb-gu\nmc-se\nmw-ig\nid-ee\nrm-mu\nyp-eu\nxl-du\new-xf\nvr-wb\nap-qh\noj-nz\nof-wi\nvj-ze\nor-vk\nuj-la\net-fa\nou-su\nct-va\nxq-sb\neq-ae\npm-sv\ndn-tf\nsx-zo\nva-hb\njo-vh\nfo-ac\noq-if\nqb-ow\nte-bl\nan-gn\nqh-gi\nmr-qt\ngp-vu\nev-jl\nii-kd\nsw-wm\nbg-me\nzz-ib\noh-kj\npe-gq\nwa-cr\njf-tt\nag-ft\nyh-ok\nom-ow\nxw-dr\nav-it\nsu-eq\nkr-ez\nwa-vj\ncz-nj\nxx-fz\nnn-vv\nmh-jg\nvw-yi\ndq-ev\nyx-nc\nht-yk\nlq-dz\nbo-it\noa-qa\nhc-mr\nbs-tf\nkq-fw\nmi-tl\nfc-ue\nkw-ei\nct-sf\nke-fd\nao-sb\nrd-zx\nmy-ts\nbn-hx\nxo-zi\nrd-me\nwo-zf\npt-gp\ngs-tm\nzl-lx\nqq-bt\nmx-qq\nwo-kq\nkw-lj\nez-bi\npc-cz\nry-jr\nqp-wm\nsn-yu\nio-mb\nmu-am\nup-pk\nmo-vm\ndu-ej\nbf-sq\nue-zr\nfu-jd\nwq-mh\nez-zh\nqt-jo\nqc-ka\nbm-sb\nym-js\nhc-ke\nzn-zx\nkj-do\ndf-ft\nes-qs\nbe-or\nkq-zf\nwz-be\nre-it\naj-cq\nna-ij\neq-yj\nds-ja\nlu-qc\nsg-jt\nnd-iz\nnu-jb\npc-cb\nfz-ln\ncz-nu\nuw-zc\nxf-ho\nml-jm\nzx-qa\nkc-xh\nra-ai\nst-mf\nkt-yj\nfq-hn\ntd-mu\njr-sq\nsx-xl\nus-ds\nuv-bj\nvw-wt\npi-dw\ngq-nz\new-jx\nek-yn\nfe-cv\nnp-pk\nzr-zt\nqj-jw\ndm-jd\nio-ra\noh-yx\nff-yn\ncw-bh\nig-xf\nnv-hx\nht-lh\nit-zr\nna-dw\nid-wt\nfd-mo\nqs-ja\nim-xh\nan-yx\ntj-qb\ner-yi\ngk-zx\nag-xe\nqz-hs\nmq-gh\nan-rk\nkr-zh\nyx-is\nnv-bn\nvl-lu\nhw-xu\nah-jm\nqo-uu\nlm-nn\nwh-fg\nfi-vq\npr-ga\nyj-uu\nfi-fh\nqy-hi\nps-eq\ngr-xo\nzb-xi\nog-nv\nqj-mq\nbf-wv\nty-qe\nem-lj\nqq-be\noo-la\nhd-ej\nwe-nz\nui-qm\nki-uv\nrm-am\nrk-oh\nbo-zy\nhd-uk\nfy-hr\nmf-ti\nek-ps\nwf-kz\nrk-yx\nmt-nl\nff-ty\nmc-be\nst-dq\npl-zt\nrp-sx\nlx-zb\nwh-be\nrm-td\nmg-ar\nbt-wh\npf-en\niv-hr\nkt-jz\nfi-vt\non-uw\nhy-wk\ncf-qw\nwi-rm\neu-uv\nwl-lv\nyk-vn\nvg-es\nch-gb\nuu-ht\npt-lr\nne-uu\nfd-lj\nzk-az\nua-me\nhe-lo\nkc-sa\ngv-uw\nje-dm\npe-ah\nbl-eu\noa-rd\nsh-wy\nce-zk\nan-iz\nou-cj\nvb-zd\nnn-kz\nxk-tp\nns-ee\nvu-ui\nce-il\nbl-bj\nzg-il\nqb-za\ntk-dn\njg-cf\nvm-mb\nbi-yk\nlm-wk\nsp-ik\nhe-io\ner-wt\nkw-mp\nvg-pi\nge-lo\nzf-jb\npl-aa\npr-jn\nyb-mg\nqp-df\nwz-dq\nsl-iy\nvd-ab\nsa-ys\nzh-ow\nsx-sn\nfq-sg\ndr-af\nlt-wa\nhs-vv\npf-og\ndu-lm\nlg-su\nkw-us\npx-io\nsg-rj\nkt-gx\nwt-un\nze-yk\nge-mz\nid-wu\nsj-jg\net-cp\niv-cx\nsf-ym\nnp-jo\num-jx\nys-ac\nzv-jv\ntc-uz\ntq-rm\nvd-uw\nfj-tf\nth-zt\nau-fc\naw-wb\npx-bm\nzo-du\npx-hl\nhk-xk\nil-en\nxm-af\nek-kh\nac-pu\nzb-cc\niy-cl\nhd-sx\naz-pa\nfi-gp\nnu-mm\nrj-mp\npp-lh\nrw-ab\nii-mb\nba-jl\njn-re\nad-dm\npu-mj\nax-xm\nzt-bo\nnl-lk\nft-ir\nsd-yb\ncv-ym\nzd-lg\nmo-ke\ngo-an\nzr-fc\nnz-jm\nip-bi\nuu-fb\noh-nd\nwx-bm\nfb-dr\nyc-pm\nnc-nd\ntm-pd\nbk-nv\nqc-vl\nnl-lo\noj-ml\njr-cm\njn-ga\nlv-mr\nnp-up\ncc-ve\ngj-cp\nmj-ij\nes-gu\nqh-id\ngb-xd\ncv-pw\nei-vp\nhr-hl\nfq-hf\nwi-am\nmq-fj\nsd-mg\nyb-ll\nky-bd\nko-pj\nhz-oj\nrc-lc\nsh-ny\nuy-zk\nlq-ib\ndo-oh\nea-ok\nnc-gn\nol-rt\nja-an\nyn-iq\npg-mm\nen-nv\nwa-tw\nzg-bs\nvv-rt\nzk-en\njj-wq\nje-uw\nwn-qb\nux-wi\nsp-ds\nvp-kw\nkm-yg\nny-ir\nqz-jk\nrh-ka\npd-lw\nof-td\nkj-an\nza-zh\npt-kh\nux-rm\nzz-oq\nvk-bt\nzg-pz\noz-dm\nbn-pa\njf-oq\ngs-fk\npw-fe\nrt-qz\nwf-lm\nek-pt\niv-uj\ncm-vx\nwg-xd\net-ay\ngk-zb\niy-sw\nha-jv\nyz-jo\nlj-us\nzc-ru\nhl-uj\nkz-ez\nxw-tz\nbk-hx\nvd-wk\nym-fe\ngx-fb\nun-tl\nwl-tc\ntm-fk\nlb-sp\ntq-yg\nhs-kz\nvr-sj\nwh-qq\nwq-cf\nvw-tl\npp-af\nkt-uu\nfx-ty\nsj-se\nci-qq\nbg-zx\nxh-zm\nso-jf\nwu-fe\nwe-jv\nje-jd\nsq-ry\nbj-md\nio-kd\nkt-qo\nfy-ya\ner-fl\nhw-bh\nwu-er\nwq-wb\nfv-ps\nni-fm\ngd-tm\nlo-mo\nrj-rs\nyh-ym\nmx-bt\nim-tm\nik-ds\njf-jp\nmk-ac\nog-bn\nga-no\nid-ns\nss-tm\nds-qs\ncc-zl\nns-yi\nab-wk\nef-jk\nuk-jp\nst-zl\nqc-gp\nun-xp\ngl-vm\nku-tk\njt-hn\nfc-pg\ntx-yt\nmo-lj\nge-tg\nvh-np\nur-jy\naa-ju\num-jy\nrw-vd\nzn-ze\nbm-cx\nny-iy\naf-tz\nmj-ea\njn-tc\nsg-lv\nze-ht\noy-sp\nxh-yu\npe-jn\nst-jl\ntq-am\noh-gn\nfc-av\nkd-ra\nip-ow\nsd-ll\nei-lj\ncw-cr\nsd-ww\ncl-rb\nwh-vk\nlg-vb\ntg-nx\nad-rc\nvb-cj\nlw-xf\nci-fg\nyr-zk\nww-mg\nor-fg\ndw-pu\nmg-yf\nnt-wb\naz-nv\nrh-vu\nsw-qp\nis-iz\npc-fq\nll-ar\nau-mm\nic-zx\nzh-ip\nfz-ht\nja-xw\nhn-cb\nrb-ny\ntm-oe\ndv-lp\nkr-qv\nwq-vr\nqv-ow\nsd-eb\nbu-ch\nog-vu\ndn-hi\nyw-va\npm-qx\nzk-bk\nbt-mc\ntr-bu\nxw-ik\nyn-lr\nyb-fp\njy-in\nkc-im\nqq-ju\nmd-ii\nfi-mr\npr-re\nsa-fk\njt-pc\nkd-ki\nsu-gr\nwz-ti\nff-bz\nmf-dq\nbh-gt\nlw-ew\nts-vj\nmq-jw\ndv-ij\nsw-sl\ndn-gi\noy-aj\nfg-vk\nse-or\nvg-pb\niy-wm\nzz-jf\nae-kt\nag-nl\nnp-xt\nuy-zx\nrp-uk\nkv-zn\nft-rb\nun-wu\nfm-bf\nqm-js\npj-wv\nxv-kj\ngu-zi\nan-oh\nzy-fc\naf-ad\nec-tc\ndu-hd\nej-rp\nlq-tt\nwy-ft\nzb-ve\nar-fo\npc-rj\nwo-ba\ngu-gr\nvg-gr\njx-jy\nfk-bf\nkz-wk\nge-si\nkc-pd\nnf-bg\ndw-ys\nip-qv\nkb-hd\noq-qe\nrb-wy\nqk-vp\nrg-mv\nfj-gh\nex-ts\neq-qo\nzi-vb\nyn-ty\nrq-hk\nwa-bh\nmf-zl\nyp-uv\ncx-uj\nga-gh\nvn-iq\ncr-ex\nmw-ew\naw-vr\npe-zv\nzf-nj\nha-nz\nki-mb\nxm-ds\nej-ph\nln-qw\ndu-kb\nra-md\nee-hm\nff-hy\nwu-wt\nrb-qp\nlm-ol\naa-rj\nco-mh\nzg-ap\noa-ef\njo-up\ncl-ir\nnc-mw\nka-vu\npg-av\nnd-do\nhz-gq\ngr-zi\nai-tp\nzv-ml\nil-pf\nww-yb\niz-rk\nlk-mz\nph-du\nkt-ne\njk-oa\nfv-gx\nah-ml\ndv-mk\nml-gq\nrw-hs\nmr-pk\nqv-bi\nrt-wk\ngz-cm\nwv-vx\nqz-ol\nsn-zo\nja-ik\nmy-tz\nct-hb\nbc-ic\nsq-ut\nlg-xo\ncf-ln\ndm-ms\noz-nz\njb-nj\naw-qw\nlb-ax\njt-rs\npx-wx\nfq-aa\nym-ct\noq-bc\npx-ao\naf-xw\nxh-fk\nyt-pu\nua-ef\nfh-ch\nva-cv\nft-wm\nag-he\nwm-sh\nbz-iq\nwe-oj\nzk-pa\nmf-lx\nwt-ns\nlt-cw\nrq-sv\nqj-gh\nza-ip\nsi-yd\nce-bk\ngs-lt\nyd-ag\net-wg\nhs-lm\nts-gt\nbl-vh\ntw-lp\ncp-gb\nky-zn\nlv-xt\nre-fj\nwc-jo\nsl-cl\nhl-la\nqs-ax\nyf-zp\njy-ho\nic-bg\nzt-fc\nvm-ei\ngr-ou\ngt-hw\nso-ig\ntx-dw\nna-zo\nac-mj\nqm-tf\nco-jg\njz-gx\nzl-jl\nve-jl\nmz-si\nmm-bo\ngx-uu\nvm-fd\nhw-lt\nad-je\ntg-lk\nfu-ad\njo-hc\nrd-jk\nzx-me\nqj-fj\nvm-us\nut-hb\nrd-ic\nhf-aa\nxp-id\nbs-gi\nxm-tz\nxd-fa\nyd-lk\nnp-lv\nbu-yn\noz-pe\nwl-qt\nwn-ez\nnd-rp\ncj-su\nvl-fi\nhz-ml\nrw-nn\nmw-ni\nrt-ab\ncm-oy\ndm-lc\nuk-mv\ngp-ui\noj-zv\nbf-oy\nyj-qo\nya-mx\nke-hj\nfk-zm\nti-cc\nst-ve\nou-lg\nmr-up\niq-hi\nxv-an\nmd-mb\nut-ok\ncq-sq\nwc-pk\noj-ha\nrc-ru\nfm-cq\nmd-ki\num-in\nea-ut\nuy-me\nyg-ux\nee-gx\nxp-yi\nem-gl\nhb-pw\ntq-of\naw-sj\nxu-lt\nlb-xw\nxh-gd\nyz-wl\nke-us\nna-pi\nzp-mg\nlt-my\nnc-is\njy-cr\nbd-vt\nbi-zh\nfb-jz\neb-yf\nhw-ry\nfe-sf\nkc-tm\nyd-nl\nok-pw\nrb-iy\nty-hy\nlx-jl\nqx-ec\nhf-sg\nel-yc\nyp-bj\nuj-sb\ndo-an\nlk-lo\nuu-fv\naz-pf\neb-ar\nmn-ec\nlx-dq\ngp-vt\nli-nj\nro-ht\nrz-oq\nac-tx\nrj-ws\nwc-wl\nvt-vq\nbn-il\nmw-zj\nzt-au\nqz-vv\nqy-pt\nlp-mj\nrh-lu\nhc-yz\ngj-fa\njt-pl\ncr-tw\nsl-wy\ntq-td\nax-yf\nxo-vg\ncr-my\njs-ap\nxd-ub\nay-ld\nlb-af\nbg-yx\nei-us\nyt-mk\nof-ux\nqz-lm\nll-fp\ntf-zg\nar-yf\nhb-fe\nhk-el\ngo-do\ngv-ad\nva-fe\nnx-ag\nme-ef\nlv-jo\nsu-vg\njs-ku\nms-lc\ngl-fd\nem-vm\nir-sh\nhv-eq\nwx-cx\nzh-qv\nnx-lo\nwu-ee\nnt-jj\nll-fo\nbo-nk\nij-ew\nut-ct\nkc-pw\nhk-tp\nhw-cr\nve-wz\nce-yr\ndu-rg\nhf-pl\nfk-yu\nli-kq\ncl-qp\nqp-iy\nfj-jw\nyp-ii\nvm-kw\npl-fq\niv-sb\nju-rj\njs-zg\nor-qq\nra-eu\nge-ag\nvh-pk\ntg-yd\nxt-mr\nqa-ic\nmg-ll\nor-fy\nvj-cr\nsp-ja\nnf-uy\nbt-ya\nki-yp\njw-pr\nqp-ft\nwv-fm\njv-oj\nxi-lx\nyw-om\nkj-gn\nna-dv\nit-ue\nbm-ao\nzi-im\nhd-rp\noh-is\nmu-wi\nvr-jj\nej-kb\nzh-wn\nua-jk\nvw-un\nax-dr\nvq-ka\nhm-un\nba-kq\npe-we\nbp-km\nwh-se\nww-ar\nil-nv\npr-ql\nfp-eb\ngn-vp\nup-wl\nwn-ow\nqm-jh\nkz-ol\nse-be\npm-hk\net-wf\nvn-fz\nht-kn\nan-nd\nvd-ol\noo-bm\nqb-qv\nqh-tk\npk-qt\nkm-tq\nbg-gk\nym-yy\nzc-ms\nau-it\nvd-wf\nzp-ww\nky-fl\nfb-kt\nct-jt\nny-cl\nmb-te\ntj-wn\nef-gk\nnv-ce\nqe-jp\nog-zk\nyq-mu\naj-gz\nxv-gn\nga-tc\npz-dn\nga-uz\nqt-np\nfy-mc\ngn-do\ngt-cr\nko-zp\nxp-hm\nrh-fi\nzy-av\nuy-qa\nut-sf\nel-vy\num-ew\nvq-bd\nka-bd\nqv-pf\nsh-ft\nzt-nk\nqm-qh\ntq-yq\npb-ou\nrk-kj\nyj-ry\ngp-wb\nav-bo\npt-bz\nel-xk\nth-au\nsh-cl\nbf-dj\nyj-ps\nph-sx\nil-hx\nsh-sw\nkv-fz\nvy-hk\nhs-qj\ngd-yu\nhv-yj\ngb-rm\nxi-av\nof-am\nsv-sm\npc-hf\nmx-mc\nxq-hl\nzc-on\nlv-wc\nws-aa\nve-zl\ngv-fu\nga-mq\nza-qv\nor-mx\npi-mk\nru-fu\nvp-hj\ntw-xu\nue-bo\nkn-fz\nsn-hd\nhn-ws\nqb-zh\nof-cn\nzm-gs\nyr-og\nol-rw\nay-wg\nfy-qq\nub-wg\nsx-kh\ncb-pl\nhe-lk\ntd-cn\nav-ue\nlr-hi\nnj-kp\nbd-rh\nzb-st\nfb-yj\nis-go\nha-we\nlb-tz\nxl-uk\nvk-mx\njf-ab\nmo-gl\npm-el\nwe-ah\npa-pf\nuu-eq\nki-cq\nvv-hx\nko-mg\nvl-ui\nbj-ki\ndq-zl\ntz-qs\nuy-gk\nsv-el\nsf-va\naj-dj\nhi-hy\nmx-ga\nyx-iz\nlv-vh\nsm-jb\nyf-yb\nra-ii\nzj-bk\ngb-bu\nzy-mm\nqb-om\nsb-px\nwk-eb\ntt-zz\nyu-zm\ntk-pz\nik-dr\noq-so\njb-qk\nrm-yq\nyx-gn\ndq-cc\nus-em\nte-bj\nbs-ap\nrw-kz\njl-mf\nkp-cx\nvu-bd\ner-ns\nwo-jb\nwz-mf\nbj-kd\ngi-qm\nsm-nu\nsf-ea\npg-zy\nkz-qz\njs-jh\nqe-if\nzf-sm\ngd-pd\nqb-cf\nrz-dz\nss-gs\nib-rz\nis-kj\nio-ii\nqc-ui\nbi-kr\nuj-xq\nae-jz\nxp-vw\nue-au\njp-ib\nay-ub\nem-ei\naz-bn\noo-xq\nyr-pf\nzv-jm\nvy-ai\nge-nl\ncv-ct\nsv-tp\ntr-fa\nli-sm\npd-xh\nym-ut\nqa-jk\nlc-jd\noj-np\nyz-zr\noq-lq\nns-hm\nyn-kh\noe-yu\npr-fj\nrc-ms\nfg-be\nni-um\nhc-pk\nbe-fy\nvk-mc\neq-fb\nvr-co\npg-zt\nlh-fz\nky-kv\nqa-ef\nyk-lh\nlq-jf\nzd-gr\nxu-gt\nmt-gh\nqp-ny\nln-jg\nkh-ff\nyg-rm\nsp-xw\nwx-iv\nbh-ts\ntr-ro\nuv-md\nxq-wx\nsu-gu\noz-gq\nay-tr\nwv-sq\ncj-zd\nyw-ip\nnn-rt\npx-hr\njx-kb\nhy-pt\nkp-zf\nmd-wz\nvk-fy\nam-km\nry-dj\ngd-gs\ngk-oa\nru-gv\nej-sn\njx-mw\nwc-qt\nzk-tq\nnu-qk\nff-lr\nsb-wx\nut-pw\nmg-fp\nlc-uw\nqx-rq\nan-nc\nph-sn\nyg-cn\nwm-ny\nzb-mf\nuk-rg\nts-tw\npd-gs\noe-sa\nhk-yc\nkh-iq\nvl-vu\nlt-cr\nzo-kb\nja-af\nho-ni\njm-jv\nte-kp\nnc-xv\nai-xk\naj-jr\nql-fj\nfv-ae\ndn-jh\nvu-qc\ncq-cm\niq-ff\nhc-wc\nbc-tt\nut-cv\nqp-wc\ngq-vm\nil-bk\nth-zy\nub-gb\nbz-qy\nuk-du\nza-tj\nyh-ct\nao-fx\nvn-ze\nrc-bh\nhw-ts\nwm-xq\nds-tz\nog-il\nqw-vr\nky-vn\nxi-cc\nws-fq\nwz-zl\noz-im\nfh-gp\nmp-ke\nnf-jk\nwc-vh\nhy-qy\nco-cf\nuv-ra\nxp-me\nmz-yd\nub-ld\nfu-rc\nuz-gh\ngp-vl\nax-sp\nfw-nu\nsa-zm\nhr-bm\npk-lv\nok-ym\nyp-kd\nhb-sf\nfi-lu\nue-nk\ngq-ha\nex-bh\npk-jo\nqt-bm\nsx-rg\npl-hn\nua-nf\ncj-es\nql-nj\nrb-wm\nej-sx\nzz-rz\nmn-ai\njw-tc\nni-jx\nkz-vd\ncz-sm\nao-wx\nfu-on\nem-hj\nyr-en\npl-ju\nth-zr\nsq-vx\nzn-fl\nvx-dj\nba-zf\net-tr\ngp-vq\nlr-bz\nof-km\nkr-pz\nqe-dz\naa-cb\nvn-lh\nel-tp\nno-pr\num-ig\nei-oo\nci-ya\nue-zt\njk-ic\nln-wb\nco-wq\nsd-pj\ntq-cn\nzp-ar\nfo-yf\njv-pe\nsa-pd\nlr-ek\nco-aw\nbc-jf\nxv-nd\nmy-xu\ncc-jl\nbg-qa\nmd-yp\nrb-ir\nqv-ez\nxl-rg\nvr-mh\nvp-us\ntc-mq\nwc-np\npp-tz\nim-fk\niz-nc\npw-yh\nga-ql\nlu-vu\nzy-nk\nqo-fb\nuv-sl\nab-ol\nvh-qt\nml-wh\nek-ff\nhf-jt\nqy-yn\nqw-sj\nce-az\nfx-iq\nzr-nk\nlc-gv\ngo-iz\ndj-sq\nba-qk\nbd-fi\npw-ea\nli-cz\nmw-ho\nvv-lm\nts-cr\nkw-fd\ntt-qe\ngj-ub\nsd-gr\ngj-ay\nms-pa\njb-kq\ncj-pb\nvp-gl\nsf-yh\nho-ew\nwm-sl\nql-qj\nho-jx\noq-tt\nlg-gu\nqh-ku\nfl-ro\nys-mj\njn-gh\nlg-gr\nah-la\ntl-ns\ncz-kq\nzk-bn\nqx-zj\ntp-qx\ndw-ij\neb-yb\nsj-nt\njs-dn\nvt-qc\nhd-zo\nxq-hr\nzp-fo\nkr-qb\ncc-lx\npp-ik\nlq-rz\nyz-up\nae-ps\nfl-yk\nld-tl\nhe-yc\nch-ld\nsn-mz\nhx-ce\nfc-it\noh-nc\nqk-zf\npb-gu\nhe-tg\nfq-jt\nzl-zb\nvx-fm\nrk-gu\ncl-ft\nml-oz\nmy-wa\nre-ql\npj-fp\njj-yt\nqk-wo\nyz-vh\npb-es\noe-gd\nmt-ge\nxh-sa\nza-om\nmb-kd\nax-xw\ner-tl\nbz-hx\nsh-sl\nwx-hr\nmy-vj\nbc-jp\nfh-vl\nso-if\ngt-cw\nux-cj\nae-gx\nol-xh\njj-aw\nxm-ja\npi-ij\nfg-se\nib-bc\nnx-xe\nhj-vm\nxp-tj\njw-yp\nhl-sb\nqp-sh\nsx-mv\nex-hw\nty-pt\nap-rw\nad-zc\npa-og\nom-zh\nkc-ss\nze-lh\ngi-jh\nmp-mo\nwg-bu\nui-fi\nem-mp\nhm-vw\nhn-pc\nea-hv\nuy-ic\nzb-jl\ntz-dr\nou-es\nge-lk\nxm-lb\nsa-im\nzc-je\nnj-nu\nvm-mp\ngx-ps\nds-lb\nbm-la\now-tj\nbc-rz\nvj-cw\njp-if\nha-hz\nzn-yk\nuv-kd\nbc-zz\nlu-vq\nex-cw\ntd-am\nna-tx\nit-nk\ntf-gi\ncz-qk\nav-au\ntr-cp\nqs-ik\nhl-cx\nwt-mi\nun-er\nti-zl\ntl-wt\ncv-yh\nme-oa\nyr-bn\nap-jh\ngj-ld\nlw-in\nkn-fq\nys-dv\ndr-ja\nrk-do\nsx-uk\ntr-gj\nrg-kb\nam-yp\nrt-hs\nik-lb\ncn-bp\nwt-yi\nur-mw\ndf-sw\nee-xp\nyg-yb\nog-az\nme-jk\non-gv\nup-xt\ntp-yc\nfy-bt\nka-fi\nph-kb\njd-ms\njk-zx\ndq-hz\nky-ro\nyn-pt\nyy-sf\nou-zd\nrp-rg\nwx-uj\njb-fw\ntg-si\nfe-ea\noq-ib\nbj-ra\nur-lw\npx-cx\nwy-cl\nje-ms\njr-oy\nrg-ej\niq-ek\nxk-vy\njl-xi\nyp-te\ncq-bf\njd-gv\nfo-yb\nff-fx\npu-dv\nvn-kv\nom-tj\nom-wn\nxi-ti\nec-pm\nsm-fw\nrq-el\nch-gj\nmt-lk\ngj-gb\ntt-rz\nnx-lk\nni-ew\nwm-ir\nrs-pl\naw-mh\nmx-fg\njg-qw\nko-yb\njt-rj\nzm-pd\nun-wq\nvb-su\noq-yq\nmg-pj\npw-ct\nar-yb\nol-vv\nrk-go\nzi-zd\nkh-fx\nao-xq\nps-qo\nhk-qx\nna-mk\nzb-wz\nuj-ao\ntw-gt\nns-mi\nmh-oa\nvy-ec\nmu-bp\nbd-gp\nyf-pj\nyg-yq\nvg-zd\nts-sf\nqs-af\nrc-je\npa-ce\nuw-ru\nwz-ev\nxf-jx\nab-wf\nrk-gn\ngz-cq\nfa-ch\nof-ty\nvx-ry\nax-pp\niv-nx\nyi-hm\nps-uu\nfl-lh\nqe-jf\nfh-ka\ndf-wm\nfv-qo\nev-lx\nvw-er\ntl-ee\nvk-wo\nsg-rs\nhb-cv\ncp-bu\npk-yz\nsi-mk\nzm-tm\nus-fd\nlq-jp\nuj-px\ncc-mf\nro-xx\nvl-vq\nkm-wi\nny-wy\nzr-au\nfp-zp\nem-fd\nna-ac\nro-vn\njs-tf\nne-hv\ngo-yx\nub-cp\nir-sw\nfm-dj\ncr-bh\now-kr\nbf-cm\nce-og\njr-bf\npp-ja\nkh-bz\nqb-bi\nxt-vh\nve-lx\nfg-np\ndo-tx\nno-mq\nci-fy\nrq-mn\nzo-rg\ntz-ja\nis-rk\nvj-xu\nka-vt\nlp-na\nti-lx\nsi-he\nnk-pg\nik-xm\ndu-mv\ntg-mf\nrg-me\ngv-je\naj-ry\ndv-gz\nno-tc\nqo-jz\npr-gh\nhf-bj\nyt-dw\nii-eu\nfg-mc\nhl-st\ncz-wo\njv-xe\ndo-yx\nik-ax\nhd-mv\ndf-iy\npw-ym\nnz-hz\nus-mp\nwb-co\nst-ev\nxx-fl\nky-yk\nwl-pk\ncx-ao\nzg-qm\nrd-nf\nis-do\nwg-ch\nqj-ga\noz-ah\nim-pd\nxt-wc\nkr-za\npu-mk\nsv-qx\naw-nt\npg-el\ngq-zv\ncn-mu\nwf-wk\nqm-pz\nzv-oz\nbs-tk\ndj-oy\nsp-qs\nlw-ni\nyt-lp\nok-hb\nns-xp\nbu-ld\nwf-qz\nez-za\nzr-zy\new-jy\nfi-qc\nlg-es\nvb-gr\nkn-xx\nvh-wl\nqy-iq\nht-xx\nza-ow\nee-un\nju-jt\nxh-ss\nwa-gt\nra-yp\nwv-cq\nil-zk\ndf-ny\nfu-ms\nbz-ek\noj-pe\nti-jl\nab-kz\njz-eq\ncf-sj\nty-bz\nfb-hv\nlu-ka\nwg-tr\nsj-gi\npa-bk\nqa-nf\nmu-of\niv-xq\ndn-ku\nbt-or\npa-il\nvl-hw\njw-uz\nqy-qw\nzx-ef\njt-cb\nho-in\nlr-fx\nkb-xl\nsi-mt\ngv-zc\nom-ez\nze-xx\nmi-yi\nlj-vp\nnd-rk\nsd-ar\nlg-pb\nct-yy\nqw-nt\nne-jz\nxt-qt\njn-no\nua-oa\nbj-eu\ntk-jh\nai-yc\nky-kn\ncj-vg\nin-tz\nef-nf\ngq-oj\nla-ao\nej-xl\nbs-qh\ndn-zg\nsv-xk\nah-gq\nae-qo\nro-fz\nyq-wi\njx-lw\ndn-bs\nrw-qz\nmm-ue\nju-ws\nwv-gz\nko-sd\num-xo\njj-wb\nrt-rw\nxm-dr\nll-zp\nux-mu\nkw-mq\nsf-cv\nrz-jp\nwl-xt\nru-lc\nba-cz\npg-bo\nsl-ny\nwh-ci\ngz-vx\ncb-ju\nbp-ux\nuv-ii\nmk-ys\ngv-ms\nez-tj\nkp-ba\nvd-nn\nwu-tl\nxm-oe\nvq-ui\nig-ur\ntw-ex\nmr-jo\npi-ac\nqc-hm\nyc-mn\nva-ym\njm-oj\nin-ni\nnd-is\nnv-zk\nww-fp\nic-ef\nqc-rh\njn-uz\ndr-pp\nii-ki\nrh-vt\ntl-vj\nfw-kp\nqv-tj\nac-dv\nzf-fw\nhv-qo\ntd-bp\nrg-sn\nio-ki\nph-zo\nvp-em\nad-uw\nrh-wv\nzd-su\nhn-sg\nbn-ce\num-lw\noe-pd\nmy-cw\nlx-st\nvw-xw\nam-yq\nex-my\nmq-ql\ngb-tr\nof-bp\naf-ik\nwk-qz\nlv-yz\nhy-yn\nay-bu\nhe-nl\neb-pj\nnu-li\nhx-pa\nno-ql\nky-lh\naz-xx\nmd-te\nju-hn\nha-ah\nhf-hn\npc-pl\nko-eb\nuk-ru\nhz-jm\noq-jp\nig-in\nkw-ke\nds-af\nxv-oh\nae-fb\nld-fa\nij-mk\nim-zm\nxt-pk\nvt-lu\nsw-ny\naj-bf\nbo-zr\nre-no\nzp-kt\nrb-zv\nai-qx\ncn-am\nex-gt\net-ld\nct-ok\nfv-ne\ntf-pz\nvj-tw\nsd-yf\nhr-ao\nys-ij\nqm-bs\ncn-rm\nzj-jy\nmq-re\nor-ya\nzr-av\nut-yh\nvk-qq\nzb-dq\non-je\nro-yk\njs-bs\nso-bc\ntg-nl\ngv-dm\ncp-ld\nxk-qx\nte-ii\nqs-dr\nry-bf\nso-tt\npz-qh\ngh-re\nhk-sv\nbh-xu\nkd-eu\ntt-jp\npp-xm\nyz-mr\ngn-iz\nzp-yb\nlq-so\ngs-kc\nrs-aa\ndm-zc\nno-qj\nne-yj\nzj-um\nru-on\nmn-hk\nwf-rt\nyh-hb\naz-bk\nel-ec\nso-ib\nrw-vv\nok-fe\nci-bt\nws-ev\nkn-aj\nwh-mc\nrb-df\nry-cq\ncf-jj\ner-mi\nex-wa\nnk-ne\net-xd\nhl-oo\ndo-iz\nit-th\ncx-la\nun-ns\nku-gi\nkh-hy\nsx-kb\nzo-xl\now-xi\nol-wf\nuu-jz\nws-pc\num-mw\nwy-wm\ngp-lu\nqt-yz\ngu-ou\ntd-ux\nvv-wf\nvk-ci\nyr-bk\nux-am\nfm-jr\nvw-mi\nev-zl\nya-qq\nll-pj\nyd-mt\nlo-tg\njp-zz\nec-tp\nmq-uz\nim-gs\nhr-uj\nir-iy\njr-cq\ngh-ql\nzn-lh\nsn-du\njb-yi\nku-zg\nxu-ex\nmv-ce\njj-qw\nrq-yc\nvt-ui\nsp-af\npt-fx\ncj-vx\ngo-kj\nnc-rk\npz-js\nbj-ii\njr-gz\nbp-wi\nhr-oo\nrp-du\nmr-vh\nkr-ip\nol-nn\nlm-rt\ngl-hj\nun-yi\npe-jm\nvb-xo\niv-bm\ngi-ap\nnc-kj\nhl-iv\nwe-zv\nhr-sb\noj-oz\nzy-zt\nmy-hw\nxd-gj\nfu-uw\nxp-wu\nif-rz\nfq-rj\nne-gx\niv-px\nqa-bs\nqm-ku\nuj-bm\nhy-bz\nqz-nn\nbu-ub\nur-fu\nxd-ld\nhw-cw\ncj-lg\nmx-se\nau-zy\nic-gk\nmi-id\ntg-mz\nva-yy\nor-ii\nsh-iy\nwi-yg\nyp-bl\nyw-kr\ngx-yj\nlu-bd\nkp-qk\ntw-lt\njw-no\nfp-ar\nyu-sa\nph-hd\nhi-bz\ntx-pi\nll-ko\nsd-zp\nlh-kn\nyd-zy\nty-lr\nuw-jd\nsq-fm\nlo-mt\ngk-jk\ntm-yu\nol-hs\ngz-oy\ngb-ay\naa-pc\ncm-aj\niz-kj\nhs-nn\nqm-tk\nai-rq\nee-er\nwe-oz\nkq-jm\niy-ft\nif-zz\nag-lo\nxl-sn\nfl-kn\nwo-nj\ncz-fw\nbd-ui\nza-ff\nac-dw\nwi-cn\njb-ba\nwq-qw\nmh-cf\nib-if\nuu-ae\ngt-lt\noe-kc\nmc-ya\nkv-lh\nts-wa\nin-ol\npi-lp\nai-pm\nxx-ky\nco-dj\nvx-bf\nnv-pf\nsw-li\nuy-jk\nys-na\nlc-on\nze-fl\ngx-hv\nuv-io\npb-zd\nxu-cr\njr-vx\nes-vb\nzi-es\nig-jy\nyy-fe\nem-kw\nju-hf\njf-if\neq-kt\nhy-ek\nlw-ho\nlt-bh\nlc-is\nmo-us\nro-kn\nbl-kd\nnp-yz\nfu-je\nyt-ac\nif-bc\nyt-mj\nfw-qk\nnu-kp\nxx-vn\nse-ci\nmc-or\nmi-hm\nnd-go\njy-xf\nsq-gz\nan-is\nok-sf\nnk-au\nhi-ek\nec-ai\nab-qz\nnt-vr\nou-vb\nkt-fv\nlo-si\nwt-lr\noo-uj\njy-mw\nig-ni\nuk-kb\nph-xl\nno-gh\njo-xt\nmn-tp\nnc-do\nwe-jm\nhe-mz\ndq-jl\nlc-ad\nnt-ok\nnz-pe\ncv-ea\nga-jw\ngu-zd\njr-dj\nre-qj\nvx-cq\nkc-fk\nuy-rd\nfz-fl\nhj-ei\ncn-ej\nhx-en\nwx-oo\npb-gr\nux-tq\nhe-xe\npj-ar\nel-qx\ncf-nt\ntq-mu\ngk-me\non-rc\naa-hn\nab-vv\nsm-qk\nzl-xi\nbk-pf\nnz-ah\ndm-rc\ntd-wi\npu-ij\nus-hj\nxi-ev\nts-cw\nvu-fh\npl-ws\nhc-lv\nxl-rp\nsg-pc\nfy-se\nvp-mo\nfd-mp\nvj-lt\nqv-om\noy-ry\njo-cc\nbc-dz\npb-xo\nmo-kw\nhd-gr\nim-oe\nht-kv\ndw-jz\nhd-xl\nzx-ua\nbd-fh\nez-yw\nsa-ss\nhj-mo\nml-pe\nmz-nx\nmq-jn\nur-zj\nry-cm\nhi-ff\ngn-go\nfk-pd\nhy-fx\ntl-hm\nav-mm\nlk-ag\nwa-mc\nlm-rw\ncz-kp\nxq-px\nys-tx\nyg-td\ner-hm\nkv-yk\nys-lp\nex-lt\ndv-yt\nzc-vb\nbp-tq\nhi-fx\nva-pw\njw-ql\nga-re\nfz-yk\nmj-pi\nwk-vv\nvn-ht\nef-bg\ntt-tk\nlo-xe\nmf-ve\nkv-ro\nwy-sw\nsb-cx\nho-um\nlj-hj\nux-yq\ngd-fk\nfo-sd\nve-rq\nrz-qe\nzy-it\nmf-ev\nzj-jx\nte-eu\nql-tc\nbu-gj\nii-bl\nws-cb\nsv-pk\nqh-zn\nse-bt\nac-lp\nek-ty\nme-qa\nkq-sm\ngx-eq\ntw-cw\nqh-tf\ncw-wa\ntf-ap\nxe-mt\nap-pz\ngj-et\nzr-pg\nwu-yi\nqy-fx\nhe-ge\nyd-nx\nln-wq\nbl-io\nsl-rb\nvn-zn\npl-rj\nnt-mh\nru-jd\nnd-gn\nvl-ka\nyw-za\nlk-hn\nxe-mz\nxk-lq\nou-xo\nvb-vg\nqb-ip\ntt-if\noh-iz\nyd-xe\nke-em\nry-gz\nqj-tc\nhe-mt\nlm-vd\nyq-of\nbs-pz\nmh-ln\nne-fb\nxe-ge\nvy-pm\nnk-th\nzi-vg\nkr-tj\nnl-si\nmp-vp\ncx-hr\nym-hb\nid-un\njr-zh\nso-zz\nit-mm\nyg-am\nxk-mn\ndw-dv\nrh-vq\nmt-mz\nfl-kv\nvl-vt\nlc-je\naw-jg\nfg-qq\nso-qe\nmj-dw\nmv-zo\nla-wx\nsb-la\nes-su\nbg-ua\new-ig\nqm-ap\nqs-pp\nyw-eq\ncv-yy\nlw-jy\nmh-wb\nba-fw\nnj-qk\nrt-mu\nau-bo\nrj-hf\nhl-wx\nmi-xp\nte-ra\nmv-xl\nco-qw\njz-ps\nba-nj\nre-tc\nxe-nl\njg-nt\nzf-gj\nmf-xi\nqk-li\nex-vj\nfp-gd\nvd-hs\nuy-ua\ngu-cj\nxf-ur\nbp-am\nyy-hb\nlx-wz\ndq-ve\nvm-lj\niv-oo\nre-jw\nmp-gl\nhy-lr\nyk-xx\nzm-kc\npb-cw\nef-uy\nmp-ei\nap-ku\nbk-en\ncn-km\nfh-lu\nin-mw\ncv-vt\npm-tp\nhf-ws\nte-kd\ngl-kw\nlb-dr\nfh-vt\nub-tr\nxp-wt\ncn-yq\nvx-aj\nfe-yh\nmy-gt\nyu-gs\nwh-mx\nmc-ci\nnf-oa\nni-zj\nyh-ea\nap-dn\njb-li\nzd-es\ntt-ib\nhm-wt\naw-ou\nnd-kj\nei-mo\ndz-if\nll-yf\nxv-is\nee-mi\nnn-ab\nnj-kq\nwb-jg\noo-sb\nqk-kq\nfm-oy\nnn-wk\nog-en\nbt-be\ndf-sl\neu-io\nbg-oa\nlv-up\nai-el\nbj-io\nvw-ee\nlb-hb\noo-px\ngo-nv\ncm-wv\nfv-lu\ngs-sa\ntj-ip\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_23_questions.txt",
    "content": "--- Day 23: LAN Party ---\n\nAs The Historians wander around a secure area at Easter Bunny HQ, you come across posters for a LAN party scheduled for today! Maybe you can find it; you connect to a nearby datalink port and download a map of the local network (your puzzle input).\n\nThe network map provides a list of every connection between two computers. For example:\n\nkh-tc\nqp-kh\nde-cg\nka-co\nyn-aq\nqp-ub\ncg-tb\nvc-aq\ntb-ka\nwh-tc\nyn-cg\nkh-ub\nta-co\nde-co\ntc-td\ntb-wq\nwh-td\nta-ka\ntd-qp\naq-cg\nwq-ub\nub-vc\nde-ta\nwq-aq\nwq-vc\nwh-yn\nka-de\nkh-ta\nco-tc\nwh-qp\ntb-vc\ntd-yn\n\nEach line of text in the network map represents a single connection; the line kh-tc represents a connection between the computer named kh and the computer named tc. Connections aren't directional; tc-kh would mean exactly the same thing.\n\nLAN parties typically involve multiplayer games, so maybe you can locate it by finding groups of connected computers. Start by looking for sets of three computers where each computer in the set is connected to the other two computers.\n\nIn this example, there are 12 such sets of three inter-connected computers:\n\naq,cg,yn\naq,vc,wq\nco,de,ka\nco,de,ta\nco,ka,ta\nde,ka,ta\nkh,qp,ub\nqp,td,wh\ntb,vc,wq\ntc,td,wh\ntd,wh,yn\nub,vc,wq\n\nIf the Chief Historian is here, and he's at the LAN party, it would be best to know that right away. You're pretty sure his computer's name starts with t, so consider only sets of three computers where at least one computer's name starts with t. That narrows the list down to 7 sets of three inter-connected computers:\n\nco,de,ta\nco,ka,ta\nde,ka,ta\nqp,td,wh\ntb,vc,wq\ntc,td,wh\ntd,wh,yn\n\nFind all the sets of three inter-connected computers. How many contain at least one computer with a name that starts with t?\n\n--- Part Two ---\n\nThere are still way too many results to go through them all. You'll have to find the LAN party another way and go there yourself.\n\nSince it doesn't seem like any employees are around, you figure they must all be at the LAN party. If that's true, the LAN party will be the largest set of computers that are all connected to each other. That is, for each computer at the LAN party, that computer will have a connection to every other computer at the LAN party.\n\nIn the above example, the largest set of computers that are all connected to each other is made up of co, de, ka, and ta. Each computer in this set has a connection to every other computer in the set:\n\nka-co\nta-co\nde-co\nta-ka\nde-ta\nka-de\n\nThe LAN party posters say that the password to get into the LAN party is the name of every computer at the LAN party, sorted alphabetically, then joined together with commas. (The people running the LAN party are clearly a bunch of nerds.) In this example, the password would be co,de,ka,ta.\n\nWhat is the password to get into the LAN party?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_24.adb",
    "content": "--  Solution to Advent of Code 2024, Day 24\n-------------------------------------------\n--  Crossed Wires\n--\n--  https://adventofcode.com/2024/day/24\n--  Copy of questions in: aoc_2024_24_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2024_24 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  r : array (Part_Type) of VString;\n\n  procedure Do_Part_1 is\n    --  Example:\n    --\n    --  x00: constant Boolean := true;\n    --  x01: constant Boolean := false;\n    --  x02: constant Boolean := true;\n    --  x03: constant Boolean := true;\n    --  x04: constant Boolean := false;\n    --  y00: constant Boolean := true;\n    --  y01: constant Boolean := true;\n    --  y02: constant Boolean := true;\n    --  y03: constant Boolean := true;\n    --  y04: constant Boolean := true;\n    --\n    --  djm : constant Boolean := y00 and y03;\n    --  ffh : constant Boolean := x03 xor y03;\n    --  fgs : constant Boolean := y04 or  y02;\n    --  kjc : constant Boolean := x04 and y00;\n    --  nrd : constant Boolean := y03 or  x01;\n    --  ntg : constant Boolean := x00 xor y04;\n    --  pbm : constant Boolean := y01 and x02;\n    --  psh : constant Boolean := y03 or  y00;\n    --  tnw : constant Boolean := y02 or  x01;\n    --  vdt : constant Boolean := x03 or  x00;\n    --  fst : constant Boolean := x00 or  x03;\n    --\n    --  bfw : constant Boolean := vdt or  tnw;\n    --  bqk : constant Boolean := ffh or  nrd;\n    --  frj : constant Boolean := tnw or  fst;\n    --  gnj : constant Boolean := tnw or  pbm;\n    --  hwm : constant Boolean := nrd and vdt;\n    --  kpj : constant Boolean := pbm or  djm;\n    --  kwq : constant Boolean := ntg or  kjc;\n    --  mjb : constant Boolean := ntg xor fgs;\n    --  qhw : constant Boolean := djm or  pbm;\n    --  rvg : constant Boolean := kjc and fst;\n    --  tgd : constant Boolean := psh xor fgs;\n    --  wpb : constant Boolean := nrd xor fgs;\n    --\n    --  z00 : constant Boolean := bfw xor mjb;\n    --  z01 : constant Boolean := tgd xor rvg;\n    --  z02 : constant Boolean := gnj and wpb;\n    --  z03 : constant Boolean := hwm and bqk;\n    --  z04 : constant Boolean := frj xor qhw;\n    --  z05 : constant Boolean := kwq or  kpj;\n    --  z06 : constant Boolean := bfw or  bqk;\n    --  z07 : constant Boolean := bqk or  frj;\n    --  z08 : constant Boolean := bqk or  frj;\n    --  z09 : constant Boolean := qhw xor tgd;\n    --  z10 : constant Boolean := bfw and frj;\n    --  z11 : constant Boolean := gnj and tgd;\n    --  z12 : constant Boolean := tgd xor rvg;\n\n    ------\n\n    x00 : constant Boolean := True;\n    x01 : constant Boolean := True;\n    x02 : constant Boolean := False;\n    x03 : constant Boolean := False;\n    x04 : constant Boolean := False;\n    x05 : constant Boolean := True;\n    x06 : constant Boolean := False;\n    x07 : constant Boolean := True;\n    x08 : constant Boolean := True;\n    x09 : constant Boolean := False;\n    x10 : constant Boolean := True;\n    x11 : constant Boolean := False;\n    x12 : constant Boolean := False;\n    x13 : constant Boolean := True;\n    x14 : constant Boolean := False;\n    x15 : constant Boolean := True;\n    x16 : constant Boolean := False;\n    x17 : constant Boolean := True;\n    x18 : constant Boolean := True;\n    x19 : constant Boolean := True;\n    x20 : constant Boolean := True;\n    x21 : constant Boolean := False;\n    x22 : constant Boolean := False;\n    x23 : constant Boolean := True;\n    x24 : constant Boolean := True;\n    x25 : constant Boolean := False;\n    x26 : constant Boolean := False;\n    x27 : constant Boolean := True;\n    x28 : constant Boolean := True;\n    x29 : constant Boolean := True;\n    x30 : constant Boolean := True;\n    x31 : constant Boolean := False;\n    x32 : constant Boolean := False;\n    x33 : constant Boolean := True;\n    x34 : constant Boolean := False;\n    x35 : constant Boolean := True;\n    x36 : constant Boolean := False;\n    x37 : constant Boolean := True;\n    x38 : constant Boolean := False;\n    x39 : constant Boolean := False;\n    x40 : constant Boolean := True;\n    x41 : constant Boolean := True;\n    x42 : constant Boolean := False;\n    x43 : constant Boolean := True;\n    x44 : constant Boolean := True;\n    y00 : constant Boolean := True;\n    y01 : constant Boolean := False;\n    y02 : constant Boolean := True;\n    y03 : constant Boolean := True;\n    y04 : constant Boolean := False;\n    y05 : constant Boolean := False;\n    y06 : constant Boolean := True;\n    y07 : constant Boolean := True;\n    y08 : constant Boolean := False;\n    y09 : constant Boolean := True;\n    y10 : constant Boolean := True;\n    y11 : constant Boolean := True;\n    y12 : constant Boolean := True;\n    y13 : constant Boolean := True;\n    y14 : constant Boolean := False;\n    y15 : constant Boolean := True;\n    y16 : constant Boolean := True;\n    y17 : constant Boolean := False;\n    y18 : constant Boolean := True;\n    y19 : constant Boolean := False;\n    y20 : constant Boolean := False;\n    y21 : constant Boolean := True;\n    y22 : constant Boolean := True;\n    y23 : constant Boolean := True;\n    y24 : constant Boolean := True;\n    y25 : constant Boolean := False;\n    y26 : constant Boolean := True;\n    y27 : constant Boolean := False;\n    y28 : constant Boolean := False;\n    y29 : constant Boolean := True;\n    y30 : constant Boolean := True;\n    y31 : constant Boolean := True;\n    y32 : constant Boolean := True;\n    y33 : constant Boolean := True;\n    y34 : constant Boolean := False;\n    y35 : constant Boolean := True;\n    y36 : constant Boolean := False;\n    y37 : constant Boolean := True;\n    y38 : constant Boolean := True;\n    y39 : constant Boolean := False;\n    y40 : constant Boolean := False;\n    y41 : constant Boolean := False;\n    y42 : constant Boolean := False;\n    y43 : constant Boolean := True;\n    y44 : constant Boolean := True;\n\n    cvk : constant Boolean := y44 and x44;\n    qjp : constant Boolean := y42 and x42;\n    kfp : constant Boolean := y41 and x41;\n    qhf : constant Boolean := y40 and x40;\n    nbc : constant Boolean := y37 and x37;\n    prn : constant Boolean := y35 xor x35;\n    qph : constant Boolean := y35 and x35;\n    rkq : constant Boolean := y34 and x34;\n    pmg : constant Boolean := y33 xor x33;\n    wrd : constant Boolean := y32 xor x32;\n    tkw : constant Boolean := y31 xor x31;\n    gpp : constant Boolean := y31 and x31;\n    rvc : constant Boolean := y30 and x30;\n    qgc : constant Boolean := y30 xor x30;\n    qrw : constant Boolean := y27 xor x27;\n    fjr : constant Boolean := y27 and x27;\n    jkt : constant Boolean := y26 xor x26;\n    dbt : constant Boolean := y25 and x25;\n    kdn : constant Boolean := y24 xor x24;\n    nrw : constant Boolean := y23 and x23;\n    sbs : constant Boolean := y21 xor x21;\n    vwh : constant Boolean := y20 and x20;\n    gpq : constant Boolean := y18 and x18;\n    jbp : constant Boolean := y18 xor x18;\n    fhn : constant Boolean := y16 and x16;\n    vch : constant Boolean := y15 and x15;\n    pvj : constant Boolean := y15 xor x15;\n    tfh : constant Boolean := y14 xor x14;\n    wbw : constant Boolean := y13 and x13;\n    wgb : constant Boolean := y13 xor x13;\n    bcw : constant Boolean := y10 and x10;\n    qpg : constant Boolean := y08 and x08;\n    vjc : constant Boolean := y07 and x07;\n    gjv : constant Boolean := y07 xor x07;\n    knd : constant Boolean := y06 and x06;\n    sfn : constant Boolean := y05 xor x05;\n    dtn : constant Boolean := y04 and x04;\n    ptv : constant Boolean := y04 xor x04;\n    rtt : constant Boolean := y03 and x03;\n    qpd : constant Boolean := y02 xor x02;\n    tng : constant Boolean := y02 and x02;\n    jrb : constant Boolean := x44 xor y44;\n    bmf : constant Boolean := x43 and y43;\n    nsb : constant Boolean := x43 xor y43;\n    sbn : constant Boolean := x42 xor y42;\n    krk : constant Boolean := x41 xor y41;\n    qwt : constant Boolean := x40 xor y40;\n    ksf : constant Boolean := x39 xor y39;\n    z39 : constant Boolean := x39 and y39;\n    spg : constant Boolean := x38 xor y38;\n    crp : constant Boolean := x38 and y38;\n    vjg : constant Boolean := x37 xor y37;\n    pfc : constant Boolean := x36 and y36;\n    dkj : constant Boolean := x36 xor y36;\n    bgg : constant Boolean := x34 xor y34;\n    hbn : constant Boolean := x33 and y33;\n    ttt : constant Boolean := x32 and y32;\n    bqn : constant Boolean := x29 and y29;\n    wtw : constant Boolean := x29 xor y29;\n    shp : constant Boolean := x28 and y28;\n    rtb : constant Boolean := x28 xor y28;\n    jck : constant Boolean := x26 and y26;\n    nfm : constant Boolean := x25 xor y25;\n    frv : constant Boolean := x24 and y24;\n    gcj : constant Boolean := x23 xor y23;\n    qgd : constant Boolean := x22 xor y22;\n    dpg : constant Boolean := x22 and y22;\n    knb : constant Boolean := x21 and y21;\n    vdc : constant Boolean := x20 xor y20;\n    mcv : constant Boolean := x19 xor y19;\n    hhb : constant Boolean := x19 and y19;\n    tdb : constant Boolean := x17 xor y17;\n    fpk : constant Boolean := x17 and y17;\n    vgb : constant Boolean := x16 xor y16;\n    ktg : constant Boolean := x14 and y14;\n    htr : constant Boolean := x12 xor y12;\n    njd : constant Boolean := x12 and y12;\n    cbm : constant Boolean := x11 and y11;\n    ksb : constant Boolean := x11 xor y11;\n    cvv : constant Boolean := x10 xor y10;\n    mnm : constant Boolean := x09 xor y09;\n    ptc : constant Boolean := x09 and y09;\n    jhr : constant Boolean := x08 xor y08;\n    hsn : constant Boolean := x06 xor y06;\n    fkt : constant Boolean := x05 and y05;\n    npk : constant Boolean := x03 xor y03;\n    sqk : constant Boolean := x01 xor y01;\n    hnj : constant Boolean := x01 and y01;\n    z00 : constant Boolean := x00 xor y00;\n    jcq : constant Boolean := x00 and y00;\n\n    bmc : constant Boolean := sqk and jcq;\n    kpf : constant Boolean := hnj or bmc;\n    pwk : constant Boolean := kpf and qpd;\n    tpv : constant Boolean := tng or pwk;\n    hrr : constant Boolean := tpv and npk;\n\n    bdk : constant Boolean := hrr or rtt;\n\n    nnq : constant Boolean := ptv and bdk;\n    svk : constant Boolean := dtn or nnq;\n    wnq : constant Boolean := sfn and svk;\n    cjh : constant Boolean := fkt or wnq;\n    hds : constant Boolean := cjh and hsn;\n    wcs : constant Boolean := knd or hds;\n    nbb : constant Boolean := gjv and wcs;\n    bwm : constant Boolean := nbb or vjc;\n    tvw : constant Boolean := bwm and jhr;\n    gqb : constant Boolean := tvw or qpg;\n    gwh : constant Boolean := mnm xor gqb;\n    pgn : constant Boolean := gwh and cvv;\n    jbk : constant Boolean := bcw or pgn;\n    hgb : constant Boolean := ksb and jbk;\n    jgf : constant Boolean := cbm or hgb;\n    dmc : constant Boolean := jgf and htr;\n    qwr : constant Boolean := dmc or njd;\n    dqm : constant Boolean := wbw and qwr;\n    nkd : constant Boolean := dqm or wgb;\n    jrd : constant Boolean := tfh and nkd;\n    bgh : constant Boolean := jrd or ktg;\n\n    vcd : constant Boolean := bgh and pvj;\n    nhh : constant Boolean := vcd or vch;\n    btr : constant Boolean := vgb and nhh;\n    ctv : constant Boolean := btr or fhn;\n    ffh : constant Boolean := tdb and ctv;\n    wtc : constant Boolean := fpk or ffh;\n    pfh : constant Boolean := jbp and wtc;\n    ppf : constant Boolean := pfh or gpq;\n    gvt : constant Boolean := ppf and mcv;\n    tjc : constant Boolean := gvt or hhb;\n    vvc : constant Boolean := vdc and tjc;\n    kgk : constant Boolean := vwh or vvc;\n    rcb : constant Boolean := kgk xor sbs;\n    tvj : constant Boolean := rcb or knb;\n    vsb : constant Boolean := qgd and tvj;\n    grk : constant Boolean := dpg or vsb;\n    cdw : constant Boolean := gcj and grk;\n    pbv : constant Boolean := nrw or cdw;\n    mhd : constant Boolean := kdn and pbv;\n    vsw : constant Boolean := frv or mhd;\n    dfq : constant Boolean := nfm and vsw;\n    kgs : constant Boolean := dfq or dbt;\n    wtd : constant Boolean := kgs and jkt;\n    mjf : constant Boolean := jck or wtd;\n    jgh : constant Boolean := mjf and qrw;\n    whc : constant Boolean := fjr or jgh;\n    jsf : constant Boolean := rtb and whc;\n    vmj : constant Boolean := jsf or shp;\n    nbw : constant Boolean := vmj and wtw;\n    bqb : constant Boolean := nbw or bqn;\n    nth : constant Boolean := qgc and bqb;\n    mwg : constant Boolean := nth or rvc;\n    vmq : constant Boolean := tkw and mwg;\n    mrg : constant Boolean := gpp or vmq;\n    vcm : constant Boolean := mrg and wrd;\n    rnc : constant Boolean := vcm or ttt;\n    dmp : constant Boolean := pmg and rnc;\n    kvw : constant Boolean := hbn or dmp;\n    gwm : constant Boolean := kvw and bgg;\n    bhd : constant Boolean := rkq or gwm;\n\n    drv : constant Boolean := prn and bhd;\n    dmj : constant Boolean := drv or qph;\n    vnw : constant Boolean := dmj and dkj;\n    jgc : constant Boolean := pfc or vnw;\n    mqh : constant Boolean := vjg and jgc;\n    bwb : constant Boolean := nbc or mqh;\n\n    wjg : constant Boolean := spg and bwb;\n    wjf : constant Boolean := crp or wjg;\n    hvf : constant Boolean := ksf and wjf;\n    jct : constant Boolean := wjf xor ksf;\n    nhk : constant Boolean := jct or hvf;\n    qwh : constant Boolean := nhk and qwt;\n    sgk : constant Boolean := qhf or qwh;\n    qvv : constant Boolean := sgk and krk;\n    pwt : constant Boolean := kfp or qvv;\n    qwg : constant Boolean := sbn and pwt;\n    gdt : constant Boolean := qwg or qjp;\n    dnc : constant Boolean := nsb and gdt;\n\n    dsk : constant Boolean := gqb and mnm;\n    tdh : constant Boolean := dnc or bmf;\n    pjg : constant Boolean := jrb and tdh;\n\n    z01 : constant Boolean := jcq xor sqk;\n    z02 : constant Boolean := kpf xor qpd;\n    z03 : constant Boolean := tpv xor npk;\n    z04 : constant Boolean := ptv xor bdk;\n    z05 : constant Boolean := svk xor sfn;\n    z06 : constant Boolean := cjh xor hsn;\n    z07 : constant Boolean := wcs xor gjv;\n    z08 : constant Boolean := bwm xor jhr;\n    z09 : constant Boolean := dsk or ptc;\n    z10 : constant Boolean := cvv xor gwh;\n    z11 : constant Boolean := ksb xor jbk;\n    z12 : constant Boolean := htr xor jgf;\n    z13 : constant Boolean := qwr xor wbw;\n    z14 : constant Boolean := nkd xor tfh;\n    z15 : constant Boolean := bgh xor pvj;\n    z16 : constant Boolean := nhh xor vgb;\n    z17 : constant Boolean := ctv xor tdb;\n    z18 : constant Boolean := wtc xor jbp;\n    z19 : constant Boolean := mcv xor ppf;\n    z20 : constant Boolean := vdc xor tjc;\n    z21 : constant Boolean := kgk and sbs;\n    z22 : constant Boolean := qgd xor tvj;\n    z23 : constant Boolean := grk xor gcj;\n    z24 : constant Boolean := kdn xor pbv;\n    z25 : constant Boolean := nfm xor vsw;\n    z26 : constant Boolean := jkt xor kgs;\n    z27 : constant Boolean := qrw xor mjf;\n    z28 : constant Boolean := rtb xor whc;\n    z29 : constant Boolean := wtw xor vmj;\n    z30 : constant Boolean := bqb xor qgc;\n    z31 : constant Boolean := mwg xor tkw;\n    z32 : constant Boolean := mrg xor wrd;\n    z33 : constant Boolean := pmg xor rnc;\n    z34 : constant Boolean := bgg xor kvw;\n    z35 : constant Boolean := bhd xor prn;\n    z36 : constant Boolean := dkj xor dmj;\n    z37 : constant Boolean := vjg xor jgc;\n    z38 : constant Boolean := spg xor bwb;\n    z40 : constant Boolean := qwt xor nhk;\n    z41 : constant Boolean := sgk xor krk;\n    z42 : constant Boolean := pwt xor sbn;\n    z43 : constant Boolean := gdt xor nsb;\n    z44 : constant Boolean := tdh xor jrb;\n    z45 : constant Boolean := pjg or cvk;\n\n    z : constant Integer_64 :=\n      Boolean'Pos (z00) * 2 ** 0 +\n      Boolean'Pos (z01) * 2 ** 1 +\n      Boolean'Pos (z02) * 2 ** 2 +\n      Boolean'Pos (z03) * 2 ** 3 +\n      Boolean'Pos (z04) * 2 ** 4 +\n      Boolean'Pos (z05) * 2 ** 5 +\n      Boolean'Pos (z06) * 2 ** 6 +\n      Boolean'Pos (z07) * 2 ** 7 +\n      Boolean'Pos (z08) * 2 ** 8 +\n      Boolean'Pos (z09) * 2 ** 9 +\n      Boolean'Pos (z10) * 2 ** 10 +\n      Boolean'Pos (z11) * 2 ** 11 +\n      Boolean'Pos (z12) * 2 ** 12 +\n      Boolean'Pos (z13) * 2 ** 13 +\n      Boolean'Pos (z14) * 2 ** 14 +\n      Boolean'Pos (z15) * 2 ** 15 +\n      Boolean'Pos (z16) * 2 ** 16 +\n      Boolean'Pos (z17) * 2 ** 17 +\n      Boolean'Pos (z18) * 2 ** 18 +\n      Boolean'Pos (z19) * 2 ** 19 +\n      Boolean'Pos (z20) * 2 ** 20 +\n      Boolean'Pos (z21) * 2 ** 21 +\n      Boolean'Pos (z22) * 2 ** 22 +\n      Boolean'Pos (z23) * 2 ** 23 +\n      Boolean'Pos (z24) * 2 ** 24 +\n      Boolean'Pos (z25) * 2 ** 25 +\n      Boolean'Pos (z26) * 2 ** 26 +\n      Boolean'Pos (z27) * 2 ** 27 +\n      Boolean'Pos (z28) * 2 ** 28 +\n      Boolean'Pos (z29) * 2 ** 29 +\n      Boolean'Pos (z30) * 2 ** 30 +\n      Boolean'Pos (z31) * 2 ** 31 +\n      Boolean'Pos (z32) * 2 ** 32 +\n      Boolean'Pos (z33) * 2 ** 33 +\n      Boolean'Pos (z34) * 2 ** 34 +\n      Boolean'Pos (z35) * 2 ** 35 +\n      Boolean'Pos (z36) * 2 ** 36 +\n      Boolean'Pos (z37) * 2 ** 37 +\n      Boolean'Pos (z38) * 2 ** 38 +\n      Boolean'Pos (z39) * 2 ** 39 +\n      Boolean'Pos (z40) * 2 ** 40 +\n      Boolean'Pos (z41) * 2 ** 41 +\n      Boolean'Pos (z42) * 2 ** 42 +\n      Boolean'Pos (z43) * 2 ** 43 +\n      Boolean'Pos (z44) * 2 ** 44 +\n      Boolean'Pos (z45) * 2 ** 45;\n  begin\n    r (part_1) := Trim_Left (+z'Image);\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n\n    function Add (x, y : Integer_64) return Integer_64 is\n\n      x00 : constant Boolean := Boolean'Val ((x / (2 ** 0)) mod 2);\n      x01 : constant Boolean := Boolean'Val ((x / (2 ** 1)) mod 2);\n      x02 : constant Boolean := Boolean'Val ((x / (2 ** 2)) mod 2);\n      x03 : constant Boolean := Boolean'Val ((x / (2 ** 3)) mod 2);\n      x04 : constant Boolean := Boolean'Val ((x / (2 ** 4)) mod 2);\n      x05 : constant Boolean := Boolean'Val ((x / (2 ** 5)) mod 2);\n      x06 : constant Boolean := Boolean'Val ((x / (2 ** 6)) mod 2);\n      x07 : constant Boolean := Boolean'Val ((x / (2 ** 7)) mod 2);\n      x08 : constant Boolean := Boolean'Val ((x / (2 ** 8)) mod 2);\n      x09 : constant Boolean := Boolean'Val ((x / (2 ** 9)) mod 2);\n      x10 : constant Boolean := Boolean'Val ((x / (2 ** 10)) mod 2);\n      x11 : constant Boolean := Boolean'Val ((x / (2 ** 11)) mod 2);\n      x12 : constant Boolean := Boolean'Val ((x / (2 ** 12)) mod 2);\n      x13 : constant Boolean := Boolean'Val ((x / (2 ** 13)) mod 2);\n      x14 : constant Boolean := Boolean'Val ((x / (2 ** 14)) mod 2);\n      x15 : constant Boolean := Boolean'Val ((x / (2 ** 15)) mod 2);\n      x16 : constant Boolean := Boolean'Val ((x / (2 ** 16)) mod 2);\n      x17 : constant Boolean := Boolean'Val ((x / (2 ** 17)) mod 2);\n      x18 : constant Boolean := Boolean'Val ((x / (2 ** 18)) mod 2);\n      x19 : constant Boolean := Boolean'Val ((x / (2 ** 19)) mod 2);\n      x20 : constant Boolean := Boolean'Val ((x / (2 ** 20)) mod 2);\n      x21 : constant Boolean := Boolean'Val ((x / (2 ** 21)) mod 2);\n      x22 : constant Boolean := Boolean'Val ((x / (2 ** 22)) mod 2);\n      x23 : constant Boolean := Boolean'Val ((x / (2 ** 23)) mod 2);\n      x24 : constant Boolean := Boolean'Val ((x / (2 ** 24)) mod 2);\n      x25 : constant Boolean := Boolean'Val ((x / (2 ** 25)) mod 2);\n      x26 : constant Boolean := Boolean'Val ((x / (2 ** 26)) mod 2);\n      x27 : constant Boolean := Boolean'Val ((x / (2 ** 27)) mod 2);\n      x28 : constant Boolean := Boolean'Val ((x / (2 ** 28)) mod 2);\n      x29 : constant Boolean := Boolean'Val ((x / (2 ** 29)) mod 2);\n      x30 : constant Boolean := Boolean'Val ((x / (2 ** 30)) mod 2);\n      x31 : constant Boolean := Boolean'Val ((x / (2 ** 31)) mod 2);\n      x32 : constant Boolean := Boolean'Val ((x / (2 ** 32)) mod 2);\n      x33 : constant Boolean := Boolean'Val ((x / (2 ** 33)) mod 2);\n      x34 : constant Boolean := Boolean'Val ((x / (2 ** 34)) mod 2);\n      x35 : constant Boolean := Boolean'Val ((x / (2 ** 35)) mod 2);\n      x36 : constant Boolean := Boolean'Val ((x / (2 ** 36)) mod 2);\n      x37 : constant Boolean := Boolean'Val ((x / (2 ** 37)) mod 2);\n      x38 : constant Boolean := Boolean'Val ((x / (2 ** 38)) mod 2);\n      x39 : constant Boolean := Boolean'Val ((x / (2 ** 39)) mod 2);\n      x40 : constant Boolean := Boolean'Val ((x / (2 ** 40)) mod 2);\n      x41 : constant Boolean := Boolean'Val ((x / (2 ** 41)) mod 2);\n      x42 : constant Boolean := Boolean'Val ((x / (2 ** 42)) mod 2);\n      x43 : constant Boolean := Boolean'Val ((x / (2 ** 43)) mod 2);\n      x44 : constant Boolean := Boolean'Val ((x / (2 ** 44)) mod 2);\n\n      y00 : constant Boolean := Boolean'Val ((y / (2 ** 0)) mod 2);\n      y01 : constant Boolean := Boolean'Val ((y / (2 ** 1)) mod 2);\n      y02 : constant Boolean := Boolean'Val ((y / (2 ** 2)) mod 2);\n      y03 : constant Boolean := Boolean'Val ((y / (2 ** 3)) mod 2);\n      y04 : constant Boolean := Boolean'Val ((y / (2 ** 4)) mod 2);\n      y05 : constant Boolean := Boolean'Val ((y / (2 ** 5)) mod 2);\n      y06 : constant Boolean := Boolean'Val ((y / (2 ** 6)) mod 2);\n      y07 : constant Boolean := Boolean'Val ((y / (2 ** 7)) mod 2);\n      y08 : constant Boolean := Boolean'Val ((y / (2 ** 8)) mod 2);\n      y09 : constant Boolean := Boolean'Val ((y / (2 ** 9)) mod 2);\n      y10 : constant Boolean := Boolean'Val ((y / (2 ** 10)) mod 2);\n      y11 : constant Boolean := Boolean'Val ((y / (2 ** 11)) mod 2);\n      y12 : constant Boolean := Boolean'Val ((y / (2 ** 12)) mod 2);\n      y13 : constant Boolean := Boolean'Val ((y / (2 ** 13)) mod 2);\n      y14 : constant Boolean := Boolean'Val ((y / (2 ** 14)) mod 2);\n      y15 : constant Boolean := Boolean'Val ((y / (2 ** 15)) mod 2);\n      y16 : constant Boolean := Boolean'Val ((y / (2 ** 16)) mod 2);\n      y17 : constant Boolean := Boolean'Val ((y / (2 ** 17)) mod 2);\n      y18 : constant Boolean := Boolean'Val ((y / (2 ** 18)) mod 2);\n      y19 : constant Boolean := Boolean'Val ((y / (2 ** 19)) mod 2);\n      y20 : constant Boolean := Boolean'Val ((y / (2 ** 20)) mod 2);\n      y21 : constant Boolean := Boolean'Val ((y / (2 ** 21)) mod 2);\n      y22 : constant Boolean := Boolean'Val ((y / (2 ** 22)) mod 2);\n      y23 : constant Boolean := Boolean'Val ((y / (2 ** 23)) mod 2);\n      y24 : constant Boolean := Boolean'Val ((y / (2 ** 24)) mod 2);\n      y25 : constant Boolean := Boolean'Val ((y / (2 ** 25)) mod 2);\n      y26 : constant Boolean := Boolean'Val ((y / (2 ** 26)) mod 2);\n      y27 : constant Boolean := Boolean'Val ((y / (2 ** 27)) mod 2);\n      y28 : constant Boolean := Boolean'Val ((y / (2 ** 28)) mod 2);\n      y29 : constant Boolean := Boolean'Val ((y / (2 ** 29)) mod 2);\n      y30 : constant Boolean := Boolean'Val ((y / (2 ** 30)) mod 2);\n      y31 : constant Boolean := Boolean'Val ((y / (2 ** 31)) mod 2);\n      y32 : constant Boolean := Boolean'Val ((y / (2 ** 32)) mod 2);\n      y33 : constant Boolean := Boolean'Val ((y / (2 ** 33)) mod 2);\n      y34 : constant Boolean := Boolean'Val ((y / (2 ** 34)) mod 2);\n      y35 : constant Boolean := Boolean'Val ((y / (2 ** 35)) mod 2);\n      y36 : constant Boolean := Boolean'Val ((y / (2 ** 36)) mod 2);\n      y37 : constant Boolean := Boolean'Val ((y / (2 ** 37)) mod 2);\n      y38 : constant Boolean := Boolean'Val ((y / (2 ** 38)) mod 2);\n      y39 : constant Boolean := Boolean'Val ((y / (2 ** 39)) mod 2);\n      y40 : constant Boolean := Boolean'Val ((y / (2 ** 40)) mod 2);\n      y41 : constant Boolean := Boolean'Val ((y / (2 ** 41)) mod 2);\n      y42 : constant Boolean := Boolean'Val ((y / (2 ** 42)) mod 2);\n      y43 : constant Boolean := Boolean'Val ((y / (2 ** 43)) mod 2);\n      y44 : constant Boolean := Boolean'Val ((y / (2 ** 44)) mod 2);\n\n      --  Half-Adder 1: Carry\n\n      cvk : constant Boolean := y44 and x44;\n      bmf : constant Boolean := x43 and y43;\n      qjp : constant Boolean := y42 and x42;\n      kfp : constant Boolean := y41 and x41;\n      c40_1_qhf : constant Boolean := y40 and x40;\n\n      c38_1_crp : constant Boolean := x38 and y38;\n      c37_1_nbc : constant Boolean := y37 and x37;\n      pfc : constant Boolean := x36 and y36;\n      qph : constant Boolean := y35 and x35;\n      rkq : constant Boolean := y34 and x34;\n      hbn : constant Boolean := x33 and y33;\n      ttt : constant Boolean := x32 and y32;\n      gpp : constant Boolean := y31 and x31;\n      rvc : constant Boolean := y30 and x30;\n      bqn : constant Boolean := x29 and y29;\n      shp : constant Boolean := x28 and y28;\n      fjr : constant Boolean := y27 and x27;\n      jck : constant Boolean := x26 and y26;\n      dbt : constant Boolean := y25 and x25;\n      frv : constant Boolean := x24 and y24;\n      nrw : constant Boolean := y23 and x23;\n      dpg : constant Boolean := x22 and y22;\n      c21_1_knb : constant Boolean := x21 and y21;\n      c20_1_vwh : constant Boolean := y20 and x20;\n      hhb : constant Boolean := x19 and y19;\n      gpq : constant Boolean := y18 and x18;\n      fpk : constant Boolean := x17 and y17;\n      fhn : constant Boolean := y16 and x16;\n      vch : constant Boolean := y15 and x15;\n      ktg : constant Boolean := x14 and y14;\n      c13_1_wbw : constant Boolean := y13 and x13;\n      c12_1_njd : constant Boolean := x12 and y12;\n      c11_1_cbm : constant Boolean := x11 and y11;\n      c10_1_bcw : constant Boolean := y10 and x10;\n      c09_1_ptc : constant Boolean := x09 and y09;\n      c08_1_qpg : constant Boolean := y08 and x08;\n      c07_1_vjc : constant Boolean := y07 and x07;\n      knd : constant Boolean := y06 and x06;\n      fkt : constant Boolean := x05 and y05;\n      dtn : constant Boolean := y04 and x04;\n      rtt : constant Boolean := y03 and x03;\n      tng : constant Boolean := y02 and x02;\n      hnj : constant Boolean := x01 and y01;\n      jcq : constant Boolean := x00 and y00;\n\n      --  Half-Adder 1: Sum\n\n      jrb : constant Boolean := x44 xor y44;\n      nsb : constant Boolean := x43 xor y43;\n      sbn : constant Boolean := x42 xor y42;\n      krk : constant Boolean := x41 xor y41;\n      s40_1_qwt : constant Boolean := x40 xor y40;\n      s39_1_ksf : constant Boolean := x39 xor y39;\n      s38_1_spg : constant Boolean := x38 xor y38;\n      s37_1_vjg : constant Boolean := x37 xor y37;\n      s36_1_dkj : constant Boolean := x36 xor y36;\n      prn : constant Boolean := y35 xor x35;\n      bgg : constant Boolean := x34 xor y34;\n      pmg : constant Boolean := y33 xor x33;\n      wrd : constant Boolean := y32 xor x32;\n      tkw : constant Boolean := y31 xor x31;\n      qgc : constant Boolean := y30 xor x30;\n      wtw : constant Boolean := x29 xor y29;\n      rtb : constant Boolean := x28 xor y28;\n      qrw : constant Boolean := y27 xor x27;\n      jkt : constant Boolean := y26 xor x26;\n      nfm : constant Boolean := x25 xor y25;\n      kdn : constant Boolean := y24 xor x24;\n      gcj : constant Boolean := x23 xor y23;\n      qgd : constant Boolean := x22 xor y22;\n      s21_1_sbs : constant Boolean := y21 xor x21;\n      s20_1_vdc : constant Boolean := x20 xor y20;\n      mcv : constant Boolean := x19 xor y19;\n      jbp : constant Boolean := y18 xor x18;\n      tdb : constant Boolean := x17 xor y17;\n      vgb : constant Boolean := x16 xor y16;\n      pvj : constant Boolean := y15 xor x15;\n      c14_1_tfh : constant Boolean := y14 xor x14;\n      s13_1_wgb : constant Boolean := y13 xor x13;\n      s12_1_htr : constant Boolean := x12 xor y12;\n      s11_1_ksb : constant Boolean := x11 xor y11;\n      s10_1_cvv : constant Boolean := x10 xor y10;\n      s09_1_mnm : constant Boolean := x09 xor y09;\n      s08_1_jhr : constant Boolean := x08 xor y08;\n      s07_1_gjv : constant Boolean := y07 xor x07;\n      hsn : constant Boolean := x06 xor y06;\n      sfn : constant Boolean := y05 xor x05;\n      ptv : constant Boolean := y04 xor x04;\n      npk : constant Boolean := x03 xor y03;\n      qpd : constant Boolean := y02 xor x02;\n      sqk : constant Boolean := x01 xor y01;\n\n      z00 : constant Boolean := x00 xor y00;  --  No carry in.\n\n      bmc : constant Boolean := sqk and jcq;\n      kpf : constant Boolean := hnj or bmc;\n      pwk : constant Boolean := kpf and qpd;\n      tpv : constant Boolean := tng or pwk;\n      hrr : constant Boolean := tpv and npk;\n\n      bdk : constant Boolean := hrr or rtt;\n\n      nnq : constant Boolean := ptv and bdk;\n      svk : constant Boolean := dtn or nnq;\n      wnq : constant Boolean := sfn and svk;\n      cjh : constant Boolean := fkt or wnq;\n      hds : constant Boolean := cjh and hsn;\n      wcs : constant Boolean := knd or hds;\n      nbb : constant Boolean := s07_1_gjv and wcs;\n      c08_bwm   : constant Boolean := nbb or c07_1_vjc;\n      c08_2_tvw : constant Boolean := c08_bwm and s08_1_jhr;\n      c09_gqb   : constant Boolean := c08_2_tvw or c08_1_qpg;\n      c09_2_dsk : constant Boolean := c09_gqb and s09_1_mnm;\n\n      z09 : constant Boolean := s09_1_mnm xor c09_gqb;\n      c10_gwh : constant Boolean := c09_2_dsk or c09_1_ptc;\n\n      c10_2_pgn : constant Boolean := c10_gwh and s10_1_cvv;\n      c11_jbk   : constant Boolean := c10_1_bcw or c10_2_pgn;\n      c11_2_hgb : constant Boolean := s11_1_ksb and c11_jbk;\n\n      c12_jgf : constant Boolean := c11_1_cbm or c11_2_hgb;\n      c12_2_dmc  : constant Boolean := c12_jgf and s12_1_htr;\n\n      c13_qwr : constant Boolean := c12_2_dmc or c12_1_njd;\n\n      c13_2_dqm : constant Boolean := c13_1_wbw and c13_qwr;  --  !!\n\n      nkd : constant Boolean := c13_2_dqm or s13_1_wgb;  --  c14?\n\n      jrd : constant Boolean := c14_1_tfh and nkd;\n      bgh : constant Boolean := jrd or ktg;\n\n      vcd : constant Boolean := bgh and pvj;\n      nhh : constant Boolean := vcd or vch;\n      btr : constant Boolean := vgb and nhh;\n      ctv : constant Boolean := btr or fhn;\n      ffh : constant Boolean := tdb and ctv;\n      wtc : constant Boolean := fpk or ffh;\n      pfh : constant Boolean := jbp and wtc;\n      ppf : constant Boolean := pfh or gpq;\n      gvt : constant Boolean := ppf and mcv;\n      c20_tjc : constant Boolean := gvt or hhb;\n      c20_2_vvc : constant Boolean := s20_1_vdc and c20_tjc;\n      c21_kgk : constant Boolean := c20_1_vwh or c20_2_vvc;\n\n      z21 : constant Boolean := c21_kgk xor s21_1_sbs;\n      c21_2_rcb : constant Boolean := c21_kgk and s21_1_sbs;\n\n      tvj : constant Boolean := c21_2_rcb or c21_1_knb;\n      vsb : constant Boolean := qgd and tvj;\n      grk : constant Boolean := dpg or vsb;\n      cdw : constant Boolean := gcj and grk;\n      pbv : constant Boolean := nrw or cdw;\n      mhd : constant Boolean := kdn and pbv;\n      vsw : constant Boolean := frv or mhd;\n      dfq : constant Boolean := nfm and vsw;\n      kgs : constant Boolean := dfq or dbt;\n      wtd : constant Boolean := kgs and jkt;\n      mjf : constant Boolean := jck or wtd;\n      jgh : constant Boolean := mjf and qrw;\n      whc : constant Boolean := fjr or jgh;\n      jsf : constant Boolean := rtb and whc;\n      vmj : constant Boolean := jsf or shp;\n      nbw : constant Boolean := vmj and wtw;\n      bqb : constant Boolean := nbw or bqn;\n      nth : constant Boolean := qgc and bqb;\n      mwg : constant Boolean := nth or rvc;\n      vmq : constant Boolean := tkw and mwg;\n      mrg : constant Boolean := gpp or vmq;\n      vcm : constant Boolean := mrg and wrd;\n      rnc : constant Boolean := vcm or ttt;\n      dmp : constant Boolean := pmg and rnc;\n      kvw : constant Boolean := hbn or dmp;\n      gwm : constant Boolean := kvw and bgg;\n      bhd : constant Boolean := rkq or gwm;\n\n      drv : constant Boolean := prn and bhd;\n      dmj : constant Boolean := drv or qph;\n      vnw : constant Boolean := dmj and s36_1_dkj;\n      jgc : constant Boolean := pfc or vnw;\n      mqh : constant Boolean := s37_1_vjg and jgc;\n      bwb : constant Boolean := c37_1_nbc or mqh;\n\n      c38_2_wjg : constant Boolean := s38_1_spg and bwb;\n      c39_wjf : constant Boolean := c38_1_crp or c38_2_wjg;\n      c39_2_hvf : constant Boolean := s39_1_ksf and c39_wjf;\n\n      z39_ok : constant Boolean := c39_wjf xor s39_1_ksf;\n      c39_1_jct : constant Boolean := x39 and y39;\n\n      nhk : constant Boolean := c39_1_jct or c39_2_hvf;\n      qwh : constant Boolean := nhk and s40_1_qwt;\n      sgk : constant Boolean := c40_1_qhf or qwh;\n      qvv : constant Boolean := sgk and krk;\n      pwt : constant Boolean := kfp or qvv;\n      qwg : constant Boolean := sbn and pwt;\n      gdt : constant Boolean := qwg or qjp;\n      dnc : constant Boolean := nsb and gdt;\n\n      tdh : constant Boolean := dnc or bmf;\n      pjg : constant Boolean := jrb and tdh;\n\n      --  Half-Adder 2: Sum\n\n      z01 : constant Boolean := jcq xor sqk;\n      z02 : constant Boolean := kpf xor qpd;\n      z03 : constant Boolean := tpv xor npk;\n      z04 : constant Boolean := ptv xor bdk;\n      z05 : constant Boolean := svk xor sfn;\n      z06 : constant Boolean := cjh xor hsn;\n      z07 : constant Boolean := wcs xor s07_1_gjv;\n      z08 : constant Boolean := c08_bwm xor s08_1_jhr;\n\n      z10 : constant Boolean := s10_1_cvv xor c10_gwh;\n      z11 : constant Boolean := s11_1_ksb xor c11_jbk;\n      z12 : constant Boolean := s12_1_htr xor c12_jgf;\n      z13 : constant Boolean := c13_qwr xor c13_1_wbw;  --  should be c13 xor s13_1\n      z14 : constant Boolean := nkd xor c14_1_tfh;\n      z15 : constant Boolean := bgh xor pvj;\n      z16 : constant Boolean := nhh xor vgb;\n      z17 : constant Boolean := ctv xor tdb;\n      z18 : constant Boolean := wtc xor jbp;\n      z19 : constant Boolean := mcv xor ppf;\n      z20 : constant Boolean := s20_1_vdc xor c20_tjc;\n      z22 : constant Boolean := qgd xor tvj;\n      z23 : constant Boolean := grk xor gcj;\n      z24 : constant Boolean := kdn xor pbv;\n      z25 : constant Boolean := nfm xor vsw;\n      z26 : constant Boolean := jkt xor kgs;\n      z27 : constant Boolean := qrw xor mjf;\n      z28 : constant Boolean := rtb xor whc;\n      z29 : constant Boolean := wtw xor vmj;\n      z30 : constant Boolean := bqb xor qgc;\n      z31 : constant Boolean := mwg xor tkw;\n      z32 : constant Boolean := mrg xor wrd;\n      z33 : constant Boolean := pmg xor rnc;\n      z34 : constant Boolean := bgg xor kvw;\n      z35 : constant Boolean := bhd xor prn;\n      z36 : constant Boolean := s36_1_dkj xor dmj;\n      z37 : constant Boolean := s37_1_vjg xor jgc;\n      z38 : constant Boolean := s38_1_spg xor bwb;\n      z40 : constant Boolean := s40_1_qwt xor nhk;\n      z41 : constant Boolean := sgk xor krk;\n      z42 : constant Boolean := pwt xor sbn;\n      z43 : constant Boolean := gdt xor nsb;\n      z44 : constant Boolean := tdh xor jrb;\n      z45 : constant Boolean := pjg or  cvk;  --  Last carry\n\n      z : constant Integer_64 :=\n        Boolean'Pos (z00) * 2 ** 0 +\n        Boolean'Pos (z01) * 2 ** 1 +\n        Boolean'Pos (z02) * 2 ** 2 +\n        Boolean'Pos (z03) * 2 ** 3 +\n        Boolean'Pos (z04) * 2 ** 4 +\n        Boolean'Pos (z05) * 2 ** 5 +\n        Boolean'Pos (z06) * 2 ** 6 +\n        Boolean'Pos (z07) * 2 ** 7 +\n        Boolean'Pos (z08) * 2 ** 8 +\n        Boolean'Pos (z09) * 2 ** 9 +\n        Boolean'Pos (z10) * 2 ** 10 +\n        Boolean'Pos (z11) * 2 ** 11 +\n        Boolean'Pos (z12) * 2 ** 12 +\n        Boolean'Pos (z13) * 2 ** 13 +\n        Boolean'Pos (z14) * 2 ** 14 +\n        Boolean'Pos (z15) * 2 ** 15 +\n        Boolean'Pos (z16) * 2 ** 16 +\n        Boolean'Pos (z17) * 2 ** 17 +\n        Boolean'Pos (z18) * 2 ** 18 +\n        Boolean'Pos (z19) * 2 ** 19 +\n        Boolean'Pos (z20) * 2 ** 20 +\n        Boolean'Pos (z21) * 2 ** 21 +\n        Boolean'Pos (z22) * 2 ** 22 +\n        Boolean'Pos (z23) * 2 ** 23 +\n        Boolean'Pos (z24) * 2 ** 24 +\n        Boolean'Pos (z25) * 2 ** 25 +\n        Boolean'Pos (z26) * 2 ** 26 +\n        Boolean'Pos (z27) * 2 ** 27 +\n        Boolean'Pos (z28) * 2 ** 28 +\n        Boolean'Pos (z29) * 2 ** 29 +\n        Boolean'Pos (z30) * 2 ** 30 +\n        Boolean'Pos (z31) * 2 ** 31 +\n        Boolean'Pos (z32) * 2 ** 32 +\n        Boolean'Pos (z33) * 2 ** 33 +\n        Boolean'Pos (z34) * 2 ** 34 +\n        Boolean'Pos (z35) * 2 ** 35 +\n        Boolean'Pos (z36) * 2 ** 36 +\n        Boolean'Pos (z37) * 2 ** 37 +\n        Boolean'Pos (z38) * 2 ** 38 +\n        Boolean'Pos (z39_ok) * 2 ** 39 +\n        Boolean'Pos (z40) * 2 ** 40 +\n        Boolean'Pos (z41) * 2 ** 41 +\n        Boolean'Pos (z42) * 2 ** 42 +\n        Boolean'Pos (z43) * 2 ** 43 +\n        Boolean'Pos (z44) * 2 ** 44 +\n        Boolean'Pos (z45) * 2 ** 45;\n    begin\n      return z;\n    end Add;\n\n    function Check (x, y : Integer_64) return Boolean is\n    begin\n      return Add (x, y) = x + y;\n    end Check;\n\n  begin\n    for i in 0 .. 44 loop\n      for j in 0 .. 44 loop\n        if not Check (2**i, 2**j) then\n          Put_Line (i'Image & \", \" & j'Image);\n        end if;\n      end loop;\n    end loop;\n    r (part_2) := +\"gwh,jct,rcb,wbw,wgb,z09,z21,z39\";\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Do_Part_1;\n  if not compiler_test_mode then\n    Do_Part_2;\n  end if;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 57270694330992\n    --  Part 2: validated by AoC: gwh,jct,rcb,wbw,wgb,z09,z21,z39\n  end if;\nend AoC_2024_24;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_24_questions.txt",
    "content": "--- Day 24: Crossed Wires ---\n\nYou and The Historians arrive at the edge of a large grove somewhere in the jungle. After the last incident, the Elves installed a small device that monitors the fruit. While The Historians search the grove, one of them asks if you can take a look at the monitoring device; apparently, it's been malfunctioning recently.\n\nThe device seems to be trying to produce a number through some boolean logic gates. Each gate has two inputs and one output. The gates all operate on values that are either true (1) or false (0).\n\n    AND gates output 1 if both inputs are 1; if either input is 0, these gates output 0.\n    OR gates output 1 if one or both inputs is 1; if both inputs are 0, these gates output 0.\n    XOR gates output 1 if the inputs are different; if the inputs are the same, these gates output 0.\n\nGates wait until both inputs are received before producing output; wires can carry 0, 1 or no value at all. There are no loops; once a gate has determined its output, the output will not change until the whole system is reset. Each wire is connected to at most one gate output, but can be connected to many gate inputs.\n\nRather than risk getting shocked while tinkering with the live system, you write down all of the gate connections and initial wire values (your puzzle input) so you can consider them in relative safety. For example:\n\nx00: 1\nx01: 1\nx02: 1\ny00: 0\ny01: 1\ny02: 0\n\nx00 AND y00 -> z00\nx01 XOR y01 -> z01\nx02 OR y02 -> z02\n\nBecause gates wait for input, some wires need to start with a value (as inputs to the entire system). The first section specifies these values. For example, x00: 1 means that the wire named x00 starts with the value 1 (as if a gate is already outputting that value onto that wire).\n\nThe second section lists all of the gates and the wires connected to them. For example, x00 AND y00 -> z00 describes an instance of an AND gate which has wires x00 and y00 connected to its inputs and which will write its output to wire z00.\n\nIn this example, simulating these gates eventually causes 0 to appear on wire z00, 0 to appear on wire z01, and 1 to appear on wire z02.\n\nUltimately, the system is trying to produce a number by combining the bits on all wires starting with z. z00 is the least significant bit, then z01, then z02, and so on.\n\nIn this example, the three output bits form the binary number 100 which is equal to the decimal number 4.\n\nHere's a larger example:\n\nx00: 1\nx01: 0\nx02: 1\nx03: 1\nx04: 0\ny00: 1\ny01: 1\ny02: 1\ny03: 1\ny04: 1\n\nntg XOR fgs -> mjb\ny02 OR x01 -> tnw\nkwq OR kpj -> z05\nx00 OR x03 -> fst\ntgd XOR rvg -> z01\nvdt OR tnw -> bfw\nbfw AND frj -> z10\nffh OR nrd -> bqk\ny00 AND y03 -> djm\ny03 OR y00 -> psh\nbqk OR frj -> z08\ntnw OR fst -> frj\ngnj AND tgd -> z11\nbfw XOR mjb -> z00\nx03 OR x00 -> vdt\ngnj AND wpb -> z02\nx04 AND y00 -> kjc\ndjm OR pbm -> qhw\nnrd AND vdt -> hwm\nkjc AND fst -> rvg\ny04 OR y02 -> fgs\ny01 AND x02 -> pbm\nntg OR kjc -> kwq\npsh XOR fgs -> tgd\nqhw XOR tgd -> z09\npbm OR djm -> kpj\nx03 XOR y03 -> ffh\nx00 XOR y04 -> ntg\nbfw OR bqk -> z06\nnrd XOR fgs -> wpb\nfrj XOR qhw -> z04\nbqk OR frj -> z07\ny03 OR x01 -> nrd\nhwm AND bqk -> z03\ntgd XOR rvg -> z12\ntnw OR pbm -> gnj\n\nAfter waiting for values on all wires starting with z, the wires in this system have the following values:\n\nbfw: 1\nbqk: 1\ndjm: 1\nffh: 0\nfgs: 1\nfrj: 1\nfst: 1\ngnj: 1\nhwm: 1\nkjc: 0\nkpj: 1\nkwq: 0\nmjb: 1\nnrd: 1\nntg: 0\npbm: 1\npsh: 1\nqhw: 1\nrvg: 0\ntgd: 0\ntnw: 1\nvdt: 1\nwpb: 0\nz00: 0\nz01: 0\nz02: 0\nz03: 1\nz04: 0\nz05: 1\nz06: 1\nz07: 1\nz08: 1\nz09: 1\nz10: 1\nz11: 0\nz12: 0\n\nCombining the bits from all wires starting with z produces the binary number 0011111101000. Converting this number to decimal produces 2024.\n\nSimulate the system of gates and wires. What decimal number does it output on the wires starting with z?\n\n--- Part Two ---\n\nAfter inspecting the monitoring device more closely, you determine that the system you're simulating is trying to add two binary numbers.\n\nSpecifically, it is treating the bits on wires starting with x as one binary number, treating the bits on wires starting with y as a second binary number, and then attempting to add those two numbers together. The output of this operation is produced as a binary number on the wires starting with z. (In all three cases, wire 00 is the least significant bit, then 01, then 02, and so on.)\n\nThe initial values for the wires in your puzzle input represent just one instance of a pair of numbers that sum to the wrong value. Ultimately, any two binary numbers provided as input should be handled correctly. That is, for any combination of bits on wires starting with x and wires starting with y, the sum of the two numbers those bits represent should be produced as a binary number on the wires starting with z.\n\nFor example, if you have an addition system with four x wires, four y wires, and five z wires, you should be able to supply any four-bit number on the x wires, any four-bit number on the y numbers, and eventually find the sum of those two numbers as a five-bit number on the z wires. One of the many ways you could provide numbers to such a system would be to pass 11 on the x wires (1011 in binary) and 13 on the y wires (1101 in binary):\n\nx00: 1\nx01: 1\nx02: 0\nx03: 1\ny00: 1\ny01: 0\ny02: 1\ny03: 1\n\nIf the system were working correctly, then after all gates are finished processing, you should find 24 (11+13) on the z wires as the five-bit binary number 11000:\n\nz00: 0\nz01: 0\nz02: 0\nz03: 1\nz04: 1\n\nUnfortunately, your actual system needs to add numbers with many more bits and therefore has many more wires.\n\nBased on forensic analysis of scuff marks and scratches on the device, you can tell that there are exactly four pairs of gates whose output wires have been swapped. (A gate can only be in at most one such pair; no gate's output was swapped multiple times.)\n\nFor example, the system below is supposed to find the bitwise AND of the six-bit number on x00 through x05 and the six-bit number on y00 through y05 and then write the result as a six-bit number on z00 through z05:\n\nx00: 0\nx01: 1\nx02: 0\nx03: 1\nx04: 0\nx05: 1\ny00: 0\ny01: 0\ny02: 1\ny03: 1\ny04: 0\ny05: 1\n\nx00 AND y00 -> z05\nx01 AND y01 -> z02\nx02 AND y02 -> z01\nx03 AND y03 -> z03\nx04 AND y04 -> z04\nx05 AND y05 -> z00\n\nHowever, in this example, two pairs of gates have had their output wires swapped, causing the system to produce wrong answers. The first pair of gates with swapped outputs is x00 AND y00 -> z05 and x05 AND y05 -> z00; the second pair of gates is x01 AND y01 -> z02 and x02 AND y02 -> z01. Correcting these two swaps results in this system that works as intended for any set of initial values on wires that start with x or y:\n\nx00 AND y00 -> z00\nx01 AND y01 -> z01\nx02 AND y02 -> z02\nx03 AND y03 -> z03\nx04 AND y04 -> z04\nx05 AND y05 -> z05\n\nIn this example, two pairs of gates have outputs that are involved in a swap. By sorting their output wires' names and joining them with commas, the list of wires involved in swaps is z00,z01,z02,z05.\n\nOf course, your actual system is much more complex than this, and the gates that need their outputs swapped could be anywhere, not just attached to a wire starting with z. If you were to determine that you need to swap output wires aaa with eee, ooo with z99, bbb with ccc, and aoc with z24, your answer would be aaa,aoc,bbb,ccc,eee,ooo,z24,z99.\n\nYour system of gates and wires has four pairs of gates which need their output wires swapped - eight wires in total. Determine which four pairs of gates need their outputs swapped so that your system correctly performs addition; what do you get if you sort the names of the eight wires involved in a swap and then join those names with commas?\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_25.adb",
    "content": "--  Solution to Advent of Code 2024, Day 25\n-------------------------------------------\n--  Code Chronicle\n--\n--  https://adventofcode.com/2024/day/25\n--  Copy of questions in: aoc_2024_25_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2024.gpr .\nwith HAT;\n\nprocedure AoC_2024_25 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2024_25\";\n\n  verbose : constant Boolean := False;\n\n  subtype Pin_Range is Integer range 1 .. 5;\n\n  type Pin_Height is array (Pin_Range) of Natural;\n\n  key, lock : array (1 .. 500) of Pin_Height;\n\n  last_key, last_lock : Natural := 0;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    subtype Pattern is String (Pin_Range);\n    pat : Pattern;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    Get (f, pat);\n    while not End_Of_File (f) loop\n      exit when pat = \"STOP.\";\n      if pat = \"#####\" then\n        --  Lock\n        last_lock := last_lock + 1;\n        for i in 0 .. 6 loop\n          for j in Pin_Range loop\n            if pat (j) = '#' then\n              lock (last_lock)(j) := i;\n            end if;\n          end loop;\n          Get (f, pat);\n        end loop;\n        if verbose then\n          Put (\"Lock \");\n          for j in Pin_Range loop\n            Put (lock (last_lock)(j), 0);\n          end loop;\n          New_Line;\n        end if;\n      else\n        --  Key\n        last_key := last_key + 1;\n        for j in Pin_Range loop\n          key (last_key)(j) := 0;\n        end loop;\n        for i in 0 .. 6 loop\n          for j in Pin_Range loop\n            if pat (j) = '#' and then key (last_key)(j) = 0 then\n              key (last_key)(j) := 6 - i;\n            end if;\n          end loop;\n          Get (f, pat);\n        end loop;\n        if verbose then\n          Put (\"Key \");\n          for j in Pin_Range loop\n            Put (key (last_key)(j), 0);\n          end loop;\n          New_Line;\n        end if;\n      end if;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    count : Natural := 0;\n    ok : Boolean;\n  begin\n    for k in 1 .. last_key loop\n      for l in 1 .. last_lock loop\n        ok := True;\n        for j in Pin_Range loop\n          ok := ok and then key (k)(j) + lock (l)(j) <= 5;\n        end loop;\n        if ok then\n          count := count + 1;\n        end if;\n      end loop;\n    end loop;\n    r (part_1) := +\"\" & count;\n  end Do_Part_1;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n\n  if compiler_test_mode then if r (part_1) /= Argument (1) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    --  Part 1: validated by AoC: 3395\n  end if;\nend AoC_2024_25;\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_25.txt",
    "content": "#####\n#####\n#####\n#.##.\n...#.\n.....\n.....\n\n.....\n.#.#.\n.###.\n.###.\n.###.\n.####\n#####\n\n.....\n.....\n.....\n....#\n.#..#\n##.##\n#####\n\n#####\n.####\n.##.#\n.#..#\n.....\n.....\n.....\n\n.....\n.#...\n.#...\n##...\n##...\n###.#\n#####\n\n.....\n.....\n.....\n....#\n#..##\n##.##\n#####\n\n.....\n...#.\n#..#.\n#..#.\n#..#.\n##.#.\n#####\n\n.....\n....#\n..#.#\n.##.#\n.##.#\n.##.#\n#####\n\n#####\n##.##\n##.##\n##..#\n#....\n#....\n.....\n\n.....\n.....\n.....\n#....\n#....\n#.#.#\n#####\n\n.....\n#..#.\n#..#.\n##.#.\n#####\n#####\n#####\n\n.....\n#.#..\n#.#..\n###.#\n###.#\n#####\n#####\n\n.....\n.#.#.\n##.##\n#####\n#####\n#####\n#####\n\n#####\n###.#\n##...\n##...\n#....\n.....\n.....\n\n#####\n.###.\n..#..\n..#..\n.....\n.....\n.....\n\n#####\n#####\n#.#.#\n..#.#\n..#.#\n..#..\n.....\n\n.....\n#....\n#..#.\n#..##\n##.##\n#####\n#####\n\n#####\n##.##\n##.##\n#..#.\n#..#.\n.....\n.....\n\n#####\n##.#.\n.#...\n.....\n.....\n.....\n.....\n\n.....\n.#...\n##...\n##.#.\n####.\n#####\n#####\n\n.....\n#.#.#\n#.###\n#####\n#####\n#####\n#####\n\n.....\n...#.\n.#.#.\n.#.#.\n.#.#.\n.#.#.\n#####\n\n.....\n..#..\n#.#.#\n#.###\n#.###\n#####\n#####\n\n#####\n####.\n####.\n####.\n#.##.\n#.#..\n.....\n\n#####\n.#.##\n.#.#.\n.#.#.\n.#...\n.#...\n.....\n\n#####\n#.###\n#.###\n#..##\n#...#\n#...#\n.....\n\n#####\n##.#.\n#..#.\n#..#.\n...#.\n...#.\n.....\n\n.....\n..#..\n..#..\n.##.#\n.####\n#####\n#####\n\n#####\n.#.#.\n.#.#.\n...#.\n...#.\n...#.\n.....\n\n.....\n...#.\n#..#.\n#..#.\n##.##\n##.##\n#####\n\n#####\n#.###\n...##\n....#\n.....\n.....\n.....\n\n.....\n..#..\n#.#..\n#.#.#\n###.#\n#####\n#####\n\n.....\n.....\n...#.\n#..#.\n#..##\n##.##\n#####\n\n#####\n#####\n##.##\n##.##\n##..#\n.#...\n.....\n\n#####\n#####\n###.#\n###.#\n###..\n#.#..\n.....\n\n.....\n.....\n.#...\n.#...\n.##..\n####.\n#####\n\n.....\n.#..#\n.#..#\n.#.##\n.#.##\n#####\n#####\n\n.....\n.#...\n.##..\n.###.\n####.\n#####\n#####\n\n.....\n.#...\n##...\n##..#\n##..#\n###.#\n#####\n\n.....\n...#.\n.#.#.\n.#.##\n.#.##\n#####\n#####\n\n#####\n.####\n.##.#\n.##..\n.#...\n.#...\n.....\n\n.....\n#..#.\n##.#.\n##.#.\n##.##\n#####\n#####\n\n#####\n#####\n#####\n.#.##\n.#.##\n....#\n.....\n\n#####\n#####\n###.#\n#.#.#\n..#..\n..#..\n.....\n\n.....\n#....\n#...#\n##..#\n###.#\n#####\n#####\n\n.....\n.....\n...#.\n...#.\n.#.#.\n.####\n#####\n\n#####\n#####\n#####\n##.##\n.#..#\n.#..#\n.....\n\n#####\n##.##\n#..##\n...#.\n...#.\n...#.\n.....\n\n.....\n.....\n...#.\n...#.\n..##.\n.####\n#####\n\n#####\n#####\n#.#.#\n#.#.#\n#.#.#\n#.#.#\n.....\n\n#####\n###.#\n###..\n##...\n#....\n#....\n.....\n\n.....\n.#.#.\n####.\n####.\n####.\n#####\n#####\n\n#####\n#####\n##.##\n.#.#.\n.#.#.\n.....\n.....\n\n.....\n.....\n..#..\n#.#.#\n#.#.#\n#.###\n#####\n\n.....\n....#\n....#\n....#\n.#.##\n.#.##\n#####\n\n#####\n##.##\n##.##\n.#.##\n...#.\n...#.\n.....\n\n.....\n..#..\n..#.#\n.####\n.####\n.####\n#####\n\n#####\n####.\n#.##.\n#.##.\n..#..\n..#..\n.....\n\n#####\n#.###\n#.###\n..###\n..##.\n..#..\n.....\n\n.....\n.#...\n.#...\n##.#.\n##.#.\n#####\n#####\n\n#####\n#####\n#####\n####.\n#.##.\n#.#..\n.....\n\n#####\n##.#.\n##...\n.#...\n.#...\n.#...\n.....\n\n#####\n##.##\n##..#\n#...#\n.....\n.....\n.....\n\n#####\n#####\n#.###\n#.#.#\n#.#.#\n.....\n.....\n\n.....\n#....\n#....\n#.#.#\n###.#\n#####\n#####\n\n#####\n#.#.#\n#...#\n#...#\n#...#\n#...#\n.....\n\n.....\n..#..\n..#..\n#.#..\n####.\n#####\n#####\n\n.....\n.#..#\n.#..#\n.#..#\n##.##\n#####\n#####\n\n.....\n....#\n.#..#\n##..#\n##.##\n##.##\n#####\n\n.....\n.....\n....#\n...##\n#.###\n#.###\n#####\n\n.....\n..#..\n..#..\n..#..\n..#..\n#.#.#\n#####\n\n#####\n.##.#\n.#..#\n.#..#\n.#..#\n.....\n.....\n\n#####\n#####\n##.##\n##.##\n##.##\n.#..#\n.....\n\n.....\n.#...\n.#...\n.#..#\n##.##\n#####\n#####\n\n.....\n.....\n...#.\n#.##.\n#.##.\n#.###\n#####\n\n.....\n.....\n#...#\n#.#.#\n#.#.#\n#.###\n#####\n\n.....\n..#..\n..#..\n..#..\n.##.#\n###.#\n#####\n\n.....\n...#.\n.#.#.\n.#.#.\n.#.#.\n.####\n#####\n\n.....\n.....\n.....\n#..#.\n#.###\n#.###\n#####\n\n.....\n.....\n.#..#\n##..#\n##.##\n##.##\n#####\n\n.....\n#.#.#\n#.#.#\n#.#.#\n#.###\n#.###\n#####\n\n.....\n.....\n.#..#\n##.##\n#####\n#####\n#####\n\n#####\n##.##\n##.##\n##.#.\n##.#.\n#....\n.....\n\n.....\n..#..\n..#..\n..#.#\n.####\n#####\n#####\n\n.....\n.....\n.....\n.#.#.\n##.#.\n#####\n#####\n\n#####\n##.##\n#..#.\n...#.\n...#.\n...#.\n.....\n\n#####\n#.##.\n#.##.\n..##.\n..#..\n.....\n.....\n\n#####\n###.#\n###.#\n##..#\n#....\n.....\n.....\n\n#####\n.#.#.\n.#.#.\n...#.\n.....\n.....\n.....\n\n#####\n#####\n.####\n..###\n..#.#\n..#..\n.....\n\n.....\n...#.\n...#.\n#.##.\n####.\n#####\n#####\n\n.....\n.....\n....#\n..#.#\n..###\n.####\n#####\n\n#####\n##.##\n##.##\n.#.##\n.#.##\n.#..#\n.....\n\n.....\n.....\n.....\n.#...\n###..\n###.#\n#####\n\n#####\n#####\n##.##\n.#.##\n...##\n...#.\n.....\n\n.....\n...#.\n...#.\n..###\n.####\n#####\n#####\n\n.....\n#.#..\n#.#..\n###.#\n#####\n#####\n#####\n\n.....\n..#.#\n..#.#\n#.###\n#.###\n#.###\n#####\n\n.....\n.....\n.#.#.\n##.#.\n##.#.\n#####\n#####\n\n#####\n#.###\n#.###\n..##.\n...#.\n.....\n.....\n\n#####\n.####\n.####\n.#.#.\n.#...\n.#...\n.....\n\n#####\n.##.#\n.##.#\n.##..\n.##..\n..#..\n.....\n\n#####\n.####\n.#.##\n.#.#.\n...#.\n.....\n.....\n\n.....\n#....\n#....\n#...#\n##.##\n##.##\n#####\n\n.....\n.....\n.....\n...#.\n.#.#.\n.#.#.\n#####\n\n.....\n.....\n..#..\n..#..\n#.#.#\n#####\n#####\n\n#####\n###.#\n#.#.#\n..#..\n.....\n.....\n.....\n\n#####\n#####\n.#.##\n.#..#\n.#..#\n.#..#\n.....\n\n#####\n####.\n.###.\n.#.#.\n.#.#.\n.....\n.....\n\n#####\n#####\n#.#.#\n#.#.#\n.....\n.....\n.....\n\n#####\n#.###\n#.###\n..###\n..##.\n...#.\n.....\n\n.....\n.#...\n.#.#.\n.#.#.\n.####\n#####\n#####\n\n.....\n...#.\n#..#.\n#..#.\n##.#.\n####.\n#####\n\n.....\n#.#..\n#.#..\n#.#..\n#.#.#\n#.#.#\n#####\n\n.....\n.....\n.#...\n.#...\n.#.#.\n.###.\n#####\n\n.....\n.....\n#....\n#....\n##.#.\n#####\n#####\n\n.....\n.....\n..#..\n..#.#\n#.#.#\n###.#\n#####\n\n#####\n#.##.\n#.##.\n#.#..\n#....\n.....\n.....\n\n#####\n#####\n#.###\n#..##\n#..#.\n#..#.\n.....\n\n.....\n..#..\n..#..\n#.##.\n#.##.\n#####\n#####\n\n#####\n#####\n#####\n.####\n..##.\n...#.\n.....\n\n.....\n..#..\n#.#.#\n###.#\n###.#\n#####\n#####\n\n#####\n###.#\n#.#.#\n#.#.#\n#...#\n#....\n.....\n\n.....\n#..#.\n#..#.\n#.##.\n####.\n#####\n#####\n\n#####\n#####\n#.###\n#.###\n#..##\n#...#\n.....\n\n#####\n#.##.\n..#..\n..#..\n..#..\n..#..\n.....\n\n.....\n#....\n#....\n#....\n#.#.#\n#.###\n#####\n\n#####\n#####\n##.##\n.#.#.\n.#.#.\n.#...\n.....\n\n.....\n..#.#\n..#.#\n#.#.#\n#.#.#\n#.###\n#####\n\n#####\n#.#.#\n....#\n....#\n.....\n.....\n.....\n\n#####\n#####\n.#.##\n.#.#.\n.#.#.\n.#...\n.....\n\n.....\n.....\n..#.#\n#.#.#\n#.#.#\n#.#.#\n#####\n\n#####\n#####\n#####\n.#.##\n.#.#.\n.#...\n.....\n\n#####\n#.###\n#.###\n#.#.#\n....#\n.....\n.....\n\n#####\n#.###\n#.##.\n#..#.\n#....\n#....\n.....\n\n.....\n..#..\n..#.#\n.##.#\n.##.#\n###.#\n#####\n\n#####\n.####\n..#.#\n..#..\n.....\n.....\n.....\n\n.....\n.....\n..#..\n..#..\n..#.#\n#.###\n#####\n\n.....\n#.#.#\n#.#.#\n###.#\n###.#\n#####\n#####\n\n#####\n#####\n.####\n.####\n..#.#\n..#..\n.....\n\n#####\n##.##\n##.##\n##.##\n.#.#.\n.....\n.....\n\n#####\n#.#.#\n#.#..\n#....\n#....\n#....\n.....\n\n.....\n.....\n.....\n..#..\n..##.\n.####\n#####\n\n#####\n####.\n##.#.\n##...\n.#...\n.#...\n.....\n\n.....\n.....\n.....\n.#...\n##.#.\n##.#.\n#####\n\n.....\n.....\n.#.#.\n.#.##\n#####\n#####\n#####\n\n.....\n...#.\n.#.#.\n##.##\n##.##\n#####\n#####\n\n.....\n#....\n##.#.\n#####\n#####\n#####\n#####\n\n#####\n#####\n#####\n#.#.#\n..#..\n.....\n.....\n\n.....\n..#.#\n#.#.#\n#.#.#\n#.###\n#.###\n#####\n\n.....\n.....\n#...#\n#...#\n##.##\n##.##\n#####\n\n#####\n#####\n#####\n#.###\n#..##\n...#.\n.....\n\n#####\n.#.##\n.#.##\n...#.\n...#.\n...#.\n.....\n\n.....\n.#...\n###..\n####.\n####.\n#####\n#####\n\n#####\n###.#\n###.#\n##..#\n##..#\n#....\n.....\n\n#####\n#.#.#\n#.#.#\n#...#\n#....\n#....\n.....\n\n#####\n#####\n#.##.\n#.#..\n.....\n.....\n.....\n\n#####\n#####\n#####\n##.##\n#...#\n#....\n.....\n\n#####\n#####\n#####\n####.\n.###.\n..#..\n.....\n\n.....\n....#\n....#\n#.#.#\n#.#.#\n#####\n#####\n\n.....\n.....\n..#..\n..##.\n..##.\n#.###\n#####\n\n.....\n.#..#\n.#.##\n##.##\n##.##\n##.##\n#####\n\n.....\n.....\n#.#.#\n#.#.#\n###.#\n#####\n#####\n\n.....\n..#..\n.##..\n.##.#\n###.#\n###.#\n#####\n\n#####\n.##.#\n.##.#\n..#.#\n....#\n.....\n.....\n\n.....\n..#..\n#.#..\n#.#.#\n#.#.#\n#.###\n#####\n\n#####\n#####\n#.###\n#.##.\n..#..\n.....\n.....\n\n.....\n.....\n#.#.#\n#.#.#\n#.###\n#####\n#####\n\n.....\n...#.\n#..##\n##.##\n##.##\n##.##\n#####\n\n#####\n#####\n####.\n.##..\n.##..\n..#..\n.....\n\n.....\n.....\n#....\n##...\n##.#.\n##.#.\n#####\n\n#####\n###.#\n###.#\n##..#\n.#..#\n.#..#\n.....\n\n#####\n#####\n##.##\n.#.#.\n.....\n.....\n.....\n\n#####\n####.\n.##..\n.#...\n.#...\n.#...\n.....\n\n.....\n#....\n#..#.\n#.###\n#.###\n#.###\n#####\n\n.....\n....#\n..#.#\n..###\n..###\n#.###\n#####\n\n.....\n....#\n#..##\n#..##\n#.###\n#####\n#####\n\n.....\n..#..\n..##.\n.####\n.####\n#####\n#####\n\n.....\n.....\n.....\n..#..\n#.##.\n#.###\n#####\n\n#####\n#####\n.###.\n.#.#.\n.#...\n.#...\n.....\n\n#####\n#####\n####.\n#.#..\n#.#..\n#....\n.....\n\n#####\n##.#.\n##.#.\n#..#.\n#..#.\n#..#.\n.....\n\n.....\n#..#.\n##.#.\n##.##\n#####\n#####\n#####\n\n#####\n#####\n#####\n#.###\n#.#.#\n..#.#\n.....\n\n.....\n.....\n.....\n..#..\n..#.#\n.##.#\n#####\n\n.....\n....#\n..#.#\n.##.#\n###.#\n###.#\n#####\n\n#####\n#####\n##.#.\n##.#.\n.#.#.\n.#.#.\n.....\n\n#####\n##.##\n.#.##\n.#.##\n...##\n....#\n.....\n\n#####\n.####\n.####\n..###\n..###\n...#.\n.....\n\n#####\n#####\n.##.#\n.##.#\n.##..\n..#..\n.....\n\n#####\n#####\n###.#\n#.#..\n.....\n.....\n.....\n\n#####\n#####\n#.###\n..###\n..#.#\n..#.#\n.....\n\n.....\n#.#.#\n#.#.#\n#.#.#\n#####\n#####\n#####\n\n#####\n#####\n#####\n##.##\n##.#.\n.#...\n.....\n\n.....\n...#.\n..###\n..###\n.####\n.####\n#####\n\n#####\n#.###\n#.###\n#.##.\n#.#..\n#.#..\n.....\n\n.....\n.....\n.....\n.....\n#..#.\n#.###\n#####\n\n#####\n#####\n###.#\n.#..#\n....#\n.....\n.....\n\n.....\n#.#..\n#.#.#\n#.#.#\n###.#\n###.#\n#####\n\n.....\n#...#\n#.#.#\n###.#\n#####\n#####\n#####\n\n.....\n..#..\n#.##.\n#.##.\n#.###\n#####\n#####\n\n#####\n##.##\n.#..#\n.#..#\n....#\n.....\n.....\n\n#####\n#####\n####.\n##.#.\n##.#.\n.#.#.\n.....\n\n#####\n.#.##\n.#.##\n.#.#.\n...#.\n.....\n.....\n\n.....\n.....\n.....\n...#.\n...##\n.#.##\n#####\n\n#####\n.##.#\n..#..\n..#..\n..#..\n..#..\n.....\n\n#####\n#.###\n...##\n...##\n....#\n....#\n.....\n\n#####\n#.###\n#.###\n..#.#\n..#.#\n..#.#\n.....\n\n#####\n#.###\n#.###\n#..#.\n#..#.\n...#.\n.....\n\n#####\n.###.\n.###.\n.##..\n.#...\n.#...\n.....\n\n#####\n##.##\n##.##\n##.##\n#..#.\n.....\n.....\n\n.....\n.#...\n##...\n##...\n##.#.\n####.\n#####\n\n#####\n#####\n.#.#.\n.#...\n.#...\n.....\n.....\n\n#####\n#.###\n#..##\n#...#\n.....\n.....\n.....\n\n.....\n...#.\n..##.\n..##.\n..##.\n#.##.\n#####\n\n#####\n#####\n.##.#\n.#..#\n....#\n....#\n.....\n\n#####\n#.###\n#.##.\n#.##.\n#..#.\n#....\n.....\n\n#####\n.####\n.####\n.####\n.##.#\n..#..\n.....\n\n.....\n.....\n..#.#\n#.#.#\n#.#.#\n###.#\n#####\n\n.....\n.....\n...#.\n.#.#.\n####.\n#####\n#####\n\n.....\n.....\n..#.#\n.##.#\n.##.#\n.####\n#####\n\n.....\n.#...\n###..\n####.\n####.\n####.\n#####\n\n.....\n..#..\n..#..\n#.#..\n#.#..\n####.\n#####\n\n.....\n.....\n#.#..\n#.#..\n###..\n###.#\n#####\n\n#####\n####.\n.###.\n.##..\n.#...\n.....\n.....\n\n#####\n.##.#\n.##.#\n.#..#\n.#..#\n.#..#\n.....\n\n.....\n...#.\n...#.\n#..#.\n##.#.\n##.##\n#####\n\n#####\n#####\n#.###\n#.###\n#.#.#\n....#\n.....\n\n.....\n.....\n.#.#.\n.#.#.\n##.#.\n#####\n#####\n\n.....\n.....\n.#...\n##...\n##...\n##.#.\n#####\n\n#####\n#.###\n#.###\n#.#.#\n#....\n.....\n.....\n\n.....\n.#...\n.#..#\n.#..#\n.##.#\n.##.#\n#####\n\n.....\n.....\n...#.\n..##.\n..##.\n#.###\n#####\n\n.....\n.#..#\n.#..#\n.#.##\n.#.##\n##.##\n#####\n\n#####\n#.##.\n..##.\n..##.\n...#.\n...#.\n.....\n\n.....\n.....\n#..#.\n#.##.\n#.##.\n####.\n#####\n\n#####\n.####\n.####\n.##.#\n.#...\n.....\n.....\n\n#####\n#####\n#.###\n#.##.\n..##.\n...#.\n.....\n\n#####\n.##.#\n..#.#\n..#.#\n..#.#\n.....\n.....\n\n.....\n..#..\n..#..\n..#.#\n#.###\n#.###\n#####\n\n.....\n...#.\n..###\n..###\n#.###\n#####\n#####\n\n.....\n....#\n#..##\n#.###\n#.###\n#.###\n#####\n\n.....\n.#.#.\n.#.##\n.####\n.####\n#####\n#####\n\n.....\n..#.#\n.####\n.####\n.####\n#####\n#####\n\n#####\n#####\n#####\n#.###\n..#.#\n..#..\n.....\n\n#####\n####.\n.###.\n..##.\n..##.\n...#.\n.....\n\n#####\n##.##\n#..#.\n#..#.\n...#.\n.....\n.....\n\n#####\n#####\n####.\n###..\n##...\n.#...\n.....\n\n#####\n#.###\n..###\n..###\n..##.\n...#.\n.....\n\n.....\n#...#\n#.#.#\n#.###\n#####\n#####\n#####\n\n.....\n#....\n#..#.\n#.##.\n#.##.\n#.##.\n#####\n\n#####\n#####\n###.#\n###.#\n##..#\n.#...\n.....\n\n#####\n####.\n.###.\n.#.#.\n...#.\n...#.\n.....\n\n.....\n#..#.\n#..#.\n#..#.\n#..#.\n##.##\n#####\n\n.....\n#....\n##...\n##...\n###.#\n###.#\n#####\n\n.....\n....#\n...##\n...##\n..###\n.####\n#####\n\n#####\n#####\n.##.#\n.##..\n.#...\n.#...\n.....\n\n#####\n##.##\n##.##\n.#.#.\n.#...\n.#...\n.....\n\n#####\n#####\n#####\n###.#\n#.#.#\n..#.#\n.....\n\n#####\n.#.##\n.#.##\n.#.#.\n.#.#.\n.#.#.\n.....\n\n#####\n#####\n#.##.\n..##.\n..##.\n..#..\n.....\n\n.....\n...#.\n.#.#.\n.###.\n.####\n.####\n#####\n\n#####\n#####\n###.#\n###.#\n#.#.#\n#.#.#\n.....\n\n.....\n.....\n.....\n.#.#.\n##.#.\n##.##\n#####\n\n.....\n.....\n...#.\n..##.\n#.##.\n#.##.\n#####\n\n#####\n#####\n###.#\n#.#.#\n..#.#\n.....\n.....\n\n.....\n.....\n.....\n.#..#\n###.#\n#####\n#####\n\n#####\n####.\n##.#.\n#..#.\n#..#.\n#....\n.....\n\n#####\n##.##\n#...#\n#....\n#....\n.....\n.....\n\n#####\n#####\n#####\n#.###\n#..#.\n#..#.\n.....\n\n#####\n#####\n.#.##\n.#.##\n...#.\n...#.\n.....\n\n.....\n.....\n.#...\n.#...\n##.#.\n##.#.\n#####\n\n#####\n#####\n##.#.\n##.#.\n##...\n#....\n.....\n\n.....\n...#.\n...##\n..###\n..###\n.####\n#####\n\n.....\n.....\n..#..\n..#..\n..#..\n.##.#\n#####\n\n.....\n..#..\n.##..\n###.#\n###.#\n###.#\n#####\n\n.....\n#..#.\n#..#.\n##.#.\n##.#.\n####.\n#####\n\n.....\n....#\n#...#\n#..##\n#.###\n#.###\n#####\n\n.....\n.....\n.#..#\n.##.#\n.##.#\n#####\n#####\n\n#####\n#.#.#\n#.#.#\n#...#\n#...#\n.....\n.....\n\n#####\n#####\n####.\n####.\n#.##.\n#..#.\n.....\n\n.....\n.#.#.\n.#.#.\n.#.#.\n.####\n.####\n#####\n\n#####\n#####\n#####\n####.\n##.#.\n#..#.\n.....\n\n#####\n###.#\n.##.#\n.##.#\n..#..\n.....\n.....\n\n.....\n.#...\n.#..#\n.##.#\n.####\n#####\n#####\n\n#####\n####.\n##.#.\n.#.#.\n.#.#.\n.#...\n.....\n\n#####\n###.#\n###.#\n##...\n.#...\n.....\n.....\n\n#####\n##.##\n##.##\n##.##\n##..#\n.#..#\n.....\n\n.....\n..#..\n#.#..\n#.#..\n####.\n####.\n#####\n\n.....\n.....\n....#\n#..##\n##.##\n##.##\n#####\n\n.....\n.....\n.....\n.#..#\n.##.#\n#####\n#####\n\n.....\n.....\n.#...\n.#...\n.#...\n##.#.\n#####\n\n#####\n#.###\n#..#.\n#....\n#....\n.....\n.....\n\n.....\n.#...\n.#..#\n.#..#\n.#.##\n.#.##\n#####\n\n.....\n.#...\n.#..#\n.#.##\n.#.##\n#####\n#####\n\n#####\n#.#.#\n..#.#\n..#.#\n.....\n.....\n.....\n\n.....\n....#\n#...#\n#.#.#\n#.#.#\n#####\n#####\n\n#####\n.####\n..###\n..##.\n...#.\n...#.\n.....\n\n#####\n.####\n.##.#\n.##.#\n.##.#\n..#..\n.....\n\n#####\n.###.\n.##..\n.#...\n.#...\n.#...\n.....\n\n.....\n.#...\n.#...\n##.#.\n##.##\n##.##\n#####\n\n.....\n#....\n#.#..\n#.#.#\n#.###\n#.###\n#####\n\n.....\n.....\n.#...\n.#.#.\n.#.#.\n####.\n#####\n\n#####\n#.###\n..###\n..#.#\n..#.#\n.....\n.....\n\n#####\n#####\n#####\n.####\n.##.#\n.#...\n.....\n\n.....\n.....\n....#\n..#.#\n#.#.#\n#.#.#\n#####\n\n#####\n.#.##\n.#..#\n.#..#\n.#..#\n.#...\n.....\n\n#####\n##.##\n##.##\n.#.##\n....#\n....#\n.....\n\n#####\n#####\n#####\n#####\n#.#.#\n.....\n.....\n\n#####\n#####\n####.\n##.#.\n#..#.\n...#.\n.....\n\n.....\n....#\n#..##\n#..##\n#.###\n#.###\n#####\n\n#####\n###.#\n###.#\n.##.#\n..#.#\n....#\n.....\n\n.....\n....#\n....#\n#..##\n##.##\n##.##\n#####\n\n#####\n####.\n##.#.\n.#.#.\n.#.#.\n...#.\n.....\n\n#####\n.####\n.###.\n..##.\n..#..\n.....\n.....\n\n#####\n#####\n.#.##\n.#.##\n.#.##\n.#.#.\n.....\n\n#####\n.####\n.##.#\n.##.#\n..#..\n.....\n.....\n\n#####\n####.\n##.#.\n#..#.\n...#.\n.....\n.....\n\n.....\n.....\n...#.\n#.###\n#.###\n#####\n#####\n\n.....\n#....\n#..#.\n#..#.\n##.#.\n#####\n#####\n\n#####\n#####\n###.#\n.##.#\n..#.#\n..#..\n.....\n\n#####\n##.#.\n##.#.\n.#.#.\n.#...\n.#...\n.....\n\n.....\n..#..\n..#..\n..#.#\n.##.#\n.####\n#####\n\n.....\n..#..\n..#..\n.##..\n.##.#\n.####\n#####\n\n.....\n..#..\n..#..\n#.#.#\n###.#\n###.#\n#####\n\n#####\n#.###\n..###\n..#.#\n.....\n.....\n.....\n\n.....\n..#..\n#.##.\n#.##.\n#.##.\n#####\n#####\n\n#####\n####.\n###..\n##...\n##...\n#....\n.....\n\n.....\n#....\n##...\n###..\n####.\n####.\n#####\n\n#####\n###.#\n###..\n###..\n.##..\n..#..\n.....\n\n.....\n.....\n.....\n#....\n##...\n###.#\n#####\n\n.....\n#.#.#\n#.#.#\n#.#.#\n###.#\n#####\n#####\n\n.....\n.....\n.....\n.#...\n##...\n###.#\n#####\n\n.....\n....#\n....#\n.#.##\n.#.##\n.####\n#####\n\n.....\n#..#.\n#..##\n#..##\n#..##\n##.##\n#####\n\n#####\n#####\n.#.#.\n...#.\n...#.\n.....\n.....\n\n#####\n###.#\n###.#\n###.#\n##..#\n.#...\n.....\n\n#####\n#####\n##.##\n##..#\n.#..#\n.#...\n.....\n\n#####\n#.###\n#.###\n#.###\n#..#.\n...#.\n.....\n\n#####\n##.##\n.#.##\n.#.#.\n.....\n.....\n.....\n\n.....\n.....\n.....\n.#..#\n.##.#\n.##.#\n#####\n\n#####\n##.##\n##.##\n#..#.\n#..#.\n#....\n.....\n\n#####\n.####\n.##.#\n.##.#\n.#...\n.#...\n.....\n\n#####\n#####\n.####\n.####\n.#.#.\n.#...\n.....\n\n#####\n###.#\n.##.#\n..#.#\n....#\n....#\n.....\n\n.....\n#....\n#..#.\n#.##.\n#.###\n#.###\n#####\n\n#####\n#####\n#####\n#.##.\n..##.\n..#..\n.....\n\n#####\n###.#\n#.#.#\n#.#.#\n#.#.#\n#.#..\n.....\n\n#####\n.###.\n.#.#.\n.#.#.\n...#.\n.....\n.....\n\n#####\n.#.##\n.#.#.\n...#.\n.....\n.....\n.....\n\n#####\n####.\n.###.\n.#.#.\n.#.#.\n.#...\n.....\n\n#####\n#####\n##.##\n##.##\n#..##\n#..#.\n.....\n\n#####\n#.#.#\n..#.#\n.....\n.....\n.....\n.....\n\n.....\n.....\n....#\n....#\n.#..#\n###.#\n#####\n\n#####\n#####\n##.#.\n#..#.\n#....\n#....\n.....\n\n.....\n...#.\n...#.\n..##.\n..###\n.####\n#####\n\n.....\n.....\n...#.\n...#.\n.#.#.\n##.#.\n#####\n\n#####\n.##.#\n.##.#\n.##.#\n.##.#\n..#.#\n.....\n\n#####\n.####\n.###.\n..##.\n...#.\n...#.\n.....\n\n.....\n#....\n#.#..\n#.##.\n#.##.\n#.##.\n#####\n\n.....\n..#..\n..#.#\n..###\n..###\n.####\n#####\n\n.....\n#..#.\n##.#.\n##.#.\n##.#.\n####.\n#####\n\n#####\n#####\n.####\n.##.#\n..#.#\n.....\n.....\n\n.....\n#.#..\n#.##.\n#.##.\n#.##.\n#####\n#####\n\n.....\n.#...\n##..#\n##..#\n###.#\n###.#\n#####\n\n.....\n.....\n.....\n#....\n#.#.#\n#.###\n#####\n\n.....\n.....\n#...#\n#.#.#\n###.#\n###.#\n#####\n\n.....\n...#.\n#..#.\n##.#.\n##.#.\n####.\n#####\n\n#####\n##.##\n#..##\n#...#\n#....\n.....\n.....\n\n#####\n#.###\n..###\n..###\n..#.#\n.....\n.....\n\n.....\n.#...\n.##..\n###..\n####.\n####.\n#####\n\n.....\n..#..\n..#..\n..#..\n..##.\n#.###\n#####\n\n#####\n.####\n.#.##\n...##\n....#\n....#\n.....\n\n.....\n.....\n.#...\n.#...\n.##.#\n.##.#\n#####\n\n#####\n##.##\n##.#.\n##...\n#....\n#....\n.....\n\n#####\n#####\n.####\n..#.#\n..#.#\n..#.#\n.....\n\n.....\n.#...\n.#...\n.#.#.\n##.#.\n#####\n#####\n\n.....\n.....\n.....\n#..#.\n#..#.\n#.###\n#####\n\n.....\n.#.#.\n.###.\n.###.\n.###.\n#####\n#####\n\n#####\n#####\n##.#.\n#....\n#....\n#....\n.....\n\n.....\n.#...\n.#...\n.#..#\n.##.#\n###.#\n#####\n\n.....\n..#..\n.###.\n.###.\n#####\n#####\n#####\n\n.....\n.....\n..#.#\n..#.#\n.##.#\n###.#\n#####\n\n#####\n#####\n#####\n.####\n.#.##\n.#.#.\n.....\n\n#####\n.###.\n.#.#.\n.....\n.....\n.....\n.....\n\n#####\n#####\n#.###\n#.###\n..###\n..#.#\n.....\n\n.....\n#..#.\n#.##.\n#.##.\n####.\n#####\n#####\n\n.....\n..#..\n..#..\n#.#.#\n#####\n#####\n#####\n\n.....\n.....\n....#\n....#\n..#.#\n.##.#\n#####\n\n.....\n#....\n#....\n##..#\n##.##\n#####\n#####\n\n#####\n#####\n#.#.#\n#...#\n#....\n#....\n.....\n\n.....\n.....\n#.#..\n#.#..\n#.#..\n###.#\n#####\n\n.....\n#....\n#....\n##...\n##..#\n###.#\n#####\n\n#####\n###.#\n###.#\n###..\n###..\n#.#..\n.....\n\n.....\n.#...\n##...\n##...\n##..#\n##.##\n#####\n\n.....\n.....\n.....\n..#..\n#.#..\n####.\n#####\n\n#####\n.####\n..###\n..##.\n..#..\n..#..\n.....\n\n.....\n.....\n..#..\n#.#.#\n#.###\n#####\n#####\n\n.....\n.....\n..#..\n#.#..\n#.#.#\n#.###\n#####\n\n#####\n###.#\n.##..\n.##..\n..#..\n..#..\n.....\n\n#####\n#####\n.#.##\n...##\n...##\n....#\n.....\n\n.....\n.....\n.#...\n##...\n##..#\n##.##\n#####\n\n.....\n..#..\n..#..\n..#..\n#.##.\n####.\n#####\n\n#####\n.#.#.\n.#.#.\n.#.#.\n...#.\n...#.\n.....\n\n#####\n#####\n#.###\n#.#.#\n..#.#\n..#.#\n.....\n\n#####\n#####\n#.###\n#.###\n..###\n...#.\n.....\n\n.....\n.....\n.....\n..#..\n#.#..\n#.##.\n#####\n\n#####\n#####\n.##.#\n.#...\n.#...\n.....\n.....\n\n#####\n.##.#\n..#..\n..#..\n.....\n.....\n.....\n\n.....\n...#.\n...#.\n...#.\n..###\n#.###\n#####\n\n#####\n.##.#\n..#.#\n..#..\n..#..\n.....\n.....\n\n#####\n##.##\n##.##\n.#..#\n.#..#\n.#...\n.....\n\n#####\n.##.#\n..#.#\n..#.#\n..#.#\n....#\n.....\n\n#####\n#####\n#####\n.#.##\n.#..#\n.#...\n.....\n\n#####\n#.###\n#..##\n...##\n...##\n....#\n.....\n\n.....\n#....\n#..#.\n#.###\n#####\n#####\n#####\n\n#####\n##.#.\n#....\n#....\n#....\n#....\n.....\n\n.....\n.....\n...#.\n#..##\n#.###\n#.###\n#####\n\n#####\n##.##\n##.##\n##.#.\n.#.#.\n...#.\n.....\n\n.....\n..#..\n#.##.\n####.\n####.\n#####\n#####\n\n#####\n##.#.\n.#.#.\n.#...\n.#...\n.....\n.....\n\n.....\n#...#\n##.##\n##.##\n##.##\n#####\n#####\n\n#####\n#####\n###.#\n#.#.#\n....#\n....#\n.....\n\n.....\n..#..\n..#..\n..##.\n..##.\n#.##.\n#####\n\n.....\n.#...\n.#...\n.##..\n.##.#\n.##.#\n#####\n\n#####\n.####\n..###\n...##\n...##\n....#\n.....\n\n.....\n..#..\n..#..\n..##.\n..###\n.####\n#####\n\n.....\n.#.#.\n.#.#.\n.#.#.\n.#.#.\n.#.##\n#####\n\n.....\n...#.\n...#.\n..###\n#.###\n#.###\n#####\n\n#####\n#.#.#\n#.#.#\n#.#..\n#.#..\n.....\n.....\n\n#####\n#####\n#####\n.##.#\n.##..\n.#...\n.....\n\n#####\n##.##\n##..#\n.#..#\n.#...\n.....\n.....\n\n.....\n....#\n#...#\n#...#\n#...#\n#.#.#\n#####\n\n#####\n####.\n####.\n.###.\n.###.\n.#.#.\n.....\n\n.....\n.....\n....#\n.#..#\n##..#\n##.##\n#####\n\n#####\n##.##\n##.##\n##.##\n##.#.\n.#.#.\n.....\n\n.....\n#.#..\n#.#.#\n#.#.#\n###.#\n#####\n#####\n\n#####\n###.#\n##..#\n##...\n.#...\n.....\n.....\n\n#####\n##.##\n.#.#.\n...#.\n...#.\n...#.\n.....\n\n.....\n#....\n#....\n#..#.\n#..#.\n##.##\n#####\n\n#####\n.##.#\n.##.#\n.##.#\n..#.#\n.....\n.....\n\n#####\n#####\n#####\n##.##\n##.#.\n#....\n.....\n\n.....\n.....\n.....\n...#.\n.#.#.\n#####\n#####\n\n#####\n#####\n#.###\n#.###\n..##.\n..#..\n.....\n\n#####\n###.#\n.##..\n..#..\n..#..\n..#..\n.....\n\n.....\n.#.#.\n##.#.\n##.#.\n##.##\n#####\n#####\n\n.....\n..#.#\n#.###\n#.###\n#####\n#####\n#####\n\n#####\n##.#.\n.#.#.\n.#...\n.....\n.....\n.....\n\n.....\n#....\n#....\n#..#.\n#.##.\n#####\n#####\n\n.....\n....#\n#...#\n#...#\n##..#\n###.#\n#####\n\n.....\n.....\n.#...\n##.#.\n##.#.\n##.#.\n#####\n\n#####\n.###.\n.#.#.\n.#.#.\n.....\n.....\n.....\n\n.....\n.....\n...#.\n.#.##\n##.##\n##.##\n#####\n\n.....\n.....\n#....\n##...\n##.#.\n##.##\n#####\n\n#####\n####.\n###..\n.##..\n..#..\n..#..\n.....\n\n.....\n..#..\n.##..\n.###.\n#####\n#####\n#####\n\n#####\n#.###\n#.###\n#..##\n#..##\n#..#.\n.....\n\n.....\n.....\n...#.\n...##\n...##\n.#.##\n#####\n\n#####\n#####\n#.##.\n#.#..\n#.#..\n.....\n.....\n\n.....\n.#...\n.##..\n.##.#\n.##.#\n###.#\n#####\n\n.....\n#..#.\n#..##\n##.##\n##.##\n##.##\n#####\n\n#####\n#.#.#\n#.#.#\n#.#.#\n#.#..\n#.#..\n.....\n\n.....\n..#..\n.##.#\n.##.#\n#####\n#####\n#####\n\n#####\n#.###\n#.###\n#.#.#\n..#..\n..#..\n.....\n\n.....\n.....\n...#.\n..##.\n..##.\n.###.\n#####\n\n.....\n.....\n.#...\n##..#\n##..#\n###.#\n#####\n\n#####\n#####\n.###.\n.###.\n.##..\n..#..\n.....\n\n.....\n#....\n##...\n##..#\n##..#\n##.##\n#####\n\n#####\n#####\n#####\n#.##.\n#..#.\n.....\n.....\n\n.....\n.#...\n.#...\n##..#\n###.#\n###.#\n#####\n\n.....\n...#.\n...#.\n...##\n#..##\n##.##\n#####\n\n#####\n###.#\n##..#\n##..#\n##..#\n.#...\n.....\n\n.....\n.....\n.#.#.\n.#.#.\n.#.#.\n.#.##\n#####\n\n#####\n#.##.\n#.##.\n#.##.\n#.#..\n..#..\n.....\n\n#####\n#####\n#.##.\n#.##.\n#..#.\n.....\n.....\n\n#####\n#####\n#####\n#####\n###.#\n.#...\n.....\n\n.....\n.....\n#.#..\n###..\n####.\n####.\n#####\n\n#####\n.####\n.####\n..##.\n..#..\n..#..\n.....\n\n.....\n.....\n#.#..\n#.#..\n#.#.#\n###.#\n#####\n\n.....\n.....\n.#...\n.##..\n.###.\n.###.\n#####\n\n.....\n#....\n#.#..\n####.\n####.\n####.\n#####\n\n#####\n##.##\n##.##\n##..#\n.#..#\n....#\n.....\n\n.....\n.....\n..#..\n..#..\n..##.\n#.##.\n#####\n\n#####\n###.#\n.##.#\n.#..#\n....#\n.....\n.....\n\n.....\n#..#.\n##.##\n##.##\n##.##\n#####\n#####\n\n#####\n###.#\n###.#\n.#..#\n.#..#\n.#...\n.....\n\n.....\n.#...\n.##.#\n.##.#\n.####\n#####\n#####\n\n#####\n#####\n###.#\n##..#\n#...#\n#...#\n.....\n\n.....\n.....\n#....\n#...#\n##..#\n##.##\n#####\n\n#####\n##.##\n.#..#\n.#..#\n.#..#\n.#...\n.....\n\n#####\n#####\n###.#\n#.#.#\n#.#.#\n#....\n.....\n\n#####\n##.##\n.#.#.\n.#.#.\n...#.\n.....\n.....\n\n#####\n#####\n#####\n.###.\n..##.\n..#..\n.....\n\n.....\n....#\n..#.#\n.##.#\n.####\n.####\n#####\n\n.....\n.#...\n.#.#.\n.#.#.\n#####\n#####\n#####\n\n.....\n..#.#\n.##.#\n.##.#\n###.#\n#####\n#####\n\n#####\n#####\n##.#.\n#..#.\n#..#.\n...#.\n.....\n\n#####\n##.##\n##.#.\n##.#.\n#....\n.....\n.....\n\n.....\n#....\n#....\n##.#.\n##.#.\n##.#.\n#####\n\n#####\n#####\n###.#\n##..#\n##..#\n#....\n.....\n\nSTOP.\n"
  },
  {
    "path": "exm/aoc/2024/aoc_2024_25_questions.txt",
    "content": "--- Day 25: Code Chronicle ---\n\nOut of ideas and time, The Historians agree that they should go back to check the Chief Historian's office one last time, just in case he went back there without you noticing.\n\nWhen you get there, you are surprised to discover that the door to his office is locked! You can hear someone inside, but knocking yields no response. The locks on this floor are all fancy, expensive, virtual versions of five-pin tumbler locks, so you contact North Pole security to see if they can help open the door.\n\nUnfortunately, they've lost track of which locks are installed and which keys go with them, so the best they can do is send over schematics of every lock and every key for the floor you're on (your puzzle input).\n\nThe schematics are in a cryptic file format, but they do contain manufacturer information, so you look up their support number.\n\n\"Our Virtual Five-Pin Tumbler product? That's our most expensive model! Way more secure than--\" You explain that you need to open a door and don't have a lot of time.\n\n\"Well, you can't know whether a key opens a lock without actually trying the key in the lock (due to quantum hidden variables), but you can rule out some of the key/lock combinations.\"\n\n\"The virtual system is complicated, but part of it really is a crude simulation of a five-pin tumbler lock, mostly for marketing reasons. If you look at the schematics, you can figure out whether a key could possibly fit in a lock.\"\n\nHe transmits you some example schematics:\n\n#####\n.####\n.####\n.####\n.#.#.\n.#...\n.....\n\n#####\n##.##\n.#.##\n...##\n...#.\n...#.\n.....\n\n.....\n#....\n#....\n#...#\n#.#.#\n#.###\n#####\n\n.....\n.....\n#.#..\n###..\n###.#\n###.#\n#####\n\n.....\n.....\n.....\n#....\n#.#..\n#.#.#\n#####\n\n\"The locks are schematics that have the top row filled (#) and the bottom row empty (.); the keys have the top row empty and the bottom row filled. If you look closely, you'll see that each schematic is actually a set of columns of various heights, either extending downward from the top (for locks) or upward from the bottom (for keys).\"\n\n\"For locks, those are the pins themselves; you can convert the pins in schematics to a list of heights, one per column. For keys, the columns make up the shape of the key where it aligns with pins; those can also be converted to a list of heights.\"\n\n\"So, you could say the first lock has pin heights 0,5,3,4,3:\"\n\n#####\n.####\n.####\n.####\n.#.#.\n.#...\n.....\n\n\"Or, that the first key has heights 5,0,2,1,3:\"\n\n.....\n#....\n#....\n#...#\n#.#.#\n#.###\n#####\n\n\"These seem like they should fit together; in the first four columns, the pins and key don't overlap. However, this key cannot be for this lock: in the rightmost column, the lock's pin overlaps with the key, which you know because in that column the sum of the lock height and key height is more than the available space.\"\n\n\"So anyway, you can narrow down the keys you'd need to try by just testing each key with each lock, which means you would have to check... wait, you have how many locks? But the only installation that size is at the North--\" You disconnect the call.\n\nIn this example, converting both locks to pin heights produces:\n\n0,5,3,4,3\n1,2,0,5,3\n\nConverting all three keys to heights produces:\n\n5,0,2,1,3\n4,3,4,0,2\n3,0,2,0,1\n\nThen, you can try every key with every lock:\n\n    Lock 0,5,3,4,3 and key 5,0,2,1,3: overlap in the last column.\n    Lock 0,5,3,4,3 and key 4,3,4,0,2: overlap in the second column.\n    Lock 0,5,3,4,3 and key 3,0,2,0,1: all columns fit!\n    Lock 1,2,0,5,3 and key 5,0,2,1,3: overlap in the first column.\n    Lock 1,2,0,5,3 and key 4,3,4,0,2: all columns fit!\n    Lock 1,2,0,5,3 and key 3,0,2,0,1: all columns fit!\n\nSo, in this example, the number of unique lock/key pairs that fit together without overlapping in any column is 3.\n\nAnalyze your lock and key schematics. How many unique lock/key pairs fit together without overlapping in any column?\n\n--- Part Two ---\n\nYou and The Historians crowd into the office, startling the Chief Historian awake! The Historians all take turns looking confused until one asks where he's been for the last few months.\n\n\"I've been right here, working on this high-priority request from Santa! I think the only time I even stepped away was about a month ago when I went to grab a cup of coffee...\"\n\nJust then, the Chief notices the time. \"Oh no! I'm going to be late! I must have fallen asleep trying to put the finishing touches on this chronicle Santa requested, but now I don't have enough time to go visit the last 50 places on my list and complete the chronicle before Santa leaves! He said he needed it before tonight's sleigh launch.\"\n\nOne of The Historians holds up the list they've been using this whole time to keep track of where they've been searching. Next to each place you all visited, they checked off that place with a star. Other Historians hold up their own notes they took on the journey; as The Historians, how could they resist writing everything down while visiting all those historically significant places?\n\nThe Chief's eyes get wide. \"With all this, we might just have enough time to finish the chronicle! Santa said he wanted it wrapped up with a bow, so I'll call down to the wrapping department and... hey, could you bring it up to Santa? I'll need to be in my seat to watch the sleigh launch by then.\"\n\nYou nod, and The Historians quickly work to collect their notes into the final set of pages for the chronicle.\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Advent of Code 2025 examples.\n--\n--  Some programs work with both HAC and \"full Ada\" compilers like,\n--  GNAT some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject AoC_2025 is\n\n   for Source_Dirs use\n     (\".\",\n      \"..\",              --  For the AoC_Toolbox package\n      \"../../../src\");   --  GNAT's access to the explicit version of the HAT package.\n      \n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\",\n       \"Fast_Unchecked\");\n\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   type AoC_Styles_Checks_Type is\n      (\"Level_0\",\n       \"Level_1\",\n       \"Level_2\");\n\n   AoC_Styles_Checks : AoC_Styles_Checks_Type := external (\"AoC_Styles_Checks\", \"Level_1\");\n\n   for Main use\n     (\"aoc_2025_11.adb\",\n      \"aoc_2025_10.adb\",\n      \"aoc_2025_09.adb\",\n      \"aoc_2025_08.adb\",\n      \"aoc_2025_07.adb\",\n      \"aoc_2025_06.adb\",\n      \"aoc_2025_05.adb\",\n      \"aoc_2025_04.adb\",\n      \"aoc_2025_03.adb\",\n      \"aoc_2025_02.adb\",\n      \"aoc_2025_01.adb\");\n   \n   case AoC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n      when \"Fast_Unchecked\" =>\n         for Object_Dir use \"obj_fast_unchecked\";\n   end case;\n\n   Common_Compiler_Options :=\n     (\"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n      \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n      \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n      \"-gnatf\",   --  Full errors. Verbose details, all undefined references\n      \"-gnatq\",   --  Don't quit, try semantics, even if parse errors\n      \"-gnatQ\");  --  Don't quit, write ali/tree file even if compile errors\n    \n   Style_Checks_1 := \n     (\"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",       --  Style: check x:no extra parens\n      \"-gnatye\",   --  Style: check e:end/exit labels present\n      \"-gnatytc\");     --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   Style_Checks_2 := \n     (\"-gnatye\",       --  Style: check e:end/exit labels present\n      \"-gnaty2\");      --  Style: check indentation\n\n   case AoC_Styles_Checks is\n      when \"Level_0\" => null;\n      when \"Level_1\" => Common_Compiler_Options := Common_Compiler_Options & Style_Checks_1;\n      when \"Level_2\" => Common_Compiler_Options := Common_Compiler_Options & Style_Checks_1 & Style_Checks_2;\n   end case;\n\n   Fast_Options :=\n     (\"-Ofast\", \"-gnatn\", \"-ffunction-sections\");\n     \n   Fast_Unchecked_Options :=\n     (\"-Ofast\", \"-gnatpn\", \"-ffunction-sections\");\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Debug_Options ;\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Options;\n         when \"Fast_Unchecked\" =>\n            for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Unchecked_Options;\n      end case;\n   end Compiler;\n\n   Common_Linker_Options :=\n     (\"-g\", \"-Xlinker\",\n      \"--stack=0x20000000,0x200000\");\n     --  ^ Absent that, GNAT-compiled programs using lots of recursion\n     --    die with error code 16#C0000005# (Windows, Access Violation)\n     --    - no Ada exception, no trace-back...\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Linker_Options;\n         when \"Fast\" | \"Fast_Unchecked\" =>\n            for Default_Switches (\"ada\") use Common_Linker_Options & (\"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend AoC_2025;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_01.adb",
    "content": "--  Solution to Advent of Code 2025, Day 1\n------------------------------------------\n--  Secret Entrance\n--\n--  https://adventofcode.com/2025/day/1\n--  Copy of questions in: aoc_2025_01_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nprocedure AoC_2025_01 is\n\n  use HAT;\n\n  input_name : constant VString := +\"aoc_2025_01\";\n\n  type Rotation_Instruction is record\n    l_r    : Character;\n    amount : Natural;\n  end record;\n\n  instr : array (1 .. 5000) of Rotation_Instruction;\n\n  type Part_Type is (part_1, part_2_dumb, part_2_smart);\n\n  r : array (Part_Type) of VString;\n\n  n : Natural := 0;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      n := n + 1;\n      Get (f, instr (n).l_r);\n      Get (f, instr (n).amount);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    dial : Integer := 50;\n    pwd  : Natural := 0;\n  begin\n    for i in 1 .. n loop\n      if instr (i).l_r = 'L' then\n        dial := dial - instr (i).amount;\n      else\n        dial := dial + instr (i).amount;\n      end if;\n      dial := dial rem 100;\n      if dial = 0 then\n        pwd := pwd + 1;\n      end if;\n    end loop;\n    r (part_1) := +\"\" & pwd;\n  end Do_Part_1;\n\n  procedure Do_Part_2_Dumb is\n    dial : Integer := 50;\n    pwd  : Natural := 0;\n  begin\n    for i in 1 .. n loop\n      --  Straightforward but unefficient method.\n      --  This part completes in 0.47 second (29x slower) with HAC on some powerful machine.\n      for j in 1 .. instr (i).amount loop\n        if instr (i).l_r = 'L' then\n          dial := dial - 1;\n        else\n          dial := dial + 1;\n        end if;\n        dial := dial rem 100;\n        if dial = 0 then\n          pwd := pwd + 1;\n        end if;\n      end loop;\n    end loop;\n    r (part_2_dumb) := +\"\" & pwd;\n  end Do_Part_2_Dumb;\n\n  procedure Do_Part_2_Smart is\n    dial : Integer := 50;\n    new_dial, a, b, delta_pwd : Integer;\n    pwd  : Natural := 0;\n  begin\n    for i in 1 .. n loop\n      --  This part completes in 0.016 second (29x faster) with HAC on some powerful machine.\n      delta_pwd := 0;\n      if instr (i).l_r = 'L' then\n        --  new_dial <- a <- b <- dial\n        --  a, b are multiples of 100.\n        new_dial := dial - instr (i).amount;\n        b := (dial / 100) * 100;\n        if dial > b and then b >= new_dial then\n          delta_pwd := delta_pwd + 1;\n        end if;\n        if new_dial rem 100 = 0 then\n          a := new_dial;\n        elsif new_dial < 0 then\n          a := (new_dial / 100) * 100;\n        else\n          a := ((new_dial + 100) / 100) * 100;\n        end if;\n        if b > a then\n          delta_pwd := delta_pwd + (b - a) / 100;\n        end if;\n      else\n        --  dial -> a -> b -> new_dial\n        --  a, b are multiples of 100.\n        new_dial := dial + instr (i).amount;\n        if dial rem 100 = 0 then\n          a := dial;\n        else\n          a := ((dial + 100) / 100) * 100;\n          if a <= new_dial then\n            delta_pwd := delta_pwd + 1;\n          end if;\n        end if;\n        b := (new_dial / 100) * 100;\n        if b > a then\n          delta_pwd := delta_pwd + (b - a) / 100;\n        end if;\n      end if;\n      dial := new_dial rem 100;\n      pwd := pwd + delta_pwd;\n    end loop;\n    r (part_2_smart) := +\"\" & pwd;\n  end Do_Part_2_Smart;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2_Dumb;\n  Do_Part_2_Smart;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2_dumb) /= Argument (2) or r (part_2_smart) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2 (dumb algo):  \" & r (part_2_dumb));\n    Put_Line (+\"Part 2 (smart algo): \" & r (part_2_smart));\n    --  Part 1: validated by AoC: 989.\n    --  Part 2: validated by AoC: 5941.\n  end if;\nend AoC_2025_01;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_01.txt",
    "content": "L45\nR35\nR42\nR33\nL6\nL32\nR32\nR10\nL9\nL46\nR25\nL32\nL47\nR32\nL18\nL18\nR38\nL43\nR39\nR6\nR7\nR1\nR37\nR7\nL19\nR17\nL41\nL9\nR25\nL1\nR30\nR16\nR17\nL28\nL23\nR45\nL49\nR38\nR47\nR25\nL49\nL26\nL29\nL40\nR40\nL20\nL29\nL20\nL3\nL12\nR27\nL27\nL73\nR65\nL9\nR25\nR84\nR8\nR52\nL65\nL44\nR25\nR32\nR38\nL38\nL57\nL75\nL38\nR94\nR17\nR59\nL57\nL12\nL64\nL41\nR74\nL22\nR52\nR96\nL96\nL82\nL48\nL85\nL39\nR24\nL75\nR10\nL85\nR62\nR52\nR21\nR15\nL77\nR99\nR78\nR50\nL60\nL61\nR71\nL93\nR30\nL64\nR96\nL819\nL7\nR638\nR90\nL71\nL76\nL31\nL693\nR44\nR60\nL4\nR84\nR382\nR34\nR155\nL55\nR124\nR857\nL92\nR71\nL651\nL9\nL967\nL33\nR72\nR28\nL48\nL386\nR978\nL20\nR93\nL84\nL33\nR60\nL25\nR84\nL17\nR64\nL66\nL19\nR19\nL37\nR49\nL12\nL40\nR44\nR96\nR65\nL65\nL43\nL98\nR741\nR814\nL17\nR3\nR185\nL85\nR83\nR17\nL22\nL2\nR27\nL78\nR13\nL678\nL69\nL91\nR34\nL34\nL545\nL43\nR40\nR98\nL50\nL558\nR46\nL95\nR79\nR747\nL97\nL25\nL97\nL49\nR56\nL44\nR37\nL20\nL75\nL33\nL370\nL74\nR672\nL10\nL902\nR12\nR66\nR43\nR91\nR76\nL65\nL11\nR922\nL334\nL88\nL17\nR783\nR34\nR31\nL43\nR12\nL67\nL68\nL2\nL41\nR78\nR1\nR83\nR16\nL17\nR236\nR81\nL76\nR76\nL705\nL345\nL30\nL90\nR70\nL763\nL43\nR498\nL72\nR36\nR44\nR69\nR56\nL61\nL23\nR35\nR46\nR78\nR98\nR839\nL38\nL87\nL99\nL1\nR626\nR62\nR681\nL81\nL78\nR878\nL15\nL785\nR413\nR787\nL31\nL41\nR840\nL68\nR87\nL960\nL92\nR65\nL30\nL370\nL35\nL4\nR39\nR27\nR604\nR70\nR199\nR69\nR28\nL49\nL65\nR70\nR51\nR39\nL543\nR90\nR45\nR15\nR54\nL4\nL379\nL21\nR98\nL7\nR76\nL767\nR227\nR84\nR92\nL30\nL273\nL33\nL67\nR46\nR11\nL36\nR179\nL264\nR63\nR49\nR52\nL52\nL48\nR5\nL535\nR530\nL23\nL77\nR96\nL40\nL56\nL30\nL467\nL63\nL640\nR75\nL57\nR80\nR56\nL54\nL475\nL25\nR93\nL518\nL16\nL126\nR60\nR7\nL7\nR7\nL4\nR51\nR53\nR369\nR49\nR382\nR24\nR76\nL944\nR11\nL91\nR169\nR47\nR1\nL93\nR18\nL18\nR56\nR32\nL88\nR62\nL62\nR5\nR17\nR78\nL33\nR32\nR13\nL12\nL59\nL4\nR90\nL95\nL83\nR51\nR34\nR66\nR479\nR72\nL51\nL341\nR97\nR89\nR80\nR103\nL38\nL26\nL63\nL54\nL53\nL94\nL86\nR20\nR38\nL72\nL319\nR26\nL30\nR656\nL80\nL1\nL52\nL78\nR78\nL1\nL99\nL523\nL50\nL76\nR49\nR19\nR536\nL662\nL70\nR656\nL79\nR99\nR201\nR99\nR82\nL81\nR61\nR89\nL50\nR92\nL192\nL81\nR75\nL40\nL65\nR38\nL27\nL65\nL81\nR52\nL11\nR25\nR15\nL71\nR36\nL436\nL21\nL336\nR72\nR886\nL65\nL262\nR46\nR16\nR543\nR868\nR32\nL13\nR70\nR32\nR47\nR21\nR90\nR10\nR105\nR25\nL30\nL26\nL373\nL20\nL29\nR45\nR3\nR61\nL61\nR76\nR538\nR60\nR25\nL99\nR215\nL23\nL92\nL98\nL87\nR48\nL42\nR462\nL95\nL788\nL69\nL980\nR83\nL92\nL80\nL62\nL21\nR178\nL66\nL53\nR85\nR377\nL46\nL82\nR28\nL246\nR68\nR83\nR17\nL22\nR52\nL29\nR9\nL32\nL92\nL37\nR29\nR12\nR85\nL97\nL34\nL66\nL90\nR55\nR12\nR23\nL707\nL781\nL12\nL66\nR66\nR744\nR19\nL19\nL911\nL49\nR38\nL653\nL237\nR597\nR89\nL18\nL60\nL36\nR94\nL51\nR5\nL94\nR36\nR6\nR39\nL13\nL26\nR15\nL25\nL27\nR58\nL21\nR11\nL61\nR711\nL39\nL47\nL97\nL878\nL8\nR61\nR73\nR22\nL948\nR97\nL97\nL55\nR55\nR62\nL62\nR79\nR68\nL447\nR32\nR81\nR34\nL36\nL30\nL716\nR89\nR415\nL69\nL37\nL23\nL73\nL67\nL85\nL458\nL78\nL98\nR10\nL91\nR53\nR96\nL85\nR436\nL45\nR763\nL18\nR9\nL1\nL8\nR11\nR37\nL699\nR151\nR64\nR36\nR58\nR58\nL14\nR468\nR62\nR16\nR52\nR85\nL72\nR87\nL687\nL606\nL975\nR87\nL19\nL39\nR5\nR84\nR50\nL52\nL69\nR6\nR50\nR19\nR46\nL95\nL62\nR50\nL593\nL17\nL64\nL19\nL95\nR56\nL966\nL72\nR37\nR40\nL45\nR4\nR907\nL71\nL95\nL15\nR84\nR44\nR11\nR76\nL37\nR13\nL92\nL53\nR69\nR1\nL14\nR13\nR589\nL89\nL569\nL406\nR60\nR15\nR57\nL80\nR52\nL63\nR34\nR32\nR81\nR287\nR58\nR42\nL13\nR63\nL50\nR63\nR37\nL88\nR88\nR1\nR62\nL29\nL60\nL17\nR54\nL11\nL71\nL29\nR35\nL86\nR58\nL43\nL293\nR59\nL106\nL24\nR84\nR2\nL26\nR40\nR473\nR3\nL397\nR42\nR93\nL14\nR96\nL41\nL93\nL90\nL76\nL96\nL35\nR67\nL60\nR28\nL72\nR72\nL85\nR13\nR486\nR612\nL26\nL93\nL7\nR62\nR17\nR821\nR191\nR16\nL69\nL18\nL15\nR12\nR18\nL1\nR23\nL49\nR62\nL70\nL72\nR98\nR87\nR45\nR961\nL44\nR37\nR756\nL90\nR626\nR28\nL32\nR77\nR79\nR91\nR551\nL67\nL83\nR452\nL11\nR11\nR2\nR98\nR391\nL430\nR864\nL26\nR99\nR2\nR89\nL89\nR68\nR6\nR26\nL428\nR211\nL70\nR97\nL10\nR70\nL86\nR22\nR45\nR749\nR38\nR62\nR94\nL94\nR32\nR880\nL19\nR88\nR219\nR76\nL43\nL658\nR15\nR2\nR8\nL42\nR242\nL95\nR97\nL2\nR86\nR14\nL46\nL48\nR94\nL38\nL69\nL93\nL25\nR25\nL84\nR81\nR33\nR215\nL445\nR95\nR521\nR61\nR523\nR72\nR28\nR75\nR98\nL73\nL14\nL351\nL63\nR28\nL93\nR93\nR97\nL91\nR659\nR33\nL98\nR40\nL27\nR387\nR77\nR881\nR42\nL477\nR77\nR65\nR35\nR79\nL460\nR497\nL70\nR54\nR95\nR673\nR32\nL119\nL81\nR47\nR53\nR119\nR46\nL25\nR60\nR97\nL44\nL53\nL53\nL52\nL87\nR2\nR17\nL10\nR568\nL3\nL63\nR928\nR318\nR159\nR76\nR35\nR146\nL94\nR36\nR88\nL2\nR91\nR679\nL34\nR55\nR11\nL23\nR78\nL76\nL84\nL6\nL338\nR83\nR91\nR878\nR35\nL49\nR898\nR837\nR67\nR96\nL60\nR5\nR44\nR837\nL55\nL11\nL90\nL696\nL26\nL57\nR74\nL63\nL8\nR8\nR606\nL6\nR8\nL8\nR27\nR54\nL81\nR604\nL639\nR66\nL31\nL102\nL11\nR95\nL70\nR488\nL19\nR381\nL42\nR41\nL23\nL704\nL50\nL11\nR409\nR44\nR26\nR74\nL64\nR938\nR60\nL16\nR17\nL99\nR656\nR173\nL91\nL40\nR5\nR6\nR39\nL656\nL7\nR53\nR675\nR29\nL4\nL15\nL66\nL54\nR79\nR3\nR63\nR21\nL32\nR96\nL96\nL53\nR225\nR6\nR47\nL22\nL94\nR92\nL68\nL32\nR57\nR633\nR79\nL69\nL17\nL612\nL92\nR83\nL62\nR14\nR64\nR27\nL605\nR62\nR9\nL13\nL64\nR83\nL67\nL91\nR82\nL59\nL42\nL494\nR94\nR75\nL782\nL93\nL56\nL244\nR50\nR86\nL36\nR545\nL82\nL63\nR80\nL87\nL93\nL23\nL177\nL28\nR67\nR361\nR92\nR42\nR470\nL4\nL34\nL44\nR33\nR45\nR726\nL55\nR32\nL15\nR412\nL12\nL418\nR30\nL65\nR581\nR81\nL12\nR17\nL2\nR55\nR35\nR53\nL98\nL45\nR797\nL10\nL51\nL9\nL182\nR70\nR85\nL52\nR52\nL51\nL34\nR46\nR15\nL76\nL490\nR40\nL50\nR255\nL55\nL478\nL94\nR943\nL2\nL69\nR11\nL11\nL13\nR86\nL59\nL614\nR799\nL21\nL55\nR28\nL30\nR84\nR74\nL87\nL23\nL52\nL61\nL83\nL97\nL870\nL6\nR82\nR69\nR49\nR65\nR335\nL393\nR63\nL70\nL356\nR56\nR54\nR78\nR68\nL43\nL57\nR51\nR649\nL64\nR91\nL63\nL864\nL26\nR26\nR21\nR72\nL299\nR6\nL26\nR27\nR95\nL69\nL74\nR91\nR54\nL83\nL54\nL69\nR8\nR39\nR57\nR4\nR645\nR455\nL194\nR282\nL23\nR35\nL47\nR66\nL75\nR72\nR3\nR81\nR86\nR14\nL780\nL75\nR47\nR48\nR60\nL40\nL25\nL35\nL411\nR532\nL41\nL80\nL31\nL27\nL677\nR35\nR68\nL51\nR51\nL68\nR32\nR22\nL42\nR18\nL30\nR55\nL155\nL494\nR161\nL67\nL421\nR54\nL97\nL436\nL87\nR98\nR689\nL24\nL76\nL30\nR27\nR3\nR39\nL39\nL502\nR45\nR528\nR76\nR53\nR858\nL58\nR95\nR18\nR767\nR887\nL53\nR3\nR817\nR89\nR13\nR55\nR9\nR934\nL18\nL16\nL86\nR86\nR450\nR31\nR819\nR79\nR21\nR66\nR14\nR20\nR30\nL30\nR2\nR98\nL92\nL98\nL10\nR74\nL914\nL64\nL96\nL88\nL15\nL839\nL658\nR236\nL919\nR53\nR86\nR76\nR2\nL18\nR467\nR98\nR19\nR97\nL88\nL71\nR48\nR14\nL95\nL52\nL329\nL28\nR65\nR901\nL52\nL930\nR20\nR6\nL6\nL64\nR83\nL721\nL28\nL70\nL75\nL273\nR48\nL753\nR74\nL743\nL78\nL26\nL590\nL18\nL893\nL20\nL53\nR98\nR47\nR655\nR53\nL11\nR909\nR69\nL89\nR35\nR30\nR4\nR52\nR68\nR793\nR87\nL4\nR74\nR99\nR31\nL845\nL55\nL43\nL57\nR56\nR43\nL99\nL98\nL2\nL8\nR42\nR66\nR72\nL470\nL2\nL6\nL94\nR89\nR911\nR18\nL618\nR939\nL39\nL45\nR92\nR43\nL58\nL932\nR43\nL43\nL82\nL68\nR50\nL80\nL2\nL69\nR93\nR79\nR279\nL6\nR23\nL78\nR77\nR384\nL46\nR8\nL67\nR40\nR62\nR578\nL8\nR91\nR37\nR5\nR24\nR349\nR65\nR27\nR35\nR78\nR22\nL48\nL52\nR98\nR2\nL835\nL16\nL49\nR817\nL52\nR35\nL8\nL92\nR32\nL32\nR87\nR814\nL9\nL46\nR72\nR38\nR16\nR10\nR25\nL7\nL13\nR67\nR2\nL15\nL964\nL777\nR1\nL91\nL10\nR39\nR62\nR99\nR38\nR70\nL13\nR5\nR1\nL96\nL5\nL13\nR13\nR88\nL15\nR627\nR8\nR92\nL1\nL36\nL522\nL75\nL66\nR49\nR98\nL47\nR72\nL55\nR9\nL909\nL519\nR2\nR465\nL77\nR33\nR3\nR19\nL43\nL15\nL2\nL47\nL36\nR73\nR23\nR4\nL75\nL25\nL960\nR81\nR79\nL60\nL88\nL91\nL61\nL4\nL954\nR3\nL14\nL42\nL46\nR31\nR26\nR51\nR70\nL73\nL48\nR94\nL94\nL934\nR29\nL55\nR60\nL94\nR94\nR871\nR16\nL64\nR34\nL57\nL80\nR80\nL68\nL27\nL263\nR9\nL807\nL442\nL2\nL586\nL14\nL25\nL84\nR71\nR11\nR89\nL48\nR86\nR28\nR89\nR7\nR64\nR12\nL67\nR96\nL218\nR818\nL29\nL13\nR54\nL41\nR69\nR81\nL66\nL208\nR24\nR28\nR72\nR71\nR29\nL97\nL55\nL42\nL83\nR44\nR18\nL36\nL941\nL208\nR76\nL46\nL37\nR31\nR57\nR19\nL12\nR46\nR60\nR927\nR33\nR9\nR429\nL92\nL91\nL2\nL93\nL17\nL759\nL40\nR2\nR325\nR48\nR336\nL61\nL54\nL34\nR62\nR29\nL40\nL38\nR31\nL68\nL81\nL13\nL69\nL6\nL67\nL85\nR85\nL2\nR70\nR701\nL89\nL80\nR38\nL38\nR31\nL31\nR477\nL77\nR63\nR82\nR55\nR167\nL67\nL63\nR25\nR938\nL891\nR91\nR16\nR91\nL981\nR61\nL61\nR74\nL80\nL86\nL359\nL63\nR88\nR46\nR84\nR8\nL11\nL32\nL64\nL331\nR60\nR440\nL45\nL806\nR51\nR83\nL56\nL82\nR55\nL92\nR176\nL93\nL91\nL527\nL973\nL41\nR547\nR21\nR842\nR49\nR882\nL390\nR122\nL97\nL53\nR18\nR65\nR30\nL95\nL865\nL35\nR80\nR965\nL145\nL97\nL97\nR94\nL729\nR93\nR89\nR669\nR8\nL30\nR72\nR702\nL2\nL72\nR183\nL18\nL765\nL4\nR80\nL76\nL30\nL870\nL521\nL879\nL52\nR80\nL45\nL15\nL68\nL73\nR1\nL32\nR4\nR563\nL63\nL32\nL68\nL41\nL76\nL83\nR39\nL10\nR71\nR78\nL59\nR81\nR43\nL177\nL70\nL96\nR66\nR34\nL29\nR763\nR66\nL13\nL310\nL8\nL66\nR14\nR90\nR393\nR5\nR795\nR89\nR27\nR670\nR319\nL43\nL60\nR743\nL33\nR88\nR84\nR281\nR699\nL12\nR36\nL56\nL32\nR27\nL4\nL40\nR44\nR20\nR12\nL1\nR79\nL37\nR491\nR9\nL360\nR689\nR571\nR89\nL89\nL54\nR17\nL63\nL56\nR688\nL975\nR343\nL19\nR19\nL19\nL77\nL4\nR30\nR770\nL84\nR216\nR68\nL6\nR57\nL51\nR12\nL5\nL348\nR63\nR95\nL7\nL132\nL78\nR296\nR525\nR79\nL3\nL414\nL59\nR2\nR74\nR50\nL37\nR87\nL8\nL20\nR45\nL970\nR359\nL23\nL58\nR850\nR4\nL31\nR53\nR99\nR43\nL6\nR79\nR284\nL46\nL33\nR79\nR992\nR6\nR62\nR26\nR921\nR27\nR9\nL522\nR79\nR24\nR76\nR4\nL32\nL72\nR50\nL50\nL50\nR30\nR84\nR95\nR41\nR81\nR19\nR159\nL22\nL27\nL10\nR30\nL30\nR45\nL845\nL82\nR31\nL53\nL96\nR15\nL43\nL72\nR71\nL71\nR54\nL83\nL71\nL71\nR871\nR46\nL434\nL181\nR81\nL955\nR643\nR47\nR53\nR80\nR912\nL92\nR76\nL76\nR87\nR34\nL502\nR64\nL83\nL538\nL962\nR567\nL67\nL56\nL76\nR6\nL744\nL830\nL17\nR61\nL433\nL3\nR8\nL792\nR38\nL62\nR29\nR7\nR32\nL68\nR56\nR96\nR63\nL61\nL77\nL593\nL819\nL573\nR841\nL32\nL64\nR63\nL51\nL573\nL64\nR93\nL29\nL276\nL35\nR35\nR3\nL47\nL40\nL81\nR65\nR897\nL28\nL69\nR21\nR31\nR648\nL78\nL22\nL88\nL49\nR8\nR98\nR56\nR2\nR65\nR8\nL71\nL31\nR38\nL87\nR51\nR593\nL93\nL77\nL23\nR97\nL95\nR55\nL49\nR92\nR93\nL95\nR2\nR678\nR80\nL65\nR55\nR35\nR417\nR928\nL29\nL67\nL47\nR15\nR45\nL72\nR23\nR64\nL5\nL55\nL29\nR28\nR632\nL15\nL36\nL57\nL565\nR43\nL45\nL97\nL621\nR62\nL47\nL53\nL31\nR31\nR33\nR12\nL125\nL71\nL14\nL35\nL92\nL97\nR537\nR86\nL34\nL61\nL39\nL363\nR63\nL80\nL60\nR40\nR42\nL25\nL79\nL738\nL40\nR70\nR40\nR624\nL80\nR33\nR77\nL82\nL26\nL16\nR79\nR721\nL975\nL24\nR284\nR15\nR527\nL27\nR83\nR17\nR14\nR86\nL9\nR9\nR42\nR58\nR85\nL420\nL97\nR9\nL23\nL1\nL53\nR99\nL846\nR995\nR47\nR37\nR168\nL46\nR46\nR208\nR9\nL10\nL96\nL11\nL35\nL44\nR250\nL50\nL24\nL63\nR55\nR68\nR343\nR84\nL84\nL15\nL585\nL713\nL50\nR63\nR6\nL6\nR80\nR39\nR53\nL72\nR15\nR85\nL32\nL210\nL167\nR9\nL90\nR15\nL397\nR699\nR73\nL89\nR61\nR40\nR873\nL985\nL80\nR18\nL31\nL107\nL19\nL82\nR12\nL35\nL146\nL30\nL31\nL69\nR20\nR61\nL81\nR23\nR390\nR93\nL24\nL576\nR601\nR3\nR90\nR6\nR94\nL774\nR2\nR281\nL709\nR460\nR31\nL46\nL38\nL21\nR14\nR14\nL27\nR2\nR747\nL297\nR78\nR89\nR36\nL599\nR79\nL616\nR34\nL40\nR15\nR77\nL592\nR67\nR21\nR552\nL40\nL12\nR12\nR49\nR51\nR7\nL108\nL99\nL71\nR71\nL28\nR55\nL20\nL907\nR77\nR23\nR7\nR47\nR146\nL83\nR80\nL97\nL684\nL211\nR57\nL62\nR20\nL164\nL256\nL22\nL99\nL37\nL34\nL70\nR29\nL96\nR32\nR45\nL48\nL27\nR74\nR70\nR83\nR4\nL4\nR14\nR23\nR15\nL44\nL8\nR787\nR55\nR42\nR82\nR34\nL51\nL291\nL58\nR28\nR73\nL5\nR4\nR617\nR96\nL16\nR903\nL91\nR91\nR80\nL41\nR61\nR350\nR64\nL992\nL22\nR72\nR28\nL78\nR29\nR36\nL87\nR12\nL393\nR81\nL93\nL8\nL96\nR95\nR45\nR12\nL94\nR39\nL80\nL77\nL59\nR91\nR47\nR478\nR22\nL15\nR685\nL76\nR7\nL23\nR95\nL95\nR64\nR39\nL745\nL11\nR130\nL27\nL50\nL62\nL34\nR50\nR41\nL95\nR27\nR91\nL25\nL93\nR722\nL95\nL27\nL44\nL841\nR73\nL88\nR36\nL83\nL91\nR531\nL49\nL342\nR74\nR951\nR73\nR56\nL321\nL45\nL45\nL28\nL535\nR18\nR185\nR319\nR58\nR30\nR741\nR9\nL35\nR42\nR51\nR58\nL12\nR54\nL203\nR7\nL204\nL63\nR34\nL62\nL42\nR209\nL27\nR51\nL50\nL50\nL59\nL61\nL88\nR246\nL97\nL41\nL67\nR29\nR16\nR99\nR54\nL68\nL63\nR52\nL52\nR24\nL24\nL363\nR32\nR31\nL18\nR18\nL13\nL50\nL37\nR39\nR7\nL90\nR80\nR64\nL92\nL8\nL581\nR77\nL16\nL85\nL95\nL286\nL14\nR29\nL58\nL232\nL463\nR24\nR76\nL76\nR36\nR564\nR26\nR274\nL5\nL95\nR61\nL94\nL73\nR94\nR12\nR18\nL65\nR77\nL55\nL75\nL42\nL85\nL73\nL461\nL605\nL679\nR8\nR9\nR57\nR71\nR49\nL73\nR489\nL63\nL2\nL575\nL536\nR999\nL32\nL25\nR969\nR63\nL730\nR24\nL22\nR41\nL76\nR19\nL319\nR26\nR883\nL7\nR50\nR48\nR43\nR57\nR92\nL41\nL23\nR72\nR48\nR93\nR4\nL15\nL211\nL60\nR230\nR611\nL58\nR4\nR69\nR575\nL57\nL33\nR30\nR70\nL71\nR36\nL170\nL13\nL82\nL1\nR34\nL33\nL76\nL843\nL81\nR8\nR92\nL353\nL1\nL13\nR67\nL34\nL4\nL16\nR654\nR11\nR89\nR30\nL82\nR52\nL45\nL89\nR90\nL45\nL31\nL1\nR33\nL81\nL31\nL48\nL445\nL92\nL15\nR49\nL67\nL86\nR90\nR33\nR81\nR53\nL41\nL51\nL86\nL75\nR749\nR78\nR45\nR35\nR93\nR3\nL99\nL4\nL33\nR75\nL42\nR46\nR97\nL131\nL13\nR1\nL58\nR20\nL3\nR41\nL33\nL67\nL15\nR15\nL30\nR31\nL13\nL88\nR66\nR26\nR8\nR50\nL41\nL94\nL815\nR42\nL34\nR853\nR68\nL75\nL76\nR86\nL822\nL72\nR75\nL955\nR10\nL28\nL81\nL19\nL63\nR87\nR904\nL413\nL87\nR280\nL94\nR62\nR52\nL13\nR13\nL343\nR43\nL54\nL546\nR49\nR51\nL90\nL97\nL915\nR2\nR763\nR20\nL459\nL46\nL78\nL28\nR21\nR7\nL3\nR3\nL92\nR92\nR53\nR30\nL283\nR46\nR69\nR42\nR43\nR37\nL49\nL87\nR30\nL28\nR44\nR53\nL77\nR93\nR34\nR50\nL667\nR467\nR15\nR73\nL74\nL63\nL19\nL46\nL1\nL85\nR42\nL542\nL34\nR90\nL76\nL636\nL490\nL11\nL12\nR13\nR56\nL68\nL27\nL25\nR93\nR55\nL94\nR66\nL18\nL404\nR322\nL842\nL59\nL6\nL41\nL62\nR40\nL54\nR24\nR102\nL48\nR93\nL47\nL70\nL30\nL41\nL59\nR19\nR16\nL61\nL37\nR87\nL70\nL54\nR6\nL421\nR73\nL58\nL88\nR52\nL973\nR9\nR830\nR70\nL55\nL94\nR439\nL49\nR54\nL27\nL234\nL7\nR73\nR72\nL62\nR504\nL96\nR590\nL8\nR66\nL96\nL73\nR179\nR18\nL28\nL325\nR59\nR33\nR79\nL986\nL826\nL18\nL82\nL65\nR428\nL63\nR38\nR1\nL22\nL17\nR16\nL25\nL42\nL45\nL269\nR31\nR92\nL63\nR42\nR63\nL26\nR26\nR7\nR71\nR85\nR118\nL26\nR11\nR34\nL25\nL82\nL493\nL90\nR88\nL62\nR47\nL26\nL1\nL869\nR13\nR4\nL9\nL19\nR6\nL81\nR92\nR16\nL8\nR899\nL259\nL41\nR26\nR74\nL554\nR54\nL59\nL41\nL50\nR42\nR32\nR3\nR73\nR5\nR93\nL92\nL6\nL89\nR89\nL743\nL26\nL231\nR18\nR82\nR28\nR29\nR143\nR57\nL74\nR17\nR20\nL75\nL21\nR76\nR60\nR239\nL43\nR44\nL244\nL17\nR161\nR36\nL31\nR47\nR390\nL42\nL209\nL78\nL54\nL307\nL47\nL5\nR53\nL53\nR481\nR6\nR13\nL725\nR25\nR28\nL33\nL95\nR69\nR31\nL42\nR18\nR62\nR62\nL182\nR78\nR4\nR496\nR4\nL401\nR1\nL25\nR325\nL31\nL54\nL44\nR87\nL443\nL35\nR55\nL35\nR24\nR88\nR33\nR87\nL86\nL18\nL95\nL7\nR99\nL87\nR62\nL36\nR31\nR9\nR93\nR703\nR68\nR53\nR1\nL28\nR62\nL341\nL2\nR87\nR92\nL92\nR49\nR51\nR44\nR56\nL768\nL287\nR28\nL19\nR46\nR168\nL4\nR636\nL4\nL28\nL45\nR77\nR76\nR99\nR74\nR92\nR59\nL41\nR34\nL22\nL318\nR18\nR3\nL7\nL509\nL58\nR31\nL81\nL98\nL206\nR54\nR995\nR505\nL699\nR99\nL947\nR6\nR32\nL66\nL23\nR9\nL214\nR3\nR558\nL67\nR41\nL32\nL54\nL51\nR28\nR77\nR82\nR18\nR638\nL38\nR20\nL63\nL89\nL218\nL750\nL31\nL69\nL90\nR19\nR49\nR86\nR36\nL71\nL9\nL36\nL57\nR73\nR23\nL323\nR63\nR37\nL74\nL226\nR4\nR21\nR69\nL94\nR559\nL70\nR86\nL75\nR9\nR26\nR76\nR98\nR91\nL518\nR64\nL10\nR164\nR788\nL988\nR92\nL594\nL62\nL36\nL8\nR108\nR26\nR82\nL33\nR12\nR413\nR834\nL749\nR47\nR68\nR516\nL43\nR715\nR881\nL69\nR915\nR85\nR17\nR450\nR20\nR13\nR80\nL80\nL26\nL213\nR403\nR36\nR49\nL24\nL77\nL49\nR8\nR79\nL46\nL40\nL844\nL363\nR18\nL444\nR33\nR65\nL833\nL963\nL69\nR71\nL71\nR83\nL7\nL88\nL186\nR592\nL14\nR38\nL18\nL58\nR58\nL31\nR22\nR582\nR27\nL72\nL41\nR56\nL43\nL67\nL33\nR93\nL93\nR59\nL59\nR30\nR38\nR47\nR43\nR42\nL63\nL837\nR77\nR59\nR37\nL73\nL99\nL1\nR79\nL494\nL59\nR74\nR61\nL911\nR50\nL39\nL16\nR122\nL68\nR1\nL48\nL930\nL22\nR10\nR90\nL8\nR6\nL635\nL38\nR75\nR26\nL80\nR81\nL27\nR414\nL73\nR57\nL62\nR664\nL151\nL35\nR86\nL79\nR37\nR14\nR20\nR32\nL8\nR20\nL36\nL809\nL98\nL41\nR62\nL72\nL36\nR94\nL65\nL835\nL86\nR78\nR39\nR76\nR971\nR22\nR9\nR91\nL50\nL99\nR49\nL73\nR43\nR30\nL393\nL40\nR33\nR12\nR71\nR108\nR45\nL718\nR69\nL87\nL144\nR11\nR16\nL97\nR14\nR896\nL80\nL16\nR40\nR11\nL28\nR9\nL63\nR59\nL377\nL51\nR63\nL42\nL821\nR35\nL35\nR69\nL49\nR16\nL36\nL88\nR3\nR685\nR98\nL77\nL67\nR46\nL59\nL31\nL13\nR3\nR81\nL33\nR49\nL84\nR587\nR97\nR58\nR590\nR19\nL15\nR60\nR91\nL55\nR85\nR2\nR22\nL954\nL77\nR72\nL53\nR58\nL11\nR711\nL64\nR71\nL7\nR710\nR490\nL74\nL11\nR98\nL79\nL83\nL51\nR60\nR802\nR38\nR737\nR468\nL11\nR13\nL9\nL990\nL87\nR96\nR371\nL2\nL386\nR19\nL19\nR80\nR18\nR35\nL95\nL12\nR20\nR33\nR21\nR15\nL615\nL14\nL31\nR12\nL67\nL358\nL42\nR42\nL42\nR7\nL6\nL55\nL48\nR7\nR34\nR211\nR28\nL86\nR2\nL494\nL50\nL56\nL20\nL29\nL45\nR56\nR94\nL91\nR777\nL36\nR47\nR53\nL385\nL15\nR16\nL16\nL43\nR43\nR36\nR43\nR21\nR38\nL31\nL314\nL42\nL51\nL8\nL56\nL519\nL17\nR168\nR810\nL17\nR64\nR75\nR24\nL605\nL76\nR57\nL64\nL36\nR9\nL9\nR78\nR22\nR70\nR985\nL55\nR8\nR92\nR283\nL83\nL32\nL778\nR74\nR1\nL65\nL97\nL903\nL958\nR6\nL948\nL13\nL63\nL24\nR273\nR27\nL74\nL26\nR81\nR11\nL50\nR664\nR694\nR34\nL34\nL18\nR73\nR60\nL15\nL89\nL11\nL8\nL92\nL31\nL559\nL78\nR68\nR52\nR95\nR92\nL15\nR38\nR38\nR43\nL22\nR79\nL72\nR43\nR50\nL21\nR42\nR58\nL93\nL7\nR15\nL15\nR78\nR89\nR53\nL23\nL54\nR57\nL629\nR8\nR38\nR926\nL953\nL286\nL21\nR17\nR55\nR67\nR178\nL13\nR113\nL53\nR50\nR73\nL70\nL26\nR1\nR22\nL97\nL823\nL91\nR56\nR13\nL42\nL13\nL52\nR17\nR245\nL23\nL143\nR92\nR64\nR206\nR15\nL21\nR83\nL50\nL21\nL17\nR47\nR68\nR90\nR48\nL44\nR831\nR917\nR48\nL56\nL914\nL30\nR64\nR218\nR18\nL414\nR58\nR850\nL490\nR96\nL903\nL75\nR78\nL26\nL81\nL90\nR8\nR33\nR931\nR625\nL68\nR77\nL9\nL543\nR25\nL682\nR31\nL31\nL685\nL15\nL66\nR91\nR63\nL46\nL42\nL28\nL1\nL22\nR92\nL865\nL95\nR781\nR82\nR72\nR59\nR98\nL753\nL19\nR56\nL157\nL13\nR13\nR18\nL55\nL65\nR21\nL910\nL9\nL40\nL159\nR99\nL75\nR75\nR47\nR96\nR57\nL92\nL71\nR63\nR59\nL49\nR90\nR81\nR19\nR84\nR16\nR94\nR6\nL549\nR477\nL32\nL43\nL68\nR70\nL55\nL23\nL77\nL1\nL85\nL14\nR37\nR6\nR3\nR27\nR37\nL75\nL769\nR94\nR540\nR72\nL965\nR85\nR8\nR79\nL33\nL28\nL84\nL10\nL24\nL79\nR498\nL19\nL15\nR14\nL94\nL482\nL64\nR252\nL11\nL93\nL7\nL591\nR540\nL75\nL65\nR91\nR42\nL42\nL72\nR72\nL94\nR19\nL25\nL21\nL57\nR22\nR856\nL17\nL83\nR439\nL39\nL92\nR80\nR78\nR844\nL45\nL42\nR477\nR92\nR5\nL97\nR57\nR143\nL73\nL89\nR59\nR3\nL76\nR76\nR816\nR29\nL28\nR53\nR36\nL39\nR25\nR979\nL6\nL54\nR47\nL440\nR82\nL430\nL9\nR332\nL1\nL92\nL50\nR26\nL76\nL565\nL27\nR711\nL46\nR17\nR29\nR81\nL64\nR96\nL38\nR6\nR96\nR67\nR93\nR44\nL36\nR436\nL184\nL27\nR11\nR97\nL55\nR81\nR37\nR40\nR521\nR779\nR94\nR45\nL65\nL71\nR71\nR26\nL737\nR37\nL94\nR68\nR81\nL580\nR886\nL73\nR728\nR84\nR9\nL586\nL95\nR30\nL1\nR94\nL95\nR83\nL9\nR70\nR21\nL821\nL15\nR15\nR33\nL33\nL74\nR58\nR16\nL718\nL26\nR544\nR64\nL64\nR930\nL18\nL12\nL56\nR53\nR67\nR236\nL534\nL95\nL57\nR60\nL74\nL848\nL201\nL60\nR73\nL740\nL85\nR13\nL91\nL61\nL502\nR51\nR96\nL45\nR18\nR82\nL952\nR36\nR16\nL56\nL417\nR17\nR51\nL54\nL41\nR94\nL929\nR35\nR13\nL613\nR312\nR99\nR51\nL17\nL866\nL679\nR594\nR6\nL22\nR32\nR90\nR19\nL54\nL341\nL87\nR63\nL38\nR38\nL5\nR5\nL84\nR62\nL5\nL25\nL70\nR22\nL358\nR58\nL10\nL41\nR51\nL63\nR63\nR87\nR99\nR24\nL76\nR94\nL28\nL73\nL27\nL26\nR29\nR10\nR87\nL24\nL60\nR84\nR55\nL54\nL99\nR72\nL38\nR64\nR22\nL37\nR15\nR940\nR60\nL88\nR39\nR7\nR15\nL73\nR743\nR60\nR35\nR26\nR66\nL22\nR70\nR23\nL609\nR8\nL737\nL63\nL81\nR25\nR74\nR82\nR36\nL51\nR28\nL21\nL30\nR538\nR656\nR40\nL96\nR66\nL52\nR29\nR202\nL76\nR31\nR73\nR37\nL734\nR24\nR77\nL77\nL68\nR54\nR7\nR98\nL91\nL32\nL49\nR11\nL4\nR43\nR80\nR2\nR20\nR653\nR89\nR787\nL11\nL17\nR28\nL59\nR59\nL82\nR75\nR35\nR70\nL898\nR198\nL79\nL27\nL92\nL13\nR35\nR534\nR12\nR58\nL26\nR386\nL27\nL12\nR80\nL83\nL30\nL17\nL54\nL43\nR77\nL77\nL38\nL962\nR96\nR451\nR61\nL8\nR962\nL94\nL68\nR64\nR36\nL14\nL11\nR15\nL12\nL62\nR985\nL25\nL76\nL51\nR34\nR217\nR61\nL913\nR52\nR86\nR11\nL69\nL18\nR90\nL379\nL70\nR92\nR57\nR9\nL81\nR37\nR35\nR92\nL5\nL63\nR776\nL611\nL585\nL60\nR79\nR15\nL923\nL92\nL97\nR37\nL85\nR19\nR703\nL81\nL60\nR962\nL96\nL897\nL28\nL155\nL45\nL18\nR61\nR793\nR49\nR522\nL31\nL176\nL3\nL33\nL89\nR861\nL40\nL22\nR35\nR91\nL40\nR40\nL1\nL32\nR51\nR36\nL546\nL50\nL90\nL468\nL76\nR76\nR87\nL184\nR90\nL76\nL17\nL82\nL79\nL913\nL77\nR80\nL29\nL95\nL58\nR53\nR52\nL68\nR92\nL50\nL39\nR213\nL99\nL1\nR845\nL45\nL94\nR99\nR31\nL37\nL95\nR96\nL94\nR67\nL673\nR24\nL24\nL26\nR823\nL397\nR93\nR48\nR69\nR90\nL82\nL6\nL62\nR50\nL17\nR117\nR10\nR658\nR846\nR59\nL5\nL68\nR42\nL48\nR5\nL99\nL839\nL49\nL137\nL75\nL47\nR47\nR68\nL68\nL108\nL64\nL28\nR43\nL43\nL6\nR6\nL21\nL611\nL568\nR33\nL25\nL8\nL37\nR35\nL53\nL18\nL90\nR875\nR88\nR69\nL69\nR498\nL98\nL33\nL67\nL448\nR3\nR40\nL81\nR74\nR15\nR72\nR625\nL86\nR86\nR4\nL78\nR92\nL96\nR20\nR58\nL2\nL98\nL20\nR86\nL16\nL21\nR22\nL92\nL59\nL3\nR98\nR5\nL61\nL80\nR58\nL17\nR73\nR90\nR3\nR4\nR97\nR33\nL32\nR72\nR20\nR49\nL14\nL95\nR53\nL53\nR93\nR7\nL17\nR33\nR56\nL22\nL49\nL81\nR80\nL93\nR58\nR35\nR70\nL18\nR33\nR10\nR21\nL40\nR8\nR11\nL2\nL3\nL45\nL30\nL3\nR5\nL46\nR37\nL25\nR16\nR9\nR9\nL40\nR6\nL6\nR26\nL44\nR27\nL47\nR25\nR20\nR30\nR28\nL45\nL33\nL42\nR18\nR34\nL14\nL37\nL43\nR25\nR28\nR26\nR31\nR6\nR21\nR28\nL40\nR5\nL39\nR13\nL7\nL35\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_01_questions.txt",
    "content": "--- Day 1: Secret Entrance ---\n\nThe Elves have good news and bad news.\n\nThe good news is that they've discovered project management! This has given them the tools they need to prevent their usual Christmas emergency. For example, they now know that the North Pole decorations need to be finished soon so that other critical tasks can start on time.\n\nThe bad news is that they've realized they have a different emergency: according to their resource planning, none of them have any time left to decorate the North Pole!\n\nTo save Christmas, the Elves need you to finish decorating the North Pole by December 12th.\n\nCollect stars by solving puzzles. Two puzzles will be made available on each day; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!\n\nYou arrive at the secret entrance to the North Pole base ready to start decorating. Unfortunately, the password seems to have been changed, so you can't get in. A document taped to the wall helpfully explains:\n\n\"Due to new security protocols, the password is locked in the safe below. Please see the attached document for the new combination.\"\n\nThe safe has a dial with only an arrow on it; around the dial are the numbers 0 through 99 in order. As you turn the dial, it makes a small click noise as it reaches each number.\n\nThe attached document (your puzzle input) contains a sequence of rotations, one per line, which tell you how to open the safe. A rotation starts with an L or R which indicates whether the rotation should be to the left (toward lower numbers) or to the right (toward higher numbers). Then, the rotation has a distance value which indicates how many clicks the dial should be rotated in that direction.\n\nSo, if the dial were pointing at 11, a rotation of R8 would cause the dial to point at 19. After that, a rotation of L19 would cause it to point at 0.\n\nBecause the dial is a circle, turning the dial left from 0 one click makes it point at 99. Similarly, turning the dial right from 99 one click makes it point at 0.\n\nSo, if the dial were pointing at 5, a rotation of L10 would cause it to point at 95. After that, a rotation of R5 could cause it to point at 0.\n\nThe dial starts by pointing at 50.\n\nYou could follow the instructions, but your recent required official North Pole secret entrance security training seminar taught you that the safe is actually a decoy. The actual password is the number of times the dial is left pointing at 0 after any rotation in the sequence.\n\nFor example, suppose the attached document contained the following rotations:\n\nL68\nL30\nR48\nL5\nR60\nL55\nL1\nL99\nR14\nL82\n\nFollowing these rotations would cause the dial to move as follows:\n\n    The dial starts by pointing at 50.\n    The dial is rotated L68 to point at 82.\n    The dial is rotated L30 to point at 52.\n    The dial is rotated R48 to point at 0.\n    The dial is rotated L5 to point at 95.\n    The dial is rotated R60 to point at 55.\n    The dial is rotated L55 to point at 0.\n    The dial is rotated L1 to point at 99.\n    The dial is rotated L99 to point at 0.\n    The dial is rotated R14 to point at 14.\n    The dial is rotated L82 to point at 32.\n\nBecause the dial points at 0 a total of three times during this process, the password in this example is 3.\n\nAnalyze the rotations in your attached document. What's the actual password to open the door?\n\n--- Part Two ---\n\nYou're sure that's the right password, but the door won't open. You knock, but nobody answers. You build a snowman while you think.\n\nAs you're rolling the snowballs for your snowman, you find another security document that must have fallen into the snow:\n\n\"Due to newer security protocols, please use password method 0x434C49434B until further notice.\"\n\nYou remember from the training seminar that \"method 0x434C49434B\" means you're actually supposed to count the number of times any click causes the dial to point at 0, regardless of whether it happens during a rotation or at the end of one.\n\nFollowing the same rotations as in the above example, the dial points at zero a few extra times during its rotations:\n\n    The dial starts by pointing at 50.\n    The dial is rotated L68 to point at 82; during this rotation, it points at 0 once.\n    The dial is rotated L30 to point at 52.\n    The dial is rotated R48 to point at 0.\n    The dial is rotated L5 to point at 95.\n    The dial is rotated R60 to point at 55; during this rotation, it points at 0 once.\n    The dial is rotated L55 to point at 0.\n    The dial is rotated L1 to point at 99.\n    The dial is rotated L99 to point at 0.\n    The dial is rotated R14 to point at 14.\n    The dial is rotated L82 to point at 32; during this rotation, it points at 0 once.\n\nIn this example, the dial points at 0 three times at the end of a rotation, plus three more times during a rotation. So, in this example, the new password would be 6.\n\nBe careful: if the dial were pointing at 50, a single rotation like R1000 would cause the dial to point at 0 ten times before returning back to 50!\n\nUsing password method 0x434C49434B, what is the password to open the door?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_02.adb",
    "content": "--  Solution to Advent of Code 2025, Day 2\n------------------------------------------\n--  Gift Shop\n--\n--  https://adventofcode.com/2025/day/2\n--  Copy of questions in: aoc_2025_02_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2025_02 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  input_name : VString := +\"aoc_2025_02\";\n\n  first, last : array (1 .. 100) of Integer_64;\n  n : Natural := 0;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    dummy_separator : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      n := n + 1;\n      Get (f, first (n));\n      Get (f, dummy_separator);\n      Get (f, last (n));\n      exit when End_Of_File (f);\n      Get (f, dummy_separator);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part (part : Part_Type) is\n    invalid : Integer_64 := 0;\n\n    procedure Check (x : Integer_64) is\n      original : constant VString := Image (x);\n      pattern, constructed : VString;\n      total_len, total_len_new : Natural;\n    begin\n      for len in 1 .. 1 + Length (original) / 2 loop\n        pattern := Slice (original, 1, len);\n        constructed := pattern;\n        total_len := len;\n        Repeats :\n        loop\n          total_len_new := total_len + len;\n          exit Repeats when total_len_new > Length (original);\n          constructed := constructed & pattern;\n          total_len := total_len_new;\n          if constructed = original then\n            invalid := invalid + x;\n            return;\n          end if;\n          exit Repeats when part = part_1;\n        end loop Repeats;\n      end loop;\n    end Check;\n\n  begin\n    for i in 1 .. n loop\n      for id in first (i) .. last (i) loop\n        Check (id);\n      end loop;\n    end loop;\n    r (part) := Image (invalid);\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  if compiler_test_mode then\n    input_name := +\"aoc_2025_02_mini\";\n  end if;\n  Read_Data;\n  Do_Part (part_1);\n  Do_Part (part_2);\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 55916882972 (mini: 1227775554).\n    --  Part 2: validated by AoC: 76169125915 (mini: 4174379265).\n  end if;\nend AoC_2025_02;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_02.txt",
    "content": "8123221734/8123333968,2665/4538,189952/274622,4975/9031,24163352/24202932,1233/1772,9898889349/9899037441,2/15,2147801/2281579,296141/327417,8989846734/8989940664,31172/42921,593312/632035,862987/983007,613600462/613621897,81807088/81833878,13258610/13489867,643517/782886,986483/1022745,113493/167913,10677/16867,372/518,3489007333/3489264175,1858/2534,18547/26982,16/29,247/366,55547/103861,57/74,30/56,1670594/1765773,76/129,134085905/134182567,441436/566415,7539123416/7539252430,668/1146,581563513/581619699\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_02_mini.txt",
    "content": "11/22,95/115,998/1012,1188511880/1188511890,222220/222224,1698522/1698528,446443/446449,38593856/38593862,565653/565659,824824821/824824827,2121212118/2121212124\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_02_questions.txt",
    "content": "--- Day 2: Gift Shop ---\n\nYou get inside and take the elevator to its only other stop: the gift shop. \"Thank you for visiting the North Pole!\" gleefully exclaims a nearby sign. You aren't sure who is even allowed to visit the North Pole, but you know you can access the lobby through here, and from there you can access the rest of the North Pole base.\n\nAs you make your way through the surprisingly extensive selection, one of the clerks recognizes you and asks for your help.\n\nAs it turns out, one of the younger Elves was playing on a gift shop computer and managed to add a whole bunch of invalid product IDs to their gift shop database! Surely, it would be no trouble for you to identify the invalid product IDs for them, right?\n\nThey've even checked most of the product ID ranges already; they only have a few product ID ranges (your puzzle input) that you'll need to check. For example:\n\n11-22,95-115,998-1012,1188511880-1188511890,222220-222224,\n1698522-1698528,446443-446449,38593856-38593862,565653-565659,\n824824821-824824827,2121212118-2121212124\n\n(The ID ranges are wrapped here for legibility; in your input, they appear on a single long line.)\n\nThe ranges are separated by commas (,); each range gives its first ID and last ID separated by a dash (-).\n\nSince the young Elf was just doing silly patterns, you can find the invalid IDs by looking for any ID which is made only of some sequence of digits repeated twice. So, 55 (5 twice), 6464 (64 twice), and 123123 (123 twice) would all be invalid IDs.\n\nNone of the numbers have leading zeroes; 0101 isn't an ID at all. (101 is a valid ID that you would ignore.)\n\nYour job is to find all of the invalid IDs that appear in the given ranges. In the above example:\n\n    11-22 has two invalid IDs, 11 and 22.\n    95-115 has one invalid ID, 99.\n    998-1012 has one invalid ID, 1010.\n    1188511880-1188511890 has one invalid ID, 1188511885.\n    222220-222224 has one invalid ID, 222222.\n    1698522-1698528 contains no invalid IDs.\n    446443-446449 has one invalid ID, 446446.\n    38593856-38593862 has one invalid ID, 38593859.\n    The rest of the ranges contain no invalid IDs.\n\nAdding up all the invalid IDs in this example produces 1227775554.\n\nWhat do you get if you add up all of the invalid IDs?\n\n--- Part Two ---\n\nThe clerk quickly discovers that there are still invalid IDs in the ranges in your list. Maybe the young Elf was doing other silly patterns as well?\n\nNow, an ID is invalid if it is made only of some sequence of digits repeated at least twice. So, 12341234 (1234 two times), 123123123 (123 three times), 1212121212 (12 five times), and 1111111 (1 seven times) are all invalid IDs.\n\nFrom the same example as before:\n\n    11-22 still has two invalid IDs, 11 and 22.\n    95-115 now has two invalid IDs, 99 and 111.\n    998-1012 now has two invalid IDs, 999 and 1010.\n    1188511880-1188511890 still has one invalid ID, 1188511885.\n    222220-222224 still has one invalid ID, 222222.\n    1698522-1698528 still contains no invalid IDs.\n    446443-446449 still has one invalid ID, 446446.\n    38593856-38593862 still has one invalid ID, 38593859.\n    565653-565659 now has one invalid ID, 565656.\n    824824821-824824827 now has one invalid ID, 824824824.\n    2121212118-2121212124 now has one invalid ID, 2121212121.\n\nAdding up all the invalid IDs in this example produces 4174379265.\n\nWhat do you get if you add up all of the invalid IDs using these new rules?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_03.adb",
    "content": "--  Solution to Advent of Code 2025, Day 3\n------------------------------------------\n--  Lobby\n--\n--  https://adventofcode.com/2025/day/3\n--  Copy of questions in: aoc_2025_03_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nprocedure AoC_2025_03 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 15;\n  input_name : constant VString := +\"aoc_2025_03\"; n : constant := 100;\n\n  r : array (Part_Type) of VString;\n\n  procedure Do_Part (part : Part_Type) is\n    bank : String (1 .. n);\n    f : File_Type;\n    jolts, total, max_n, pos, d, digits_amount : Natural;\n  begin\n    total := 0;\n    Open (f, input_name & \".txt\");\n\n    case part is\n      when part_1 => digits_amount := 2;\n      when part_2 => digits_amount := 12;\n    end case;\n\n    while not End_Of_File (f) loop\n      Get (f, bank);\n      pos := 1;\n      jolts := 0;\n\n      for rest in reverse 1 .. digits_amount loop\n        max_n := 0;\n        for k in pos .. n - rest + 1 loop\n          --  We always need the highest possible n-th digit.\n          --  And, the first occurrence of it is always the best: you have\n          --  more choice for the next digit.\n          d := Ord (bank (k)) - Ord ('0');\n          if d > max_n then\n            max_n := d;\n            pos := k + 1;\n          end if;\n        end loop;\n        jolts := jolts * 10 + max_n;\n      end loop;\n\n      total := total + jolts;\n    end loop;\n\n    r (part) := +\"\" & total;\n    Close (f);\n  end Do_Part;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Do_Part (part_1);\n  Do_Part (part_2);\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 17613.\n    --  Part 2: validated by AoC: 175304218462560.\n  end if;\nend AoC_2025_03;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_03.txt",
    "content": "5435113354324445355543423523324245133533362334234141663246333323544553332443432533433423343343453463\n1233344353772433633431345263345236724342224345344274554423535244944463342134833266322656314543515475\n5576745375324233563243233436732333523533636533753554414665233366234224423732347223363713264622236523\n5222525121222422563623622342122222236224232431233222533412222434244222222262316223222221232342213323\n4435354664423232224355463421531435433224734524344224733444432436344243244533362444545674243542634543\n4522223113123312224212222214121243522823123223524255222321162314152221321122221252541223223242221222\n7715743377257934377437237862344454824443325453755356866767684636467643544764752724362417343657567342\n6523864515231325622456222644174686462454428234444724653576263285224336446352253264246244362929656426\n3466625654666454445665346665665566663732483655475855164647326366527566566576544415865645575644536643\n1122223224244222152222512545122212231222232225321122221142122212232222972214212121252221221222242212\n6534268233326239326648265632335833323223473631923422723291654523333235236322423363342536153322378532\n4555732424665482324835745822333631633662252934516556533232242524111354282289422476516222469234477234\n5255425253426533545444555452546163525345456341782353554252552254425252815554455314542525554524443323\n2222332232222333253221233222422237322333323392322322332432923322222322243222233322142243322343322222\n3223324233332323233331332231233432334433324222133313332122242331723132231233223433224333352333331333\n2224221562223224212221221222211321422221112422233232122222222422222222211422423222222232232221222224\n2121353331232222324224322223222322214432232232425224423312121143432222225225213227244425428223234442\n3234233235333632753353333333353443133453342443233344543333423321334414534334533222421213323234333435\n2233222122322234444342132337329431322374222124134233214351233243123356375442213234123432433445422447\n5657353272375262725544726457535473426755734112433642575265223147226544316261275624736211753727152289\n3622453333455615313535433655542422333436542533364235535441325345214445441345553426543422433444525443\n4223235316324333322242343433353133233232422632272221443321633233443433346133232424672433343342333343\n2633323323234534236333623333231383322237233323613341113123322463235435374462643925254353223449625333\n4442214735222532221438725223533336343336321323222434383443322223434327255131333142255253243443232335\n5563487886335668666493846844554285575656758566669368646867373678668657565486656866535846283366546865\n3228253234225312424353215214532221422322331222412232113232224224222362415222243342343223118433422314\n3435363333233337453396343373348343427893363353369344243243325493323333436842339593335318333393552322\n3222224452224155723555286536491525222352645618332474753245446634235343235355696244573463247423542633\n7343454543352456557554525555524355335555433434445555553754535534456464535654565553345333534455555555\n4333133331321433343233254233333333332233315323233343123343435333232434334334233373322334313353323323\n2212322122212222122332314123222222122221222224233324212322332412222222522242221422322121222342123322\n2721232121354232244426234143554822344132544338463131422132316223221228422243143322122332282222615742\n2123226223122322213721223222281212622222365421224133222222224212147729423252222634272233243222224122\n8225444321227231186352525234212242556552221443231635325642443523412463536763524265133344424724433342\n4333442233124833223436324123232243531342133433224442534433395326333321343432233234133221323434333333\n5352445253512235254443446435333455241543543463453243415533345853464462334353543335454274434554245413\n4342222333222552432344333226352334325633232224232352515784433423322242855223332546543524165246342232\n4223344323422223336343262363372316345322453232533333234334234663643424346423333242415653353424234253\n6263428246423623363264635654526226372222142355668223314566214265246312541261245543227662623653454362\n2273336331272235254713332422332643342223343333332332122314226323332345323582253242445223323322245231\n4322234845232662236324224322182245247244367242522424212234232422723218198225222915521222268564411521\n3433253332333532345333323422433233423243313324333631254243244255333253113363285452224245324232232235\n1143492333422423336912623553424421324742531223446629632732242332333351329224544322343972221431323364\n3342424231333335733152322226323124214225367372627223275332422333413352564363432246323232215433252153\n5587829445884636482654145646782533363348738488965858788843452546373544894477994653421555279386445548\n2312325132575255433332362232222542242333723534452522572563552254242525534341234533333233334356225351\n2331122213133321222223232222322332322312332232222233522271233231332232312222241223333113223222422223\n3534325413554232325254512334336633252323573674321152427628233553273152333233122822353523483332725543\n2222722322222213322222212222222122221222225222221222113251223212112111122123121222222322232122222242\n5652234232663254118444532444552564425764453426742955425324162723845341436551358415354422522433432538\n2932122232253211521222132232232122322333232125423231222322332323332232123223322233222222212422332252\n7253223242547732357534512342433333233357423332342332433343335343335333343433452143834333361533352444\n2222242211224427263221122213221423252222211237422222223824212612224422441633222222223322722312123422\n1122242322422227124312493231242262322237183233234627223323235223222232252211432135322322252423222522\n5513625653443564554544344548444541545526656445244544545145456455355534545535718246455415357363556546\n1222228264622222463264252352326422143123231223143321435422225412221242221322136231143254124622823234\n4668655544562525244555555544446946543646543355559525455645534443552558655353454153564261573555554336\n2226252126147222222251281225222225225244522425263222212622213313222212132223223423221142432221322231\n5332537364333222353314336342213343762334364344343343394342443142523434334612433445942634344332233678\n1344233339652845433647536439442146443343744444322363643731834964839444264654262944433343433826243433\n2781552142222524723162423423633311152243332625235412335422524232332254233222525211251424311252112165\n2333633213542313212234421262313265392221232353422523221333725322252342421521522223433331353155223333\n6544843557445454477544654583334434553455434445755275835548425348455674843754457238464753439339545443\n2225176232246822422522222662292212683372222835212732945285522562265232933535122252663386222634521223\n3648323653333216232535332325333533342283232533322353233227432452713234332339213552328322226323323323\n5633646655526971582281363775455439333363266535582936666553663763728566456535855129699264355358363534\n4232433332333242293431232133222121322223222132332323222182321222262323223231121322333321233223232222\n4344655422352142552342346612445323644352236344423264345233324253246254343342853322643334364544265443\n1222222422242421244263322222431244361323314122322332321232332222342282122343124252863343371223323234\n2233234232231314332243323331333231661223222322232224323223223312224212643432331222221325212314321223\n4585424333435123142334435344324333574424332335462323548645541234334448243435664387123224234252834335\n4353263232264352321123922232651211342343131233335433334436323121224122132246123222233533225324441326\n2342322432223332233223382322453263222224411331223342323224222123326222632133222212323223343232212231\n4434733735542454444153446353344654324426337649333636353744513333334863333275429244556244247635232724\n4334741434328231357433211143614362384322446224492442232224342244243713344422143443333243324316234423\n2552111222222443333241232223126232322722223251122242211623324431222166622222222237523214222232623282\n4444454545455444555446543543474515654454445254425425145346556442233235555453445545434545555435247463\n2222222223222232221122222221123215122221222112212212222222123251222222222132222222232212222132232632\n5453569247722653252223751462234539228856835215912364562123224222422532666382422243732223234644437564\n3513532323323333532325333232332223923634433433333433352343254253332535233334324442333323423233323322\n1232226215227211127143232324662232312221153212282442254222135122522221223552211222215262222222643221\n3373363325372233496622336333343338425322233643333323333643232932333339326234243733431313333335333233\n5262252725375673844565695677452742643652556466757653467842466346476564477365286656766645476936777773\n4973939623777674483526515657982389568693527229486547957994869795857776395649577557776894577538959518\n4336244332323333333323333343333133432233343362142233432223213333933343234243242333424423234242332343\n3444444223424334144244429344324944434344434544354433443442344434343452344445344322344635443444493344\n3134521222132222522523312211223521422272411223212322222223243263543224221223252222221432422421443153\n6272924132234218127342331776264225555237327229315115823162121273732437124425493327441532325337425174\n5444223542325425263316442615743475443122663533254273433623144442223422522424442444624443346522116444\n9233225522332222321253326264423823733236476632624235521362112522232342422222123223522375134323227323\n7255323516928543264677235524667867238278726776253467657396529967766779551356475764333433375547256665\n2525472336544743374233436955267423422865435344464666322481446384332154333423364636534222723428328743\n2314335931264432514533231544626253323363453223644332346364434658435335442643732654332327244329373247\n3252352322313255332322123222422331355322232322622233333332333234152243332235723329332243121222323234\n2272313213422153212211222262222221422423322513322233212313322133223321222114432322422352321231322221\n2774253153222333243133353233546433372434253323657733732323333133433252234323335311565654323333333133\n2223232131222421229222225423221222254332422222231323234229213122222215342755342337122332332333322225\n3573532537264315533523224443354666214638246321444334459334465233632455631725246534552945844826253572\n3444756323537363556473235735567622746225263423552566645533552244533564224743536342534664662627337862\n1555336343554522213334442333353343759485347445426524533942563425323255845145535354323433263345653453\n4461384744645548434423434448454466534444424844494144363466424347478484433781448425434838434423842743\n7621285337423873536653937774342223274456333763347273384742335728658544332388467665374434547784345814\n5633233233232332334232332333223333332333333332333373333332333323333343322343233442323333335353311332\n3231211324231444321523322222322423443224224223221222334222552222522333244422223345352341421222242242\n4553354423444151311141144535243411314142443545545252145415445554223341551441145244122143242312336789\n5765565899996897799687787574486889887452869954459964296566698748644956887995746559946786584673999966\n7946769529775566672759756265976475746769585777765755555579455668646858686768566744675485479575765575\n6421524236223452962453524162367626796541132586422323734221212617537753232425315524231322722532765252\n2123125234345422522337352225553352523241234312232225221113222251134563333114423454272522245334333342\n2241323413334212324373343923342335312122214739252312235313342232231348323233333344333432743445429636\n4223233223153822333323322443314762442355223443444233432463323332533422113313524353435427434376312231\n4215422122222151725111222211224451212122242252121611223222232225232422222123222222262212224121431221\n2413214275164556258388122372217112266222232522222266142222224212111252351223425122224152526223212846\n1323636363685335369223652333465762165568722532352251552382145357234293353563233532222433374335623365\n3442425244554423133535453555423545252153443442222543544244425546464553532425454515553435454435442453\n3745545555562535543645555446454433553535594566525577454634524446475546755553445654554445545555445455\n5616268445219212622135525627573525824722682234476427236414263262292667744321525113564225627522762223\n3122241222231222332212322242232224123222223212432242112222222212222243212221312222132224132342222224\n5235464435334631424362246264134234334673344436523552323544242334322344523343453422365447321473433345\n1224224224322222152218122222432132439826224269283291242432225122222271846158526211214228522926362492\n4522345233524223213497361443343144233434432233242434967323442443244333637533143434111412453413274443\n1334332444354334413433144333313732344432234443345132261223333131324343213234422132233132334333232423\n2525527445536165529424545542423125262243442255135552522742443535424521462323442552421334344444155234\n2323522233242652331114234233324132172222222232132222243222222332532422332317273323623213434232232223\n3484655554943975444624244445443468352345344933455434414648544483446433456463525733546333344446488665\n5565562332353673457513264254523646353325333422554652452235525285456236946425443525564653226536425512\n8616225642214422558634267662262565424543462453368356272861513564575263632632616422323232661343285438\n6333224463434353443335332333433323334333435243243344333331323431436333337323334325232334634234332443\n1233222334412421444424144343131231414221443422441221213322143421443143334243421243222223431142256789\n2212223525232234223415253222234233363232352331353632533223322333233563333223335332222442131242132173\n3816323383284643928733322242344833684774363323343232536384342363537353134331331334352373224323423333\n6447955463327313384577448539764343367429555473755247738464358653477334343945547838875456754784823363\n5434244323433433434343563364819474374543273633435344824232473244334642337428465423344423353434434432\n7442353261225224522233323727572533332445331623222295232752228372231217852632161238231232436342232232\n4526223432124145422142222124182121671242223222412363212524223173261245333435214641242663245322223521\n4263562733555685663522242313434726124643355533558226544138654644475352425436253456366735666544332657\n4341315536331534333454535744123633456334333453636333736334424533343432424333345656476243523443763633\n1324343444393434423414443244234444453535444644449544444253433444534446244451456464424434443433363252\n2112224231241221222232222222422134222222132122231312132242122221213224222242222222342222232122211528\n4385535213555333232225523228265793216328622226632332472262222222512265533322225342324275352223326143\n5243532545945342334345364434154433431494628952782552473755525425725244643565443433826551333322254353\n4223212323322422243324113232221222223231233112242232321622231332222222222233254422222326224222342232\n3332255342242343826166532324242524432445172341231245387335235422322763423221467272263529933268437351\n1542466264121455566412665243646411646141116516454156662516544663655241155331421243266641413226665789\n5554455445427145865432355555555547145442454345543745554534654333235553533256845325355455535262245524\n2354232552352524723356231424552455123563645522461245542424544242444233335463442422432552432454523532\n4316625313325234514328252432321244774244214583222554353534735222834347321373732211464264412343722652\n2124923223212136421292213223223282224332281722423725222215376282163226251235212313228726112233226922\n7437652335153364536533537533545238334435524343424523463631142485285343335238233624733457334345273584\n4432228273343343215583433543323212333224236223355337222323333332345234332434333235242435462732332333\n7553547893569536378624439279549153554453536866554549468525592874454477737666779494576549796896643415\n2124221834224131213222323122212233232172125222323231324222325221422624317561223232422221222232332422\n5344434563445335453343447245666334345455593633333359553532842724354855675395434569426346449336343359\n7323134454424646623244626222222425623272821225253221462263224424732533741329123223432218165238335233\n2333353433134553232323333235213322333435333234332362433311434234333332333363434333333331433633337313\n3344332343443435344254248353434433644437346254423333343444234777124334243235241442141441642344443433\n4133222221222563554332222274323243563533453254329772432235442432232223331236122512252143332535822253\n2122322321123522222329232322232412322222254123232162321222223124451615214232212212324245221222424422\n6652684336373647767544333643438577743841633347337636653377258533793368685635326838763284323453332833\n2222242223416222242432122322222122223222242121212121223322212222422223442222212214112222242212122322\n2332223222822452222442212722232111221224312212212422212231222262534224332122522112111222431252242222\n5586633437564634774847177673758536498678467645435726969787134233753534533523834354823836766899569987\n3265182213234225423251133242336323233333343443322232323244334213223434233324453333833112222323223322\n4311225222222342222212221222122222222114531223251222462222326331221223222222222222535222231221222215\n8353353532212327242242223333233633734342332362231221233633312338342222262293134224272363372232425535\n6637568865784585854864857854884827877786646684697458554354466886856487448336888567884488456377585735\n8764876657764358887668956357793774525775795784756969553336626979755347473689447936775685248575571643\n3324222333321123232533222112341324233322325333232124232362222251122123223332125222223333333326112322\n5154454432334412668333483246547544634434544444244643134643564443345555542415445424363344454544442444\n5529595579554725215997464852546265545525545496757145285786556596357946559343572694858563555726254435\n3236113122412222222143211221112261222222272223322242241222223312223322232222321322225232222212212275\n2222227231322342222222222221122213222121222242222122222222233112233322212122422221222222221221222322\n5545555234513444744563336433465534426473325262565223624554382644444325465643444148645473535674442431\n2234333232244344332712342623134322412344224443274524412432411243323131224222343422222333472233432424\n4223333224415333332433332333543342632343333333343335424442345321334453232433153323432334332332333343\n6364543445435432334632254455423526234534363333535534435335534454593343534443475325454435624238833314\n2533344296437155726714623465525736434473253844437436344546323746844152742433564335743236383447552556\n4435653443755434445263653255358645637345224332433333544534375353336342534765354445643443454543224153\n7343213233483342331333372222333232174436323523432223343342325232383323244321565332143341333323333232\n3343341322433346345412332444333332333341633253323532142134423242343433343644337341333253333334331333\n4954666664556733566643675747683864546956336546796534255726645435447545665546566525455333537324765633\n2561463486484556662526656544762655655734756665375447745726633527236646723726674574373726747516742546\n2523232233321432322233232353323343221444346331442232332313214224284223444133631432742312424225444423\n1225135534233234226463225963263632342756423233542334357454312452542627472425252374763432465354636447\n3659362562686326315225343345488676426546362326734463634384445632725635233726625565443734652757782223\n5533153332326424444355455444542424524424333242534263414455242443431442544642543434433353322321433243\n5512532522364334355422295343634723372235223144393222652155225337335336323353233373235232533253322724\n2223232222211244223222312412233223222231313222241224222142232221322212424223222242322322223322222241\n4525848623523725652313133544563445546234954552333457744253585372323765554133679483636944549315344393\n3215232333333322114333343334335343253334432434133213223133153222134423223323333532133333623222233323\n3835154427421885116485134521856581134543364365776468584466324358784887887164711752653158338583868759\n4544417321543442725422244543474244423344345272322237122262441444213354224454162814547423444841431371\n3252383844525728554545655333544472757555545565555543542555555345463123455473256426436465512545275964\n2277638522444242216243373936387272431444175333323743425266473745412476747122633514112862137734246355\n4316444535443343344466624434646444645443464544434467335443435443444334374443244464444433443641443434\n2235443543325832223264242433624436343523234643924632439321341235415312231532424232434212532425593132\n3221234342643222211233221513434732257113432222322312421234323322321253433334124122444423372322122422\n5638224368353237455587341753633943585755645442635743383273437235552587573346531353335563334585357234\n9494545546464453366456345474434544756854463344455364335951544545522334434443475832244534923386454453\n4212222344622233366212256216226628462122221625532232326322455222225242622256243112325252252221222242\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_03_questions.txt",
    "content": "--- Day 3: Lobby ---\n\nYou descend a short staircase, enter the surprisingly vast lobby, and are quickly cleared by the security checkpoint. When you get to the main elevators, however, you discover that each one has a red light above it: they're all offline.\n\n\"Sorry about that,\" an Elf apologizes as she tinkers with a nearby control panel. \"Some kind of electrical surge seems to have fried them. I'll try to get them online soon.\"\n\nYou explain your need to get further underground. \"Well, you could at least take the escalator down to the printing department, not that you'd get much further than that without the elevators working. That is, you could if the escalator weren't also offline.\"\n\n\"But, don't worry! It's not fried; it just needs power. Maybe you can get it running while I keep working on the elevators.\"\n\nThere are batteries nearby that can supply emergency power to the escalator for just such an occasion. The batteries are each labeled with their joltage rating, a value from 1 to 9. You make a note of their joltage ratings (your puzzle input). For example:\n\n987654321111111\n811111111111119\n234234234234278\n818181911112111\n\nThe batteries are arranged into banks; each line of digits in your input corresponds to a single bank of batteries. Within each bank, you need to turn on exactly two batteries; the joltage that the bank produces is equal to the number formed by the digits on the batteries you've turned on. For example, if you have a bank like 12345 and you turn on batteries 2 and 4, the bank would produce 24 jolts. (You cannot rearrange batteries.)\n\nYou'll need to find the largest possible joltage each bank can produce. In the above example:\n\n    In 987654321111111, you can make the largest joltage possible, 98, by turning on the first two batteries.\n    In 811111111111119, you can make the largest joltage possible by turning on the batteries labeled 8 and 9, producing 89 jolts.\n    In 234234234234278, you can make 78 by turning on the last two batteries (marked 7 and 8).\n    In 818181911112111, the largest joltage you can produce is 92.\n\nThe total output joltage is the sum of the maximum joltage from each bank, so in this example, the total output joltage is 98 + 89 + 78 + 92 = 357.\n\nThere are many batteries in front of you. Find the maximum joltage possible from each bank; what is the total output joltage?\n\n--- Part Two ---\n\nThe escalator doesn't move. The Elf explains that it probably needs more joltage to overcome the static friction of the system and hits the big red \"joltage limit safety override\" button. You lose count of the number of times she needs to confirm \"yes, I'm sure\" and decorate the lobby a bit while you wait.\n\nNow, you need to make the largest joltage by turning on exactly twelve batteries within each bank.\n\nThe joltage output for the bank is still the number formed by the digits of the batteries you've turned on; the only difference is that now there will be 12 digits in each bank's joltage output instead of two.\n\nConsider again the example from before:\n\n987654321111111\n811111111111119\n234234234234278\n818181911112111\n\nNow, the joltages are much larger:\n\n    In 987654321111111, the largest joltage can be found by turning on everything except some 1s at the end to produce 987654321111.\n    In the digit sequence 811111111111119, the largest joltage can be found by turning on everything except some 1s, producing 811111111119.\n    In 234234234234278, the largest joltage can be found by turning on everything except a 2 battery, a 3 battery, and another 2 battery near the start to produce 434234234278.\n    In 818181911112111, the joltage 888911112111 is produced by turning on everything except some 1s near the front.\n\nThe total output joltage is now much larger: 987654321111 + 811111111119 + 434234234278 + 888911112111 = 3121910778619.\n\nWhat is the new total output joltage?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_04.adb",
    "content": "--  Solution to Advent of Code 2025, Day 4\n------------------------------------------\n--  Printing Department\n--\n--  https://adventofcode.com/2025/day/4\n--  Copy of questions in: aoc_2025_04_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nprocedure AoC_2025_04 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; n : constant := 10; np1 : constant := 11;\n  input_name : constant VString := +\"aoc_2025_04\"; n : constant := 136; np1 : constant := 137;\n\n  type Map_Type is array (0 .. np1, 0 .. np1) of Character;\n\n  map : array (0 .. 1) of Map_Type;\n\n  initial : Map_Type;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for w in 0 .. np1 loop\n      initial (w, 0) := 'W';\n      initial (w, np1) := 'W';\n      initial (0, w) := 'W';\n      initial (np1, w) := 'W';\n    end loop;\n    while not End_Of_File (f) loop\n      for y in 1 .. n loop\n        for x in 1 .. n loop\n          Get (f, initial (x, y));\n        end loop;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    rolls, res : Natural;\n  begin\n    res := 0;\n    for y in 1 .. n loop\n      for x in 1 .. n loop\n        rolls := 8;\n        if map (0)(x, y) = '@' then\n          rolls := 0;\n          for xx in -1 .. 1 loop\n            for yy in -1 .. 1 loop\n              if abs xx + abs yy /= 0 and then map (0)(x + xx, y + yy) = '@' then\n                rolls := rolls + 1;\n              end if;\n            end loop;\n          end loop;\n        end if;\n        if rolls < 4 then\n          res := res + 1;\n        end if;\n      end loop;\n    end loop;\n    r (part_1) := +\"\" & res;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    rolls : Natural;\n    m : Natural := 0;\n    moved, total : Natural;\n  begin\n    total := 0;\n    loop\n      moved := 0;\n      map (1 - m) := map (m);  --  Clone current map.\n      for y in 1 .. n loop\n        for x in 1 .. n loop\n          rolls := 8;\n          if map (m)(x, y) = '@' then\n            rolls := 0;\n            for xx in -1 .. 1 loop\n              for yy in -1 .. 1 loop\n                if abs xx + abs yy /= 0 and then map (m)(x + xx, y + yy) = '@' then\n                  rolls := rolls + 1;\n                end if;\n              end loop;\n            end loop;\n          end if;\n          if rolls < 4 then\n            map (1 - m)(x, y) := '.';\n            moved := moved + 1;\n          end if;\n        end loop;\n      end loop;\n      total := total + moved;\n      exit when moved = 0;\n      m := 1 - m;\n    end loop;\n    r (part_2) := +\"\" & total;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  map (0) := initial;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1320.\n    --  Part 2: validated by AoC: 8354.\n  end if;\nend AoC_2025_04;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_04.txt",
    "content": ".@.@@@@@@@@@@@@.@.@..@@.@@@.@@.@@@@@@@.@.@@@@...@..@@.@@@.@@@@@@@@@...@@..@...@@...@..@.@.@.@.@.@@@@@.@..@@.@.@.@@@@.@@.@@@@..@@@@.@..@@\n@@@@@.@@@.@@@.@@@@..@@@..@@@.@@@...@@@@@..@.@@@@@..@.@@.@@@.@.@.@@.@@.@@@@@.....@@..@@.@.@@.@@@@@@@@@@@@@@@.@@@@.@..@@@.@.@@@@@@.@@.@..@\n@.@..@@@@@.@@@.@.@@.@@@@@@@..@@@@@@@..@@@@@@@.@@@@.@@.@@@.@.@@@.@@@.@@.@.@.@@.@@@.@.@@@.@..@@..@..@@..@@@@@@.@@...@@.....@@@@@@@..@@..@@\n@.@@.@..@..@@@..@@@.@.@@.@.@@@@@.@@......@@@.@@@.@@@@@@.@.@.@@@@..@.@.@..@.@..@.@@.@...@@..@@@@@.@...@@@..@.@.@@@@@@@.@@@@@.@@@..@@@@.@.\n.@.@..@.@@.@@@@.@@.@.@.@@@@@@.@@@@.....@@..@@.@.@@@@@@@@.@.@@@...@.@@...@@@@@@@@.@@...@@.@@@@@.@...@..@.@..@.@@@@@@@@@@@@@@@@@@@@.@@.@..\n@@@@@.@@@@@.@@.@@@@@@@@.@@@.@..@@.@.@@@@@.@@@@.@..@.@@.@@@.@@.@@@@@.@.@@@.@@@..@@.@@@..@@@.@@@..@@..@@.@..@@@@.@.@@@.@.@@@@@.@@@@@@.@@..\n@.@@@..@@@.@@@@@@@.@@@.@.@@@@@...@.@@@@@@@.@@.@.@@..@@@@.@.@.@.@@@@@@@@.@@@@@@@@.@.@@@.@@@@.@@@@.@@.@@@..@@@@.@@@@.@@@@@@..@@.@@.@@@@@.@\n@@@.@@.@@@.@...@@@@...@.@@@..@@@@@@..@.@@@@@@.@..@@.@@@@@@@@@.@.....@@@@@@@@@@.@@..@@@.@@@.@.@@@@.@@..@@.@@.@@@@@..@@@@.@..@@.@.@...@@..\n@@@@@.@.@..@@@@.@@@@@.@@.@.@..@@..@@@@@@.@@@@@@..@.@@@@@@..@@@.@@@@@@.@.@.@@@.@@..@@@@.@.@@@@.@@@@@@@.@@@@@@@@.@.@@@@...@@@.@@@@@@@...@@\n.@.@@@..@@@.@@@.@@@@@..@.@.@..@..@@@....@@.@@.@@@.@.@@..@.@@@.@@@.@..@.@..@@@@@@@..@.@.@@@@@.@@@@.@.....@..@@@@@@@.@@.@@@@@.@..@@@@@@.@@\n.@@..@@@.@@....@@@@.@@@@@.@@@@.@...@.@...@@@@@.@@@@@@.@@@@..@@.@@...@@@@@@@..@@@..@.@.@.@.@..@.@.@@..@@@@@@.@@@@@@.@.@@.@@@@.@.@@...@.@@\n.@@.@@.@@@@@@.@@.@.@.@@@@.@@.@@.@@@@@@.@@@@@@@@@@.@@.@@.@@.@...@@@..@@@.@@.@@@@@.....@@@..@@.@@@@.@@.@.@@@@@@@@@@..@@..@.@.@.@@..@.@@@@@\n@@@@@@@@@.@@@.@.@@@@@@@.@@@@@@@@@.@.@@@..@@@@.@..@@@....@...@..@@....@@@@@@@@.@@.@@..@@@@@@.@@@@.@@@@@@@@.@@@@...@.@.@@@@@.@@@..@@@@@@@@\n@.@@@@@..@@.@@@@@.@..@@@@.@.@@@@..@.@..@@@@@@@@@@.@..@@.@..@.@.@..@.@@@@@@@@@.@@@.@@@@@@@@@@.@@@@@@..@@@...@@@@@@@.@@.@@@.@.@...@@....@@\n@@@@@.@@..@@..@.@@@..@.@.@@@@@@..@@@@@@@@..@..@@@@@@@@@...@@@@@@@@@@@@..@@..@.@.@.@.@@.@@.@.@@..@@@@@@@.@@@@.@@@@@@@@..@@@@@.@.@@..@@@..\n..@.@@@.@@@.@@.@@@@@@..@.@@@@@@.@.@@@@@@@@@@@@@.@...@.@...@@@@.@.@@@@@@@@..@@@@.@..@.@@.@@@.@@@@@@.@@@.@@@@@.@@@@.@@@@.@.@.@@..@@@@@.@@@\n@@@.@@@@.@@@..@.@@.@@@@.@.@@@@@@.@@@..@@@@..@@.@.@@@@.@@@@.@.@@@..@@@@@@@@.@...@@@@@@@@@@@@@@@@@@@.@.@@.@@@.@.@@..@..@.@....@.@@.@..@..@\n@.@@@@..@.@@.@@@@.@....@@@.@@.@.@@@.@.@@..@@.@@@.@@.@@@@@@@..@.@@@@@@@@@@..@@@@.@.@.@@@@.@@@@@.@@@...@@@@....@.@.@.@@@@@@@@@.@@@.@@.@@.@\n.@@@..@@@....@@.@.@@@@@.@@.@@@@@@...@@.@@@@@@@@.@.@@@@@.@@.@.@@@@.@@.@@@@.@@.@@@@@...@.@@.@@@@@@@@.@.@.@@.@@..@.@.@@.@@.@.@@@@@.@.@.@@.@\n@.@.@.@@@.@@@.....@.@@@@.@@@@.@@@@@...@.@@@.@@@@@@@@@.@@.@.@@@.@@@@.@@@@@@@..@.@@.@@@...@.@@@.@@@@.@@@@@@..@@@@@...@..@.@@@.@@.@@@@@@@@@\n.@@.@.@@@.@@.@@@@@.@.@.@@.@@@@.@..@@@@..@@@@.@@@@.@@@@.@@..@@....@@@@@@..@@@.@@@@.@.@@..@.@@@@..@@@@@@@@@@.@@@.@@.@@@@..@@@.@@@.@@@@@..@\n@@@@..@@@.@@.@@@@.@@@..@.@.@.@@@@@.@..@@@@.@@..@@@@.@@@@@@@@@@@@@.@..@@@@.@@@@@@@..@@.@@@@@@@.@@.@@@@@.@....@.@..@@@@@.@..@@...@.@@@.@@.\n.@..@@.@@.@@@...@@@.....@@@...@@@@@@@....@.@@@.@@@..@@@@@@.@@@...@@@@@@..@@.@@@.@.@.@.@@@...@..@@@@.@@@.@..@@@@.@.@@@.@@@@@..@.@@@@..@@.\n@@@@.@@@@..@@.@@..@@@.@.@@.@.@.@@@.@@.@@....@.@@...@@...@@@@@.@.@.@@@@.@@@@@@@.@.@.@@.@..@@@@.@..@..@@.@.@..@@@...@.@@@@@@@@@@@@@@@@.@@@\n@@@@@..@.@@..@@@.@@.@@@@@.@.@@@@@.@..@@.@@@.@...@@@@@@@@.@@.@@..@@.@@@@@@@@.@..@@..@@..@.@@.@@...@.@.@@@@@@@@@@..@@@@@@@.@@@@.@@@@.@@@@.\n@@@@@.@@@@@@.@@@@@..@@.@..@@@@@@.@.@@.@@@@@.@@@.@@.@@.@@..@...@@.@.@@@@@.@@@.@@@.@@.@@@@.@@@.@@@...@.@...@..@@@@@..@.@@@@.@@@...@@...@@.\n@..@.@@.@..@@....@.@@@.@@@@@@@@.@@@..@.@@@@@@.@...@@.@@@..@......@.@@.@@....@.@@..@@@@@@@@@@@@@@..@@.@@.@@.@@@..@@@@@@@@..@.@@@@@.@@.@@@\n.@@.@@@..@@@.@@@@@..@.@.@@.@@@@@@@@@.@@@.@@@@@..@@..@@@@.@..@...@@.@@..@...@@.@@@@@@.@..@@@.@.@@@@.@.@@.@.@@@@.@@@@@@@@.@.@@.@@@@@.@@...\n@@@..@.@@....@@..@...@@.@..@@.@.@@..@@@@....@.@@@@.@@@@@@.@@@@.@@@.@@@@@@@@@@@.@..@@@@@@@@@@.@@@.@@@@@@@..@...@.@@@.@@.@.@@@....@@@.@@@@\n.@@.@@@@@.@@.@@.@@..@@@@..@.@@...@..@@@@@.@.@@.@..@.@@@@@@.@@.@@...@.@@@@@@@@@.@.@.@...@.@.@@@...@.@@@@@@@@..@@...@.@@@@@@...@@.@@@@...@\n@@@@@...@...@@@@..@@@@@.@@@@..@@@@@@@.@.@@@@@@.@@@@@@@@@@@@.@@@.@@@@.@@@.@.@@@@@.@..@@...@...@.@@..@@@.@.@@..@..@@@@@@...@@@@@@@@@@.@.@.\n@.@@.@@@@@@@@@..@@@@@.@.@@@@.@....@@@@.@@@@..@..@@@.@@@@@@@..@@@@@@@..@.@...@@....@@@@@@@@@.@@@.@@@..@@@@@...@.@@@..@@.@@.@.@@@.@.@@.@@@\n@@.@@@@@@@@@@@@@@@.@@@@@@..@..@.@@...@.@.@@@@@@@@@@@.@.@@@@@@.@.@@@@@@.@@@@.@@@...@@@@@@@.@@@..@@@@@@@@@@.@@@@@..@@.@@..@...@.@@@@@.@@@@\n..@...@.@@@@@@..@@@.@@@@@@@@@.@@.@@@.@.@@.@@@.@.@@@.@.@@@@@@..@@.@.@@....@@@...@@@@@@@@@@@@@@@@@@@.@@@@@@.@@.@@@@@@@...@@@@@@@@@@.@..@@@\n@@@.@@.@@.@.@@.@@.@@@@...@@@@@.@...@@.@.@.@.@@@.@.@.@@@@@@..@@..@...@.@@@.@.@@@@.@@@...@@@@@@.@@@@@@@@@.@@..@.@..@..@@.@.@@@@@@...@@..@@\n@.@@.@@@@.@@@@@@@@@@.@@@.@@@.@@@@@@@@@@.@@@..@.@@......@.@@@@@@@@@@@@@....@@@@.@..@.@...@@@@@@.@..@@..@@@.@.@@@.@.@@.@..@..@@@.@..@@..@@\n@@@@@@.@.@@@...@@.@@@@...@@@@@@..@@@@.@.@.@..@@@@.@..@@@@.@.@...@@@@@@@@@..@@@.@.@.@@@..@@@@@@@..@@@@@@@.@.@@@..@@.@@@..@@.@@@..@@.@@.@@\n@@..@@@@.@.@.@@@@.@@.@@...@@@.@@@@.@@.@@@@@.@@@@.@.@.@@.@@@@@..@..@@@.@..@.@..@@.@.@@@@@@.@.@@@@@@@@.@@@@@@@@@.@@.@@.@..@....@@@@@@@@.@.\n.@@.@.@@..@.@.@@@@@.@@@@@@.@@@.@@.@@@@.@.@@@@@@@@@@.@.@@@@@.@..@.@@.@.@....@.@.@@.@@.@..@@@@@@@@@@@@@...@@@@.@...@@@@.@@@@..@@..@.@.@@.@\n@.@@@@@@@@@@@@@@.@.@@@.@.@.@@.@..@@@...@@.@@.@.@@.@@.@@@@@@@.@.@..@@...@@@@.@.@.@@.@...@@@@@..@@@@@@@@@..@@.@....@@@@@@@@.@@...@@@@@.@@.\n..@@@.@@@@@@.@.@@@@@@@@@@@@@.@.@.@@@.@...@.@@@...@@.@@@..@@...@@..@.@@.@@@@@@@.@.@@@@@@.@.@@.@@.@@@@@@...@@@.@@@.@.@.@@.@..@.@@..@@@@@@@\n...@.@.@.@.@@..@@.@@.@.@@.@..@@@.@.@..@@..@@@..@@@.@@.@...@@.@@.@@@@....@.@.@@.@@.@.@.@.@@.@@.@@@....@@@@@.@@@.@.@.@@@.@.@..@@..@@@@.@@@\n@@@@@@@@@@@@@.@.@@@.@..@@@.@.@.@.@@..@..@@@@@@@@@..@.@..@.@@..@.@@@@.@@@@@@@@@@@@..@..@@@.@..@@..@..@@@@.@@@@@.@@..@.@@@@.....@@..@..@@@\n@@.@..@@.@..@@.@@.@..@@...@@.@.@@...@.@..@@@@@@@@..@@@.@@@@@@@@.@@...@@..@@@@@@@@@.@@....@@...@.@@.@@.@.@@@@@.@@@@.@@@..@...@.@.@@.@@@@@\n@@.@@@@@@..@.@@@@@.@@@@.@@..@@@@@@@.@@@.@.@.@@@@@@@@.@.@@@@..@..@.@.@@@...@@@@@.@@.@.@@..@.@.@.@@.@@.@@....@@..@@.@.@@@@@@....@.....@@..\n@@@@@.@@.@.@@@.@@@..@@@@@@@@@@@.@.@..@@@@@@..@.@@@@@@@.@@@@@.@@@@@@@@@@@@.@.@@@...@@...@.@.@@@.@@@@.@.@.....@@@@@@..@@@@@@@@..@..@@.@@@@\n@.@.@@@@@.@@..@@@@@@.@.@@.@@@@@.@.@@.@@@.@@.@.@....@@@.@@.@@@.@@.@@@@@.@.@@@.@...@@@.@.@@@@@@@.@...@.....@..@@@.@@...@@.@.@@.@.@.@.@.@@@\n@@@@.@@@@.@.@.@.@@@@@@@@@@.@@@@@@@@@@@.@.@@.@.@@@...@@@..@@.@..@.@@@@..@..@.@@..@.@@@@@.@@@@@.@.@@...@@@@@@@.@@.@@@@@.@.@@@.@...@...@@.@\n@@@.@@@.@@@@..@@...@@.@@@@@@@.@.@.@.@.@.@..@..@@..@@@.@@@@@..@.@@.@@...@.@@..@@@.@@....@@.@@..@@@@.@@.@@@@..@@..@@@@..@@@.@.@@@@.@@@@@.@\n@@..@@.@.@@@@.@@@@@@@@.@@@@@.@@@.@.@.@.@.@@@@..@@@@.@@@..@..@..@@@@@@@@@@.@.@.@@@@..@@@@@..@@@@..@..@@@@@@@@...@@.@.@@@@@@@@@@@...@@@.@.\n@@.@@@@@.@@@.@@.@.@...@@@.@.....@@@@.@..@@..@..@@@@@.@@..@@@@@@@@@@@.@@.@@.@@..@.@@@@@.@@@@@@@@..@@@....@@@.@@@.@.@....@@.@@.@@..@.@@@..\n@@@.@@@.@@.@.@@@@@@@..@@@..@@..@@@..@@@.@.@@.@@@@.@.@@@.@@....@@@.@@.@.@@.@..@....@.@@@@@@@@@.@...@@.@@.@@@@@.@....@@.@..@.@.@@@@@.@.@@.\n.@..@@@@.@@@@.@@@@.@.@..@.@....@@@.@@@.@@.@.@..@@@.@@.@.@@.@@@@..@@@@@@@@@.@@@@@@@..@.@@@@@@..@@@@@.@.@@@@@@.@@@.@@@@@@@@@..@@.@@@@@@..@\n.@@@.@@...@@@@@..@@..@@@@@@@@@.@@@.@.@@.@@@.....@@.@.@@@@@...@@.@..@@..@@.@@...@@.@...@...@@.....@@@.@..@@@..@@@@@@..@@.@@..@@@.@@@.@@@@\n@@@@@@@@@@@@@@@@..@...@..@@.@@@@@..@.@@@@@.@@@@@..@.@@@@@@@.@@@@@...@@@@@@.@...@@@.@@@.@.@@@@.@.@@.@.@..@@.@@@...@@@@@@.@...@.@@@@.@@@@@\n.@.@@@@@@.@..@@@@@@@@.@@..@@@@@@...@..@@@@..@@@@.@@.@@@@.@.@@@@.@@@..@@@@@.@@@@@@@..@.@@@.@@@@.@.@@@.@@@.@@@@.@@....@.@..@.@@...@.@..@.@\n.@.@.@@.@@@..@@.@@@@@@@@@@@@@@...@@.@@@@@@@..@..@.@@@@@@.....@@.@@.@.@@.@@@@@..@@@@@.@@@..@@.@@.@@@.@.@@@@..@@@.@@@.@@@@@@@.@@.@.@@@@.@.\n@.@@@..@@.@.@.@.@@.@..@.@@@.@.@@.@@@@@@@@@.@@@@@@@..@@..@@.@@..@.@@@.@.@@.@.@@@..@..@@@@.@...@..@@@.@@@@.@@@@@.@@.@.@@@@.@@@@@@@..@@@@..\n@@@.@@@.@@.@@@@@@@......@.....@.@..@..@@@..@.@@@@..@@.@...@.@@.@@@..@@@@@.@@.@@@.@@@..@.@@..@.@@@@@.@@@@@.@@@.@@@@....@@@@@@.@@.@@@....@\n..@@@@@.@@@@.@@..@@@@@@.@.@@.@@@@.......@..@..@.@@@.@@@@@@@.@@@.@@@.@.@..@@@@@.@@@@@.@@.@..@@@@@...@.@..@@@@@.@@@@.@...@@@@@@.@.@@.@@@@@\n..@@@@.@.@@@@....@.@@@..@@....@@.@@@.@@@@@.@@@@@@@.@@.@@..@@..@..@@..@@@.@@@@.@.@.@.@@@@.@@.@.@@@..@.@..@@@@@...@.@@..@@@@@..@@@@@..@..@\n.@@.@@.@@@@@..@@@@@@@@.@@@@@@@@@.@@.@.@..@@@@..@@..@@.@@...@.@@@@@@@.@@@.@@@..@.@@@.@@@.@@@@@@@.@@.@.@@.@.@@@.@.@.@@@.@@.@...@@@@...@@@@\n@@.@@@.@.@@@@@@@...@.@..@@@.@@@@.@.@.@@@@...@@@@@.....@@...@@@@@..@.@@..@@@.@@@.@....@@...@@@.@.@@@@@@@..@@@.@.@@@.@.@..@.@.@@@@....@@..\n.@@@@.@@..@.@.@@@@.@@.@@.@@@.@@@.@@..@@@@.@@.@...@@@@@@@@.@@@@....@@@@...@@...@@@...@.@.@@.@..@@@@.@@@.@@@.@@@.@@@@@@@@@@.@@..@.@@@.@@@.\n@.@.@@@.@.@.@@@@@@@@..@@@.@.@@@.@@@.@@.@@@..@@@@..@.@..@@@@@.@....@@@@@.@@@@@@.@@@@@.@.@@@@@@@.@@...@.@@@@@@@@.@@@@@.@@..@.@...@.@..@.@@\n@..@..@@@@.@@@@@@@.@@@@@@.@@.@@..@.@@@.@@@@@.@@@@@@@.@@@.@@@.@@.@..@@@@@.@...@.@..@.@@.@...@@@.@@.@@.@@@@@@.@@@@@@@@@..@@.@.@@.@@.@..@@@\n@.@.@@....@@@.@@@.@.@@...@.@.....@@@@.@.@@.@..@@@.@@@.@@@...@..@@@@.@@@@.@@@@..@@@..@@@@..@@.@@@@.@@@@@@@@@.@@...@..@.@..@@.@@...@@@.@@.\n.@@@.@.@@@@@@@..@.@@..@.@..@@@@..@@.@@@.@@.@.@...@.@@@@@..@@.@@.@@@@@..@@...@@@@@@.@@@@@.@....@.@..@@@.@@.@..@.@@@@.@.@@@..@@@@.@@....@@\n@@@@@.@.@@@@@@@@@@..@@@@.@@.@@.@.@@@@@@@@@@@@..@@@@@..@@.@..@@@@@.@@...@@@@@@@@@@@@@.@@@@.@@.@@@@@.@@..@@...@@@@.@@@@@@@@@.@.@@@.@@...@@\n.@..@@@.@.@@@@.@@@..@@.@....@@@@.@..@.@@..@@@@@@@@.@@..@..@@@@@@@@.@@.@@@.@.@@.@.@.@...@.@.@@.@..@.@@.@.@@@@@@....@@.@@.@@@@@.@@@@@.@@@@\n...@.@@@@..@@...@..@@.@@@@@@@@..@@..@@@.@@...@@.@.@.@@@@.@@@.@...@.@@.@@@..@@@@@@@@.@@@@@@..@.@@..@@..@@...@@@......@.@@@.@@.@@@@@@..@@.\n@@@@@..@.@.@.@@.@@@.@.@@.@@@@@.@@@@@@@@@@@...@@@@.@@@@@.@@@@@@@..@@@@.@@.@.@..@@..@@..@@@.@@.@@@.@.@@@.@@.@.@@@@.@@@.@@.@@@.@.@..@.@.@@@\n.@@@@.@@...@@@@@@@@@..@@@.@..@.@@@@@@@@@.@@.@.@@@.@@.@.@.@@@@@@@.@@@@@@@@@@@....@@@@.@.@.@@@@..@@@@@@.@..@.@@@@.@@@@@@.@@@....@.@@.@...@\n@@@@.@...@@@@.@..@.@@.@@.@@@@@@.@@.@@.@@@@@@@@@@@..@..@@.@.@.@@@@.@@@@..@.@@.@@@@...@@@@..@...@.@@@@@@..@.@@.@...@@..@@@@.@.@@@@@@@@@.@.\n.@.@@@..@@@..@@.@.@@@@@@@@@.@@.@@@@@@.@@...@.@@@@@@@@@@.@@@@.@.@@..@@@@@.@@.@@@..@@@@@@@@.@@..@..@@@@@@..@.@@.@..@.@.@.@..@@@..@.@@@@.@@\n@@......@@@.@@@.@@@.@.@@@@@@.@.@@@@@@@.@@@@@.@.@@@@@.@@.@@@@@.@.@.@@@@@@@@.@@@@@@@.@......@@@.@@@@.@.@@@@@@@.@@@@.@@.@@@.@@.@@@@@@@@@@@@\n@@.@@..@....@@.@.@@@@@@@@@@@@..@@.@..@.@@.@@.@.@@.@.@@@.@@..@..@.@@@..@@@.@.@@@..@...@@@@...@@@@@@....@.....@@@@@.@.@@@@.@@@@@.@@@@..@.@\n...@..@.@@@.@.@@@...@.@@@@.@.@@.@@.......@@@..@@@@.@.@@@@..@.@@@.@@@@@@@.@.@@@.@@@@.@@@@@@.@..@@@..@..@..@..@@@@@.@@@...@...@@@.@.@.@..@\n@@@..@@@.@.@@@..@@...@@.@.@.@@@@@@@.@@@@@..@@@@@@@.@@.@@@.@@@@@@.@.@@@@..@.@..@@@@@@@@@..@.@.@..@@@@@.@@@@@@.@@@@@..@.@@..@.@@@@@@@@@@.@\n...@@..@.@@@@@@@.@...@@.@@@@@@@@@@.@.@.@@@@.@@@@@@@.@..@.@@@@...@@@@@.@@@@...@@@@@@@.@...@@@@..@@..@@@..@@.@@@@...@@.@@@@...@@@.@@.@@@@.\n.@@.@.@.....@@@@@@@@...@@.@@@...@@@@@.@@@@.@@@..@@@.@.@@@@.@.@@@@@...@@.@@@.@.@@@@..@@@@@@.@.@.@@@.@@@..@..@.@.@@@.@.@..@@@.....@..@..@.\n..@.@@@@.@...@.@@@.@@...@.@@@.@..@....@@@@@@..@@@@@.@@.@@@@...@@@..@@@...@.@@@..@@@@@..@@.@@..@...@@..@@@@.@@.@@@.@.@@@@.@@@@@..@@@@@@@.\n@..@.@@....@..@@@.@@.@@@..@@@.@@@@@.@@@@..@@.@.@@.@@@@@@@@@.@@@..@@@@@.@@@.@.@@@.@....@@@@@@@@@...@@@@@@@@@@@@.@@@.@@.@@@@....@@@.@@....\n@@.@@..@@..@@..@.@@@@@...@...@@..@@@@@.@@.@@@@....@@@.@@@..@@.@@@@@@.@@..@..@.@@.@@@@@..@.@@@.@@.@@.@@.@@.@@@@@@@..@@@@@@.@@.@@@@@..@.@.\n.@@.@@....@@..@..@@@.@@.@.@.@..@@@@.@@@.@@@@.@@@..@@@...@..@..@..@@@@@@..@@.@@@@@@@@@@.@@@@..@@.@@@..@.@@@@....@@@@@@.@..@.@@.....@.@@@@\n@@@.@@...@@..@@@@.@@@@@@@..@...@@@@.@@@.@.@@@.@@@@@@@@..@.@@.@@@..@..@@@@..@@.@@@@@.@@.@@.@@@@@@@@@@..@.@.@.@@@.@.@@..@.@.@@@@@.@@.@@.@@\n@@@.@.@@@@@@@.@@@@.@@@@@@@@.@@@@@.@@@@.@@@.@.@@@.@@@@@@@@@@.@@.@...@@@@..@@@@.@..@@@@@..@@.@@@.@@...@@..@.@.@@@@@@@..@@.@@.@..@..@@@@.@@\n.@@.@@.@@@.@.@@@@@.@@.@@@.@.....@@@@@@....@@@@@.@@.@.@@@@@.@@..@..@..@......@.@@@.@@@@..@@..@@@.@...@@.@@@.@@@@@@@.@.@@@.@@@.@@@@@.@@@@.\n@@@@..@..@@@.@@.@.@@@@....@...@@.@@.@..@.@@.@@@..@.@.@@@..@.@..@@.......@@@.....@@@@.@.@@@.@.@@..@.@@.@.@..@.@...@.@.@.@@@@@@@@@@@@@....\n@@@@@@.@@@@.@....@@.@@@@@@@@@@.@@.@@@..@...@.@@@.@@...@@..@@@@@.@@.@.@@@@@@@@@@.@...@.@@...@..@.@...@.@@@@@@@@@@@..@@...@@@@..@.@@....@@\n@@@.@@.@@@@..@@..@.@@.@.@@.@..@.@@@@@..@.@.@@@.@.@..@@@@@@@@@@@..@.@.@.@@.@@@@@@@...@@@.@@.@..@@.@@@@@@@.@@@@@@@@@@@@@@.@@@@.@@@.@.@@@..\n@@@.@@@@@.@@@@@@@@@@@@@@..@@.@@.@@.@.@...@@@@@..@@.@@..@..@.@@@..@..@.@@.@@@.@@@@.@@@..@@.@@@@.@.@.@@.@.@@.@@@@@@.@@@@@.@@..@@@@@@@.@.@@\n..@@...@@@@@@@.@.@@.@.@@@@@@@.@.@@@@@@@@.@@.@@@@@@@@@.@@@@..@@@@@....@.@@@.@@@@.@@@@@.@...@.@@@@@@@@@.@.@.@.@@@....@@@@.@@.@...@@@@@.@.@\n.@...@..@..@@.@@@@@.@...@.@@@.@@@@@.@@@@...@.@.@@@@.@@..@@@@.@@@@.@.@.@..@@.@@.@@........@@.....@.@@@@.@@...@..@@@@@..@@@.@.@@@.@@@.@@@.\n..@@@@@@...@@@@@.@@.@@@..@@@@@@@..@@@@.@@@@..@.@@@@@@.@@@@.@@..@@@@@@@.@@.@.@.@@@@.@...@@.@.@@@@.@@@@.@..@@.@@@.@@@@.@.@.@@@@@..@.@....@\n@@.@......@@@@@@@@.@.@@@@@@..@..@@.@.@@....@@.@@@@@..@.@@....@.@@@@@.@..@@@.@@..@@@@@@.@@@@.@.@@@@.@.@.@.@@@@.@@@@@.@@.@@@@..@@@.@@@@..@\n.@@@@....@....@@@...@@@.@@@@.@@.@@.@..@.@.@.@.@@@.@@...@.@@.@@.@..@@..@.@.@@....@..@@.@@@@@@.@@@..@@...@@.@@@.@@...@@...@@.@@@@@.@@.@@..\n@@.@.@@@@@..@...@@@@.@.@@@.@@@@@@@@@@@.@@.@.@.@@.@@.@@@@.@.@.@.@@@...@@@@@.@@..@@@..@@@@@@@@@.@@@@.....@@@@.@@.@@..@..@..@@.@.@@@@@...@.\n@.@.@@@@...@@@@.....@@@.@.@@@..@@..@.@@@@.@@.@@@@.@@..@@.@@@@@@@..@.@..@@@.@..@@@@@.@.@.@..@@.@@@.@@@@@....@@@@@.@@@@..@@.@@@@...@..@@.@\n@...@@...@@@@.@@@@@.@..@@@...@.@@@..@@...@.@.@@@@@..@..@.@@..@@.@@.@@@.@@.@@@@@.@@@@@..@@@@@@@.@.@@@@.@@@@..@@.@@@.@@@@@@.@@@@@@.@@@@.@@\n.@@.....@.@@.@@..@@@@@.@..@@@..@.@@@@@@...@.@@@...@.@@@@@@..@@....@..@.@@.@@.@@@.@@.@..@.@@.@@.@@@@@@@@@@.@@..@@@@@@...@.@@@.@@.@@.@..@@\n.@@.@.@.@@@@@.@@@@@@.@.@@.@@.@@.@@@@.@@@@@@@@.@@@@.@@.@....@.@@@@@@.@@.@.@@@.@@@..@.@@.@@@@.@@@@.@.....@.@.@@.@@.@@....@@.@..@.@@.@@@.@@\n@.@@.@@..@@@@.@@@@.@@@@..@@@.@@@@@@.@@@@@.@@@..@@@..@@.@..@@@.@@@..@@@@@.@@..@@@@...@@@@@@@@@.@.@.@..@@@.@.@@.@.@@@..@@@@..@@.@@@@@.@@@@\n.@@..@.@@..@..@@@@@.@@.@@@.@.@.@@.@@@.@@@.@.@.@@.@.@.@@@.@.....@@.......@.@@@@@.@@@@@..@@.@@..@@@@@.@@.@.@@@@.@@.@@@@@@@@.@.@@.@.@...@@.\n@@@.@.@@.@@@@@@.@@@.@.@@@..@@@@@.@@@@.@@.@@.@@.@.@@@.@@@@.@@@@..@@@@@.@@@..@@@.@@@.@.@.@@@@..@@@@.....@.@.@.@@@.@.@..@@.@@@@@.@@@@@@.@@@\n....@@@@..@.@@.@@.@@@.@@@.@@..@@@.....@..@...@@@@@.@....@@..@.@@@@@@@@@..@@@@@@.@@@.@@@@@@@@@.@.@@..@@@@@@@@@@@.@@@...@@..@@@@@@@@..@@@@\n..@@@@@@@.@@@@.@....@...@@@@@.@.@@..@.@@@@@.@@@@..@.@@.@.@@@@@@@.@@.@.@@@....@@..@@@@@@@@.@@.@.@@.@@.@@.@@.@@@..@@@@@@@@@@@.@.@...@@@@@@\n@@@@@.@.@@@@@..@@@@@@@.@@@@@@.@@...@.@..@@.@@@@.@@@@@@@@@@..@...@@.@@@@@@..@@@..@@@.@@@.@@@@@@@@..@@.@@@@..@@.@.@@@...@@@@..@@.@@..@@@@@\n...@@...@@@@@..@.@.@..@@.@@.@@.@@@..@@@@@.....@@@@@@@@@@.@..@.@@@@..@@@.@@.@..@@....@.@@@@@@@@@@@@.@@.@@.@@@@@..@@@@@@@@@@@@@..@.@@@@@@@\n..@@@..@@@@@@.@@@@@@@.@@@@@@@.@@@@@@...@.@@.@.@.@..@.@@@..@@@@@@.@@@@@@..@@.@@@....@@.@.@.@.@@@@@@@@@.@@@.@.@@@.@@@@.@....@@...@@@@...@@\n.@@.@.@..@@@..@@@@@.@@@@@@@@@.@.@..@@@@@@@@@@.@@@@@@@@.@@..@@.@..@@.@..@@.@@...@@@@.@@..@.@.@@@.@@@..@.@@..@@.@@@@...@@.@@@@@@@@.@.....@\n@.@.@@@@@.@.@@@@@@..@@@@@@...@@@@@@@@@..@@@.......@.@@@@@@@.@@@@@@@@@@@@@@@.@.@@@@@@@@@@@..@@..@@@@@@@@.@@..@@@@@.@.@@@@@@@@@@@@@@@@@@@.\n@@.@.@@..@@@@.@@@@.@.@@@@...@@@..@@@.@@@@.@..@@...@@.@@.@@.@.@..@.@@@@..@@@@@@@@@@@@.@@@@@@@..@@@@@@@@@@.@.@.@@.@@@@@.@.@..@@@..@@.@@@..\n..@@@...@@@@@@.@.@@.@@@@@...@.@@@.@@....@@@@@@@@@@.@@.@@@.@@..@@@@@.@..@@@@@.@@@@@.@.@.@@...@.@@.@.@@.@@@@@.@@@@..@@@@@@..@@..@@@@@@@@@.\n@@..@@.@@@@@@@@@@@.@.@@@@@.@..@@@.@@@@@@@@@@..@@@@.@..@@@@@.@.@@@.@.@....@@.@..@..@@@@@@@@@@.@@..@@@..@.@@.@@.@.@@@@@...@@@.@@@.@@@.@@@@\n@@.@@.@.@@.@@@@@@@@..@@@@@@@.@@@..@@.@..@@.@..@@@@@@.@@@@@@.@@@..@..@@@@..@@.@@@@@@.@@.@@.@@@.@@.@@@.@...@.@@.@.@@.@@....@@@@@...@@..@.@\n@...@@@@..@..@@.@@@.@@@@@@@@@..@.@@...@@@@@@@....@@.@...@@.@@.@@.@@.@@@@@@@.@@@..@.@@@@@.@@..@@@@@@@.@@@.@@.@@@.@@@..@...@@...@@@@@@.@..\n@..@..@.@@@@@..@@@@.@@@@@@.@@..@@..@@.@..@@.@@.@@@.@.@.@@..@@...@@.@.@@.@..@@@...@@.@@@.@@@@.@@.@@@...@@@.@@@.@@@.@@@.@@@@@@.@@@..@@@@@@\n.@@.@@@@@@@@@@@.@.@@@@@.@.@.@@@@.@@.@@..@@@.@@@@..@@...@@..@@@@@@.@@.@@..@@@@@.@...@.@@@@@@@.@@...@@@.@@...@@@@...@@.@@.@.@..@.@@@.@@@@@\n@.@..@@.@@..@@@@@@@@@@@@..@..@@@@@@@@.@...@..@@@..@@@@.@@@@@..@@@@@@.@@@@@@@@@.@@@.@@@.@@......@@@..@@@.@..@.@@.@.@@.@....@..@@@.@@@.@.@\n..@@@.@@@@.@@@@.@@@@@@@@@@@@@@@@..@..@@@..@@@..@@@@@.@@.@...@@.@@@@..@@..@@.@.@.@@..@.@@@@@@.@.@.@..@@@.@@.@@.@..@@@@@.@..@@@@@@@@@.@.@@\n@.@@.@@@@.@@@@@@@@@@.@.@@@@@@@@@.@.@@@@...@....@@@@@@@@.@@..@@@..@@.@@@@@@@@@@@.@@@@..@@.@.@@..@@@.@@@@@@@..@...@@..@@@@.@@@@@.@.@@...@.\n.@.@@@@..@@@@@.@..@@.@@.@@@@..@@..@.@@@..@.@.@@@@@.@..@@@..@.@@@.@@@@..@.@.@@@@@@...@..@@@...@.@..@@@@......@@@@.@@@@@@.@@@..@..@@@@@@.@\n.@..@.@.@..@.@@@.@.@@.@.@@.@.@@.@@@@@.@@@@@@@...@@@@@.@.@.@@.@@.@.@@.@@.@..@@.....@@@@@.@.@...@.@.@@@.@@@.@..@@@@.@.@.@@@@@..@@@.@@@.@@@\n@@..@@.@.@..@.@@@@.@@@@.@@@@@@..@@@@.@.@@..@@@@..@@.@@@@@@@@@...@@.@@.@.@@@@@@.@@@.@@@@@@@@@.@@.@@@@@@.@@@@@@.@@@@@@@@@@.@@...@.@.@@...@\n.@.@@@@@@@.@.@@.@..@.@.@@@@@@@.@.@@@@@@.@@....@@@@.@@.@@..@.@@..@@@@@@@....@@@..@@.@..@@@.@@.@...@@@@..@..@@@@@...@@..@@@.@@@..@@@..@@@.\n@..@@@@.@..@@@@@.@@.@@.@@@@.@@@..@@.@@@@@.@@@@@.@@@@@@.@..@@...@@...@.@.@@.@@@....@....@@@@@..@@@@@@.@@@@@.@.@@.@@@.@@.@.@.@@@@@@@@@.@..\n@..@@.@.@.@@@.@..@@@.@.@.@@@@..@@....@@@.@@@@.@@...@@.@@@....@..@.@..@.@@...@@.....@...@@@@.@..@.@.@..@@...@@.@....@@@@@@@@@@@@@@...@@.@\n@@@..@.@....@@@@.@@@.@@@.@@@@@@@@@@.@@...@@@..@@.@.@@.@..@@@.@@..@.@.@@@@@@...@@..@@@@...@@.@@@@...@.@.@@@@@.@@@@.@@@@..@@..@..@@@.@...@\n@@.@@.@@.@..@@@..@@@@..@@@@.@@@.@.@@@@.@@.....@.@@@.@.@..@@.@@@@@@@.@@@.@.@@@@@@@@@@.@@@.@.@@@.@@@@@@.@.@..@@@..@@@.@@.@..@@..@@@@@@@@@@\n@@@...@.@...@@.@@@.@@..@@@.@@@@.@@..@@.@.@.@@.@@.@@.@@@@@@@@.@.@@@@.@.@@..@@.@.@@@@@.@..@@@@@@@@......@@@@@@@@@@.@....@..@@@.@.@@@@.@..@\n.@@@@@@@@.@@@@@.@.@@@@@@@@@.@@@.@@@.@@@.@.....@@@@@@@.@@@@@@.@@@@@@.@@@@.@.@.@.@@@@.@@@@@@.@@@@..@@@.@@@.@.@@@.@@@@@@@@@@@.@.@.@...@...@\n...@@@@@.@.@..@@.@@@@.@@@@@@@.@@@@.@@@..@.@@@@@@@.@.@@..@@..@@.@@@@@@.@@@@.@.@..@@@.@@.@@@@..@.@@@@@@@@@@@.@@.@@@...@@@@@.@@.@.@@@.@@@.@\n..@.@@@@@@.@.....@.@@..@...@..@@@@@@.@..@@@.@.@.@@.@.@@@@..@@@..@@@@@@@.@@@.@.@@@@@@..@@...@.@@.@..@@@@@.@..@@@..@@@.@@@@.@.@@...@@@.@@@\n@@@.@@@@@@@@@....@@@.@@@@@@...@@@.@@@.@.@@@@@.@@@@...@@.@@@...@@@@@@@@@@@@@@@.@.@@@.@@@@@@@@@@.@@@@@@..@@.@.@@@..@@@.@@@@@@@.@@@@@@@@..@\n@.@@@@@.@..@..@@@.@@..@@@@@@@@@.@@@@@@@@.@..@@.@@@.@@.@.@@@@.....@.@@.@.@@@.@.@@@...@@@.@.@.@.@..@.@@@@.@@...@@..@@..@.@@.@@.@@@@.@.@@@@\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_04_questions.txt",
    "content": "--- Day 4: Printing Department ---\n\nYou ride the escalator down to the printing department. They're clearly getting ready for Christmas; they have lots of large rolls of paper everywhere, and there's even a massive printer in the corner (to handle the really big print jobs).\n\nDecorating here will be easy: they can make their own decorations. What you really need is a way to get further into the North Pole base while the elevators are offline.\n\n\"Actually, maybe we can help with that,\" one of the Elves replies when you ask for help. \"We're pretty sure there's a cafeteria on the other side of the back wall. If we could break through the wall, you'd be able to keep moving. It's too bad all of our forklifts are so busy moving those big rolls of paper around.\"\n\nIf you can optimize the work the forklifts are doing, maybe they would have time to spare to break through the wall.\n\nThe rolls of paper (@) are arranged on a large grid; the Elves even have a helpful diagram (your puzzle input) indicating where everything is located.\n\nFor example:\n\n..@@.@@@@.\n@@@.@.@.@@\n@@@@@.@.@@\n@.@@@@..@.\n@@.@@@@.@@\n.@@@@@@@.@\n.@.@.@.@@@\n@.@@@.@@@@\n.@@@@@@@@.\n@.@.@@@.@.\n\nThe forklifts can only access a roll of paper if there are fewer than four rolls of paper in the eight adjacent positions. If you can figure out which rolls of paper the forklifts can access, they'll spend less time looking and more time breaking down the wall to the cafeteria.\n\nIn this example, there are 13 rolls of paper that can be accessed by a forklift (marked with x):\n\n..xx.xx@x.\nx@@.@.@.@@\n@@@@@.x.@@\n@.@@@@..@.\nx@.@@@@.@x\n.@@@@@@@.@\n.@.@.@.@@@\nx.@@@.@@@@\n.@@@@@@@@.\nx.x.@@@.x.\n\nConsider your complete diagram of the paper roll locations. How many rolls of paper can be accessed by a forklift?\n\n--- Part Two ---\n\nNow, the Elves just need help accessing as much of the paper as they can.\n\nOnce a roll of paper can be accessed by a forklift, it can be removed. Once a roll of paper is removed, the forklifts might be able to access more rolls of paper, which they might also be able to remove. How many total rolls of paper could the Elves remove if they keep repeating this process?\n\nStarting with the same example as above, here is one way you could remove as many rolls of paper as possible, using highlighted @ to indicate that a roll of paper is about to be removed, and using x to indicate that a roll of paper was just removed:\n\nInitial state:\n..@@.@@@@.\n@@@.@.@.@@\n@@@@@.@.@@\n@.@@@@..@.\n@@.@@@@.@@\n.@@@@@@@.@\n.@.@.@.@@@\n@.@@@.@@@@\n.@@@@@@@@.\n@.@.@@@.@.\n\nRemove 13 rolls of paper:\n..xx.xx@x.\nx@@.@.@.@@\n@@@@@.x.@@\n@.@@@@..@.\nx@.@@@@.@x\n.@@@@@@@.@\n.@.@.@.@@@\nx.@@@.@@@@\n.@@@@@@@@.\nx.x.@@@.x.\n\nRemove 12 rolls of paper:\n.......x..\n.@@.x.x.@x\nx@@@@...@@\nx.@@@@..x.\n.@.@@@@.x.\n.x@@@@@@.x\n.x.@.@.@@@\n..@@@.@@@@\n.x@@@@@@@.\n....@@@...\n\nRemove 7 rolls of paper:\n..........\n.x@.....x.\n.@@@@...xx\n..@@@@....\n.x.@@@@...\n..@@@@@@..\n...@.@.@@x\n..@@@.@@@@\n..x@@@@@@.\n....@@@...\n\nRemove 5 rolls of paper:\n..........\n..x.......\n.x@@@.....\n..@@@@....\n...@@@@...\n..x@@@@@..\n...@.@.@@.\n..x@@.@@@x\n...@@@@@@.\n....@@@...\n\nRemove 2 rolls of paper:\n..........\n..........\n..x@@.....\n..@@@@....\n...@@@@...\n...@@@@@..\n...@.@.@@.\n...@@.@@@.\n...@@@@@x.\n....@@@...\n\nRemove 1 roll of paper:\n..........\n..........\n...@@.....\n..x@@@....\n...@@@@...\n...@@@@@..\n...@.@.@@.\n...@@.@@@.\n...@@@@@..\n....@@@...\n\nRemove 1 roll of paper:\n..........\n..........\n...x@.....\n...@@@....\n...@@@@...\n...@@@@@..\n...@.@.@@.\n...@@.@@@.\n...@@@@@..\n....@@@...\n\nRemove 1 roll of paper:\n..........\n..........\n....x.....\n...@@@....\n...@@@@...\n...@@@@@..\n...@.@.@@.\n...@@.@@@.\n...@@@@@..\n....@@@...\n\nRemove 1 roll of paper:\n..........\n..........\n..........\n...x@@....\n...@@@@...\n...@@@@@..\n...@.@.@@.\n...@@.@@@.\n...@@@@@..\n....@@@...\n\nStop once no more rolls of paper are accessible by a forklift. In this example, a total of 43 rolls of paper can be removed.\n\nStart with your original diagram. How many rolls of paper in total can be removed by the Elves and their forklifts?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_05.adb",
    "content": "--  Solution to Advent of Code 2025, Day 5\n------------------------------------------\n--  Cafeteria\n--\n--  https://adventofcode.com/2025/day/5\n--  Copy of questions in: aoc_2025_05_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nprocedure AoC_2025_05 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; ranges : constant := 4; ingredients : constant := 6;\n  input_name : constant VString := +\"aoc_2025_05\"; ranges : constant := 187; ingredients : constant := 1000;\n\n  from, to : array (1 .. ranges) of Integer;\n  id : array (1 .. ingredients) of Integer;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in 1 .. ranges loop\n      Get (f, from (i));  --  NB: replaced all '-' by ' '.\n      Get (f, to (i));\n    end loop;\n    for i in 1 .. ingredients loop\n      Get (f, id (i));\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    count : Natural := 0;\n  begin\n    for i in 1 .. ingredients loop\n      for j in 1 .. ranges loop\n        if id (i) in from (j) .. to (j) then\n          count := count + 1;\n          exit;\n        end if;\n      end loop;\n    end loop;\n    r (part_1) := +\"\" & count;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    count : Natural := 0;\n    modified : Boolean;\n    enabled : array (1 .. ranges) of Boolean;\n  begin\n    for i in 1 .. ranges loop\n      enabled (i) := True;\n    end loop;\n\n    Merging :\n    loop\n      modified := False;\n      for i in 1 .. ranges loop\n        for j in 1 .. ranges loop\n          if i /= j and then enabled (i) and then enabled (j) then\n            if from (j) in from (i) .. to (i) then\n              to (i) := Max (to (i), to (j));\n              enabled (j) := False;\n              modified := True;\n            end if;\n            if to (j) in from (i) .. to (i) then\n              from (i) := Min (from (i), from (j));\n              enabled (j) := False;\n              modified := True;\n            end if;\n          end if;\n        end loop;\n      end loop;\n      exit Merging when not modified;\n    end loop Merging;\n\n    for i in 1 .. ranges loop\n      if enabled (i) then\n        count := count + to (i) - from (i) + 1;\n      end if;\n    end loop;\n\n    r (part_2) := +\"\" & count;\n\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 798.\n    --  Part 2: validated by AoC: 366181852921027.\n  end if;\nend AoC_2025_05;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_05.txt",
    "content": "484155089502467 484512074248320\n327626855857871 327839020372374\n537199009780696 541029389615243\n324153507327596 324355964932738\n173465989350447 174041788222911\n272663544666906 272663544666906\n152868490671419 154360265852862\n334565314570930 336048544225520\n106674076603254 107536478616833\n363046535191057 365733424846852\n143852691024200 149853768977406\n513247409695401 521804010955295\n330373417143016 330956155155726\n33228806536288 34781051094522\n104978535117550 105727571504542\n105727571504542 106382462636384\n480181317870752 481376655879090\n392619573203723 399658137237572\n507064558575642 510928211367973\n31269013157556 32964221268164\n70746675484895 79383949442561\n488384911502333 488739524722600\n245264863918656 248440699812419\n66108233250077 69763977702508\n158354044192140 159602837769606\n352968125118640 359903538807905\n177637503356342 177768248104438\n425225371783345 428185880910613\n337517774842228 338699568015001\n413116823808052 421482453687743\n324355964932738 324787726958767\n21031505924359 29336206500785\n178762017395739 179306786525152\n283124359892576 288153917955743\n104238754491838 104978535117550\n156665511220055 158040260496243\n338247146166164 339788754907221\n179536222619975 180228661508492\n474667184537974 475812255497205\n513247409695401 521804010955295\n106887900874655 107536478616833\n175392398092002 175732866298956\n526139005782144 526139005782144\n35410277445200 36916358845884\n164076435824111 169840064957070\n133425032733176 139934998714644\n490674555618697 490885111740712\n179786208538406 180553730844907\n302346553875535 307433027610821\n179974705855165 180553730844907\n535002393179139 538558642399142\n44042155826769 48485113111141\n213624552370199 219348371651378\n172619324074780 172877499427963\n94528043269341 98873034317961\n205261145714311 209868219379161\n184779217941336 186667644665468\n322101662480758 322234504977633\n262039770461003 262039770461003\n41875022229570 45906391518435\n123353799692990 123353799692990\n472616439285348 474000437648419\n164076435824111 169840064957070\n177768248104438 177966938826842\n171117176820731 171869292146532\n547332612003149 547332612003149\n37424193557969 39105929131744\n101571946459934 102315599870875\n494764112303360 500892212366204\n215878956252212 219348371651378\n332071647060451 333275653431219\n172223413862387 172619324074780\n343059617550421 349658206244594\n32398106302077 33821920045244\n62268552683460 69763977702508\n479178474644199 480641496160741\n103399160626151 103679584369887\n526139005782145 530329158936682\n477382678085753 478659206508893\n352968125118640 352968125118640\n252193370768120 260075547729033\n503954701580 6201080066693\n6201080066694 7139048210272\n491761166450629 491902594324657\n324983512198420 325884415693302\n316494299906814 320522086960363\n467509841566778 471811317565211\n154583318057153 156059831409040\n307433027610822 309166768178612\n241735356768237 245264863918655\n106189609258943 106887900874655\n113184461842736 113184461842736\n157309114531452 158807509412759\n405794282692748 410151465111344\n322562853182400 323349337173519\n329392752538402 329600089281791\n416454584217619 418657627464396\n476445154558831 477740195072234\n52321883454900 57264044440557\n285940653177318 290122783606908\n139934998714644 139934998714644\n104238754491838 104978535117550\n435069087551255 438068571490810\n106674076603254 106887900874655\n494764112303360 498339466050479\n488384911502333 488739524722600\n433395071188269 441714193170789\n483173469016124 483876364342976\n382952029544932 382952029544932\n272663544666907 278898829344501\n30517568996683 31934161587780\n446467331372924 449790867859745\n480957198725802 482308516753345\n340216156305507 341718829614154\n335576964661675 337073420302056\n171269045448034 171869292146532\n322234504977633 322838357184566\n328299411279389 329144168796675\n36486032858102 37779434330475\n482564738939348 483424624675311\n329843762496517 330062103963728\n343059617550421 346964428300776\n141909036863330 147391313413681\n327247289135445 327839020372374\n10922455590682 18048485396100\n339273504804747 340626526043886\n453340687216566 461539243082300\n24552273221200 26517533186483\n374979031812261 378129333728028\n510928211367974 510928211367974\n478218077956627 479645063914504\n174041788222911 174346031234314\n559173122141199 562097848259759\n113184461842737 118169846892007\n382952029544933 390301071864488\n81543407926368 84497261070632\n105408705742278 106024442272978\n491531238739012 491902594324657\n428185880910613 428185880910613\n260075547729034 260075547729034\n313883655354623 320522086960363\n174041788222911 174346031234314\n191717416530192 199687058207157\n336507649028291 337969660720965\n153577994966155 155092017715908\n103183231617090 103399160626151\n70746675484895 76153416335407\n57264044440558 57264044440558\n332803389475321 334388906138526\n171269045448034 171869292146532\n38316177713166 40091262905581\n84497261070634 87512083133515\n106189609258943 106674076603254\n378129333728029 378129333728029\n547332612003149 548435610366690\n410151465111344 410151465111344\n486966262648163 487773819017583\n464168729967780 467509841566777\n173265729856132 173465989350447\n155722135599830 156927657943610\n473459660138827 475150269845108\n333858227074656 335312735045959\n487773819017583 488249317523391\n330373417143016 330623658555129\n94528043269341 98873034317961\n392619573203723 399658137237572\n203106437735893 205261145714309\n232703951471611 239341944463919\n172223413862387 173033171008712\n182821432918211 190283971945510\n151130743713884 152260090603062\n475285443653571 476657816081333\n199687058207157 199687058207157\n221829521326154 229542350570658\n159395463557657 160782166956609\n179306786525152 179786208538406\n174041788222911 174805432404479\n262039770461003 269736060293387\n554841339364567 559173122141197\n123353799692990 128560306281572\n444809669679604 449790867859745\n101831951224850 102162268389164\n365733424846854 370976617474324\n34440576402312 36063022673365\n152001032352489 153287102386040\n292589544764606 298318988515383\n232703951471611 234901660011328\n\n465648994325263\n485726374948528\n475690590637294\n196300608673016\n325500055841075\n200391175665352\n17944830705256\n319006389890415\n151008315208808\n330762627717238\n540107358809277\n56579943828298\n304827419309353\n218793968762758\n558979672005912\n463149947708692\n207132310251074\n27688126629980\n410787718804716\n266815787492858\n349549957351422\n453161293260865\n440124194013821\n224935111486614\n458189929672612\n222354803951091\n385496645295297\n159737743445676\n435085730350147\n339049336984817\n108289691196866\n63269002874293\n6685408969929\n560711096442918\n447842282857842\n384258392057600\n418317339187012\n526232998972781\n318185626019900\n173954241244574\n76885713250977\n138953839992455\n38446781284879\n2993091307541\n89328498019533\n287583058061187\n253388687193171\n65815885278170\n143667792195956\n56993769071203\n158687367691714\n315658700075614\n158128483336434\n222191777973717\n272622212776187\n545192047362089\n376186038765117\n242947268747893\n471085877835535\n129965216056599\n207778752587957\n252471880342054\n262906375116580\n534224313922897\n413878652736777\n197035964264903\n279549224671724\n44153866205768\n25490437132400\n456047749271344\n460454825298853\n269978250340095\n25320286312005\n273115319581907\n150161800308438\n110871266684605\n319420592547997\n345738432687570\n305793320149559\n148713889489739\n499294517093216\n31226367130878\n172612656724594\n430075577395089\n539700736071107\n248490622736321\n357783308268551\n265119880018962\n231291290345527\n226150538134399\n510440855670848\n557968955261200\n366753606894739\n548046875564109\n487949898298134\n508297681301651\n85813530184312\n26085582228207\n248098174814414\n74638591550079\n308178419048394\n95835736571751\n275218649532607\n394868159876364\n10285869395759\n465200373669687\n286750097376153\n420455004515755\n338547854534866\n348720612223320\n12958774971518\n245763283083902\n332351236310594\n276158906164860\n59042749656947\n451943792959362\n330391629603314\n48157493287167\n398240465941344\n414801973326926\n378550285283921\n22163595467061\n480779429139335\n556351665029871\n559638909723239\n347211750008710\n324727023947861\n177948083905540\n62813318066679\n339398092073741\n400934619177864\n86790992465901\n15852914116516\n154253986279527\n42345202069561\n107418220431964\n327726786214697\n479901768278245\n490972852957601\n501860254654435\n187476104076465\n515234099215970\n105613677798811\n76576992517982\n63602685134794\n370446294064094\n125293600622010\n348624405047279\n229414892467206\n550111725377520\n253601022800835\n246015599038208\n26716224090075\n106628682325906\n149367265754691\n344227585534865\n414436225034212\n373044568770668\n508032292480710\n538747633140176\n239129875011217\n267903056026239\n269079461276087\n390868090347716\n138622100881942\n38844613237894\n322994927085853\n454018508978606\n311534498907291\n329122626881814\n180970002094700\n376068250617145\n177634058757307\n490881830234258\n7017946450359\n410609014613452\n358602206782982\n230210485077799\n166311033674041\n254871960396830\n479583246001450\n418333891442833\n13018415298209\n110436931200781\n377848248759981\n37055407062199\n395771536090537\n285625857320076\n457071547846483\n454462175815748\n243572281764729\n493838152934481\n136306603477083\n272965132772929\n359523134895474\n218062604316076\n196080099320404\n62242223744221\n147151311756565\n146316101931905\n146976702862809\n510395092805891\n131718330043246\n449648193586388\n435829963434261\n440625359718663\n365172596783271\n540396006775329\n234779165152900\n264534238804314\n66806025266187\n275069701001412\n366062798029719\n244456093804383\n527700086323868\n166529351298605\n362955521436431\n482919085310378\n283257341505810\n153232880696306\n394552242781153\n343768049178508\n333950895480298\n551853617580089\n143677863519490\n74060167453409\n456310322303431\n134025061222202\n408728099607080\n34573640312491\n193928098114300\n490066275814021\n86303373869837\n245645106780938\n52636102151296\n297258182795550\n278363025356332\n119956165401884\n39912089231581\n427018367648629\n487183658692128\n223315477094328\n517175429318316\n68881075516914\n33094051437104\n388410883822250\n531869844960512\n256328382826175\n175275083136438\n83289029741724\n465763280963667\n31646298618953\n333168648755117\n366242861943763\n75156722777953\n508265614839503\n98796946465642\n559020601116488\n5467108109577\n105366513196271\n164428413619744\n83151142391341\n185014262064857\n497629158286618\n31153262748994\n298043610770489\n283925378412319\n28694803075972\n455906018804610\n151868806777935\n363620235563789\n36347910669144\n196354303370134\n388483018172112\n360582809724943\n232150072570533\n96237634389515\n505851323146100\n168577897920329\n268532747533171\n414271786676737\n510738155126151\n42288604743357\n464845452560036\n350521576763663\n2790553607883\n286601432695738\n68581668330233\n497747478353430\n488060165737320\n210394112436035\n531938419333390\n235733370183364\n499411335343391\n406594297115866\n534179913427567\n141237867072244\n518890750016543\n25086593475095\n276643782014667\n103653487570393\n33747448093872\n85394611729114\n180863610744209\n230621930891177\n65398129849574\n106310501531592\n105863422604792\n378489487582599\n331387514827061\n6561622918944\n432933925759374\n499456656539730\n222338928476450\n394316775471077\n306705011159801\n517178697140196\n148102225673100\n55116866718253\n301492363170310\n424350017261844\n104156598979714\n6368571580028\n145394106705778\n517700100504249\n455652082476752\n421442262713380\n373884444959820\n420923707716902\n529939677020279\n263306921865810\n415279461779662\n158195109422211\n554221248253924\n193383508459957\n217823095636530\n441869358121903\n286873626157484\n34675944352140\n274323027667503\n264311656855279\n387673053556249\n82868052293172\n316511965956741\n151612982915105\n425826466685883\n491238761663825\n350486059871862\n413513421497176\n236567477096492\n408896153104255\n467470679972033\n164704456622599\n63685936847397\n390979670666774\n474928971607942\n135026465304050\n359056540419958\n66745809311184\n126018096549244\n305062744049016\n194071199277840\n501509723548996\n476827185200581\n275626747234735\n430013005023040\n518410150791484\n72131242700198\n340383414749962\n477665601493098\n535561806427643\n407555137195755\n217291279819907\n557986608664834\n16142893632580\n182124459880116\n404140756484309\n296110516420275\n171643098351907\n486931627408613\n207113534380670\n524077154282500\n228864907023232\n383365617894903\n70103795249694\n50512979173728\n397605945336496\n26013092471759\n395241421268710\n465334300964440\n261858369021755\n527684923283476\n427630216321229\n198238026697491\n457457910251150\n401506984329048\n349178450263450\n546647139996296\n184462947778898\n306367401529528\n539563594059532\n39345489728847\n103010746227197\n98116787456608\n386846358756692\n104610778208354\n26576694008613\n156565542157075\n192084240612390\n259556465772815\n15904195560740\n236132852584233\n434644090364311\n99881487051684\n426905232171523\n522034565059278\n314506139726295\n299499714003961\n183820232806506\n206850974659307\n135663766665821\n102089365540214\n425945138241774\n414725338716582\n84837001135774\n226352656640955\n288721160221131\n116097857625794\n468257741655738\n349131393125042\n97858344250848\n475522348864872\n472826892261099\n69455870488880\n131805399737993\n216094584070180\n58455712847916\n366711602802177\n357054615859808\n78357619210085\n152990852088797\n342524073993073\n450043621091613\n201845269573400\n142430583159100\n556503021827212\n85161652291815\n290058445580149\n178728724583453\n418131998829096\n427697703225770\n25904543179754\n105297352146790\n418123737779902\n383678551854912\n468730983371397\n124787414786575\n308383651669639\n53248099552727\n171498826192589\n376406135890811\n445258595316244\n263231728643009\n324208810777119\n388583324784949\n458331277070896\n148031092492796\n382018948513853\n136077295163143\n308555646984109\n14614285259270\n461653649248830\n158318118603163\n435013238520636\n326150076739969\n475399121253465\n156106959019712\n208688809717157\n29842605290273\n202268072059860\n282993801201526\n153365611642795\n540921552967436\n320960886502819\n469707792686103\n105242779432445\n479012505415829\n118156584567709\n70836294505690\n528644756078017\n102749524223928\n343794580364717\n556579065871742\n38122311901867\n312016631085668\n505198292111546\n144563040821956\n406991234444632\n160317680143063\n350140714964482\n66925480163405\n232902001009144\n536755664481759\n21196120357836\n173665364262475\n5420853189190\n101147507820255\n284293797695935\n461399398995401\n464546187321105\n541878525900454\n279404587265427\n550800427007755\n235673928376398\n452515441844173\n509555045565249\n481221087162142\n415796518011797\n555464484523481\n245486050836754\n1312729187484\n461351154425133\n446085579349094\n539735263671492\n324308812517461\n267452870204054\n179862138942359\n87063631074434\n77676965428230\n47495874689531\n83250190393567\n287503596941017\n396444990457477\n124519706839242\n157839982935656\n495062791439310\n154512214075405\n208785614070698\n418534616900849\n487111934977198\n116686672775696\n17278207794169\n297792271040321\n545485324397541\n26910544487003\n227986077033638\n331470468561325\n396739005101185\n420261747916524\n60882138247537\n314400885398908\n507321940974182\n479607363750629\n274028634022721\n290214480779409\n255150656469724\n406333418726889\n209633642668851\n82851650413018\n174415875855808\n347647962998358\n142865843659110\n346951844710054\n145296662557462\n370773076584528\n126214747850220\n547652353458667\n1023351263968\n169755175398654\n518599429906635\n33846742681732\n168672976381620\n224753538745291\n484122613844692\n204986873429997\n548186280004784\n151971816872087\n2413001123517\n215217411624094\n252715157090472\n246882536494029\n314841111397180\n45576108912322\n274774894152420\n364637463845199\n158997318823023\n467729730148300\n364161875382173\n27548860861942\n118010407564078\n153109272880074\n341236750027155\n548263482896529\n354565236617873\n426774118014985\n203943800062495\n364485490818434\n347129355238045\n389282748200872\n402591881455477\n37109245860638\n322524359738963\n23352577264101\n60112554654836\n99069004043586\n335518138579949\n557705378914003\n332954879797108\n159249252478289\n192303686883130\n84311997851419\n323811763014534\n397881987568871\n41263853930161\n314204432093487\n94630391383561\n125537195647648\n455484220609279\n275106701648714\n161582427450661\n136613479485433\n196012947779387\n498418367271002\n343934545259218\n2109961804682\n225347192591111\n187751534783876\n62432768102721\n90240593769245\n243347328031763\n180262096694629\n400611561547347\n68580731244073\n448857492874889\n162511353947722\n174067633194412\n174454835018391\n6733952033973\n512566408826733\n196428147016599\n173987768218259\n438425145431191\n98795447051414\n562151356355741\n511061394152804\n464834443408759\n258839398859279\n63647412759537\n500359969724673\n414674931688430\n486342755507303\n383495876744797\n247959228222071\n478395383849061\n335314989684365\n401680212074279\n54662260419310\n195575312971134\n329701660363513\n557203258155487\n303934913812278\n549196383540217\n316558010658840\n388894303598071\n508495705576650\n365382037848947\n434160208706186\n490719268527649\n22757508593407\n74173060080537\n394529116580444\n198579420316664\n218648394504284\n250844719945739\n519177115726079\n210995283950867\n478926704240966\n322125338086841\n222231141633906\n24243547233806\n475228412705872\n538016030134645\n539685388009141\n112200167208259\n34998189396523\n242034427621752\n481097694329618\n162102242581143\n171163156509241\n417698127705874\n289327511951933\n150231091159121\n86318216985599\n212157894516578\n211034711980000\n352280810580118\n215902883235127\n501602712242483\n275284982144704\n228519292815627\n255308739610203\n388103293212389\n11062160873834\n211605059954128\n409504977518037\n166887900685401\n269906845954803\n242809833732335\n70542864360841\n29246218481549\n28171334842885\n408392861262973\n25987925230493\n69690389331629\n64881435704887\n538200095965370\n464951259269603\n62530051010143\n481562836269822\n275588779592943\n121462168598953\n294262042995506\n362773254065101\n185452277418500\n253776377158625\n553020845442987\n450981282843183\n482825359338299\n92951712090079\n401789488969013\n82691587449395\n460547332437770\n550369009765200\n204765006219353\n383424935026763\n411451885278109\n544768399768969\n354106107278808\n351814733606870\n345205736531054\n553990438058685\n234530753617837\n142037700543505\n166205529744183\n282574350096660\n349310470286847\n461168096150528\n174088527209052\n273407649865353\n560772075847388\n373669265382428\n527940044219641\n526220055349415\n61333301482305\n277381088312766\n398653996346101\n537358286465034\n420041777878728\n190904884792541\n414135951466143\n307427122957800\n175496838477939\n224045469192409\n396641535383079\n12932297615290\n29305595689889\n320494881948653\n35634989953013\n463400091256918\n364308441200109\n287733984223493\n286312417663097\n14476535040100\n72345157790618\n467979218411243\n398300177864406\n509810162779476\n86494614774768\n337887243617068\n183004315538293\n301315508280444\n32819467122530\n364101460589897\n272127482531487\n14661880480118\n558085063855258\n477774912319456\n149379002920977\n182144611410986\n261364167690385\n297193844543228\n368675600885719\n217918407064700\n250917765917926\n485979592516414\n27419266468566\n281119855989076\n53342876607506\n168385081690418\n68071599924640\n295085841498947\n433634500661453\n98210283393150\n417925823041044\n118046126998437\n125931519008518\n54101783039771\n296563685725698\n125385974251141\n140596318930571\n297613888680909\n556556247766534\n77556654164724\n520726672992536\n527962296094224\n314838704938152\n104567359857678\n229378218651487\n535163096560007\n421878548905206\n22292022004456\n226694762920368\n325433562224972\n350927689838638\n68747614466057\n278288373610990\n123329215731971\n127638721913602\n262467205139544\n439437567436922\n33169828276782\n365819063105421\n107419826143114\n159492842181615\n245826906772378\n33701292015819\n111130590303550\n143267425161404\n88518370001945\n99709748831684\n507144340395665\n17005295074631\n394597409724205\n456109774133764\n220266796928414\n194337113829451\n168376744056032\n196324880604945\n316303815900806\n260225614006305\n126676005306073\n287800426485627\n296010450965831\n452327757155989\n386915979105242\n12884154162742\n178299434462745\n289780425057671\n524692852474367\n8049748421905\n287512776418562\n497495353423812\n356953912190227\n105152422060130\n75715726194756\n449471922988083\n178960727226775\n16506135862435\n380008863901350\n484802537945341\n487269642070212\n257689206088793\n437162197656802\n167690406405337\n295131584027702\n423128589715610\n247857337979598\n447294653683025\n528754659447288\n197150348372392\n85527781232882\n325643026875656\n85416649290624\n343351960079471\n222144605855719\n95242848385552\n418257702534682\n479749851030221\n439327119253406\n216007727430876\n159556006351623\n285136231800700\n266346349408836\n213204893467649\n132329408393058\n167396552278400\n13430771760342\n272999234705345\n2181291406670\n354267124354129\n3915477000394\n275667302930232\n355703471654279\n171573697499122\n476108734602434\n250333255771422\n284187391074728\n542883247228251\n268388512130581\n348724909067450\n560982897255963\n82425178945262\n36793327303651\n472679026025886\n533185603352637\n440862633593872\n314693292941017\n377142702705622\n146391068281354\n436927110770106\n195928939466611\n464708458561253\n534281577040719\n112247600527291\n76450436291102\n297995326049950\n13894251352689\n124192647936767\n459599244668614\n283615760282882\n431457068564814\n514669417032595\n393253024342883\n303594090232073\n216329092129347\n451781660318266\n538732013128567\n51394498892905\n97563862042322\n555360678665621\n77125009216030\n6152085147952\n479065478792799\n106892288326794\n425624436244334\n364781708077558\n23520178833448\n52848164391780\n216773473113383\n64529056817782\n366397062395405\n533542103965367\n506373117858768\n204343504228015\n126207040767367\n245758805851139\n255365791457351\n403718281368516\n431078684518872\n136406177504001\n14152106004280\n481612673665150\n5255589275675\n556247473776668\n146648767168484\n534052369132154\n255694301437722\n174802115600729\n85420697896041\n9915837268881\n356870117868642\n312389014496808\n526053044616034\n368205286083856\n216240149607142\n204496240924157\n533836527185372\n376000060036219\n552828975199029\n53503756659340\n185432188845668\n524669951477891\n455840130412128\n5212891951706\n442635246848462\n459658055857457\n163443771410584\n12527116890639\n344961051023748\n117138982479414\n198297242149820\n283663699949587\n424555341493375\n435688311529195\n342348741243927\n38933572204739\n554703298864698\n395433357795370\n93543372994982\n495748168198728\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_05_questions.txt",
    "content": "--- Day 5: Cafeteria ---\n\nAs the forklifts break through the wall, the Elves are delighted to discover that there was a cafeteria on the other side after all.\n\nYou can hear a commotion coming from the kitchen. \"At this rate, we won't have any time left to put the wreaths up in the dining hall!\" Resolute in your quest, you investigate.\n\n\"If only we hadn't switched to the new inventory management system right before Christmas!\" another Elf exclaims. You ask what's going on.\n\nThe Elves in the kitchen explain the situation: because of their complicated new inventory management system, they can't figure out which of their ingredients are fresh and which are spoiled. When you ask how it works, they give you a copy of their database (your puzzle input).\n\nThe database operates on ingredient IDs. It consists of a list of fresh ingredient ID ranges, a blank line, and a list of available ingredient IDs. For example:\n\n3-5\n10-14\n16-20\n12-18\n\n1\n5\n8\n11\n17\n32\n\nThe fresh ID ranges are inclusive: the range 3-5 means that ingredient IDs 3, 4, and 5 are all fresh. The ranges can also overlap; an ingredient ID is fresh if it is in any range.\n\nThe Elves are trying to determine which of the available ingredient IDs are fresh. In this example, this is done as follows:\n\n    Ingredient ID 1 is spoiled because it does not fall into any range.\n    Ingredient ID 5 is fresh because it falls into range 3-5.\n    Ingredient ID 8 is spoiled.\n    Ingredient ID 11 is fresh because it falls into range 10-14.\n    Ingredient ID 17 is fresh because it falls into range 16-20 as well as range 12-18.\n    Ingredient ID 32 is spoiled.\n\nSo, in this example, 3 of the available ingredient IDs are fresh.\n\nProcess the database file from the new inventory management system. How many of the available ingredient IDs are fresh?\n\n--- Part Two ---\n\nThe Elves start bringing their spoiled inventory to the trash chute at the back of the kitchen.\n\nSo that they can stop bugging you when they get new inventory, the Elves would like to know all of the IDs that the fresh ingredient ID ranges consider to be fresh. An ingredient ID is still considered fresh if it is in any range.\n\nNow, the second section of the database (the available ingredient IDs) is irrelevant. Here are the fresh ingredient ID ranges from the above example:\n\n3-5\n10-14\n16-20\n12-18\n\nThe ingredient IDs that these ranges consider to be fresh are 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, and 20. So, in this example, the fresh ingredient ID ranges consider a total of 14 ingredient IDs to be fresh.\n\nProcess the database file again. How many ingredient IDs are considered to be fresh according to the fresh ingredient ID ranges?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_06.adb",
    "content": "--  Solution to Advent of Code 2025, Day 6\n------------------------------------------\n--  Trash Compactor\n--\n--  https://adventofcode.com/2025/day/6\n--  Copy of questions in: aoc_2025_06_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nprocedure AoC_2025_06 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; l : constant := 15; m : constant := 3; n : constant := 4;\n  input_name : constant VString := +\"aoc_2025_06\"; l : constant := 3772; m : constant := 4; n : constant := 1000;\n\n  a : array (1 .. m, 1 .. n) of Integer;\n\n  op : array (1 .. n) of Character;\n  pos_op : array (1 .. n) of Positive;\n  dig_it : array (1 .. m, 1 .. l) of Character;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    k : Integer;\n    f : File_Type;\n    s : VString;\n  begin\n    --  Read the numbers:\n    Open (f, input_name & \".txt\");\n    for i in 1 .. m loop\n      for j in 1 .. n loop\n        Get (f, a (i, j));\n      end loop;\n    end loop;\n    Close (f);\n\n    --  Parse operator row:\n    Open (f, input_name & \".txt\");\n    Skip_Line (f, m);\n    Get_Line (f, s);\n    Close (f);\n    k := 0;\n    for i in 1 .. Length (s) loop\n      case Element (s, i) is\n        when ' ' =>\n          null;\n        when others =>\n          k := k + 1;\n          pos_op (k) := i;\n          --  put_line(i);\n          op (k) := Element (s, i);\n      end case;\n    end loop;\n\n    --  Parse digits or blanks individually for Part 2:\n    Open (f, input_name & \".txt\");\n    for i in 1 .. m loop\n      for j in 1 .. l loop\n        Get (f, dig_it (i, j));\n      end loop;\n    end loop;\n    Close (f);\n\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    total : Integer := 0;\n    sumprod : Integer;\n  begin\n    for j in 1 .. n loop\n      if op (j) = '+' then\n        sumprod := 0;\n      else\n        sumprod := 1;\n      end if;\n      for i in 1 .. m loop\n        if op (j) = '+' then\n          sumprod := sumprod + a (i, j);\n        else\n          sumprod := sumprod * a (i, j);\n        end if;\n      end loop;\n      total := total + sumprod;\n    end loop;\n\n    r (part_1) := +\"\" & total;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    last : Integer;\n    s : VString;\n    total : Integer := 0;\n    sumprod : Integer;\n  begin\n    for j in 1 .. n loop\n      if j = n then\n        last := l;\n      else\n        last := pos_op (j + 1) - 2;\n      end if;\n      if op (j) = '+' then\n        sumprod := 0;\n      else\n        sumprod := 1;\n      end if;\n      --  Parse each cephalopod number, with possible\n      --  leading or trailing blanks:\n      for k in pos_op (j) .. last loop\n        s := +\"\";\n        for i in 1 .. m loop\n          s := s & dig_it (i, k);\n        end loop;\n        if op (j) = '+' then\n          sumprod := sumprod + Integer_Value (s);\n        else\n          sumprod := sumprod * Integer_Value (s);\n        end if;\n      end loop;\n      --  NB: the \"right-to-left\" mention in \"Cephalopod math is\n      --  written right-to-left in columns\" is irrelevant, it's\n      --  just to confuse readers.\n      total := total + sumprod;\n    end loop;\n    r (part_2) := +\"\" & total;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 4449991244405.\n    --  Part 2: validated by AoC: 9348430857627.\n  end if;\nend AoC_2025_06;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_06.txt",
    "content": "95 62 793 567 8181 73  5 55 76   59 3498 51 3   53 59 7821 93 45  2  5  4 8  517 341 5   472  24 55  59   6 67  525 499   4 178 323  8 9912  1 78  43 666 758 473 39 9634 96  952  5 8344  2  3 42  8    3  452 521 85 81  2   61 92   26  8683 683 99 2  11 825 4493 92 853 549   6 1  21 226 826 218 9  182 7672 88 9596 71   56  13 6146 59 41 631 751 556 373 83  1  93 158 47 9  41 67   75 7666 7936 1  8  217 3289 57  47 59   74  3 96     49 53 82 789 51 561  7   85 5  2174  6 586 6684  782 45 41 38  73  378  47 53 4   6 161 23 4331 13 384  5  19   8 2115 191 13  35 835  7 51   3 948 323   19 269   4  3 87 15 26 195 39  623 73   35 767 8292 71 29 38 2547 15  833 522   9 1281  323   6 4  285 69 234 7229 6  4   962  16 33 45  236  8 445 4337 8   21 384 7   1593 44 9  5517 18  3425 36 6    91     7 5855  311 725 25     2  2    3 753 812 978 647 29 618 95   51 8851  9 874 47 366 9  88  7 22 879 182 65  36 365 344 4799 781 25 72  714 311 69 5   27   83 769 8788 25   95  29 15 12  1   6  13 385 4354 22  73 22 587 278 17 54  13 7    2 226 849 36 16 51  333  75  27  4 5631 3   54  28 66 47  56 522   7 637 17 687 8743 76 77  196 54 3   11 317 172  2 99 6    5 14 76 368 8  1  7953 23  56  5  82 782  4 23 3693 48  34   23 16  53  61 22 474  7 8   6  912 296  8 2   19 776 19   6  317 8732 955  17 7   2 21  291 46 95  1 9  4433 617 8    14 793 3825 3864 696 44 12  96 16  78 84 73 26 88   8 96 27  4 57 27 8  556  832 53 8596   4 5   351 5888 18  141 873 87  858 891 4  699 491 82   35  9 92 9    15 3  85 11   3   4 78 21 65 5  418 867 6  84  3551 6866 7    38 32 5832 48 352 91 45   9  9  161  9338 78 783 9  514 27 345  1  39 1  218  84 4543 7  54 318 981 9    2 48 88 56 7973 9    92 5   793 27 26  39 88 62 363  97 6   865 62 14 739 553  7 72 2  6   5  67 859 963 1652 16 718 67 5   31   86 23 569   4  6 71 79 4  33   8  39 26 21 8  37 41    9  14 871  5 4  88 53 34    2 651 89  99 344 2  359    5 5   3425 235 545  13 23 9751 686 3697 68 66 63   253  1166 267 52  88 7152  57 819 245 28 2616 781 2  984 925 71  71 7   246 83 89 41   9 336 97 272   4 685 8  46 753 3  4  56   13 64 976  14 276 11  18 837   6 597 29  17   6 45 5947 3    92 7   7  5575 43 236 44 222   8 34 671 2612 18  9   235 75 269 9158 38   81  2 74 9    5   4767 336  683 1317 98 86   9227 7    2 16 8464 529 25 32 84 23 29 233  38  37 621 383 9763 171 44   489 81 75 17   59 25 12 68 655  7 93  89  71 72 8  7     6 419 7  96 652   4 3   3142 49 28 656 9498  49 582  1 884  885 85  439 6   53 22 2857 3     6 337 93   5154 94 68 659 82 8   33  73 16 13 68 862 35 81 515 48   43 1  5833  8 34 271 7   6    45 22 48  81  4 2  224 819 22 22 4  176 47 38 67 745 592 8547 758   6 75 562 24 77  43 6923 32 34   1464 461 177 898 47 2423 98 182 2491 2593  9 57   96 65 556 284   94 3    7173 8126 7345 62 77 1      2 87  12   21 1  16 1   7689 29 532 72 843   3 33 176 78 11 1813 21  94 779 86 544 398 84 6   36  28 674 37 98 363 644 37 2   96 73  91  86 58 65 6413 53  739  81 2869 135 16 93 6348 395 48 21 285  5  15 187 13 33 6862 47 592 231 9984 691 218 21   81 982   2  3 47 91  3697 819 874 638 65   11 16 375 528 47  93  77 43   48 78   83  215  75 51  88 93  24 44 2     5 395 35 68  6585 564 48 911 1616 91  83 646  328 76 5  656 166 48 21 992  3  892 894 977  18 39 85  2255 5484 2464 743   1 4   1  4   7 272    5 53 5  1    272 57 895   46 79  91 311 59 62 7743 61 457 17 395 462 11 768 99 49 431 61 558  34 2381 5463 1  384  3   34  42 185 22 591 557 36 31 419 86 134 5    2 9  622 897 354 1318 383   5 86  145 876 54 181 63 837 46 78 195 4    4  12 64  25 11 49 357 973 822 68   241 674 416 247 5458  49    3 541 54 61  553 53  36 515 478 9711 12  8 5154 93  1315 278   5 92   726 596 37 67   49 9  77 1   35  896 21 32  74 82 699 3  4  741   9   3 11  5461 688 889 9537  398 729 298  5\n67 21  33 613 4255 65  5 73 69   27 2623 72 6   25 56 5812 29 76 58 73  4 65 135 139 3   797 717 212 32  44 44  712 7161 73 879 726  7 7535  1 775 92 482 572 226 82 1466 89 2971 34 2541 66 77 97  94   7  153 253 65 62  67  42 2325 35  2644 356 44 4  88 355 3629 64 977 985  43 6  13  85 163  44 7  925 915  93 5423 737 957  17 432  25 58  97 246 514 194 752 2  55 286 26 71 14 9   398 1826 8113 85 9  892 9293 22 922 2649 42 74 5759  326 41 62 186 28 259  5   35 52 8761 11 437 7389  711 51 69 75  656 649  87 94 3   6 184 91 5313 47 9564 21 14 878 9229 332 366 35 365  7 222 47 311 719  453 567 816  8 74 74 14 295 849 563 66  793 693 9877 61 56 8  7661 71  915 712  49  449 6693  25 6  438 22 114 1625 7  28  234  87 19 163 674 59 791 4994 41  39 421 88  748  92 65 4148 22  9685  5 4    36    67 1827 9552 817 54  1195 53  919 542 587 13  886 85 939 7897 24 1582 75 291 52 851 9  89  1 14  46 253 11 328 275 6   341  698 46 64  865 289 73 4   55  423 898  199 891  51  43 98 24 64  74 283 334 3712 63  75 14 931 354 51 44  38 65  64 693 762 45 93 19   57 419  65 69 6893 945 91  26 38 82 857 681 392 916 73 781 7633 64 42  623 96 85  94 179 522 97 82 55  82 84 69 245 9  5  8667 39  62  3 233 26   7 77 6289 426 77 5689 353 23  2  97 275  7 7   71 26  594 12 46  42 472 5428 81 655 2313 672 414 5  22 618 476 48 71 65 37 3114 411 2   123 361 1355 134  914 84 476 67 43  71 82 14 26 34 223 15 19  7 81 53 8  971 7789 74 2883 615 9   732 6985 1   889 783 12  925 511 69 652 392 89  819 77 65 47   62 12 19 96  97  76 66 96 66 78 599 822 96 892 8491 1368 93   89 52 411  93 247 27 26   81 2  843  2171 26 412 14 181 38 891 59  72 6  494 738 412  58 53 621 923 8   23 41 68  4 3756 414 212 3   665 21 588 26 46 95 163 926 24  76  68 61 736 514  5 77 17 56  3  67 798 56  7932 87 374 48 8   391  99 72 433  15 19 61 82 4  8   44 522 24 66 8  53 77 6431 513 978 76 9  99 98 94  574 268 39  56 194 14 323    5 264 1682 729 979  62 68 3187 394 1883 44 12 58   414  8373 969  8 882 7187  63 166 155 57 1528  66 73 642 423 52 113 48  752 87 11 31  89 245 55 991  17 259 3  2  553 6  3  97  775 59 243  56 445 222 36 455 674 459 15  668  3 12  645 14  895 62  13 1116 26 523 48 225  24 58 652 997  274 78  889 25  46 755  576  3  39 96 548  68  1252 2628 273 7414 53 126  1238 56   3 25 1457  42 65 88 83 36 53 73   28  12 997 265 8571 876 755  579 66 27 64   58 64 57 23 724 31 66  44 815 98 12 1     8 294 78 79 479  38 12  2957 77 32 557 4384  31 993 84 1142 674 52 9268 68  36 41 4856 62   98 933 797  3875 99 11 488 21 626 348 11 67 18 18 163 25 27 21  61  774 9  4451 32 15 774 58  76   86 59 37  89  5 4  895 563 44 26 9  597 54 27 6  812 355 9464 214  25 35 989  4 63  99 8958 92 9963 392  788 397 458 29 4824 71 366 5873  566 34 8519 81 36 867 662  366 913  9482  191 8272 39 89 22    25 19 225 3428 54 46 315 8788 35 346 84 441  24 56 619 58  8 1496 59 321 592 44 662 994 88 44  69 585 733 16 28 687 538 14 24  58 26 444 963 42 35 7683 442 553  21 7561 773 49 24 9565 698 59 46 993  1 248 143 73 98 1633 72 528 297 7191  48 251 4417 37 855  43  9 89 74   138 613 827 637 18  631 51 241 817 421 53 161 18  471 516  589 482  93 92  77 75  29 98 2     3 185 77 98  7965 842 68 881 4455 258 59 899  382 67 6  194 737 87 27 564 57 3359 422 159  43 78 528 6464 5329 7429 249  91 43  2  2   9 764  311 15 88 3426 165 27 559  844 31  32 466 93 56 6757 65 86  48 351 711 31 729 72 93 694 89 157  77 6466 1552 21 524  81  73 452 984 43  67 794 11 95 456 97 785 95  81 2  555 576 581  783 711  39 299 548 417 51 657 55 699 58 26 713 97   1 611 38  93 24 48 578 564 464 66   739 888 863 195 8871 797  888 313 64 783 514 41  35 162 978 2786 86  4 9423 896 2546  93   2 494  157 523 52 1811 72 89 99 33  32  933 85 79 818 83 655 32 1  791   1  49 999 2691 423 237 1966  235 227 789  3\n47 46   5  57 416  83  9 62 9769 29 8739  4 784 43 6  4593 48 83 33 41 84 71  83 616 254 181 874 865 691 63 367 447 5358 77 579 179 76 6671 61 796 66 829  46 868 19 5774 52 2421 11 56   19 99 576 264  5  445 113 45 55  62  73 1319 94  6221 417 66 93  9 34  4711 58 614 195 637 71 13   2 855  78 95 713 349   6 1442 371 185 114 772  62 53  26 31  426 681 949 56 1  22  32 56 5  8   889 765  2159 19 56  13  613  3 611 1998 69 13 9777 4979 33 61 968 35 971 55 8673 44 614  11  56 1975 4237 56 69 486 173 377 886 32 89 64 311  2 152  49 9898 12 18 543 6731 589 689 33 494 25 996 99  24 675 8542 116 788 82 27 75  2  57 295 2   644 731 886 119  29 75 5    17 75 7911 367  96  631 1269 971 42 127 74 95  7963 23 348 814  27 9  161 922 88 687 3179 512 95  96 73  128  81 43 9739 837 6987  7 852  391 8878  156 5896  72 773 8125 42 3568 429 461 95  43  96 598 8551 14  993 88 276 49 827 25  9 16 67  35 83  13 184 169 2   7    189 27 11 6797 893 55 654 32  828 451  532 6241 78  46 46 4  54 562 526 317  145 941 39 27 254  87 64 396  6 73 839 125 23  53 67 431  32 669 166 64 17   787 279 39 11 16 168 434 866 268 53 54  8569 42 269 953  5 65  85  98 168 95  4 68 913 83 91 437 42 61 1172 86  36 39 854 92  63 75 593  782 29 9112 174 928 8  16 197 44 64  27 24   88 74 876 85 966 8883 83  63  727 292 163 62 43 114 157 99 25 66 18 1932 178 3  6549 78  5561 896  336 62 729 49 63 832 38 92 98 99 265  6 39 96 65 65 69 597 2825  8 8148 875 377  72 7534 8   355 541 46 3981 958 87 838 129 93  357 89 68 476  29 65 39 29 546 122 75 37 24 21 792 769 73 537 9834  687 977  48 12 987  47 41  75 9629 65 84 513  8417 37 458 86  28 58 744 83 358 63 35  159 161  98 65  65  63 595 91 45 69  9  733 482 257 57  684 39 767 76 58 47 618 386 325 21  14 7  483 291 88 62 61 132 3  6  72  73  2722 62 728 79 863 1915 15 73 76   54 18 78 77 15 3  976 711 82  8 86 13 67 1594 841 655 26 63 14 48 94  567 14  794  2 8   57 21   615 521 4781  18 168 394 62 913  937 5235 93 97 313  6842 5146 616  9 178 217   46 448 76  83 166   33 92 733 491 77 248 51  556 67 2  567 62  51 43 313 646 743 74 5  56  19 62  1 1845 29 65  477 56  951 49  74 961 428 662 226 73 17  754 579 624 15  68  839  1 791 11 487 836 2  211 364  131 298 414 83  42 952  679  1  42 43 3492 22  368  2468  49 63   7  883  2444 849 69 85 4469  38 58 12  9 1  81 52  881  68 287 771 8292 783 112  426 84 24 5  9371 44  1 75  73 82 86 572 613  7 25 212  52 723 35 21  18 746 224 7726 38  1 852 755  275 628 44 3238 735 46 3118 841 16 57  411 391 847 134 5118 89   72 7  559 13 361 843 17 81 92 1  832 66 53 1   64 3757 28 9283 63 13 792 987 272 912 51 22  99 65 59  48 476 44 43 69 575 61 21 6  73   46 65   261 592 13 188  5 43  55 2253 87 1761 753   28 646 866 78 123  39 953 4283   26 42 5838  2 85 32  61  7424 9494 86    947 265  59 56 333 6773 65 452 6267 89 38 485  237 6  558 94 488 463 77 533 12  6 946  16 192 947 46 7   227 5  82  33 114 492 38 63 126  36 92 455 26 82 589 319 75 66  762 779 1151 16 23   271 23 94 13   59  62 78 5   83 621  24 64 56  339 35 998  26 7917  77 674 9523 66 179  87 15 87 322   86 845 135 252 51 6189 61 475 57  973 71 758 8   722 4147 246 948 133 331 55 16 837 33 73  412 411 27 71  667   27 38 929 7596 487 54 843 3485 67 66 37   59 93 55 647 57 4185 454 396 689 99 385  331 642  7679 748 123 21  66 8  91 936 8715 13 19 3549  22 97 857 6496 263 83 839 57 51 5236 78 68  87 443 778 28 553 36 54 814 34 561 272 477  9589 17 9354 73  86 765 811 21  66  22 61 97 643 23 657 51 663 2  537 756 63   518 447 992 244 335 8   23  25 93 521 79  4 785 42   4 691 85 929 43 84 632  55  84 2279 78  362 863 775 5443 475 2799 248 19 356 326 6   49 64  879 7437 37  3 378  863 3866  42 994 1851 48  46  4  3491 27 94 46 945 246 23  1  33 533 39 734 73 93 625 143 317 991 639  897 669 8621 9922 162 733  8\n35 73   1   3 2    52 76 15 5435 5  1352  4 355 31 6  55   99 41 75 79 93 96  66 72  694 378 431 498 254 77 298  94 3299 47 838 158 21  367 94 137 17 865  87   4 75  666 84 2424 13 3    44 51 353 6115 72 56  186 64 366 817 85 4987 998 318  359 7  65  7 34  5166 92   6 252 326 31 34   9 9     6 88 456 659   9 17   539 418 386 598  47 34   8 43   29 96  254 69 7  96  5  95 8  4  1348 5      14 41 55  53   25  6 245 8867 57 22 9696 5687  2 32 198  7  43 92 6494 76 113  77  56  551 8359 55 3  317 912 159 355 42 96 48 772  7 94   98 5598 97 74 691 253   56 856 85 389 47 483 94   4 345 5273 796 378 12 6  94  8   6 934 9   276 516 564 392  3  15 8    27 52 2794 25  273  577 7714 186 94  56 37 33  688  72 668 137 958 6  951 97  14 227 6641 281  6  59 468 74    2 75 48   171 56    2 9822 817 7273   99 6162  31 214 8833 49 2847  49 768 8   37  41 721 7638 59  813 51  77 35 917 12  9 95 3   13 92  3  675  79 2   7      1 64 79 9482 328 68 351 358 165  33   91 9858 64 828 53 5  89 176 311 399  731 163 75 94  83   2 27 372  5 43 544 87  37  1  71 731   9 277 856 11 4    414 213 15 31 54 843 161 674  23 11 7   45   15 235 9    9 89 777   9 558 93  6 27 327 16 34 98  97 86   53 394 32 11 695 6   95 28 715  416 71 9227 528 714 7  34 867 47 985 32 46   26 65 798 63 539 2641 59  61   17  61 418 52 24 738  43 89  9 61 77  387  62 22 1698 4   2978 28     1 54 181  2 56 578 69 36 33 62 514  1 95 55 19 85 65 74  3275  2 5167 174 468  35 6378 4  7537 19  93 6563 118 74  61 939 647 592 66 18 6328 66 44 75 68 813 373 82 57 66 42 787 511 19 531 999     2 6536  2 53 38    1 8   76 9659 78 87 6878 7219 87 666 46   6 75 439 32 227 88 45  631 54   17 32  81   2 275 12 7  6   7   44 998 922 495 97  25 614 36 95 87  83 296 493 9   41 9  767 252 24 42 64 255 61 5  45  6     57 46  89 57 986 4663 4  53 3   847 51 65 78 13 4  423 374 89  6 81  5 18 9191 259 485 28 36 8  88 584 757 9   653  3 7   15 24  1549 818 973    5 328 587 16 675  644 2328 81 76 9981 2684 39   461  6 668 3    177 282 29  68 38     7 65 936  69 73 156 375  76  8 7  783 83   4  8 7   341 91  41 5  82  38 97  4 9876 15 3   514 76  353 84  29 913 83  192 939 28 45   54 861 373 223 92  884  3 331  7 3   476 7  816 573  999 746 872 88  57 23   6628 1  41 23 9274 711 35   3767  46 8    4  5868   64 574 68 67 9668  92 94 95  9 9  88 2   556 423 121 729 829  286 4617 253 62 2  7  3694 74  1 93   1 74 96 629 895  6 78 2963 66 521 48 92  68 769 889  594 9   8   3 745  291   5 71 9252 38   7 1346 998 76 83   12 127 346 99  5217 3    6  8   79 44 395 734 29  1 67 2  11  55 71 3   2  9849 38 8325 44 66 55  446 816 945 6  716 68 43 91   5 894  9 16 25  26 57 64 5  42    6 7    465 212 4  18   7 43 648 1454 19 2922 3     66 83  253 1  68   83 2   318    52 71 2248  3 14 53  95  1827 3515 71     94 8    6  74 287 8924 84 668 8777 17 14 131   68 4  328 63   2 823 25 971  2  5 137  37 777   2 68 6   25  4  763 52 483 583 34  2   9  36 67 555 81 81 955 239 59 3    26 261 1641  7 38   914 48  4 17   12  28 4  4   13 593   9 16 49   28 3  939  47  281   7 649 2367 58  72 395 31 4  114    9 361 43   37 28 6914  5 881 2   993 54 637 1  3392 8142 828 9   885 982  1 75 694 31 355 859 936 71 656 76    55 98 368 629  895 48 33  4434 66 25 8    54 35 11 93  34 4995 378 373 554  6 639  465 439  6313 712 491 682 23 52 66 19  6258 18 65 6678  93  5 725 3643 458 95 24  88 89  235 15 6   3  91  211 38 75  36 91  85 56  74 331 292    25 65 4558 349 49 431 494 64  21  15 97  9 51  43  24 62 948 48 32  985 24     4  66 973 456   8 1   99  56 1  82  49  4 57  66 279 795  7 273  2 39 42   64   9 7448 5   492 794 6    855 127 8163  38  9 198 268 2  395 8    29 347  68 46 462  977 6832   9 312 5169 56  72  5  5121 32 46 71 968 892 7   3   8 125 72 462 22 73 581 264 263 829 245  6   851 16   6411 175  62 31\n*  +  +   +   +    +  +  *  +    *  +    +  +   *  +  +    +  +  +  *  +  *  +   +   *   *   +   *   +   +  +   *   +    +  +   *   *  +    +  +   *  *   +   *   *  +    *  +    +  +    *  *  *   +    *  +   *   *  +   +   +  +    *   +    +   +  *  *  *   +    *  *   +   +   *  +  *   +   +   *  +   +    *  +    +   *   *   +    +  *  *   *   +   +   *   *  +  *   +  *  *  *  +    +    +    +  *  +   +    +  *   +    +  +  +    +    *  +  *   +  +   *  +    *  +    *  *   +    +    +  *  *   *   *   *   *  +  *  +   *  +    *  +    *  *  *   +    *   +   +  +   *  +   +  +   *   +    *   *   +  *  *  *  +   *   *   +   +   +   +    *  *  +  +    *  +    *   *   +    +    +   *  +   +  *   +    *  *   +   *   *  *   +   +  +   +    +   *  +   *   +    *  *  +    *   +    *  +    *   +    +    +    *   *   +    *  +    *   *   *   *   *  +   +    +  +    +  *   +  *   +  *  *  *  *   *   *  +   *   +   +    *   +  +  +    +   *  *   +   *   *   +    +    *  *   *  *  +  *   *   *   +    *   *  +  *   +   +  +   *  *  +   +   +   +  *  *   *   *   *   *  +    *   *   *  +  +  +   +   *   +   +  +   +    *  +   *   *  +  *   +   *   *  +  +  *   *  +  +   *  *  +    *   +  +  *   *   *  *  +    +   *  +    *   +   +  +  *   +  +   *  +   +   +  *   +  +   +    *  +   +    *   *   *  *  *   *   +  +  +  +  +    *   *  +    *   +    +    *   *  *   *  +  *   *  +  +  *  +   *  *  +  +  +  +  +   +    +  +    *   *   *   +    *  +    +   *  +    +   +  *   *   *   +   *  *  +    *  +  *  *  +   *   +  +  +  *  *   *   +  +   +    +    +    *  *  +    +  +   +  +    +  *  +    +    +  +   *  +   *  +   +  +   *  *   +   +    +  *  *   +   *   *  +  *  *  +    *   *   +   *   +  *   *  +  *  *   +   *   *   *  +  *   *   +  +  +  *   +  +  +   +   +    *  *   +  *   +    *  *  *   *   *  +  *  *  +  +   +   *  *  *  +  +  +    *   *   *  *  +  *  *   *   *   *   *  +   *  *   +    *   +    *   *   +   *  +    *   +    +  *  +    +    +    *   +  *   +    *   *   *   +  +    *   +  +   +   *  *   *   +   +  *  +   +  *   *  *   *   *   +  *  +   +  +  +  +    +  *   *   *   +   +  *   *   +   *   +   +  *  +    *   *   *   *  +    *  *   *  *   +   *  *   +    *   *   +   +  *   +    +    +  *  *  +    *   +    +    +   +    +  +    +    +   +  +  +    *   +  +  +  +  *  *   +   +   *   *   +    +   +    +   +  +  *  +    *  *  +  *   *  *  *   +   +  +  +    *  +   +  *  *   *   *   +    +  *  +   +    *   +   +  +    *   *  +    *   +  *  +    *   *   *   +    +    *  *  *   *  +   *   *  *  *  +  +   +  *  *   +  +    *  +    *  *  +   *   *   +   *  +   *  *  *  *   +   +  *  +  +   +  *  +  *   +   +    *   +   +  *   *  *  *   +    +  +    +    +   *   *   *  +    *  +   +    +    +  +    *  *  *   +   +    +    +    +    +    +  *  *   +    +  *   +    +  +  *   +    *  +   *  *   *   *  +   *  *  +    +  *   +   *  *   +   *  *   *  *   *   *  +  +   *   +  +   +  +  +   *   *  *  +    *   +    *  +    +   *  *  +    +   *  *  +   *  +   +   *  *  +    *  *   +   +    *   *   +    +  +   *   *  +  *   +    +   +   *   *  +    *  +   +   *   +  *   +  +    +    *   *   *   *   *  +  *   *  *   *   *   +  *   +    *   +  +   +    *   *  *   +    *  +  +   +   +  *  *   +  +    *   *   +   *  +   +    +    +    *   *   +   *  +  +  +   +    *  *  +    *   *  *   +    +   *  *   +  *  +    +  +   +  *   +   *  +   *  *  +   *  +   *   +    +    *  +    +   *  +   *   *  *   *   +  +  +   *  *   *  +   *  *   +   *   +    +   +   *   *   +   *  *   +  *   +  +  *   +  *   *   +  +   *  *  *   *   +   +    *   +   *   +   +    +   +    *   *  +   +   +  *   *   *   +    +  *  +    *   +    +   *   +    *   +   *  +    +  *  *  +   *   *   *  *  *   *  +   +  *  +   *   +   *   +    *   *   +    +    +   *   + \n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_06_questions.txt",
    "content": "--- Day 6: Trash Compactor ---\n\nAfter helping the Elves in the kitchen, you were taking a break and helping them re-enact a movie scene when you over-enthusiastically jumped into the garbage chute!\n\nA brief fall later, you find yourself in a garbage smasher. Unfortunately, the door's been magnetically sealed.\n\nAs you try to find a way out, you are approached by a family of cephalopods! They're pretty sure they can get the door open, but it will take some time. While you wait, they're curious if you can help the youngest cephalopod with her math homework.\n\nCephalopod math doesn't look that different from normal math. The math worksheet (your puzzle input) consists of a list of problems; each problem has a group of numbers that need to either be either added (+) or multiplied (*) together.\n\nHowever, the problems are arranged a little strangely; they seem to be presented next to each other in a very long horizontal list. For example:\n\n123 328  51 64 \n 45 64  387 23 \n  6 98  215 314\n*   +   *   +  \n\nEach problem's numbers are arranged vertically; at the bottom of the problem is the symbol for the operation that needs to be performed. Problems are separated by a full column of only spaces. The left/right alignment of numbers within each problem can be ignored.\n\nSo, this worksheet contains four problems:\n\n    123 * 45 * 6 = 33210\n    328 + 64 + 98 = 490\n    51 * 387 * 215 = 4243455\n    64 + 23 + 314 = 401\n\nTo check their work, cephalopod students are given the grand total of adding together all of the answers to the individual problems. In this worksheet, the grand total is 33210 + 490 + 4243455 + 401 = 4277556.\n\nOf course, the actual worksheet is much wider. You'll need to make sure to unroll it completely so that you can read the problems clearly.\n\nSolve the problems on the math worksheet. What is the grand total found by adding together all of the answers to the individual problems?\n\n--- Part Two ---\n\nThe big cephalopods come back to check on how things are going. When they see that your grand total doesn't match the one expected by the worksheet, they realize they forgot to explain how to read cephalopod math.\n\nCephalopod math is written right-to-left in columns. Each number is given in its own column, with the most significant digit at the top and the least significant digit at the bottom. (Problems are still separated with a column consisting only of spaces, and the symbol at the bottom of the problem is still the operator to use.)\n\nHere's the example worksheet again:\n\n123 328  51 64 \n 45 64  387 23 \n  6 98  215 314\n*   +   *   +  \n\nReading the problems right-to-left one column at a time, the problems are now quite different:\n\n    The rightmost problem is 4 + 431 + 623 = 1058\n    The second problem from the right is 175 * 581 * 32 = 3253600\n    The third problem from the right is 8 + 248 + 369 = 625\n    Finally, the leftmost problem is 356 * 24 * 1 = 8544\n\nNow, the grand total is 1058 + 3253600 + 625 + 8544 = 3263827.\n\nSolve the problems on the math worksheet again. What is the grand total found by adding together all of the answers to the individual problems?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_07.adb",
    "content": "--  Solution to Advent of Code 2025, Day 7\n------------------------------------------\n--  Laboratories\n--\n--  https://adventofcode.com/2025/day/7\n--  Copy of questions in: aoc_2025_07_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nprocedure AoC_2025_07 is\n\n  use AoC_Toolbox, HAT;\n\n  --  input_name : constant VString := +\"mini\"; m : constant := 16; n : constant := 15;\n  input_name : constant VString := +\"aoc_2025_07\"; m : constant := 142; n : constant := 141;\n\n  map : array (1 .. m, 1 .. n) of Character;\n  j0 : Positive;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    f : File_Type;\n    c : Character;\n  begin\n    Open (f, input_name & \".txt\");\n    for i in 1 .. m loop\n      for j in 1 .. n loop\n        Get (f, c);\n        map (i, j) := c;\n        if c = 'S' then\n          j0 := j;\n        end if;\n      end loop;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    total : Integer := 0;\n  begin\n    map (2, j0) := '|';\n    for i in 3 .. m loop\n      for j in 1 .. n loop\n        if map (i - 1, j) = '|' then\n          if map (i, j) = '^' then\n            map (i, j - 1) := '|';\n            map (i, j + 1) := '|';\n            total := total + 1;\n          else\n            map (i, j) := '|';\n          end if;\n        end if;\n      end loop;\n    end loop;\n    r (part_1) := +\"\" & total;\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    beam : array (1 .. m, 1 .. n) of Natural;\n    total : Integer := 0;\n  begin\n    for i in 1 .. m loop\n      for j in 1 .. n loop\n        beam (i, j) := 0;\n      end loop;\n    end loop;\n    beam (2, j0) := 1;\n    for i in 3 .. m loop\n      for j in 1 .. n loop\n        if beam (i - 1, j) > 0 then\n          if map (i, j) = '^' then\n            beam (i, j - 1) := beam (i, j - 1) + beam (i - 1, j);\n            beam (i, j + 1) := beam (i, j + 1) + beam (i - 1, j);\n          else\n            beam (i, j) := beam (i, j) + beam (i - 1, j);\n          end if;\n        end if;\n      end loop;\n    end loop;\n    for j in 1 .. n loop\n      total := total + beam (n, j);\n    end loop;\n    r (part_2) := +\"\" & total;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 1562.\n    --  Part 2: validated by AoC: 24292631346665.\n  end if;\nend AoC_2025_07;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_07.txt",
    "content": "......................................................................S......................................................................\n.............................................................................................................................................\n......................................................................^......................................................................\n.............................................................................................................................................\n.....................................................................^.^.....................................................................\n.............................................................................................................................................\n....................................................................^.^.^....................................................................\n.............................................................................................................................................\n...................................................................^.....^...................................................................\n.............................................................................................................................................\n..................................................................^.^.^.^.^..................................................................\n.............................................................................................................................................\n.................................................................^.^...^...^.................................................................\n.............................................................................................................................................\n................................................................^.^.^.^.^.^.^................................................................\n.............................................................................................................................................\n...............................................................^.^.^.....^.^.^...............................................................\n.............................................................................................................................................\n..............................................................^.^.^.^...^.^.^.^..............................................................\n.............................................................................................................................................\n.............................................................^.^.^.^.......^.^.^.............................................................\n.............................................................................................................................................\n............................................................^.^.^...^.^...^.^.^.^............................................................\n.............................................................................................................................................\n...........................................................^.^.^...^.^...^.^.^.^.^...........................................................\n.............................................................................................................................................\n..........................................................^...^.....^.^.^.^.^.^...^..........................................................\n.............................................................................................................................................\n.........................................................^.^.......^.^...^.^.^...^.^.........................................................\n.............................................................................................................................................\n........................................................^.^.^.^.^...^.....^.^.....^.^........................................................\n.............................................................................................................................................\n.......................................................^.^.^.^.^.^...^.^.....^.^...^.^.......................................................\n.............................................................................................................................................\n......................................................^.^.^...^...^...^...^.^.^.^.^.^.^......................................................\n.............................................................................................................................................\n.....................................................^.^...^...^...^.^.^.^.^.^...^.^...^.....................................................\n.............................................................................................................................................\n....................................................^.^.^.....^.^.........^...^.^.^.....^....................................................\n.............................................................................................................................................\n...................................................^...^.^.^.....^.^.^...^...^.....^.^.^.^...................................................\n.............................................................................................................................................\n..................................................^.^.^.^.^.^.^...^.^.^...^...^.......^...^..................................................\n.............................................................................................................................................\n.................................................^...^.....^.^.^.^.....^.^...^.....^.^.^...^.................................................\n.............................................................................................................................................\n................................................^...^.....^.^.^.^.^.^.^.^.^.^.............^.^................................................\n.............................................................................................................................................\n...............................................^.^.^.....^.^.....^.^.^.^.^.....^.....^...^.^.^...............................................\n.............................................................................................................................................\n..............................................^...^.^.^.^.^.^.^.^.^.^.^.^.^.....^...^.^.^.^...^..............................................\n.............................................................................................................................................\n.............................................^.^.^...^.^.^...^...^.^.^.....^...^.....^.^.^...^.^.............................................\n.............................................................................................................................................\n............................................^.^.......^.^.^.^.....^.......^.^.^...^.^.........^.^............................................\n.............................................................................................................................................\n...........................................^...^...^...^...^.^.........^.^...^.^.....^.....^.^.^.^...........................................\n.............................................................................................................................................\n..........................................^...^.^...^.^.^.^.^...^.^.^.^.^.^.....^...^...^.^.^.^.^.^..........................................\n.............................................................................................................................................\n.........................................^.^...^.^...^.^.....^.^.......^.^.....^.^.^.^.^.^...^.^.^.^.........................................\n.............................................................................................................................................\n........................................^.^...^.^...^.^.......^.......^.^.^.^.^.^.^.......^.^.^...^.^........................................\n.............................................................................................................................................\n.......................................^.^.^...^.^...^.^...^.^...^.....^.^.^...^.......^...^.^.^.^.^.^.......................................\n.............................................................................................................................................\n......................................^.....^.^.....^.....^...^...^.^.^...^.^.^.^.....^.^.^...^.^.^...^......................................\n.............................................................................................................................................\n.....................................^.^.....^.^.^...^.....^.^.^.^...^.^.......^.^...^.^.^...^.^.^.^.^.^.....................................\n.............................................................................................................................................\n....................................^.^.^.^...^.......^.^...^...^.....^...^...^.^...^.^.^.......^.^.^...^....................................\n.............................................................................................................................................\n...................................^.^.....^.....^.^.^.^.^.^...^.^.^.^.^.^.....^.^...^.^...^.^.^...^.....^...................................\n.............................................................................................................................................\n..................................^...^...^.^.^...^.^.^.....^.^.^.....^.^.^.^.^.^.^.^.......^.^...^.^.^.^.^..................................\n.............................................................................................................................................\n.................................^.^...^.^.^.^.^...^.^...^.^.^.^.......^.^.^.^.^...^...^.^.^.^.^.^.^.......^.................................\n.............................................................................................................................................\n................................^...^.^.^...^.^.^.^.^...^.^.^...^...^.^...^.^.......^.^.^.^.^.....^.^.^.^.^.^................................\n.............................................................................................................................................\n...............................^.^.^.^.^...^.^.^.....^.^...^...^.^...^.^.^.^.^...^.^.^.^.^...^.^.^.^.^.^.^.^.^...............................\n.............................................................................................................................................\n..............................^.^.^.....^...^.^.^.^...^...^.^.^.^.^.^.^...^.^.^.......^...^.^.^.^.^.^...^.^.^.^..............................\n.............................................................................................................................................\n.............................^.....^.^...^.^.^.^...^.^.^.^...^...^...^.^.^.^.....^.^.......^...^.^...^.^.^.^...^.............................\n.............................................................................................................................................\n............................^.^.^...^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^...^.^.^.^.^.^.......^.^.^...^.^...^.....^............................\n.............................................................................................................................................\n...........................^.^...^...^...^.^.^.^...^.....^...^.^.^.^.^.^.^...^.......^.^.^.^.^...^...^.......^.^.^...........................\n.............................................................................................................................................\n..........................^.....^...^.^.^.....^.^.^...^...^...^.....^...^...^.^.^.^.^.^.^.^.^.....^...^.^.^.......^..........................\n.............................................................................................................................................\n.........................^.^.^...^.^.....^.^...^.^.^...^.....^.^.^.^.....^...^...^.^.^...^.^...^.....^.^.^.^.....^.^.........................\n.............................................................................................................................................\n........................^...^.^.^.^.^.......^.^.^.......^.^.^...^.^.....^.^.^.^.^...^.^.^.......^.^.^.........^.^.^.^........................\n.............................................................................................................................................\n.......................^.^.^.^.^.....^.^...^.^.^...^.^.^.^...^.^...^...^...^.....^.^.^.^...^.^.^.^...^.......^.^.^.^.^.......................\n.............................................................................................................................................\n......................^.^.^.^.^.^.....^.^.......^.^.^...^.^.^.^.^.^...^.^.^.^...^.^...^...^.......^.^.^.^...^.^.^.^...^......................\n.............................................................................................................................................\n.....................^.^.^.^...^.^.^.^.^.^.^...^...^.^.^.....^.^.^...^.^.^.....^.^.^.....^...^.^.^.^.^.^.^.^.^.^...^...^.....................\n.............................................................................................................................................\n....................^.^...^.^.^.^...^...^.........^.^...^...^...^...^.^...^.^.^...^...^...^...^.^.^.^.^.^.^...^.^.^.....^....................\n.............................................................................................................................................\n...................^.^.^...^...^...^.^.^...^.^.^...^.....^.^.^.^.....^.^...^...^.^...^...^.^.^.^.^.^...^.^.^.^...^.....^.^...................\n.............................................................................................................................................\n..................^.^.......^.^.^...^.^.^...^.^.....^.^.^.^.^.^.^.^.....^...^.^.^.........^.............^.......^...^.^.^.^..................\n.............................................................................................................................................\n.................^.^.........^...^.^.......^.^.^.^.^.^.^.^.^...^.....^.^.^.^.........^.^.^.^.^.....^...^...^.^.^.^.^...^...^.................\n.............................................................................................................................................\n................^.^.^...^.^.^.....^.^.^...^.^.^.^...^...^.^...^.^.^.^.^.^...^.^...^.^.^.....^...^.^...^...^.^...^.^.^.....^.^................\n.............................................................................................................................................\n...............^.^.^.^.^.^.^.^.....^...^.^.^.^.^...^.........^.^.^.^...^.^.^.....^...^...^.^.^.^.^.^.^.^.^.^...^...^.^.^.^.^.^...............\n.............................................................................................................................................\n..............^.^.^...^.^.^.^...^.^...^.^.^.^.^.^.^.^.^.^...^.^...^.....^.^...^.............^.^...^.^.^.^.^...^.^.^.^.....^.^.^..............\n.............................................................................................................................................\n.............^.^.^.^.....^...^...^.....^.^...^...^.......^...^...^.^...^...^.^.^.^.^.^.^.^.^.....^.^.^.^.^.^.^...^...^.^.^.....^.............\n.............................................................................................................................................\n............^...^.^.^.^.^...^...^.^.^.....^.^.^.^...^.^...^...^...^...^.^.......^.^.^.....^...^...^.^.^.^.^.^.......^.^.^...^.^.^............\n.............................................................................................................................................\n...........^.^.^.^.^.^.^.^...^.^...^.^.^.^.^.......^.^.^...^.^.^.^.^.^.^.^...^.^...^.........^.^.^.^.....^...^.^...^.^.^.^.....^.^...........\n.............................................................................................................................................\n..........^.....^.^.^.....^.....^.....^.^.^.^.^.^.^.^.^.....^.^.^.^.^...^.^.^...^.......^.^...^...^...^.....^...^.^.^.^.^.^.^.^.^.^..........\n.............................................................................................................................................\n.........^...^...^.^.^.....^.^.^.^.^.^...^...^...^...^.......^.^.^.^.^.^.^...^.^.^.^.^.^.........^...^.^.^...^.^.....^.^.^.^.^.....^.........\n.............................................................................................................................................\n........^.^.....^.^.^.^...^.^.^.^...^.^.^.^.^.^...^.^.^...^.^.^.^...^...^...^.........^.^.^.^.^.....^.^.^...^.^.^.^.^...^...^.^.^...^........\n.............................................................................................................................................\n.......^.^.^.^.^.^.^.......^.^.........^.^.^.^.^.^.^.^.^.^.^...^...^.^...^...^...^...^...^.^.....^...^...^...^.^.^.....^...^...^.....^.......\n.............................................................................................................................................\n......^.^.^...^.^.^.^.^.^.^.......^.^.^.^.^.^.^.^.....^.....^.....^.^.^.^.^.^.^.^...^.^.^.^.^.^...^.^.^.......^.^.....^.^.^.^.....^.^.^......\n.............................................................................................................................................\n.....^...^.^.^.^.....^...^...^.....^.^.^.^.^.^.^.....^.^.^...^...^.^.^.^.^.^...^...^.^.^.^.....^.^.^.^...^.....^.^...^...^.^...^.^.^.^.^.....\n.............................................................................................................................................\n....^.^.^...^.^.^.^.^.^...^...^.^.^.^.^...^.^.^.^...^...^.^...^.^.^...^.^.^.^.^.^.....^.^.^.^.^.^.....^...^.^.^.^.^...^.......^...^.....^....\n.............................................................................................................................................\n...^.^.^.....^.^.^.^.^.....^...^.....^...^.^.^.^.^...^...^.^.^.^.^.^.^...^.^.^...^.^.^.....^.....^...^.^.^.^.^...^.^...^...^.^...^.^.^.^.^...\n.............................................................................................................................................\n..^.^.......^.^.^.^...^...^.^.....^.^.^.^.^.^...^.^.....^...^.^.....^.^...^.^.^...^...^.^.^.^.....^.^.^...^...^...^.^.^.^...^.^.^...^.^...^..\n.............................................................................................................................................\n.^.^...^.^.^...^...^...^.^.....^.^.....^.^.^.^...^.....^.^.^.^...^.^.^.^.^.^...^.^.^.....^.^.^.^.^.^.^...^.^.^.^.....^.^.^.^.^.^.^.^.....^.^.\n.............................................................................................................................................\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_07_questions.txt",
    "content": "--- Day 7: Laboratories ---\n\nYou thank the cephalopods for the help and exit the trash compactor, finding yourself in the familiar halls of a North Pole research wing.\n\nBased on the large sign that says \"teleporter hub\", they seem to be researching teleportation; you can't help but try it for yourself and step onto the large yellow teleporter pad.\n\nSuddenly, you find yourself in an unfamiliar room! The room has no doors; the only way out is the teleporter. Unfortunately, the teleporter seems to be leaking magic smoke.\n\nSince this is a teleporter lab, there are lots of spare parts, manuals, and diagnostic equipment lying around. After connecting one of the diagnostic tools, it helpfully displays error code 0H-N0, which apparently means that there's an issue with one of the tachyon manifolds.\n\nYou quickly locate a diagram of the tachyon manifold (your puzzle input). A tachyon beam enters the manifold at the location marked S; tachyon beams always move downward. Tachyon beams pass freely through empty space (.). However, if a tachyon beam encounters a splitter (^), the beam is stopped; instead, a new tachyon beam continues from the immediate left and from the immediate right of the splitter.\n\nFor example:\n\n.......S.......\n...............\n.......^.......\n...............\n......^.^......\n...............\n.....^.^.^.....\n...............\n....^.^...^....\n...............\n...^.^...^.^...\n...............\n..^...^.....^..\n...............\n.^.^.^.^.^...^.\n...............\n\nIn this example, the incoming tachyon beam (|) extends downward from S until it reaches the first splitter:\n\n.......S.......\n.......|.......\n.......^.......\n...............\n......^.^......\n...............\n.....^.^.^.....\n...............\n....^.^...^....\n...............\n...^.^...^.^...\n...............\n..^...^.....^..\n...............\n.^.^.^.^.^...^.\n...............\n\nAt that point, the original beam stops, and two new beams are emitted from the splitter:\n\n.......S.......\n.......|.......\n......|^|......\n...............\n......^.^......\n...............\n.....^.^.^.....\n...............\n....^.^...^....\n...............\n...^.^...^.^...\n...............\n..^...^.....^..\n...............\n.^.^.^.^.^...^.\n...............\n\nThose beams continue downward until they reach more splitters:\n\n.......S.......\n.......|.......\n......|^|......\n......|.|......\n......^.^......\n...............\n.....^.^.^.....\n...............\n....^.^...^....\n...............\n...^.^...^.^...\n...............\n..^...^.....^..\n...............\n.^.^.^.^.^...^.\n...............\n\nAt this point, the two splitters create a total of only three tachyon beams, since they are both dumping tachyons into the same place between them:\n\n.......S.......\n.......|.......\n......|^|......\n......|.|......\n.....|^|^|.....\n...............\n.....^.^.^.....\n...............\n....^.^...^....\n...............\n...^.^...^.^...\n...............\n..^...^.....^..\n...............\n.^.^.^.^.^...^.\n...............\n\nThis process continues until all of the tachyon beams reach a splitter or exit the manifold:\n\n.......S.......\n.......|.......\n......|^|......\n......|.|......\n.....|^|^|.....\n.....|.|.|.....\n....|^|^|^|....\n....|.|.|.|....\n...|^|^|||^|...\n...|.|.|||.|...\n..|^|^|||^|^|..\n..|.|.|||.|.|..\n.|^|||^||.||^|.\n.|.|||.||.||.|.\n|^|^|^|^|^|||^|\n|.|.|.|.|.|||.|\n\nTo repair the teleporter, you first need to understand the beam-splitting properties of the tachyon manifold. In this example, a tachyon beam is split a total of 21 times.\n\nAnalyze your manifold diagram. How many times will the beam be split?\n\n--- Part Two ---\n\nWith your analysis of the manifold complete, you begin fixing the teleporter. However, as you open the side of the teleporter to replace the broken manifold, you are surprised to discover that it isn't a classical tachyon manifold - it's a quantum tachyon manifold.\n\nWith a quantum tachyon manifold, only a single tachyon particle is sent through the manifold. A tachyon particle takes both the left and right path of each splitter encountered.\n\nSince this is impossible, the manual recommends the many-worlds interpretation of quantum tachyon splitting: each time a particle reaches a splitter, it's actually time itself which splits. In one timeline, the particle went left, and in the other timeline, the particle went right.\n\nTo fix the manifold, what you really need to know is the number of timelines active after a single particle completes all of its possible journeys through the manifold.\n\nIn the above example, there are many timelines. For instance, there's the timeline where the particle always went left:\n\n.......S.......\n.......|.......\n......|^.......\n......|........\n.....|^.^......\n.....|.........\n....|^.^.^.....\n....|..........\n...|^.^...^....\n...|...........\n..|^.^...^.^...\n..|............\n.|^...^.....^..\n.|.............\n|^.^.^.^.^...^.\n|..............\n\nOr, there's the timeline where the particle alternated going left and right at each splitter:\n\n.......S.......\n.......|.......\n......|^.......\n......|........\n......^|^......\n.......|.......\n.....^|^.^.....\n......|........\n....^.^|..^....\n.......|.......\n...^.^.|.^.^...\n.......|.......\n..^...^|....^..\n.......|.......\n.^.^.^|^.^...^.\n......|........\n\nOr, there's the timeline where the particle ends up at the same point as the alternating timeline, but takes a totally different path to get there:\n\n.......S.......\n.......|.......\n......|^.......\n......|........\n.....|^.^......\n.....|.........\n....|^.^.^.....\n....|..........\n....^|^...^....\n.....|.........\n...^.^|..^.^...\n......|........\n..^..|^.....^..\n.....|.........\n.^.^.^|^.^...^.\n......|........\n\nIn this example, in total, the particle ends up on 40 different timelines.\n\nApply the many-worlds interpretation of quantum tachyon splitting to your manifold diagram. In total, how many different timelines would a single tachyon particle end up on?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_08.adb",
    "content": "--  Solution to Advent of Code 2025, Day 8\n------------------------------------------\n--  Playground.\n--\n--  https://adventofcode.com/2025/day/8\n--  Copy of questions in: aoc_2025_08_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2025_08 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  n : Natural := 0;\n  rounds : Positive;\n  input_name : VString;\n\n  r : array (Part_Type) of VString;\n\n  subtype max_range is Integer range 1 .. 1000;\n\n  box : array (max_range) of Point_3D;\n\n  procedure Read_Data is\n    dummy_comma : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      n := n + 1;\n      Get (f, box (n).x);\n      Get (f, dummy_comma);\n      Get (f, box (n).y);\n      Get (f, dummy_comma);\n      Get (f, box (n).z);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  verbose : constant Boolean := False;\n\n  procedure Do_Parts is\n    size, size_1, size_2, size_3, max_size : Natural;\n    best_i, best_j : Positive;\n    best, dist2 : Integer_64;\n    pair_connected : array (max_range, max_range) of Boolean;  --  We use only the upper triangle (i < j).\n    circuit : array (max_range) of Natural;\n    c_j : Positive;\n  begin\n    for i in 1 .. n loop\n      circuit (i) := i;\n      for j in 1 .. n loop\n        pair_connected (i, j) := False;\n      end loop;\n    end loop;\n\n    for round in Positive loop\n      best := Integer_64'Last;\n      for i in 1 .. n loop\n        for j in i + 1 .. n loop\n\n          dist2 :=\n            Integer_64 (box (i).x - box (j).x) ** 2 +\n            Integer_64 (box (i).y - box (j).y) ** 2 +\n            Integer_64 (box (i).z - box (j).z) ** 2;\n\n          if dist2 < best and then not pair_connected (i, j) then\n            best := dist2;\n            best_i := i;\n            best_j := j;\n          end if;\n\n        end loop;\n      end loop;\n\n      pair_connected (best_i, best_j) := True;\n\n      --  Merge circuits.\n      for i in 1 .. n loop\n        for j in i + 1 .. n loop\n          if pair_connected (i, j) then\n            c_j := circuit (j);\n            for k in 1 .. n loop\n              if circuit (k) = c_j then\n                circuit (k) := circuit (i);\n              end if;\n            end loop;\n          end if;\n        end loop;\n      end loop;\n\n      if round = rounds then\n        size_1 := 1;\n        size_2 := 1;\n        size_3 := 1;\n        for c in 1 .. n loop\n          size := 0;\n          for i in 1 .. n loop\n            if circuit (i) = c then\n              size := size + 1;\n            end if;\n          end loop;\n\n          if verbose then\n            if size > 1 then\n              Put_Line (+\"Size: \" & size);\n              for i in 1 .. n loop\n                if circuit (i) = c then\n                  Put_Line (+\"    \" & box (i).x & \", \" & box (i).y & \", \" & box (i).z);\n                end if;\n              end loop;\n            end if;\n          end if;\n\n          if size > size_1 then\n            size_3 := size_2;\n            size_2 := size_1;\n            size_1 := size;\n          elsif size > size_2 then\n            size_3 := size_2;\n            size_2 := size;\n          elsif size > size_3 then\n            size_3 := size;\n          end if;\n        end loop;\n        r (part_1) := +\"\" & size_1 * size_2 * size_3;\n      end if;\n\n      if verbose then\n        Put_Line (+\"Circuit list, round \" & round);\n        for c in 1 .. n loop\n          size := 0;\n          for i in 1 .. n loop\n            if circuit (i) = c then\n              size := size + 1;\n            end if;\n          end loop;\n          Put_Line (+\"  circuit \" & c & \": \" & size);\n        end loop;\n      end if;\n\n      max_size := 0;\n      for c in 1 .. n loop\n        size := 0;\n        for i in 1 .. n loop\n          if circuit (i) = c then\n            size := size + 1;\n          end if;\n        end loop;\n        max_size := Max (max_size, size);\n      end loop;\n\n      if max_size = n then\n        if verbose then\n          Put (+\"\" & box (best_i).x & \", \" & box (best_j).x);\n          Put_Line (+\"Final round = \" & round);\n        end if;\n        r (part_2) :=\n          Trim_Both (+\"\" & Integer_64'Image (Integer_64 (box (best_i).x) * Integer_64 (box (best_j).x)));\n        exit;\n      end if;\n\n    end loop;\n  end Do_Parts;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n\n  if compiler_test_mode then\n    input_name := +\"aoc_2025_08_mini\";\n    rounds := 10;\n  else\n    input_name := +\"aoc_2025_08\";\n    rounds := 1000;\n  end if;\n\n  Read_Data;\n  Do_Parts;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 72150 (mini: 40).\n    --  Part 2: validated by AoC: 3926518899 (mini: 25272).\n  end if;\nend AoC_2025_08;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_08.txt",
    "content": "97087,38864,23753\n75016,36080,24819\n30660,97751,22587\n59383,11790,81126\n2600,8401,80432\n46494,70797,47058\n81732,20950,69200\n15728,92220,74530\n54831,40458,91147\n89441,6168,34566\n72454,92628,51454\n77856,17035,10876\n28523,97878,71598\n76225,80828,17571\n26470,5547,70927\n51295,63717,52536\n46497,18958,68258\n23193,28622,49485\n87424,10885,44181\n80738,63528,37589\n87670,55102,94358\n40880,50031,6830\n38549,67920,77663\n39036,36994,88345\n41639,71553,74006\n16909,80500,83974\n28873,7268,88436\n85846,41546,93048\n20012,74589,27198\n77547,71990,24027\n60618,14924,38900\n17154,20294,52963\n61320,56700,36468\n79242,41846,68987\n50563,1498,73464\n49557,33592,11047\n46615,73849,67322\n1081,95388,30075\n98047,4511,38627\n93255,83340,57782\n29717,94577,66723\n5774,68659,95647\n3861,20635,53818\n26628,92003,85496\n68241,15467,7597\n77509,49485,24373\n66205,98086,82794\n22386,85405,29848\n68704,89280,51779\n27029,38642,47315\n84271,60574,49976\n11589,10437,71306\n66803,96256,61748\n29100,89168,98830\n77224,36565,3825\n45689,29133,50145\n99081,32962,44012\n56545,77873,53900\n50439,38918,62693\n8911,940,85181\n66969,41485,68611\n34252,96481,2757\n34091,67890,85439\n91267,50465,43388\n92272,41303,92974\n21735,14555,92943\n77443,87368,98735\n96458,22360,28460\n43795,10997,60603\n64382,36955,7627\n99601,71857,30302\n85775,25087,89886\n18421,43215,30783\n31479,15815,87092\n91888,16999,48348\n48416,36846,78393\n62755,27322,82861\n88363,52398,90553\n4342,5515,84104\n6651,88662,21598\n60674,5603,84490\n64962,45338,7046\n68766,84441,19302\n69877,98980,77998\n10918,73415,97647\n72818,76946,69416\n51249,29239,92705\n20590,31927,65323\n11300,16278,47940\n56199,33153,82920\n49505,90987,18854\n65720,6827,97637\n22227,79692,3627\n13700,90239,21153\n64704,69760,3780\n3981,42328,6289\n32918,74804,1547\n98004,74426,55201\n66870,60013,83220\n21170,65747,43971\n15997,26311,41519\n51096,70514,97639\n19266,31988,31206\n25481,21444,64953\n57703,52068,21290\n97883,71478,59023\n35513,60856,84330\n10616,34277,53701\n55678,27448,46413\n45081,81211,20837\n67270,86441,79006\n89774,11792,8916\n8838,74779,67897\n86338,2446,32523\n87014,79452,95714\n74768,36728,30740\n94847,39339,42645\n25677,17350,90584\n65448,33374,72148\n94754,17905,60155\n61769,70908,93806\n5573,41174,71348\n95137,77478,73268\n14174,39334,65991\n9099,43383,59702\n74631,52496,74418\n78580,78403,63883\n41996,4722,5589\n18059,76201,48913\n93374,65858,17110\n50787,32689,2465\n39373,95901,18892\n16125,99439,76959\n50709,63568,69224\n12876,47512,83549\n62337,1315,76088\n41578,50487,6477\n23129,78865,67689\n6812,13357,81241\n94658,74821,39149\n61762,42645,81381\n33585,69019,29317\n3381,21718,54835\n74742,29928,25553\n5822,85342,67749\n66525,16866,31768\n20311,9342,47353\n33425,82189,65834\n97164,9726,45411\n34171,96115,44692\n48152,83544,52553\n87344,19009,17575\n21844,2043,37966\n10414,59050,18808\n74498,21361,20396\n68487,95430,59021\n91459,27696,2332\n1344,95089,26735\n47281,38607,75772\n74663,44615,12423\n59019,40304,97320\n83624,41669,58905\n63437,98368,12025\n50587,18468,96639\n15403,79238,13253\n46540,41850,16584\n67042,6189,96944\n24460,77059,41763\n35394,24430,18341\n33221,59517,84585\n71127,10737,63046\n42389,62869,6006\n94508,74728,83658\n8576,16759,73620\n8549,62635,245\n41541,89066,62477\n40807,63838,5828\n32755,79201,78529\n71412,54033,93124\n53882,49789,95670\n64994,11008,98088\n91276,14645,28240\n16226,70709,47843\n24061,7987,94376\n64254,99744,57075\n7507,5168,97602\n17110,94723,97769\n87947,14709,8846\n72638,81464,99053\n26168,30767,94065\n14264,36722,10196\n90440,67746,69309\n27159,48948,58556\n23527,27433,24272\n75493,94978,98072\n12181,81043,34540\n33237,20822,40668\n41440,78891,30192\n8916,5360,65669\n32015,36246,51336\n76250,19182,50586\n8479,39839,71581\n2936,89039,41326\n24696,49678,86903\n23853,21266,98765\n56820,30926,23841\n41077,29519,15927\n97872,60801,29118\n63702,78420,3699\n52853,49378,77354\n34018,28210,65230\n17691,29302,96959\n96408,44150,17404\n71708,22734,27940\n17064,39333,76512\n84050,87993,32554\n37935,52797,59518\n80068,760,67110\n89823,65558,74789\n62930,7116,53954\n99398,73462,16668\n71075,47813,36713\n85803,80701,86889\n99366,74952,85960\n86220,4479,94918\n73271,15883,43426\n86385,14786,39331\n48142,31080,86006\n59639,13618,78614\n40122,59427,15235\n67900,99276,40995\n14643,16596,79707\n9738,1839,71027\n5367,95212,72069\n47415,90466,97234\n82421,43336,81569\n13931,24834,66914\n54588,22617,16232\n76084,10716,67901\n70894,67753,21239\n73159,39718,28408\n36858,47337,82183\n95455,19011,58014\n62319,69732,24372\n90399,14470,21458\n97528,22412,92748\n25330,40385,14771\n54176,97326,86283\n23527,4059,79184\n12494,1187,15340\n48189,32635,45117\n20993,62162,1649\n58430,21013,11653\n36354,55533,80407\n51555,4208,16732\n23506,35498,97147\n12781,41393,84711\n24838,7923,30341\n42623,13249,83124\n20249,50445,31548\n38137,66623,7317\n39323,59312,8610\n82379,14132,21119\n13000,33556,98438\n3725,61686,68124\n77716,1382,12277\n89522,45666,431\n90922,778,26277\n69218,17908,41670\n49347,11962,33388\n89957,29719,45466\n78407,48963,90138\n1535,98811,18448\n22561,92883,13140\n23332,77652,99553\n14428,77470,52243\n93184,36989,35893\n49848,64379,97641\n38727,80723,13988\n34111,50181,51288\n11691,87027,24574\n44344,78325,64232\n93402,82927,64200\n53290,19013,93764\n40881,8937,34625\n78373,4052,93527\n21698,68368,69717\n29872,24871,89301\n93915,84546,84709\n7604,30053,16046\n68237,56253,69615\n33915,87610,65579\n67487,43129,35435\n56,97068,21103\n114,74538,92093\n54139,1569,93859\n29379,65242,53686\n97940,71942,97926\n88512,66095,96121\n90974,93502,24459\n54834,29548,18878\n40604,6153,89253\n10381,80502,50447\n84923,43384,41815\n47771,86172,58692\n80772,21564,91094\n86320,79991,25548\n39556,50692,93847\n52702,62960,64854\n84463,81908,80455\n80337,72986,87213\n67520,77081,71166\n13314,4667,70361\n91051,49801,7491\n20996,14923,5861\n97994,55231,22907\n394,87554,1993\n46598,83159,48246\n9588,38611,97472\n78566,10013,10592\n80575,56769,6868\n6409,84174,87719\n99139,99092,34197\n12870,46012,55785\n48879,75969,82216\n26089,367,35539\n15546,17717,53511\n37934,60968,16358\n2156,18652,73749\n41817,67383,74060\n48153,62469,32874\n38199,11270,88171\n92193,39995,2424\n46302,33500,93042\n28224,5474,14651\n53920,88869,30662\n879,54364,1708\n36418,77206,79028\n98612,1282,76592\n93152,41576,36372\n14504,75370,9366\n79830,12599,39998\n32492,51968,63413\n32973,45535,34502\n9048,6900,38414\n82524,17894,56443\n1219,86357,72135\n66927,2107,39110\n66425,70179,22370\n46767,45416,44338\n6658,23585,19397\n52881,5422,24167\n26680,15054,78641\n73090,6569,90207\n58853,6785,94331\n55470,3263,54221\n627,55248,91425\n62063,32138,6106\n90666,45543,1834\n87892,36256,93235\n59273,35892,79574\n17082,935,46226\n93425,58824,43809\n2752,89509,1113\n22686,45768,75470\n91800,2072,6582\n36085,49807,40813\n85673,69891,51719\n63765,21907,5185\n92212,46650,84911\n90738,5352,13316\n79174,41350,35540\n48380,16036,77356\n59173,1563,36051\n43245,3900,75540\n29297,12517,60515\n58782,43041,74848\n71383,64326,5664\n74496,43278,29925\n61400,94826,25783\n3237,63742,8011\n18807,96040,35506\n78529,94262,25741\n72644,97496,2854\n42055,56754,57153\n72947,46890,90506\n52880,25537,80370\n81523,26830,28645\n54178,56698,72729\n92748,42199,81839\n86751,82836,79461\n14638,32648,54698\n4132,14156,49913\n45569,98378,31740\n57759,90110,26102\n88989,32657,40042\n26465,13138,77308\n33031,38733,12161\n69911,47438,7020\n76670,26697,53304\n33020,46987,21881\n5959,14824,68024\n57667,51474,73325\n16037,34918,18025\n31892,46976,40897\n44195,75894,20887\n94377,55260,86724\n68367,96915,97204\n69381,8839,60516\n2151,86900,14725\n71042,9488,81357\n56655,9814,46142\n16348,11387,75966\n64461,75285,73100\n13589,4488,13261\n69527,61607,41848\n96196,44461,73370\n76288,92388,57670\n36061,27373,70076\n60190,98192,21928\n26302,98043,53735\n66476,41918,59430\n52872,1522,54236\n20612,7161,82969\n30497,33430,28248\n48994,44256,84612\n7527,23866,24058\n3703,84491,19072\n94720,95134,15639\n97604,40476,71296\n96825,20717,24427\n587,89769,44435\n27867,98619,89297\n42442,67298,55778\n49804,14974,87181\n42048,76779,82463\n57122,74951,18116\n35737,57033,865\n47917,19796,60588\n79232,86740,8944\n12809,86091,12502\n1139,92760,63788\n77734,27950,97055\n41389,5578,72847\n28132,71397,9010\n89381,16213,67420\n87564,57238,2513\n61194,51435,48362\n9930,10953,4787\n58186,86280,4036\n64716,94209,23552\n80463,78007,82189\n97897,19201,29296\n20531,91777,41105\n67923,78001,18086\n91114,49451,25864\n72064,23657,26048\n30445,59703,69292\n88808,8850,50060\n54428,77003,92151\n46101,59895,13632\n15376,76132,76071\n93968,770,51631\n63096,61546,54198\n82027,82888,22882\n8540,61971,96861\n23761,22278,69762\n38433,82952,46190\n19062,74821,27384\n71393,61018,78100\n21164,53740,25712\n73566,31104,3528\n44638,24851,26635\n37042,98309,33021\n2268,4147,62286\n62357,17088,50839\n72554,82457,26318\n9664,27860,16593\n94127,66582,86790\n74267,10578,58220\n84962,94230,26636\n56431,90261,37790\n83536,91393,68549\n14230,62298,13615\n49459,36301,58067\n58490,51813,47588\n86160,33731,54801\n21668,22427,24813\n27421,49475,42044\n1578,61932,33255\n46417,625,93425\n27841,7768,63756\n37261,80327,41744\n88462,88485,43053\n68357,18556,15673\n80501,95412,93074\n48461,74266,62739\n21527,19901,714\n2883,50427,37025\n19927,88922,87659\n35636,61735,63760\n10078,36629,22217\n40250,69242,84237\n22445,66961,48673\n72963,18199,11022\n2235,85760,55838\n84556,1386,86000\n24052,53657,43383\n59042,65235,13933\n72842,53789,53031\n91514,65344,62697\n66127,56426,29413\n21323,52624,91608\n37692,41149,76855\n97254,80681,86172\n21902,79654,97991\n3172,19548,56351\n29515,44965,36138\n36260,8991,26964\n31711,12626,7341\n10397,62529,47511\n5515,55359,28405\n65195,14091,67132\n98219,95841,57781\n17564,35112,84308\n50711,46772,99788\n67756,16635,89678\n32200,21952,66222\n67006,2019,23861\n60588,85271,13324\n97550,41036,98149\n42956,23597,34580\n49380,62149,47716\n93544,91424,22172\n22197,55993,14609\n94454,30620,27975\n27694,19602,60591\n64766,66326,95976\n5415,38063,22773\n93459,50343,11312\n55508,10287,64973\n43337,56036,57465\n15150,8468,92363\n95541,86293,62600\n72694,9980,88090\n21878,51678,74106\n77068,22682,46969\n50636,79453,36939\n21650,44892,39184\n59601,83296,73668\n23890,19868,32010\n14619,40348,93992\n75807,71371,87575\n85442,4364,31317\n83571,52976,42457\n15998,66167,94639\n77917,71029,90885\n66619,99564,13879\n32570,31633,77153\n36974,72466,88699\n44900,41673,99871\n51530,4507,79369\n35241,78709,73079\n81386,49281,47748\n60742,33672,96105\n34861,55665,68163\n35496,61052,18458\n5131,4012,86307\n80239,52844,22653\n41069,60,98392\n42498,36880,57616\n59896,22862,75475\n40506,2308,79623\n2353,74441,90560\n6297,22087,47304\n92117,55824,98570\n89633,80927,26914\n14703,5433,3917\n51845,18745,47416\n75124,61084,64848\n13322,69549,58708\n84777,7125,14942\n87798,48438,77430\n74054,79572,69722\n70584,78929,48532\n48917,37690,12296\n29385,66279,21490\n26385,12502,26563\n43750,76610,62379\n19716,78060,14630\n38743,97415,52902\n3109,49764,52656\n205,61577,70284\n34697,74523,40669\n50351,83909,85449\n19860,17672,50588\n43039,83737,65418\n83835,34128,13617\n89211,76890,61630\n27714,45734,14694\n63592,64541,3477\n39356,22317,63994\n23509,76013,3704\n99921,76025,12390\n74528,30693,74884\n12229,11380,92105\n6721,48296,83914\n74588,79658,42650\n687,26223,6625\n98455,95913,60027\n34074,42306,96793\n30966,94206,82517\n94444,81330,89796\n36258,87021,35840\n59422,16153,25121\n96645,37623,69727\n60300,37557,41178\n77871,34497,3270\n27977,81664,97542\n68072,88852,81099\n62133,17119,21920\n40388,99748,57286\n81685,18960,10603\n2340,96209,96469\n18106,74532,61280\n66095,10117,20970\n83802,70279,80908\n14702,91861,54392\n89043,37110,17290\n19397,95815,67242\n585,87616,59349\n15250,56852,24610\n42787,69227,65880\n23736,26885,98193\n26671,92232,62970\n97334,15685,33095\n40442,36435,54087\n95248,91876,97783\n69365,35631,611\n67917,4371,66070\n81388,88171,7269\n30968,59753,14754\n30597,9687,4451\n90614,80007,61498\n57774,71813,12947\n27550,38725,71720\n75996,90425,54865\n10990,44608,29738\n81078,71667,50165\n34322,42040,14513\n32545,65809,53452\n2011,79434,62823\n33035,80864,20516\n51205,66931,67009\n17631,9040,25834\n70119,44501,10001\n1712,80500,47067\n42391,16412,20824\n72408,84358,29262\n39221,2209,56280\n18927,51552,65180\n91163,23427,55521\n84002,31474,61757\n49021,55725,83294\n78468,85980,99608\n68236,14192,95210\n3075,45352,86176\n76896,49112,23516\n35046,25239,26606\n69247,3663,34279\n61162,56123,62688\n2797,54066,89510\n88104,40344,17460\n31908,3484,69138\n97856,83332,44447\n93511,925,10842\n97198,74425,96961\n82986,2624,50762\n66901,17935,99361\n11785,74995,50193\n20274,97142,63246\n34727,86842,27466\n83431,98880,2404\n47460,42966,72805\n14773,52946,36804\n46177,98401,82349\n15042,64973,56242\n67918,2083,1391\n95715,61126,70761\n41596,86269,89916\n54544,69471,73217\n61448,73245,46184\n8208,42084,9281\n84638,73887,92129\n16242,45377,24704\n98649,78396,76452\n41186,79384,98196\n37931,37636,44755\n43568,85323,67395\n25163,82769,92331\n12660,45834,12220\n18098,12058,61339\n2591,27949,86670\n23388,56573,58661\n49173,26735,64334\n42980,79805,63797\n31366,25948,92873\n75295,30072,83990\n97505,44723,28280\n2302,33083,83235\n82392,46430,72749\n49684,52921,38839\n84992,60535,28924\n93315,3694,55539\n3670,81274,19203\n87926,65650,80092\n87817,19927,90793\n49603,92966,94322\n97819,77737,40036\n66078,58928,48114\n47242,61638,12261\n93269,9334,61000\n66350,78393,69083\n94045,5567,97094\n76144,9645,30438\n77288,44428,16918\n98864,79991,20973\n42495,70301,4260\n42423,77076,11815\n79050,3735,56900\n64736,58088,79181\n82772,83512,96545\n11632,6234,25620\n40682,38105,32750\n88366,72664,15106\n56907,73279,13979\n43754,91376,88401\n28812,84230,71721\n76369,53652,95893\n50450,19245,14254\n89708,80403,66093\n92858,4795,96776\n47371,99339,37775\n46433,30006,70921\n19042,26837,33089\n55381,27212,16518\n28339,86391,91524\n4993,86696,86838\n93950,11853,74348\n45118,85580,35699\n80711,84942,32998\n13572,67055,2186\n62612,9096,54828\n35347,47510,5454\n57539,8465,733\n19442,87321,77467\n89715,1008,7668\n90357,53130,53874\n36170,57067,87801\n36014,36563,11742\n29573,42009,47387\n35571,97887,64788\n27167,15647,24804\n3111,12929,19716\n80863,58628,82921\n19876,23518,26876\n36041,53376,80120\n68333,82903,45529\n83218,76290,27992\n69708,68119,79161\n82676,90347,33430\n6630,16910,36290\n37255,56220,47647\n19788,32609,53327\n96781,38467,33598\n51051,85936,37925\n92516,53261,82681\n36899,70904,16048\n68519,17552,13931\n28965,66879,4098\n16643,52330,85868\n14259,77250,83318\n89754,91750,11827\n98854,92349,62816\n96915,23471,49270\n5715,72073,55778\n32305,55832,79486\n57066,73279,68782\n18600,23471,25062\n34459,21821,81285\n70023,32672,4730\n30085,10037,78802\n48012,15777,53938\n60173,36039,15212\n17637,71773,11560\n14249,16247,35966\n30379,34911,36857\n24224,82701,26308\n72780,80367,27817\n54283,96257,91532\n99942,71064,75133\n34083,39909,97745\n61444,82204,89495\n27106,15435,54056\n22735,34314,79203\n57590,46698,39619\n89935,10550,68794\n85448,66157,48469\n29412,94761,12055\n3868,39104,56379\n48062,69056,35013\n13821,81691,25451\n98754,8365,4824\n24285,72533,76682\n8929,65860,58032\n72261,81579,10533\n88192,43583,19907\n30592,36415,70874\n49191,55612,39300\n90630,8994,59667\n12957,39653,15578\n75402,63757,96091\n99487,93938,86111\n66282,24638,46413\n15359,86925,5073\n10266,68540,61484\n73473,76011,9735\n38112,31705,15896\n46511,19969,77599\n40019,28038,3703\n67085,16462,28339\n89708,39172,85855\n66383,40530,19662\n66587,21109,68487\n83376,31151,28546\n67961,13780,26611\n10956,24518,61807\n10132,46986,5292\n95309,4143,86319\n81389,8482,33022\n83018,42103,52992\n54943,35907,16650\n74081,27377,783\n26326,14721,54072\n73481,98095,57078\n24460,31638,99743\n35140,25260,90144\n22113,96585,38650\n45719,71360,51154\n34184,11422,24409\n91106,63368,25590\n95260,45351,9585\n41281,5044,59769\n73100,93301,11565\n46879,68240,77853\n76624,16520,84602\n54342,88502,9387\n164,23736,12809\n50980,25318,51545\n74715,48232,66808\n71341,78988,35249\n45112,12542,12230\n7133,32688,35326\n24218,21233,32049\n91827,3032,88490\n94490,71539,18298\n48359,59665,64611\n6588,97509,23673\n33973,97767,76096\n89916,81291,29986\n68469,97610,59838\n89976,98632,90360\n5922,40508,39414\n5331,52238,24507\n9392,69230,56837\n22212,37422,88297\n82,23376,92265\n18408,27596,8256\n16873,21576,22596\n89210,62535,24880\n87957,87043,78072\n36013,82721,23684\n90729,70294,54540\n33892,87468,61499\n17692,94984,13137\n62996,63877,64164\n92631,66348,42217\n89,31181,37204\n76780,38666,75303\n78532,89946,35303\n28548,9979,92242\n72265,96865,89733\n8201,51540,55425\n34180,73070,49991\n82275,86599,64994\n68767,55950,7841\n94953,33155,52611\n10540,37851,32736\n63843,28266,90505\n46810,46250,67049\n19169,86971,57378\n24788,90951,26680\n5217,16735,94019\n9497,45319,2518\n11624,37497,86799\n42260,49644,82150\n60365,88395,21309\n38955,85146,44219\n56511,60372,81349\n40117,37322,59504\n28729,6877,27752\n30921,76568,64616\n64328,62288,54858\n44233,29192,94595\n43275,73412,21145\n57412,35118,9085\n90027,5293,46425\n55229,86387,17947\n58880,53907,86088\n15746,28160,79814\n83064,53153,5244\n56022,92557,19902\n54700,71667,56164\n25164,25890,99761\n7457,67770,69496\n96488,38407,55668\n60856,81510,99247\n50098,25278,3998\n91253,89827,80191\n51246,48411,33877\n49753,48413,1599\n28390,43793,79664\n31065,5976,63062\n66187,19388,10525\n24154,6119,49051\n74088,31615,89471\n54304,67120,42305\n79323,45387,81692\n12566,13402,10702\n67127,25955,50135\n56574,16878,15918\n15417,29112,47971\n10617,13723,43966\n33662,87159,45652\n19968,55148,69481\n27035,15283,58794\n92304,68860,20563\n15823,75833,46738\n94280,27101,69365\n40385,79811,36588\n73031,42629,21727\n77056,46483,51353\n42038,74034,15366\n7599,81590,10921\n2971,8477,51843\n67250,60901,5164\n2660,52130,40769\n927,86458,73579\n41527,59739,77996\n2514,15223,77131\n51961,12275,18636\n16012,76663,58925\n87939,43418,58421\n26535,34787,85202\n40996,18184,93284\n74329,27058,45897\n21343,79720,34290\n1961,93477,51723\n5165,7158,59952\n41305,181,45353\n73637,92392,78341\n63799,72495,33147\n25406,85728,91343\n67511,7049,95359\n86986,24910,95388\n4636,39605,51761\n93286,40880,37919\n52610,34343,53928\n70442,69310,53632\n56192,84261,61879\n53491,30361,94651\n46019,53412,35427\n17955,32048,34772\n36000,6425,47825\n25279,54374,64627\n39192,58669,15436\n38696,19599,66771\n72625,25967,41598\n9403,54588,55088\n34063,9437,11862\n94931,68541,84476\n41578,3340,67354\n79559,349,91967\n94504,43232,23839\n2375,87408,99546\n34707,46653,55301\n65551,82963,62266\n13109,13500,15659\n62101,58633,77195\n26584,78201,28603\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_08_mini.txt",
    "content": "162,817,812\n57,618,57\n906,360,560\n592,479,940\n352,342,300\n466,668,158\n542,29,236\n431,825,988\n739,650,466\n52,470,668\n216,146,977\n819,987,18\n117,168,530\n805,96,715\n346,949,466\n970,615,88\n941,993,340\n862,61,35\n984,92,344\n425,690,689\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_08_questions.txt",
    "content": "--- Day 8: Playground ---\n\nEquipped with a new understanding of teleporter maintenance, you confidently step onto the repaired teleporter pad.\n\nYou rematerialize on an unfamiliar teleporter pad and find yourself in a vast underground space which contains a giant playground!\n\nAcross the playground, a group of Elves are working on setting up an ambitious Christmas decoration project. Through careful rigging, they have suspended a large number of small electrical junction boxes.\n\nTheir plan is to connect the junction boxes with long strings of lights. Most of the junction boxes don't provide electricity; however, when two junction boxes are connected by a string of lights, electricity can pass between those two junction boxes.\n\nThe Elves are trying to figure out which junction boxes to connect so that electricity can reach every junction box. They even have a list of all of the junction boxes' positions in 3D space (your puzzle input).\n\nFor example:\n\n162,817,812\n57,618,57\n906,360,560\n592,479,940\n352,342,300\n466,668,158\n542,29,236\n431,825,988\n739,650,466\n52,470,668\n216,146,977\n819,987,18\n117,168,530\n805,96,715\n346,949,466\n970,615,88\n941,993,340\n862,61,35\n984,92,344\n425,690,689\n\nThis list describes the position of 20 junction boxes, one per line. Each position is given as X,Y,Z coordinates. So, the first junction box in the list is at X=162, Y=817, Z=812.\n\nTo save on string lights, the Elves would like to focus on connecting pairs of junction boxes that are as close together as possible according to straight-line distance. In this example, the two junction boxes which are closest together are 162,817,812 and 425,690,689.\n\nBy connecting these two junction boxes together, because electricity can flow between them, they become part of the same circuit. After connecting them, there is a single circuit which contains two junction boxes, and the remaining 18 junction boxes remain in their own individual circuits.\n\nNow, the two junction boxes which are closest together but aren't already directly connected are 162,817,812 and 431,825,988. After connecting them, since 162,817,812 is already connected to another junction box, there is now a single circuit which contains three junction boxes and an additional 17 circuits which contain one junction box each.\n\nThe next two junction boxes to connect are 906,360,560 and 805,96,715. After connecting them, there is a circuit containing 3 junction boxes, a circuit containing 2 junction boxes, and 15 circuits which contain one junction box each.\n\nThe next two junction boxes are 431,825,988 and 425,690,689. Because these two junction boxes were already in the same circuit, nothing happens!\n\nThis process continues for a while, and the Elves are concerned that they don't have enough extension cables for all these circuits. They would like to know how big the circuits will be.\n\nAfter making the ten shortest connections, there are 11 circuits: one circuit which contains 5 junction boxes, one circuit which contains 4 junction boxes, two circuits which contain 2 junction boxes each, and seven circuits which each contain a single junction box. Multiplying together the sizes of the three largest circuits (5, 4, and one of the circuits of size 2) produces 40.\n\nYour list contains many junction boxes; connect together the 1000 pairs of junction boxes which are closest together. Afterward, what do you get if you multiply together the sizes of the three largest circuits?\n\n--- Part Two ---\n\nThe Elves were right; they definitely don't have enough extension cables. You'll need to keep connecting junction boxes together until they're all in one large circuit.\n\nContinuing the above example, the first connection which causes all of the junction boxes to form a single circuit is between the junction boxes at 216,146,977 and 117,168,530. The Elves need to know how far those junction boxes are from the wall so they can pick the right extension cable; multiplying the X coordinates of those two junction boxes (216 and 117) produces 25272.\n\nContinue connecting the closest unconnected pairs of junction boxes together until they're all in the same circuit. What do you get if you multiply together the X coordinates of the last two junction boxes you need to connect?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_09.adb",
    "content": "--  Solution to Advent of Code 2025, Day 9\n------------------------------------------\n--  .\n--\n--  https://adventofcode.com/2025/day/9\n--  Copy of questions in: aoc_2025_09_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2025_09 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  --  input_name : constant VString := +\"mini\";\n  input_name : constant VString := +\"aoc_2025_09\";\n\n  red : array (1 .. 1000) of Point;\n  n : Natural := 0;\n\n  r : array (Part_Type) of VString;\n\n  procedure Read_Data is\n    unused_separator : Character;\n    f : File_Type;\n  begin\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      n:= n + 1;\n      Get (f, red(n).x);\n      Get (f, unused_separator);\n      Get (f, red(n).y);\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Do_Part_1 is\n    s, s_max : Integer_64;\n  begin\n    s_max := 0;\n    for i in 1 .. n loop\n      for j in i + 1 .. n loop\n        s := Integer_64(abs(red(i).x-red(j).x)+1) * Integer_64(abs(red(i).y-red(j).y)+1);\n        if s > s_max then\n          s_max := s;\n        end if;\n      end loop;\n    end loop;\n    r (part_1) := +\"\" & Trim_Left (+Integer_64'Image(s_max));\n  end Do_Part_1;\n  \n  procedure Do_Part_2 is\n    s, s_max : Integer_64;\n    mouth_top    : constant := 50174;  --  Top part of the pacman's mouth.\n    mouth_bottom : constant := 48596;  --  Bottom part of the pacman's mouth.\n    mouth_x      : constant := 94582;\n    is_top, ok, point_k_in_rect : Boolean;\n  begin\n    s_max := 0;\n    for i in 1 .. n loop\n      if red(i).x = mouth_x and then (red(i).y = mouth_top or else red(i).y = mouth_bottom) then\n        is_top := red(i).y = mouth_top;\n        for j in 1 .. n loop\n          if red(j).x < mouth_x then\n            if        (is_top and then red(j).y > mouth_top)           --  Point j above mouth.\n              or else ((not is_top) and then red(j).y < mouth_bottom)  --  Point j below mouth.\n            then\n              ok := True;\n              for k in 1 .. n loop\n                point_k_in_rect := red(k).x in red(j).x + 1.. mouth_x - 1;\n                if is_top then\n                  point_k_in_rect := point_k_in_rect and then red(k).y in mouth_top + 1.. red(j).y - 1;\n                else\n                  point_k_in_rect := point_k_in_rect and then red(k).y in red(j).y + 1 .. mouth_bottom - 1;\n                end if;\n                ok := ok and not point_k_in_rect;\n                exit when not ok;\n              end loop;\n              if ok then\n                s := Integer_64(abs(red(i).x-red(j).x)+1) * Integer_64(abs(red(i).y-red(j).y)+1);\n              end if;\n              if s > s_max then\n                s_max := s;\n              end if;\n            end if;        \n          end if;        \n        end loop;\n      end if;        \n    end loop;\n    r (part_2) := +\"\" & Trim_Left (+Integer_64'Image(s_max));\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 4749838800.\n    --  Part 2: validated by AoC: 1624057680.\n  end if;\nend;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_09.m",
    "content": "% Matlab / Octave script to plot the figure\n%\nx = csvread('aoc_2025_09.txt');\nplot(x(:,1),x(:,2));\n\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_09.txt",
    "content": "97839,50187\n97839,51418\n98477,51418\n98477,52600\n97593,52600\n97593,53826\n97775,53826\n97775,55054\n97845,55054\n97845,56233\n97465,56233\n97465,57483\n97608,57483\n97608,58579\n96811,58579\n96811,59852\n97008,59852\n97008,61033\n96717,61033\n96717,62334\n96880,62334\n96880,63489\n96457,63489\n96457,64646\n96051,64646\n96051,65657\n95227,65657\n95227,66837\n94921,66837\n94921,68027\n94622,68027\n94622,69047\n93911,69047\n93911,70060\n93212,70060\n93212,71120\n92635,71120\n92635,72596\n92849,72596\n92849,73389\n91754,73389\n91754,74603\n91423,74603\n91423,75740\n90939,75740\n90939,76321\n89599,76321\n89599,77746\n89534,77746\n89534,78350\n88294,78350\n88294,79381\n87652,79381\n87652,80751\n87413,80751\n87413,81696\n86631,81696\n86631,82560\n85757,82560\n85757,83382\n84844,83382\n84844,84206\n83940,84206\n83940,84858\n82877,84858\n82877,85750\n82046,85750\n82046,86260\n80883,86260\n80883,87208\n80098,87208\n80098,88347\n79444,88347\n79444,88713\n78195,88713\n78195,89333\n77149,89333\n77149,90043\n76167,90043\n76167,90587\n75078,90587\n75078,91641\n74294,91641\n74294,92071\n73137,92071\n73137,92508\n71993,92508\n71993,93110\n70937,93110\n70937,93943\n69982,93943\n69982,94328\n68818,94328\n68818,94683\n67646,94683\n67646,95050\n66484,95050\n66484,95138\n65231,95138\n65231,96310\n64331,96310\n64331,95940\n62951,95940\n62951,96391\n61818,96391\n61818,96987\n60710,96987\n60710,97190\n59505,97190\n59505,96879\n58213,96879\n58213,97722\n57119,97722\n57119,97166\n55819,97166\n55819,97745\n54666,97745\n54666,97742\n53448,97742\n53448,98007\n52246,98007\n52246,98267\n51034,98267\n51034,98470\n49810,98470\n49810,98262\n48588,98262\n48588,98022\n47376,98022\n47376,97624\n46185,97624\n46185,97999\n44929,97999\n44929,98024\n43692,98024\n43692,97280\n42567,97280\n42567,96960\n41393,96960\n41393,96827\n40185,96827\n40185,96238\n39079,96238\n39079,96684\n37717,96684\n37717,96571\n36476,96571\n36476,95754\n35447,95754\n35447,95464\n34260,95464\n34260,94960\n33148,94960\n33148,94733\n31928,94733\n31928,94380\n30749,94380\n30749,93612\n29754,93612\n29754,92588\n28902,92588\n28902,92325\n27680,92325\n27680,92040\n26449,92040\n26449,91353\n25438,91353\n25438,90516\n24525,90516\n24525,90387\n23155,90387\n23155,89486\n22287,89486\n22287,88416\n21558,88416\n21558,88164\n20219,88164\n20219,86821\n19735,86821\n19735,86167\n18705,86167\n18705,85155\n17987,85155\n17987,84913\n16550,84913\n16550,84073\n15658,84073\n15658,83006\n15003,83006\n15003,82108\n14180,82108\n14180,80918\n13697,80918\n13697,80382\n12440,80382\n12440,79182\n11992,79182\n11992,78337\n11092,78337\n11092,77091\n10750,77091\n10750,76233\n9854,76233\n9854,75223\n9177,75223\n9177,74226\n8474,74226\n8474,73087\n8018,73087\n8018,72269\n6957,72269\n6957,70795\n7182,70795\n7182,69951\n6125,69951\n6125,68563\n6271,68563\n6271,67731\n5101,67731\n5101,66547\n4778,66547\n4778,65200\n4955,65200\n4955,64241\n3978,64241\n3978,62979\n3960,62979\n3960,61794\n3701,61794\n3701,60765\n2769,60765\n2769,59574\n2468,59574\n2468,58225\n3049,58225\n3049,57049\n2747,57049\n2747,55867\n2442,55867\n2442,54643\n2487,54643\n2487,53478\n1841,53478\n1841,52227\n2406,52227\n2406,51018\n2473,51018\n2473,50174\n94582,50174\n94582,48596\n2009,48596\n2009,47397\n2365,47397\n2365,46143\n1843,46143\n1843,45001\n2683,45001\n2683,43797\n2775,43797\n2775,42479\n2160,42479\n2160,41424\n3205,41424\n3205,40171\n3106,40171\n3106,38868\n2869,38868\n2869,37745\n3423,37745\n3423,36645\n4010,36645\n4010,35554\n4580,35554\n4580,34404\n4951,34404\n4951,33049\n4777,33049\n4777,31917\n5239,31917\n5239,30850\n5852,30850\n5852,29916\n6735,29916\n6735,28754\n7113,28754\n7113,27735\n7780,27735\n7780,26320\n7728,26320\n7728,25544\n8824,25544\n8824,24250\n9045,24250\n9045,23184\n9655,23184\n9655,22440\n10732,22440\n10732,21595\n11633,21595\n11633,20324\n11970,20324\n11970,19659\n13085,19659\n13085,18479\n13572,18479\n13572,17583\n14400,17583\n14400,16906\n15457,16906\n15457,15867\n16133,15867\n16133,15383\n17351,15383\n17351,14556\n18228,14556\n18228,13309\n18750,13309\n18750,12641\n19780,12641\n19780,12253\n21017,12253\n21017,11069\n21646,11069\n21646,10560\n22777,10560\n22777,9597\n23598,9597\n23598,8853\n24576,8853\n24576,8780\n25951,8780\n25951,7864\n26827,7864\n26827,7601\n28063,7601\n28063,6935\n29084,6935\n29084,5913\n29952,5913\n29952,5397\n31065,5397\n31065,5302\n32347,5302\n32347,4647\n33404,4647\n33404,4202\n34545,4202\n34545,4010\n35768,4010\n35768,4073\n37052,4073\n37052,3941\n38266,3941\n38266,2861\n39255,2861\n39255,3369\n40606,3369\n40606,3042\n41773,3042\n41773,2609\n42929,2609\n42929,2225\n44105,2225\n44105,1748\n45283,1748\n45283,2332\n46557,2332\n46557,1675\n47738,1675\n47738,2385\n48979,2385\n48979,1804\n50188,1804\n50188,1737\n51411,1737\n51411,1988\n52623,1988\n52623,2448\n53808,2448\n53808,1826\n55089,1826\n55089,1951\n56310,1951\n56310,2824\n57415,2824\n57415,2496\n58705,2496\n58705,3475\n59750,3475\n59750,3658\n60944,3658\n60944,3202\n62312,3202\n62312,4128\n63319,4128\n63319,3826\n64685,3826\n64685,4784\n65652,4784\n65652,4734\n66966,4734\n66966,5412\n68012,5412\n68012,5604\n69257,5604\n69257,6711\n70095,6711\n70095,7060\n71271,7060\n71271,7843\n72230,7843\n72230,8110\n73464,8110\n73464,9092\n74296,9092\n74296,9127\n75698,9127\n75698,9689\n76793,9689\n76793,10879\n77456,10879\n77456,11732\n78331,11732\n78331,11970\n79675,11970\n79675,12644\n80703,12644\n80703,13616\n81482,13616\n81482,14818\n82035,14818\n82035,15485\n83066,15485\n83066,16276\n83987,16276\n83987,17268\n84703,17268\n84703,18250\n85418,18250\n85418,19090\n86290,19090\n86290,19787\n87349,19787\n87349,20771\n88066,20771\n88066,21986\n88463,21986\n88463,22781\n89434,22781\n89434,23591\n90412,23591\n90412,24650\n91025,24650\n91025,25931\n91254,25931\n91254,26923\n91962,26923\n91962,28166\n92198,28166\n92198,28940\n93359,28940\n93359,30162\n93623,30162\n93623,31247\n94173,31247\n94173,32499\n94314,32499\n94314,33454\n95216,33454\n95216,34580\n95692,34580\n95692,35889\n95596,35889\n95596,36999\n96114,36999\n96114,38116\n96649,38116\n96649,39319\n96857,39319\n96857,40464\n97338,40464\n97338,41631\n97767,41631\n97767,42884\n97695,42884\n97695,44173\n97221,44173\n97221,45292\n98160,45292\n98160,46525\n98102,46525\n98102,47740\n98289,47740\n98289,48979\n97634,48979\n97634,50187\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_09_questions.txt",
    "content": "--- Day 9: Movie Theater ---\n\nYou slide down the firepole in the corner of the playground and land in the North Pole base movie theater!\n\nThe movie theater has a big tile floor with an interesting pattern. Elves here are redecorating the theater by switching out some of the square tiles in the big grid they form. Some of the tiles are red; the Elves would like to find the largest rectangle that uses red tiles for two of its opposite corners. They even have a list of where the red tiles are located in the grid (your puzzle input).\n\nFor example:\n\n7,1\n11,1\n11,7\n9,7\n9,5\n2,5\n2,3\n7,3\n\nShowing red tiles as # and other tiles as ., the above arrangement of red tiles would look like this:\n\n..............\n.......#...#..\n..............\n..#....#......\n..............\n..#......#....\n..............\n.........#.#..\n..............\n\nYou can choose any two red tiles as the opposite corners of your rectangle; your goal is to find the largest rectangle possible.\n\nFor example, you could make a rectangle (shown as O) with an area of 24 between 2,5 and 9,7:\n\n..............\n.......#...#..\n..............\n..#....#......\n..............\n..OOOOOOOO....\n..OOOOOOOO....\n..OOOOOOOO.#..\n..............\n\nOr, you could make a rectangle with area 35 between 7,1 and 11,7:\n\n..............\n.......OOOOO..\n.......OOOOO..\n..#....OOOOO..\n.......OOOOO..\n..#....OOOOO..\n.......OOOOO..\n.......OOOOO..\n..............\n\nYou could even make a thin rectangle with an area of only 6 between 7,3 and 2,3:\n\n..............\n.......#...#..\n..............\n..OOOOOO......\n..............\n..#......#....\n..............\n.........#.#..\n..............\n\nUltimately, the largest rectangle you can make in this example has area 50. One way to do this is between 2,5 and 11,1:\n\n..............\n..OOOOOOOOOO..\n..OOOOOOOOOO..\n..OOOOOOOOOO..\n..OOOOOOOOOO..\n..OOOOOOOOOO..\n..............\n.........#.#..\n..............\n\nUsing two red tiles as opposite corners, what is the largest area of any rectangle you can make?\n\n--- Part Two ---\n\nThe Elves just remembered: they can only switch out tiles that are red or green. So, your rectangle can only include red or green tiles.\n\nIn your list, every red tile is connected to the red tile before and after it by a straight line of green tiles. The list wraps, so the first red tile is also connected to the last red tile. Tiles that are adjacent in your list will always be on either the same row or the same column.\n\nUsing the same example as before, the tiles marked X would be green:\n\n..............\n.......#XXX#..\n.......X...X..\n..#XXXX#...X..\n..X........X..\n..#XXXXXX#.X..\n.........X.X..\n.........#X#..\n..............\n\nIn addition, all of the tiles inside this loop of red and green tiles are also green. So, in this example, these are the green tiles:\n\n..............\n.......#XXX#..\n.......XXXXX..\n..#XXXX#XXXX..\n..XXXXXXXXXX..\n..#XXXXXX#XX..\n.........XXX..\n.........#X#..\n..............\n\nThe remaining tiles are never red nor green.\n\nThe rectangle you choose still must have red tiles in opposite corners, but any other tiles it includes must now be red or green. This significantly limits your options.\n\nFor example, you could make a rectangle out of red and green tiles with an area of 15 between 7,3 and 11,1:\n\n..............\n.......OOOOO..\n.......OOOOO..\n..#XXXXOOOOO..\n..XXXXXXXXXX..\n..#XXXXXX#XX..\n.........XXX..\n.........#X#..\n..............\n\nOr, you could make a thin rectangle with an area of 3 between 9,7 and 9,5:\n\n..............\n.......#XXX#..\n.......XXXXX..\n..#XXXX#XXXX..\n..XXXXXXXXXX..\n..#XXXXXXOXX..\n.........OXX..\n.........OX#..\n..............\n\nThe largest rectangle you can make in this example using only red and green tiles has area 24. One way to do this is between 9,5 and 2,3:\n\n..............\n.......#XXX#..\n.......XXXXX..\n..OOOOOOOOXX..\n..OOOOOOOOXX..\n..OOOOOOOOXX..\n.........XXX..\n.........#X#..\n..............\n\nUsing two red tiles as opposite corners, what is the largest area of any rectangle you can make using only red and green tiles?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_10.adb",
    "content": "--  Solution to Advent of Code 2025, Day 10\n-------------------------------------------\n--  Factory\n--\n--  https://adventofcode.com/2025/day/10\n--  Copy of questions in: aoc_2025_10_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2025_10 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n  input_name : VString;\n\n  max_lights : constant := 10;\n  max_buttons : constant := 20;\n\n  r : array (Part_Type) of VString;\n\n  verbose : constant Boolean := False;\n  do_part_2 : constant Boolean := False;\n\n  procedure Read_Data is\n    c : Character;\n    light, lights : Integer;\n    f : File_Type;\n    buttons : Natural;\n    diagram, test : Integer_64;\n    button_bits : array (1 .. max_buttons) of Integer_64;  --  Light is 0-based.\n    button : array (1 .. max_buttons, 1 .. max_lights) of Boolean;  --  All 1-based.\n    fewest_presses, presses, res_1, res_2 : Natural;\n\n    type Press_Combination is array (1 .. max_buttons) of Natural;\n    type Counters is array (1 .. max_lights) of Natural;\n\n    target : Counters;\n\n    procedure Explore (press : Press_Combination; joltage : Counters; shift : Natural) is\n      ok : Boolean := True;\n      new_button : Integer;\n      new_press : Press_Combination;\n      new_joltage : Counters;\n    begin\n      if verbose then\n        Put (\"Presses: \");\n        for b in 1 .. buttons loop\n          Put (press (b), 2);\n        end loop;\n        Put (\". Jolts: \");\n        for l in 1 .. lights loop\n          Put (joltage (l), 3);\n        end loop;\n        Skip_Line;\n      end if;\n\n      for l in 1 .. lights loop\n        ok := ok and joltage (l) = target (l);\n        if joltage (l) > target (l) then\n          return;\n        end if;\n      end loop;\n      if ok then\n        --  This combination of buttons makes the joltages match.\n        presses := 0;\n        for b in 1 .. buttons loop\n          presses := presses + press (b);\n        end loop;\n        fewest_presses := Min (presses, fewest_presses);\n        return;\n      end if;\n\n      --  From here we know we have an incomplete joltage.\n      --  We try something: press each button individually.\n      for b in 1 .. buttons loop\n        new_button := 1 + (b + shift - 1) mod buttons;\n        for pow in 0 .. 0 loop\n          new_press := press;\n          new_joltage := joltage;\n          new_press (new_button) := new_press (new_button) + 2 ** pow;\n          for l in 1 .. lights loop\n            if button (new_button, l) then\n              new_joltage (l) := new_joltage (l) + 2 ** pow;\n            end if;\n          end loop;\n          Explore (new_press, new_joltage, shift + 1);\n        end loop;\n      end loop;\n    end Explore;\n\n    press_0 : Press_Combination;\n    joltage_0 : Counters;\n\n  begin\n    res_1 := 0;\n    res_2 := 0;\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n\n      light := -1;\n      Get (f, c);  -- [\n      diagram := 0;\n      loop\n        Get (f, c);\n        exit when c = ']';\n        light := light + 1;\n        if c = '#' then\n          diagram := diagram + 2 ** light;\n        end if;\n      end loop;\n      lights := light + 1;\n\n      buttons := 0;\n      loop\n        Get (f, c);\n        case c is\n          when '(' =>\n            buttons := buttons + 1;\n            button_bits (buttons) := 0;\n            for l in 1 .. max_lights loop\n              button (buttons, l) := False;\n            end loop;\n            --  Put ('b');\n            --  Put (buttons,0);\n            --  Put ('(');\n          when ')' =>\n            null;\n            --  Put (')');\n          when '{' =>\n            exit;\n          when '0' .. '9' =>\n            light := Ord (c) - Ord ('0');\n            button_bits (buttons) := button_bits (buttons) + 2 ** light;\n            button (buttons, light + 1) := True;\n            --  Put (button (buttons, l) - 1, 2);\n          when others =>\n            null;\n        end case;\n      end loop;\n\n      if verbose then\n        for b in 1 .. buttons loop\n          for l in 1 .. lights loop\n            if button (b, l) then\n              Put (\"1 \");\n            else\n              Put (\"0 \");\n            end if;\n          end loop;\n          New_Line;\n        end loop;\n      end if;\n\n      for l in 1 .. lights loop\n        Get (f, target (l));\n        Get (f, c);\n      end loop;\n      if c /= '}' then\n        Put_Line (\"Data error on joltage\");\n      end if;\n\n      --  Puzzle 1, light diagram.\n      --  The order of the button presses is not relevant, and two presses are equivalent to zero presses.\n\n      fewest_presses := buttons;\n      --  !!  HAC borks on that : \"for n in Integer_64 range 0 .. 2 ** buttons - 1 loop\"\n      for n in 0 .. 2 ** buttons - 1 loop\n        --  Test all button combinations.\n        test := 0;\n        presses := 0;\n        for b in 1 .. buttons loop\n          if Sim_AND (2 ** (b - 1), Integer_64 (n)) /= 0 then\n            presses := presses + 1;\n            test := Sim_XOR (test, button_bits (b));\n          end if;\n        end loop;\n        if test = diagram then\n          --  This combination of buttons makes the light diagram match.\n          fewest_presses := Min (presses, fewest_presses);\n        end if;\n      end loop;\n      res_1 := res_1 + fewest_presses;\n\n      --  Puzzle 2, joltages.\n      --  It is actually an underdetermined linear equations system\n      --  with integer solutions.\n      \n      if do_part_2 then \n        for b in 1 .. buttons loop\n          press_0 (b) := 0;\n        end loop;\n        for l in 1 .. lights loop\n          joltage_0 (l) := 0;\n        end loop;\n        fewest_presses := Integer'Last;\n        Explore (press_0, joltage_0, 0);\n        res_2 := res_2 + fewest_presses;\n      end if;\n\n    end loop;\n    Close (f);\n    r (part_1) := +\"\" & res_1;\n    r (part_2) := +\"\" & res_2;\n  end Read_Data;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  input_name := +\"aoc_2025_10_mini\";\n\n  Read_Data;\n\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    if do_part_2 then\n      Put_Line (+\"Part 2: \" & r (part_2));\n    end if;\n    --  Part 1: validated by AoC: 477 (mini: 7).\n    --  Part 2: validated by AoC: .\n  end if;\nend AoC_2025_10;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_10.txt",
    "content": "[.##......] (0,1,3,4,6,7,8) (1,2,3,5,6,8) (0,1) (3,5,6,7) (2,5,7) (1,2,3,4,5,7,8) (7) (0,1,3) (0,3,7) (1,4,6) {36,63,29,56,28,48,43,52,23}\n[.##....#] (0,1,2,3,4,5,7) (0,2,3,7) (1,3,5,6) (0,1,2,6) (2,3,5,6,7) (2,4) (0,1,2,3,7) (0,2,3,5,6,7) {171,166,199,75,30,65,170,64}\n[.#.#.] (0,2,3,4) (1,3) (0,2) (1,4) {1,27,1,7,20}\n[#...#] (1,4) (2,3) (0,2,3) (1,2,3) (0,1,4) {7,22,11,11,15}\n[##.#.#.] (1,3,4,6) (4,5) (0,1,3,4) (0,4,6) (1,2,3,4) (1,2,4,5) (0,1,4,5,6) (0,3) (0,2,4,5) {46,44,15,39,72,45,31}\n[.##.] (1,3) (1) (0,3) (0,1,3) (1,2,3) (3) {23,40,20,64}\n[...#] (0,2) (0,1,2) (3) (2,3) (1,2) {27,177,206,19}\n[.###.] (2,3,4) (0,3,4) (0,4) (3) (0,2,3) (0,1,3) {24,3,19,41,20}\n[##.#] (0,1,3) (0,1,2) (2,3) {19,19,14,31}\n[#..#] (0,3) (1,2,3) (0,1,3) {139,13,6,145}\n[.#..##] (0,2,3) (1,4) (1,2,4) (5) (0,1,2,4,5) (4,5) (2) (2,3) {34,30,58,25,36,30}\n[##..#] (0,2,3) (2) (0,1,2,4) {25,5,45,20,5}\n[..#..] (0,3) (0,1) (3) (1,2,4) (0,2) (0,2,4) (1,2,3,4) {35,10,22,23,20}\n[#.#..###..] (3) (3,5,6) (0,1,2,3,4,9) (0,4,5,6) (5,6) (0,1,2,3,5,6,7,9) (1,2,3,4,5,7,8,9) (1,2,3,6,7,8,9) (9) (0,6) (2,3,4,5,6,7,9) (1,2,3,4,5,6,9) (8) {28,40,43,64,44,35,39,5,21,58}\n[.....#.#.] (3,4) (1,4) (0,2,3,5,6,8) (1,4,5,7) (0,3,4,6,7,8) (0,1,2,3,5,8) (2,4,5) (2,5) (2,3,5,8) (6) {24,29,22,43,58,28,19,16,24}\n[#.#.] (0,2) (1,3) {3,14,3,14}\n[#.#...] (1) (0,2,3,4) (1,2,3,5) (3,4) (0,2) (3) (0,1,2,3,5) {31,28,36,57,23,17}\n[#.#...#] (0,2,4,5) (0,1,2,3,4,6) (0,6) (2,3,4,5,6) (0,2,6) (0,3,4,6) {42,11,33,34,42,21,47}\n[.###...#.#] (1,2,3,4,5,7,8) (0,1,2,4,5,6,7,9) (3,5) (0,1,2,3,4,6,7,8,9) (1,2,9) (0,1,2,4,6,7,9) (7) (0,2,3,4,5,6,8,9) {59,58,77,52,67,61,59,60,34,69}\n[##......#.] (1,3,5,6,7,8) (1,2,6,7) (0,6) (0,3,4,5,6,8) (4,9) (0,1,2,3,4,5,6,7,8) (0,3,4,6,8,9) (1,4,6,7) (0,4) (1,2,4,5,8) (1,2,5) {38,41,30,18,50,30,44,27,31,4}\n[.####.#.] (0,4,6,7) (1,2,3) (1,2,3,4,6) (1,5,7) (4,5) (0,1,2,4,5,6) {21,165,163,162,40,4,39,22}\n[.###] (0,3) (1,2) (0,1) (2) {5,5,1,1}\n[...#.#..#] (0,3,4,5,6,7,8) (1,4,6,8) (1,6) (1,2,3,4,5,6,8) (1,2,3,4,5,7,8) (2,3,4,5,8) (0,1,3,7) (0,1,4,5,6) {27,78,35,46,74,54,64,20,58}\n[####..#] (2,4) (3,4,5,6) (2,3,5,6) (0,1,3) (1,2,4,5,6) (0,1,3,5) (0,2,5,6) (1,2,3,4) {33,56,57,48,53,46,36}\n[.##.#] (0,2,3) (0,3,4) (0,1,2,3) (2,4) (0,1) {132,20,31,121,118}\n[#.#.#.#..#] (1,2) (5,7,8) (0,2,3,5,9) (3,4,5,7,8) (1,2,3,7,9) (0,2,9) (2,4,5) (0,2,3,4,5,6,7,9) (0,1,4,6,7,8,9) (1,3,4,6) (0,1,2,4,5,7,8,9) (0,2,3,4,6,7,9) {185,26,193,179,185,183,154,188,37,194}\n[...#..] (2,3,4,5) (2,3) (0,1,3,4) (1,2,5) (5) (0,1) {23,42,42,29,15,33}\n[...#.#] (2,5) (0,1) (0,3,4) (3,5) (4) (1,4) (0,1,2,3) (0,1,2,5) {43,48,41,28,198,42}\n[#####.#] (0,1,6) (0,3,4,5,6) (0,1,5) (1,4,6) (0,2,4,5) (0,1,2,3) (1,2,3,6) (0,1,4,5,6) (0,2,3,4) {96,62,44,46,75,71,60}\n[.#..###..] (0,2,3,5,8) (2,3,5,6) (6,7) (0,3,4,8) (1,2,3,4,8) (4,5,8) (1,2,4,5,6,7,8) (2,3,4,5,6,7,8) (1,2,4,5,8) (0,6) (0,2,7) {41,46,237,193,211,214,195,187,219}\n[#..#.##.#.] (5,6) (8) (1,3) (0,1,3,5,6,8,9) (6,9) (0,2,4,5,6,7,8,9) (1,2,3,6,8) (2,3,4,5,6,8,9) (1,2,4,5,7) {21,47,49,49,42,64,61,24,56,45}\n[#.##....#] (0,1,4,5,6) (0,2,4,5,6) (1,2,3,4,5,6) (0,1,2,5,7,8) (3,6,7) (0,2,4,5) (1,3,5,6,7,8) (0,4,6,7) (2,4,8) (2,5,6,7,8) {37,37,58,24,51,69,68,43,51}\n[##..] (1,2) (3) (1,3) (0,3) (0,2,3) (0,1) {140,133,7,34}\n[.#..#] (1,2,4) (3,4) (2,3,4) (0,4) {20,19,25,11,50}\n[##..####.] (0,2,6,8) (1,2,3,5,6,7) (4,6,7,8) (0,2,3,4,5,6,7,8) (2,4,6,8) (1,2,3,4,5,6,7,8) (3,8) (5) (0,1,6,8) (2,4,7,8) {15,25,37,25,48,22,58,43,63}\n[.#.#####] (0,1,3,4,6) (2,3,5,6,7) (0,5,6,7) (4,7) (0,2,3,4,6,7) (0,1,2,3,5,6,7) (0,1,5) (0,2,6,7) {48,36,47,56,33,43,60,61}\n[##..#.#] (0,1,2,4,6) (2,6) (2,4,6) (0,1,5) (1,3,4,5) (0,2,3,4,6) (1,3,4,5,6) (2,3,5) (3,4) {44,46,150,42,44,44,151}\n[##.#.] (1,3,4) (0,2,4) (0,2,3) (0,1,4) (0,1,3) (1,3) {41,36,30,44,33}\n[..##.#....] (0,1,2,4,5,7,8,9) (0,3,4,8) (0,1,2,3,4,5,8,9) (2,7,8,9) (0,1,2,3,5,8,9) (0,2,4,5,7,8,9) (3,4,8) (0,1,2,3,5,6) (1,6) (0,1,3,4,9) (0,2,4,7) {265,241,259,62,261,233,13,231,262,264}\n[#.....#.] (3,4,5,7) (2,4,6,7) (0,1,4,5,6,7) (1,5,6) (4,6) (0,5,7) (0,3) (1,3,5,7) (0,3,4,5,6,7) {59,31,5,34,49,65,68,51}\n[##.#] (0,1) (0,1,3) (1,2) (1,3) {28,52,16,20}\n[.#.#] (0,3) (3) (2,3) (0,1) (1,2,3) (2) {16,25,49,48}\n[.#......#] (0,3,4,5,6,7,8) (2,4,5) (0,1,2,4,6,7,8) (0,2,3,4,5,6,8) (1,2,4,8) (3) (0,1,5) (0,1,2,5,6,7) (3,5,6) (1,8) {49,64,37,31,34,51,39,29,43}\n[..#.#..] (2,4) (2,5,6) (4,5,6) (2,3,4,6) (0,1,3,4,5,6) (0,3,4) (1,2,4,5,6) (0,2,3,4) (0,2,3,4,5,6) {34,7,54,50,73,26,42}\n[#...#] (1,2,3,4) (0,1,3) (0,1,2,3) {35,43,25,43,8}\n[..#.#..#..] (0,2,4,6) (2,4) (5,6,7,9) (0,1,2,3,4,6,7,8) (1,2,3,8,9) (0,1,4,5,6,8,9) (3,4,7,9) (0,2,5,7,8,9) (3,4,5,6,7,8) (2,3,5,6,7,8,9) (1,2,3,4,5,6,7,9) (4,9) {46,48,71,47,69,77,71,62,66,95}\n[.#.#.###.] (0,6) (0,2) (5,8) (4,7,8) (1,2,3,5,8) (0,2,7) (1,3,5,6,7) {41,28,44,28,5,48,25,20,45}\n[#.###.##] (1,2,3,5,6,7) (2,4,6,7) (5,6,7) (0,1,2,4,5,6) (0,2,3,4,6,7) (3,4,5,6) (1,2,3,4) {12,28,55,47,62,27,54,38}\n[...#.#####] (0,4,5) (0,1,8,9) (6,8,9) (0,1,3,4,5,6,7,8) (0,3,7) (0,5,7) (3) (4,6,9) (5,7) (1,2,5,9) (0,1,2,5,6,7,8,9) (3,4,5,6,8) (0,1,2,3,4,5,6,7,8) {43,42,29,38,32,67,33,46,36,30}\n[..#.#####] (2,3,5,6,7) (3,7) (0,5,7,8) (0,1,2,4,5,6,7) (0,1,3,4,5,6,7,8) (0,1,2,3,4,5,7,8) (0,2,3,4,5,6,7) {58,23,30,51,38,59,30,76,38}\n[.##.....#.] (0,3,5) (3,6) (1,3,4,5,6,7,9) (0,1,2,3,4,6,7,8) (0,2,4,5,6,7,8) (0,2,4,5,7,8) (1,2,3,5,6,7,9) (0,3,9) (0,5,6) (0,1,2,3,6,8,9) {81,59,50,114,49,58,87,57,42,61}\n[##....] (0,1,2,3,5) (0,1,2,4) (2,4) (1,3) (0,1,3) {26,42,18,40,7,11}\n[.##.#...#.] (4,5,9) (0,1,4,7,8) (3,5,9) (0,9) (5,6) (0,1,2,4,5,7,8,9) (3,5) (1,2,6,9) (1,3,4,5,6,8,9) {29,48,23,23,46,51,30,25,30,62}\n[.#..#.#] (2,6) (2,3,5,6) (0,1,2,3,4,5) (0,1,6) (0,5) (0,3,4,5,6) (1,3,4) {48,51,46,56,47,41,56}\n[.#..#] (0,4) (1,3,4) (0,2,3,4) (1,4) (0,2,4) (2,3,4) (0,2,3) {39,20,30,33,45}\n[#.##.] (2,4) (1,2,4) (0,2,3) {111,5,134,111,23}\n[.##.] (0,1,2) (1,2) (0,1,3) {11,14,13,1}\n[..#.#.] (0,4) (0,2,5) (1,3) (0,1,3,4,5) (0,1,2,3,4) {61,36,39,36,41,22}\n[.##.] (0,1,2) (0) (2) (0,2) (2,3) (3) {32,15,160,136}\n[##.###] (1,3) (0,4,5) (1,2,4) (1,2) (2) (0,2,3,4) (0,1,3,5) {23,37,41,11,36,19}\n[.##.] (2,3) (0,1,3) (0,2,3) (0,1) {9,3,14,16}\n[...##.####] (0,1,3,5,6) (2,6,7,8) (1,2,4,5,6,7,8,9) (0,1,5,7,8,9) (0,3,4,7,8,9) (1,4,8) (0,2,3,6,7,9) (1,4,5,7,8,9) (0,2,5,8) (1,6,8,9) (0,1,2,4,6,7) (0,1,2,3,4,5,6,7) {72,112,79,37,80,63,96,108,88,75}\n[#.##..#] (0,3) (0,6) (2,4,5) (0,3,4,5,6) (0,2,4,5,6) (2,4) (0,4) (0,1,2,3,4,5) {36,10,20,24,29,22,9}\n[..##.###.#] (5,6,7,8) (1,4,7) (0,5,9) (7,9) (1,2,3,4,5,6,7,8,9) (1,2,3,6,8) (3,7,8) (4,6,9) (1,2,3,6,9) {11,26,21,23,37,27,43,27,19,54}\n[...####..#] (1,2,5,7,8) (0,2,6,7) (1,2,8,9) (0,1,3,4,5,9) (0,2,4,5,6,7,8) (7) (1,4,7) (1,2,3,5,7,8) (0) (1,6,9) (1,2,3,4,5,6,7,8) (0,4,5,7,8,9) (0,1,3,4,5,6) {49,58,68,37,50,67,60,92,62,24}\n[#####..#] (0,3,7) (0,1,2,3,4,5,7) (0,2,3,4,6) (0,2,4,5) (0,4) (1,2,4,5,6,7) (0,1,3,5,6) (0,2,5,6,7) {82,36,60,55,63,53,47,52}\n[##.###..#] (2,4,8) (2,3) (0,4,5,8) (0,1,2,3,5) (1,2,4,7) (6,7,8) (0,2,4,6,8) (0,1,2,4,5,6,8) (0,1,3,4,5,6,7) (0,3,7,8) {55,42,60,14,66,35,50,40,64}\n[###..#####] (1,2,4,5,6,7,8) (0,1,2,5,6,7,8,9) (2,4) (0,4,6,8) (2,3,4,6,9) (1,3,4,5,6,7,8,9) (0,1,2,3,6,7,9) (2,4,5,6,7) {23,34,192,173,193,28,192,41,26,178}\n[.#..#] (1,4) (2,3) (0) (1) (1,2,3) {14,42,18,18,12}\n[.##..] (0,3,4) (0,2) (1,3,4) (1,3) (1,4) (0,1,2,3) (1,2,3,4) {29,44,36,45,47}\n[#....#..##] (3,5,9) (2,3) (1,2,3,4,5,7,8,9) (4,5,6) (0,1,2,4,6,8,9) (0,1,2,3,4,7,9) (3,6) (0,1,2,3,4,8) {28,44,64,76,146,135,137,17,43,54}\n[..###.#..] (0,2,5,7) (0,1,3,5,6) (4) (1,8) (0,1,4,6,7,8) (0,2,3,6) (0,1,2,6,7,8) (0,1,2,5,6,7) (1,5,7,8) {36,67,25,6,25,27,31,48,63}\n[##.....] (1,3,5,6) (0,3) (0,5) (3,4) (1,2) (0,2,3,4,6) (0,1,5,6) (1,2,3,6) {13,19,21,39,18,1,16}\n[##.####] (0,1,5,6) (0,2,4) (1,3,6) (0,1,2,3,5,6) (1,2,3,4,6) {222,226,215,209,30,202,226}\n[.##.#] (3,4) (2,4) (1,2,3,4) (0,2,4) (0,2) {35,12,60,17,50}\n[...#..#] (2,3) (0,2,3,5,6) (1,2,4,5,6) (1,4,5) (2,3,4,5) (1,3) {18,204,46,33,202,220,38}\n[..##.#.#.#] (1,3,4,6,8) (2,5,7,9) (5,8) (2,4,5,7,8) (1,2,3,4,5,6,7) (0,1,3,4,5,6,7,8,9) (1,5,6) (0,1,8,9) (2,5,6,7,9) {9,42,53,34,44,54,48,54,33,33}\n[###..##.] (2,6) (0,1,3,4) (0,1,2,3,4,5,6) (3,4) (2,4,5,6,7) (1,2,4,6) (5,7) (0,1,3) {4,9,19,9,16,14,19,14}\n[#.#######.] (2,8,9) (0,5,6) (8) (1,2,4,6,7,8,9) (2,3,4,6,9) (0,1,2,4,6,8) (0,2,3,4,9) (0,1,2,3,5,7,8,9) (0,1,5,6,7,8) (1,3,5,7,8) (0,2,3,6) {35,15,60,42,39,4,31,9,30,44}\n[.##..##..] (0,5,6) (1,3,4) (0,1,3,5) (3,5,6,7) (0,1,5,7) (3,4,5,7,8) (1,2,5,6,8) (0,1,2,3,7) (0,2,3) {44,43,22,70,34,68,36,57,25}\n[.#...] (2) (1,2,3) (0,1) (3,4) (0,3,4) (1) {1,11,7,25,18}\n[..##] (0,3) (1,2,3) (0,2) (0) (1,3) {24,10,8,16}\n[.##.] (1,2,3) (1,3) (0,3) (0,1,2) (0) {44,28,16,40}\n[..#......] (1,3,4,5,6,7,8) (0,2,3,4,6,7,8) (0,1,5,6,8) (2,3,4,8) (0,1,2,5,6,8) (5,6) (3,4,6,8) (0,1,2,3,4,5,8) (0,2,3,6,8) (0,7) {51,42,37,24,16,52,64,5,63}\n[#.#.#] (1,2) (1,3) (0,1,2) (3) (1,4) {16,41,25,20,5}\n[.########.] (0,1,3,9) (0,1,2,7) (0,1,2,3,4,6,7,9) (0,2,3,4,5,8,9) (2,7) (0,1,2,3,6,8) (0,1,2,3,4,5,8,9) (0,1,2,5,7) (0,1,3,4,5,6) (1,2,4,5,6,9) (2,4) {79,87,96,54,60,50,48,42,26,44}\n[#.#.] (0,3) (1,2,3) (2,3) (2) {11,18,47,48}\n[#...] (1,2) (1,3) (2) (0,2,3) (0,3) (0,1,2) {36,27,39,36}\n[###.#.#.##] (0,1,2,4,6,8,9) (1,2,3,4,5,6,7,8,9) (0,1,3,5,6,8) (0,1,2,3,4,5,7) (0,1,2,3,4,6,7,8,9) (1,2,3,4,5,6,8) (0,1,2,5,6) (6,7,9) (4,5) (0,1,3,4,5,6,7,8,9) {71,81,42,58,57,91,252,217,54,213}\n[#.#####.] (0,2,3,4,5,7) (0,2,3,4,5,6) (3,5,6,7) (2,4,5) (2,3) (1,7) (0,2,3,4,5,6,7) {44,19,64,59,54,59,30,51}\n[###..] (0,2,4) (0,1,2,3) (1,4) {25,135,25,13,134}\n[#..###.#..] (3,4,6) (2,5,9) (8) (0,3,4,5,6,7,8) (0,1,2,4,6,8) (0,2,8) (0,2,3,5,6,7) (1,2,5,7,8) (2,3,4,5,6,7,8,9) (0,5,6,7,8) (1,2,3,4,5,6,7) (1,3,4,5,7,9) {20,27,175,49,47,190,41,40,39,171}\n[..#..##..] (0,3,4,5,6,8) (4,5,6,8) (3,6,8) (5,8) (0,1,2,4,5,6,8) (0,1,2,7) (0,2,3,4,7,8) {39,19,28,28,47,40,46,9,57}\n[#####] (0,1,3) (0) (0,1,2,3) (2,4) (3,4) (2) (0,1,3,4) {247,47,35,62,32}\n[..##..##] (0,1,3,4,5,6) (0,3,6) (2,5,6) (1,2,4) (1,2,3,4,5,7) (0,2,3,4,6) {21,19,30,23,25,27,36,2}\n[#...#.####] (1,2,3,7,8,9) (2,4,6,7,8) (0,1,2,3,4,7,8,9) (0,1,5,7,9) (0) (2,9) (1,2,5,8) (0,3,4,6,8) (0,1,2,3,5,6,7,9) (4,7) {56,47,58,52,41,25,32,47,53,47}\n[#...##] (1,2,4,5) (1,2,4) (1,2,3,5) (0,4) {1,21,21,14,8,16}\n[...#] (0,2) (1,2) (1,3) (0,1,2) (3) {21,19,33,19}\n[.#.#..] (2,5) (0,2,3,5) (1,2,3,5) (3,4,5) (0,1,4,5) {13,14,40,27,6,46}\n[#.#.#.###] (0,3,4,7) (2,3,5,7,8) (0,1,3,7,8) (0,5,7) (2) (2,5,6,7,8) (0,1,4,7) (3,4) {29,11,180,33,22,44,17,60,35}\n[##.######] (0,1,3,4,5,6,7,8) (0,3) (1,2,3,4,5,6,8) (0,3,5,6,7) (0,2,3,4,5,6,7) (0,1,2,4,5,7) (2,3,4) {58,27,40,56,46,50,37,42,14}\n[.#...] (0,1,3) (1) (0,4) (0,2,3) (1,2) (0,1,2) {13,33,18,9,3}\n[.#..###] (2,5,6) (0,1,2,3,4,5) (0,2,3,5,6) (1,4,5,6) (1,2,4,6) {19,33,40,19,33,25,31}\n[.#..#####.] (1,4,5,6,7,8) (1,3,5,9) (0,1,2,3,6,7,8,9) (2,5,6) (0,1,2,3,6,8) (3,7,9) (2,4,6,8,9) (1,3,6,7,8) {26,75,40,62,27,39,75,57,69,44}\n[##.#..] (2,3,4,5) (1,2,3) (3,4) (1,3) (0,5) {176,21,36,47,26,195}\n[##...#] (0,1,2,4,5) (1,4) (0,2,3,5) (0,1,2,3) (1,3,4,5) (0,3,4,5) {31,34,25,36,31,27}\n[#..##.#] (0,1,3,5,6) (1,2,5,6) (1,3,4,5,6) (0,1,2,3,4,5) (0,1,3,5) {27,56,30,45,37,56,30}\n[.##...##] (1,3,4,5,6,7) (1,2,6,7) (0,3,6,7) (0,4,5,6) (1,3,4,6,7) (1,2,5,6) {35,225,212,29,32,37,260,224}\n[...##.#.] (3,4,6) (3,4,5,6) (1,2,4,6) (0,1,2,7) (0,1,3,4,6,7) (0,1,3,6) {31,43,20,54,54,12,66,19}\n[....#.#..#] (4,7,9) (2,8) (0,2,3,4,6,7,9) (4,5,6,7,8,9) (0,1,2,3,4,5,8) (0,1,2,3,5,7,9) (2,6,8,9) (2,3,4,8) (1,8) (0,1,2,4,5,6,7,8) {7,20,36,14,34,15,33,23,60,34}\n[#.##...] (1,4) (0,1,3,4,6) (0,4) (3,4,6) (1,2,4,6) (1,2,6) (0,5) {46,39,13,15,56,19,28}\n[#.#.##.] (5,6) (4,6) (0,2,3,4,5,6) (4,5) (0,1,5) (0,1,2,4,6) (2,3,5) (1,2,3) (1,5,6) {32,40,29,14,39,61,55}\n[####..#..] (4,8) (1) (6,7) (0,2,5,6,7,8) (0,1,2,4,6,8) (1,2,8) (0,1,3,5,7) (0,1,2,4) (0,4,5,7,8) (2,3,5,6) (0,5) {61,56,61,33,31,64,38,32,49}\n[###.] (1,2,3) (0,1,3) (1,3) (0,2,3) (0,3) (0,2) {69,20,34,51}\n[..#...] (1,2) (5) (1,2,3,5) (0,2,4,5) (0,1,2,4) (0,3,5) (2) {38,40,55,27,22,45}\n[#.#.#..] (1,2,3,4,6) (0,1,4,5,6) (0,1,2,4,5) (2,4,5) (2,3) (3,4,6) (2,3,4,5) (0,1,2,3,4,5) (5,6) {19,24,49,36,44,37,22}\n[..###..] (1,3,6) (0,4,5) (4,5,6) (0,3,5,6) (0,4,6) (0,2,4) (1,2,3,4,5,6) {42,36,25,53,49,43,75}\n[.#####.] (1,2,4,6) (0,1,2,3,6) (0,2,3,4,5) (0,4,5,6) (1,3,4,6) {27,26,20,22,41,21,42}\n[#######.##] (4,6) (1,3,4) (0,3,4,5,8,9) (1,2,4,5,6,7) (2,3,4,6,7,8,9) (4,8) (0) (0,1,2,3,4,5,9) (0,2,3,4,5,8) (0,1,3,4,5,6,7,8,9) (0,1,4,5,6) {60,40,41,48,86,67,43,19,41,28}\n[..#..#..] (1,2,4,5,6) (6) (0,3) (0,3,4,7) (0,2,4,5,6,7) (1,7) (0,1,2,4,5,6) {31,17,23,13,33,23,32,20}\n[.##..#] (1,2,4,5) (1,2) (2,3,4,5) (1,4) (0,3) (5) {20,29,17,26,33,18}\n[.##.#.#] (1,2,4,6) (0,1,3,4) (0,6) (0,1,2,3,5) (1,4,5,6) (0,2,3,6) (1,3) (2,4,5) {36,47,49,42,35,36,30}\n[.##..##.#] (2,6) (0,3,4,5,6,8) (0,1,4) (3) (0,4,6,8) (1,8) (0,2,4,5,6) (2,3,4,5,6,8) (1,4) (4,5,8) (0,3,6,7,8) {36,46,18,30,64,23,37,0,49}\n[......##] (0,1,2,4,5,7) (2,3,7) (1,3,4,5,6,7) (2,3,4,7) (5,7) (1,4,7) (0,7) (0,1,4,7) {30,37,14,8,39,21,4,55}\n[.#..###.] (1) (4,6) (0,1,2,3,4,7) (0,1,4,7) (2,3,7) (0,1,5,7) (1,4,5) (0,3,5,6,7) (0,2,6,7) (0,1,2,3,5) {47,38,32,16,26,22,39,44}\n[##..] (0,2) (0,1,3) (1,2) {28,38,26,20}\n[#..###.] (0,1,2,3,5) (2,3,6) (0,3,4,6) (0,2,4,6) (0,1,6) (5,6) {43,20,39,44,23,19,53}\n[.#.##...] (0,4) (0,2,3,4,5,7) (1,3,4) (1,2,3,5,6,7) (0,1,3,4,7) (1,2,4,5,6,7) (3,4,6) (1,2,5,6) (1,3,6,7) (1,2,3,5) {22,81,47,79,52,47,66,50}\n[####] (0,1,2,3) (1,3) {12,15,12,15}\n[##..##.#] (0,1,2,3,5,6) (1,2,3,4,6,7) (1,2,6) (1,4,5,7) (2,5) (2,4) (0,2,3) (0,1,2,3,4) (6) (6,7) {22,62,78,42,51,26,52,27}\n[##..#.###] (3,4,5,6,8) (1,5,7) (0,3,4,5,6,7,8) (0,1,3,5,7) (0,1,2,3,5,6,8) (2,3,4,5,7) (0,1,2,3,5,6,7,8) {45,42,41,73,46,88,51,58,51}\n[###.] (1,2,3) (0,1,2) {11,29,29,18}\n[#..##.] (0,2,5) (1,4) (1,2,4) (1,2,4,5) (4,5) (1,3) (3,5) (0,1,5) {29,35,30,25,24,59}\n[##...#] (2) (1,4,5) (0,2,3,5) (0,1,4) (0,1,2,3,5) {33,31,39,25,25,42}\n[###.] (0,3) (3) (0,2) (0,1) (1,3) {17,17,7,18}\n[..##..#.] (0,6) (0,2,3,4,5,7) (0,2,3,5,6) (0,4,5) (0,1,2,3,4) (0,1,2,3,6) (5) (3,5) (0,7) {72,23,42,43,38,45,27,8}\n[..###.#.#] (0,1,2,3,4,5,6,8) (1,2,7,8) (3,4,6,7) (0,2,4,5,6,7) (0,1,2,4,5,6,7) (2,3,4,6,7,8) (0,1,4) {29,36,52,175,200,19,190,206,37}\n[.#.###] (0,4) (0,1,3,5) (2,3) (0,1,3) {31,26,5,31,5,7}\n[#.##] (0,1) (1,3) (1,2) (0,2) (0,1,3) (2,3) {35,37,27,16}\n[.....###.] (4,5,6) (0,2,6) (0,2,3,4,6,7,8) (0,2,3,4,7,8) (1,6,8) (0,2,5,6,7) (4,6,7) (0,5,6,7) (3,4) (3,7) (1,2,3,5,6,7,8) {62,9,54,42,56,36,85,68,34}\n[#....##] (4) (1,2,3,4) (0,1,3,4,5,6) (0,3,4,5) (0,5,6) (2,3,4) (0,1,4,5,6) (3) (0,1,2,4,6) {53,26,21,65,64,44,33}\n[..###] (0,1,3) (2,3,4) (0,2,4) (0,1,2) {53,38,39,22,19}\n[###...##..] (3,5,7,8,9) (8,9) (3,4,6,8,9) (0,3,7,9) (2,4) (1) (0,1,2,4,6,7,8,9) (0,1,2,6,7) (1,3,4,5,6,8,9) (1,2,4,5,7,9) (0,1,3,4,5,8,9) (2,4,5,7) (1,5,6,9) {34,63,41,50,64,53,33,64,52,88}\n[##.##..#.#] (4,6) (2,9) (0,1,2,3,4,5,7,8) (0,1,4,5,6,7) (0,1) (0,1,3,4,5,6,7,8) (2,6,9) (3,4,5,7,8,9) (0,2,3,8) (0,1,2,3,4,6,7) (2,7,9) (0,1,3,6,7,8) (2) {84,67,61,63,75,47,73,79,54,34}\n[.#.#..#...] (0,2,3,4,5,6,8,9) (1,2,3,4,6,9) (0,2,3,6,7,8) (0,1,3,6,7,8) (0,2,4,5,9) (1,3,5,6,9) (0,1,3,6,8,9) (1,2,6,7,8) (0,1,4,5,6,7,8) (4,6,7) (4,9) (0,1,2,3,4) {61,72,50,71,51,31,90,44,70,61}\n[#.#.#.] (1,3,4) (2,5) (0,1,2,4) (5) (0,1,3,4) (0,1,2,4,5) (2,4) {36,50,34,34,58,140}\n[.#.....#.] (4,5,6,7) (5) (0,1,4,5,6,8) (1,2,3,4,6,7,8) (0,2,6,7) (4,7) (1,6,7) (0,1,3,4,5,8) (1,7) {31,43,34,20,56,30,58,71,31}\n[####.#.] (4,6) (0,1,2,3,4,5,6) (1,2,6) (2,3,4,5) (0,1,2,3,5) {28,48,54,34,26,34,40}\n[...#.#...] (1,8) (0,2,4,5,6,8) (1,3,5,8) (0,2,4,5,7) (0,1,3,4,8) (0,3,5,6,7,8) (0,7,8) (0,6,7,8) {69,38,25,31,30,51,36,58,83}\n[.#...###.] (2,3,7) (0,3,4,5,8) (1,2,5) (1,2,3,4,5,7,8) (1,3,4,5,6,7,8) (0,1,2,3,4,5,6,7) (0,1,4,8) (2,3,6,7,8) {36,45,56,58,46,46,19,45,42}\n[##.#####] (0,1,2,3,5) (0,1,3,4,7) (1,3,4,5,6,7) (4,5,6) (2,3,6) (2,3,4,5,6,7) (1,4,5) (0,2,3,4,5,6,7) (2,7) {48,181,46,185,198,203,169,172}\n[#.#####.#] (2,4,5,6,7,8) (0,2,5) (1,3,4,6,7) (0,1,2,3,5,6,7,8) (0,2,3,4,5,6,8) (1,4,5,6,7,8) (0,1,2,7) (3,8) (0,2,5,6,8) {60,229,73,56,213,231,240,242,234}\n[.....#] (0,2,4) (1,2,3,4) (2) (0,1,2,4) (1,2,4,5) (5) (0,2,3,4,5) (3,4) {25,26,71,32,67,28}\n[.#.##.####] (0,2,3,4,6,7,8,9) (5,6,7,8) (1,2,3,4,6,7,9) (0,3,7,8,9) (0,2,3,5,7,9) (2,4,7) (0,1,2,3,4,6,7,9) (0,1,3,6,7) (0,3,8) (2,3,6,9) {65,49,53,83,40,22,67,88,32,53}\n[.###.] (0,2,3,4) (1,4) (2,3,4) {20,12,22,22,34}\n[..#..#] (0,1,2) (0,1,3,4,5) (0,1,2,5) (0,4) (1,3,5) (2,3,4,5) (0,1) {45,50,19,23,18,23}\n[.##.##...] (3,7) (0,1,2,3,5,6,7) (1,2,3,4,6,8) (1,2,5,8) (1,3) (0,1,2,5,6,7) (0,1,2,3,4,5,6,8) (0,3,5,7,8) (0,4,5,8) (4,7) {217,237,232,233,38,236,213,202,64}\n[###..#.] (0,3,4) (0,1,2,3,4,6) (3,4,5,6) (0,1,3,6) (0,1,5) (0,2,4) (3,4) {61,46,20,73,66,39,47}\n[#.#.#...] (0,1,2) (0,1,3,4,5,7) (2,3) (0,2,5,7) (3,4,5,6) (0,1,2,3,6) (2,4,5,6,7) {16,15,163,38,138,139,153,132}\n[#.###.] (1,3) (1,3,5) (5) (0,1,5) (0,2,3,4,5) (2,4,5) (2,3,5) (0,1) {23,19,34,32,26,47}\n[..####.] (3,4,6) (2,3,4,5) (0,3,5) (3,5) (1,2,4,5) (1,3,4,5) (3,4) (0,6) {18,8,26,63,63,34,32}\n[..##.#] (1,2,4) (0,1,2,5) (2,3,5) (0,1,2,4,5) {152,172,184,12,28,164}\n[.##....#] (1,2,4,5,6) (1,2,4) (0,1,2,3,5,6,7) (0,1,2,3,4,5) (3,5,6) (0,1,6) (3,5,7) (0,3) (1,2,4,5) {42,68,53,45,35,69,49,28}\n[..#.##] (2,4,5) (0,1,4) (1,4,5) (3,5) (1,2,3,4,5) (0,1,3,4) {29,200,26,46,209,199}\n[#.#.] (0,2) (1,3) {11,6,11,6}\n[.##......#] (1,3,4,6,8,9) (1,2,9) (0,1,3,4,7,8) (2,4,5,6,7,8,9) (0,1,2,3,4,7,8,9) (0,4,9) (6,7,8) (0,1,2,3,5,6,8,9) (0,2,3,5) {74,67,166,73,187,143,149,152,180,189}\n[##.####..] (2,4,5,7,8) (5,7) (0,1,3) (0,1,2,3,4,5,6,7) (1,2,4,5,7,8) (0,1,3,4,5,6) (0,1,2) (0,2,5,6,7,8) {54,58,56,44,63,68,40,51,33}\n[..#..] (0,1,3) (2,3,4) (1,2) (3,4) (0,4) (1,2,3,4) {21,32,27,29,22}\n[#..####] (0,3,5,6) (2,3,5) (1,3,4) (1,2,4) (0,4,5) (2,3,4,5) {9,24,14,28,34,18,0}\n[..#.#...#] (0,2,5) (1,3,6) (3,4) (1,2,7) (1,2,3,4,5) (0,2,4,7,8) (4,6) (0,3,4,5,6,7,8) (0,2,3,5,7,8) {41,32,60,52,58,50,26,32,26}\n[.##.##.#] (0,3,4,7) (0,7) (1,2,3,4,6) (2,6) (1,2,3,4) (0,1,2,5,6,7) (1,3,5,7) (0,2,3,6) {36,7,10,21,14,5,10,37}\n[#####.#.] (0,1,2,3,4,5) (1,2,6) (0,1,2,3,5,7) (3,7) (0,1,2,7) (5,6) (6) (0,3,6) (1,2,4) (0,5) {219,62,62,53,18,203,35,34}\n[#.###] (0) (0,1,2,4) (0,2) (1,2,4) (0,3) (0,1,3) (3,4) {200,188,30,185,17}\n[#..#..] (1,4) (0,3) (0,2,3,4) (0,2,4) (1,4,5) (0,5) {34,20,21,9,41,19}\n[#.#..] (2,4) (3) (0,1,4) (1,2,4) {8,10,12,4,20}\n[...#####.] (1,4,5,6,7,8) (1,4) (0,1,2,3,6,7,8) (2,5,6) (0,3,4,5,7,8) (1,2,3,5,7,8) (0,1,2,4) (1,4,8) (0,5,7,8) {26,53,208,23,36,206,218,40,43}\n[####.##.#] (0,3,5,6,8) (3) (2,3,5,6,7,8) (0,1,2,3,6,7,8) (1,2,3,8) (0,1,2,8) (0,1,2,3,4,6,8) (0,2,3,4,6) (0,5,6,7,8) (0,2,3,7) (2,3,8) {101,50,99,117,34,40,81,50,99}\n[....##] (0,1,2,3) (1,5) (0,3) (0,1,2,3,4) (0,1,4,5) (0,2,3,4,5) (4,5) {217,191,198,217,194,18}\n[##.##.] (1,4,5) (0,1,3,4) (0,2) (0,4) {7,8,2,3,10,5}\n[#...#...] (0,2,4,7) (0,1,2,4,5,6) (0,1) (3) (0,2,4) (1,2,5,6) (0,1,2,3,5,6) (1,2,3,5,6,7) (2,5) (1,2,3,5) {32,56,65,50,17,56,42,10}\n[...#.#..] (0,3,4,5) (2,3,4,5,6,7) (2,4,6,7) (2) (0,1,4,5,7) (0,1,2,4,5,6) {34,21,44,22,56,43,28,37}\n[#..#.#....] (0,1,2,3,4,6,7,8) (0,7,8,9) (2,5,6) (3,4,7,9) (0,1,2,3,5,6,7,8,9) (0,2,5,6,9) (3,8) (1,5,7,8,9) {213,24,58,30,26,47,58,209,200,212}\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_10_mini.txt",
    "content": "[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}\n[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}\n[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_10_questions.txt",
    "content": "--- Day 10: Factory ---\n\nJust across the hall, you find a large factory. Fortunately, the Elves here have plenty of time to decorate. Unfortunately, it's because the factory machines are all offline, and none of the Elves can figure out the initialization procedure.\n\nThe Elves do have the manual for the machines, but the section detailing the initialization procedure was eaten by a Shiba Inu. All that remains of the manual are some indicator light diagrams, button wiring schematics, and joltage requirements for each machine.\n\nFor example:\n\n[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}\n[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}\n[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}\n\nThe manual describes one machine per line. Each line contains a single indicator light diagram in [square brackets], one or more button wiring schematics in (parentheses), and joltage requirements in {curly braces}.\n\nTo start a machine, its indicator lights must match those shown in the diagram, where . means off and # means on. The machine has the number of indicator lights shown, but its indicator lights are all initially off.\n\nSo, an indicator light diagram like [.##.] means that the machine has four indicator lights which are initially off and that the goal is to simultaneously configure the first light to be off, the second light to be on, the third to be on, and the fourth to be off.\n\nYou can toggle the state of indicator lights by pushing any of the listed buttons. Each button lists which indicator lights it toggles, where 0 means the first light, 1 means the second light, and so on. When you push a button, each listed indicator light either turns on (if it was off) or turns off (if it was on). You have to push each button an integer number of times; there's no such thing as \"0.5 presses\" (nor can you push a button a negative number of times).\n\nSo, a button wiring schematic like (0,3,4) means that each time you push that button, the first, fourth, and fifth indicator lights would all toggle between on and off. If the indicator lights were [#.....], pushing the button would change them to be [...##.] instead.\n\nBecause none of the machines are running, the joltage requirements are irrelevant and can be safely ignored.\n\nYou can push each button as many times as you like. However, to save on time, you will need to determine the fewest total presses required to correctly configure all indicator lights for all machines in your list.\n\nThere are a few ways to correctly configure the first machine:\n\n[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}\n\n    You could press the first three buttons once each, a total of 3 button presses.\n    You could press (1,3) once, (2,3) once, and (0,1) twice, a total of 4 button presses.\n    You could press all of the buttons except (1,3) once each, a total of 5 button presses.\n\nHowever, the fewest button presses required is 2. One way to do this is by pressing the last two buttons ((0,2) and (0,1)) once each.\n\nThe second machine can be configured with as few as 3 button presses:\n\n[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}\n\nOne way to achieve this is by pressing the last three buttons ((0,4), (0,1,2), and (1,2,3,4)) once each.\n\nThe third machine has a total of six indicator lights that need to be configured correctly:\n\n[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}\n\nThe fewest presses required to correctly configure it is 2; one way to do this is by pressing buttons (0,3,4) and (0,1,2,4,5) once each.\n\nSo, the fewest button presses required to correctly configure the indicator lights on all of the machines is 2 + 3 + 2 = 7.\n\nAnalyze each machine's indicator light diagram and button wiring schematics. What is the fewest button presses required to correctly configure the indicator lights on all of the machines?\n\n--- Part Two ---\n\nAll of the machines are starting to come online! Now, it's time to worry about the joltage requirements.\n\nEach machine needs to be configured to exactly the specified joltage levels to function properly. Below the buttons on each machine is a big lever that you can use to switch the buttons from configuring the indicator lights to increasing the joltage levels. (Ignore the indicator light diagrams.)\n\nThe machines each have a set of numeric counters tracking its joltage levels, one counter per joltage requirement. The counters are all initially set to zero.\n\nSo, joltage requirements like {3,5,4,7} mean that the machine has four counters which are initially 0 and that the goal is to simultaneously configure the first counter to be 3, the second counter to be 5, the third to be 4, and the fourth to be 7.\n\nThe button wiring schematics are still relevant: in this new joltage configuration mode, each button now indicates which counters it affects, where 0 means the first counter, 1 means the second counter, and so on. When you push a button, each listed counter is increased by 1.\n\nSo, a button wiring schematic like (1,3) means that each time you push that button, the second and fourth counters would each increase by 1. If the current joltage levels were {0,1,2,3}, pushing the button would change them to be {0,2,2,4}.\n\nYou can push each button as many times as you like. However, your finger is getting sore from all the button pushing, and so you will need to determine the fewest total presses required to correctly configure each machine's joltage level counters to match the specified joltage requirements.\n\nConsider again the example from before:\n\n[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}\n[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}\n[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}\n\nConfiguring the first machine's counters requires a minimum of 10 button presses. One way to do this is by pressing (3) once, (1,3) three times, (2,3) three times, (0,2) once, and (0,1) twice.\n\nConfiguring the second machine's counters requires a minimum of 12 button presses. One way to do this is by pressing (0,2,3,4) twice, (2,3) five times, and (0,1,2) five times.\n\nConfiguring the third machine's counters requires a minimum of 11 button presses. One way to do this is by pressing (0,1,2,3,4) five times, (0,1,2,4,5) five times, and (1,2) once.\n\nSo, the fewest button presses required to correctly configure the joltage level counters on all of the machines is 10 + 12 + 11 = 33.\n\nAnalyze each machine's joltage requirements and button wiring schematics. What is the fewest button presses required to correctly configure the joltage level counters on all of the machines?\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_11.adb",
    "content": "--  Solution to Advent of Code 2025, Day 11\n-------------------------------------------\n--  Reactor\n--\n--  https://adventofcode.com/2025/day/11\n--  Copy of questions in: aoc_2025_11_questions.txt\n--\n--  Related links:\n--    https://forum.ada-lang.io/\n--    https://www.reddit.com/r/adventofcode/\n\n--  The files aoc_toolbox.ad* are located in the upper directory: ..\n--!hac_add_to_path ..\n--\nwith AoC_Toolbox;\n\n--  For building this program with a \"full Ada\" compiler,\n--  such as GNAT, you need the explicit version of the HAT package.\n--  The files hat*.ad* are located in ../../../src\n--  See also the GNAT project file aoc_2025.gpr .\nwith HAT;\n\nwith Interfaces;\n\nprocedure AoC_2025_11 is\n\n  use AoC_Toolbox, HAT, Interfaces;\n\n  input_name : constant VString := +\"aoc_2025_11\";\n\n  r : array (Part_Type) of VString;\n\n  type Device is\n  (you,\n   imt,\n   grh,\n   yae,\n   luf,\n   ypt,\n   rlf,\n   xls,\n   ggr,\n   xgr,\n   mze,\n   xfb,\n   wms,\n   lpm,\n   wov,\n   oop,\n   cnb,\n   xaz,\n   svr,\n   vya,\n   zuk,\n   gvw,\n   ztu,\n   jmg,\n   hxf,\n   dsq,\n   jpr,\n   qba,\n   zyt,\n   wke,\n   hbz,\n   xru,\n   wsw,\n   ifh,\n   xpt,\n   elr,\n   bbg,\n   bye,\n   ceb,\n   msa,\n   gzq,\n   ufd,\n   jev,\n   gix,\n   see,\n   rnu,\n   axr,\n   efu,\n   cnf,\n   vzq,\n   ehj,\n   xup,\n   tak,\n   omn,\n   kmj,\n   hpe,\n   xzx,\n   qiu,\n   sar,\n   wur,\n   zvs,\n   bez,\n   esf,\n   taz,\n   fgw,\n   wqf,\n   zab,\n   ars,\n   pmn,\n   lay,\n   imd,\n   rak,\n   ixj,\n   pka,\n   wrm,\n   bik,\n   slz,\n   wxx,\n   hju,\n   dcs,\n   yuo,\n   ucg,\n   vtp,\n   znh,\n   slu,\n   qeh,\n   ing,\n   ogh,\n   mlo,\n   nhx,\n   wrf,\n   ihw,\n   yut,\n   drp,\n   ywc,\n   bsl,\n   uhu,\n   mcp,\n   lce,\n   vax,\n   fdo,\n   lmn,\n   ebx,\n   cdt,\n   oka,\n   zny,\n   bxj,\n   azn,\n   aps,\n   pvr,\n   kxq,\n   fry,\n   tth,\n   ize,\n   vfi,\n   qtx,\n   qck,\n   lft,\n   iur,\n   dqs,\n   xci,\n   ayn,\n   frn,\n   fhh,\n   jkp,\n   fka,\n   lcc,\n   yrq,\n   zaw,\n   ggb,\n   vkw,\n   nmm,\n   kak,\n   ejn,\n   yba,\n   hlb,\n   lka,\n   gfk,\n   arh,\n   gtw,\n   imk,\n   mox,\n   fuu,\n   nfe,\n   bdv,\n   asn,\n   yas,\n   cyr,\n   wdt,\n   mef,\n   ihs,\n   box,\n   sqj,\n   olv,\n   hsh,\n   ifc,\n   nko,\n   oim,\n   fwk,\n   djs,\n   pew,\n   vka,\n   mbw,\n   mgz,\n   lvp,\n   bxp,\n   lgw,\n   mbu,\n   jdx,\n   boq,\n   ltz,\n   com,\n   fll,\n   obk,\n   vht,\n   zyh,\n   hni,\n   vsy,\n   kfc,\n   mka,\n   uoh,\n   byu,\n   pwf,\n   rxh,\n   zxf,\n   lvi,\n   mfj,\n   one,\n   qsj,\n   gko,\n   boe,\n   pum,\n   tvs,\n   irl,\n   bqb,\n   qsl,\n   kyx,\n   the,\n   fob,\n   nfq,\n   ams,\n   cwr,\n   gia,\n   fmh,\n   ndx,\n   fpc,\n   ysn,\n   cwa,\n   lfq,\n   wth,\n   hjx,\n   vkn,\n   afp,\n   zgd,\n   fph,\n   riq,\n   ajh,\n   qvo,\n   vzk,\n   wld,\n   xym,\n   akx,\n   mmq,\n   nft,\n   ppl,\n   dkm,\n   wgp,\n   vlb,\n   gou,\n   vwe,\n   qpu,\n   rho,\n   han,\n   swp,\n   wji,\n   sef,\n   jje,\n   xly,\n   lkw,\n   tvg,\n   tat,\n   fft,\n   tym,\n   cqz,\n   xbu,\n   enr,\n   sjd,\n   piz,\n   kgv,\n   cwm,\n   ogu,\n   cxx,\n   qfb,\n   ptb,\n   pui,\n   zkr,\n   pif,\n   oaw,\n   qjd,\n   pcx,\n   pwt,\n   szq,\n   lfc,\n   haj,\n   etc,\n   jdz,\n   sjq,\n   cuq,\n   qun,\n   pny,\n   fwa,\n   mgf,\n   uxl,\n   vzo,\n   alf,\n   xvf,\n   dyq,\n   yek,\n   wcn,\n   xcd,\n   jcv,\n   gqb,\n   rab,\n   srf,\n   kme,\n   ahr,\n   ljd,\n   kmd,\n   swz,\n   qnt,\n   pqj,\n   bio,\n   pbv,\n   gip,\n   dus,\n   vzx,\n   tii,\n   sve,\n   fcg,\n   irm,\n   osd,\n   ftn,\n   xpf,\n   dlh,\n   boc,\n   lke,\n   fbf,\n   zuj,\n   kwq,\n   dac,\n   vcd,\n   cju,\n   ayb,\n   jna,\n   hfg,\n   ajl,\n   dxs,\n   vwv,\n   iwf,\n   mcy,\n   qhv,\n   ove,\n   gdl,\n   fhl,\n   oiu,\n   fbj,\n   lff,\n   rxs,\n   hxe,\n   bkg,\n   jaf,\n   xhd,\n   yor,\n   zpc,\n   ovj,\n   ixl,\n   hlr,\n   gbv,\n   kdd,\n   osb,\n   tfa,\n   qvu,\n   jdy,\n   nkv,\n   ojn,\n   rfy,\n   xmm,\n   jzt,\n   mio,\n   frk,\n   kqf,\n   kft,\n   pqr,\n   kcx,\n   ytn,\n   wau,\n   ljj,\n   jzg,\n   ryr,\n   xcb,\n   uco,\n   pqf,\n   mgb,\n   diw,\n   aak,\n   vha,\n   pgu,\n   phe,\n   zir,\n   vbv,\n   fwb,\n   ipq,\n   xlv,\n   aai,\n   qnf,\n   sym,\n   ppg,\n   nak,\n   vqp,\n   hca,\n   tla,\n   xmh,\n   brj,\n   ohg,\n   mck,\n   bne,\n   uug,\n   wuh,\n   how,\n   glc,\n   isf,\n   elg,\n   mgq,\n   upa,\n   agt,\n   kot,\n   ftb,\n   uzi,\n   brh,\n   aev,\n   ats,\n   eae,\n   foi,\n   qdl,\n   ngp,\n   yir,\n   cfh,\n   asf,\n   vwl,\n   lyf,\n   hlc,\n   etm,\n   zrk,\n   fse,\n   rus,\n   nei,\n   izt,\n   ptn,\n   ebd,\n   rcr,\n   txb,\n   lkh,\n   zal,\n   wpb,\n   ooc,\n   wjd,\n   ona,\n   qqj,\n   zco,\n   izi,\n   hpj,\n   rpb,\n   miw,\n   qte,\n   wpu,\n   awd,\n   byh,\n   fac,\n   rbx,\n   dwc,\n   wbn,\n   hly,\n   sdj,\n   une,\n   ujn,\n   ouy,\n   swg,\n   amb,\n   dap,\n   nnz,\n   xfk,\n   nik,\n   nmz,\n   bic,\n   enh,\n   pcm,\n   qnw,\n   dhn,\n   dqx,\n   skx,\n   mpw,\n   wyd,\n   nso,\n   mjd,\n   cmu,\n   jdo,\n   cxk,\n   gua,\n   ewp,\n   fzl,\n   gkv,\n   cnt,\n   bja,\n   kbq,\n   ums,\n   mjn,\n   qdj,\n   ulf,\n   gcc,\n   sjy,\n   kow,\n   xjh,\n   ogt,\n   znt,\n   jox,\n   bhg,\n   xnn,\n   wzm,\n   pgr,\n   kwb,\n   elm,\n   tei,\n   gvy,\n   ryk,\n   dkw,\n   epu,\n   vwt,\n   hwr,\n   jjf,\n   cir,\n   yxm,\n   jvd,\n   byz,\n   rrt,\n   vjs,\n   wax,\n   xdb,\n   ozj,\n   bao,\n   pue,\n   fgc,\n   hkw,\n   xob,\n   smv,\n   vnu,\n   gir,\n   hou,\n   lne,\n   sfj,\n   qmn,\n   otd,\n   qfo,\n   ujb,\n   ped,\n   dcm,\n   hai,\n   vns,\n   kjs,\n   aso,\n   rpp,\n   fjw,\n   ezl,\n   huk,\n   mzm,\n   zzp,\n   ahf,\n   auy,\n   xva,\n   wci,\n   bhk,\n   tur,\n   zvu,\n   nkt,\n   pdz,\n   fnj,\n   tco,\n   jix,\n   cwe,\n   jmd,\n   cji,\n   aod,\n   kdb,\n   xos,\n   --  Example:\n   aaa,\n   bbb,\n   ccc,\n   ddd,\n   eee,\n   fff,\n   ggg,\n   hhh,\n   iii,\n   --  Other example:\n   tty,\n   hub,\n   --\n   tuo);  --  Out\n\n  connection : array (Device, 1 .. 50) of Device;\n  connections, paths : array (Device) of Natural;\n\n  procedure Read_Data is\n    unused_separator : Character;\n    asm : String (1 .. 3);\n    i : Integer;\n    f : File_Type;\n    s : VString;\n    row : Device;\n  begin\n    for d in Device loop\n      connections (d) := 0;\n    end loop;\n    Open (f, input_name & \".txt\");\n    while not End_Of_File (f) loop\n      Get (f, asm);\n      row := Device'Value (asm);\n      Get (f, unused_separator);\n      --  put (row'image & ':');\n      i := 0;\n      Get_Line (f, s);\n      loop\n        Delete (s, 1, 1);  --  ' '\n        i := i + 1;\n        connection (row, i) := Device'Value (To_String (Slice (s, 1, 3)));\n        --  put (i, 0); put (\" \" & connection(row,i)'Image);\n        Delete (s, 1, 3);\n        exit when Length (s) = 0;\n      end loop;\n      connections (row) := i;\n      --  new_line;\n    end loop;\n    Close (f);\n  end Read_Data;\n\n  procedure Reset_Paths is\n  begin\n    for d in Device loop\n      paths (d) := Integer'Last;\n    end loop;\n  end Reset_Paths;\n\n  function Count_Paths (from, to : Device) return Natural is\n    res : Natural;\n  begin\n    if from = to then\n      return 1;\n    elsif from = tuo then\n      --  Put_Line (\"OUT\");\n      return 0;\n    else\n      --  Memoization, get:\n      if paths (from) < Integer'Last then\n        return paths (from);\n      else\n        res := 0;\n        for i in 1 .. connections (from) loop\n          --  Put (+\"From: \" & from'Image & \", Node: \" & i & \"/\" & connections (from) 'image & \": \" & connection (from, i)'Image);\n          --  Skip_Line;\n          res := res + Count_Paths (connection (from, i), to);\n        end loop;\n        --  Memoization, set:\n        paths (from) := res;\n        return res;\n      end if;\n    end if;\n  end Count_Paths;\n\n  procedure Do_Part_1 is\n  begin\n    Reset_Paths;\n    r (part_1) := +\"\" & Count_Paths (you, tuo);\n  end Do_Part_1;\n\n  procedure Do_Part_2 is\n    res : Integer;\n  begin\n    Reset_Paths;\n    res := Count_Paths (svr, fft);\n    Reset_Paths;\n    res := res * Count_Paths (fft, dac);\n    Reset_Paths;\n    res := res * Count_Paths (dac, tuo);\n    r (part_2) := +\"\" & res;\n  end Do_Part_2;\n\n  compiler_test_mode : constant Boolean := Argument_Count >= 1;\n  T0 : constant Time := Clock;\n\nbegin\n  Read_Data;\n  Do_Part_1;\n  Do_Part_2;\n  if compiler_test_mode then\n    if r (part_1) /= Argument (1) or r (part_2) /= Argument (2) then\n      Set_Exit_Status (1);  --  Compiler test failed.\n    end if;\n  else\n    Put_Line (+\"Done in: \" & (Clock - T0) & \" seconds\");\n    Put_Line (+\"Part 1: \" & r (part_1));\n    Put_Line (+\"Part 2: \" & r (part_2));\n    --  Part 1: validated by AoC: 423.\n    --  Part 2: validated by AoC: 333657640517376.\n  end if;\nend AoC_2025_11;\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_11.txt",
    "content": "you: wms hkw ove qba ats\nimt: swz aev ams bhg yir\ngrh: fph cuq pcx\nyae: qiu mef\nluf: zir jdx jmg\nypt: ahf wov hai\nrlf: haj yxm\nxls: qnw ppg\nggr: xmh vka\nxgr: hlc mzm\nmze: ljj ppg ysn qnw\nxfb: diw cxx vlb mgf\nwms: xcd hni\nlpm: dap\nwov: rbx skx ztu\noop: djs rfy\ncnb: haj\nxaz: tur kmd wsw\nsvr: qnf jjf xjh omn\nvya: mgq qqj asn\nzuk: xvf lff cju\ngvw: xfk jje gir\nztu: hlr lka\njmg: dap tei\nhxf: mjd vns mlo\ndsq: vkw vtp cwm\njpr: izt esf\nqba: cju xvf lff fcg\nzyt: yek imd qsl\nwke: tuo\nhbz: nnz qck\nxru: wuh\nwsw: mgq\nifh: ejn pif\nxpt: ouy\nelr: izi wke ljd oim\nbbg: xnn ove hbz gkv fdo frn vfi uxl rrt wms dcs vkn\nbye: jna xgr vcd\nceb: cwa\nmsa: hly gir\ngzq: byz\nufd: ihs ped\njev: wbn\ngix: wdt\nsee: nfq\nrnu: nei wdt azn\naxr: oop pgu\nefu: aai ejn\ncnf: oaw ryk wpb\nvzq: lka hlr zkr aps\nehj: tuo\nxup: esf\ntak: wld xob\nomn: xfb fry tvg fll pwt oka vwe rpp bja miw boq elm\nkmj: bsl xzx tco\nhpe: une tvs\nxzx: bbg gia fwk you\nqiu: bdv nkt uco\nsar: boc tfa qvo vzq\nwur: pdz wld xob\nzvs: bbg\nbez: kow tvs hju une\nesf: tuo\ntaz: nft\nfgw: mzm hlc\nwqf: mka gko\nzab: wuh xzx\nars: mjn jmd\npmn: uug vzx\nlay: you bbg fwk\nimd: see\nrak: tuo\nixj: kow tvs une\npka: txb\nwrm: sjq kme\nbik: aps\nslz: tvs kow une\nwxx: nfe\nhju: ypt xls swg wci wth\ndcs: qvu\nyuo: xhd ryk\nucg: lpm zaw zir\nvtp: tuo\nznh: vya phe wsw kmd\nslu: ulf msa gvw amb nkv\nqeh: yor\ning: cji hlb\nogh: gfk haj yxm\nmlo: ptn mmq alf nft\nnhx: skx\nwrf: jkp fhl\nihw: cwa rlf xbu\nyut: hjx xmm\ndrp: vkw vqp vtp\nywc: com wxx ize\nbsl: fwk gia zvu bbg\nuhu: foi wrm qnt\nmcp: vqp cwm\nlce: nak uzi\nvax: auy fgw cwr\nfdo: qck lvi nnz\nlmn: han obk fuu\nebx: nko kdd boe vht\ncdt: qiu\noka: uug lkh\nzny: sef dxs fac elg\nbxj: gcc huk\nazn: tth aps\naps: ufd ogt bxj jaf zpc ptb jev\npvr: mjd vns\nkxq: vns\nfry: uug\ntth: hxe jev zpc bio yba enr mbw ujb bxj ogt ryr dkw slu\nize: nfe hlc\nvfi: lvi qck\nqtx: xup ouy\nqck: piz ohg\nlft: ogh kgv\niur: dlh lcc\ndqs: aps zkr hlr\nxci: ahf bhk hai\nayn: tth hlr lka\nfrn: lff\nfhh: lka tth zkr aps\njkp: fnj vbv\nfka: fnj vbv\nlcc: hju tvs\nyrq: wrm\nzaw: dap\nggb: pew lgw\nvkw: tuo\nnmm: ona ums vha xos\nkak: tuo\nejn: ixj kyx\nyba: ftb\nhlb: vht\nlka: ryr zrk ufd slu lfc ptb bio zpc cqz hxe mbw jaf dkw cxk jzg smv jev ogt bxj ujb enr yba\ngfk: fmh znh aso qdl jdy qeh kot\narh: fft eae\ngtw: tth lka\nimk: pdz wld xob\nmox: irm\nfuu: ftn\nnfe: cwe ndx etc qhv agt vzk dcm cmu oiu fwb ahr zgd mgz wyd byh ajh lkw fob rho sve sfj lce riq znt yut ogu\nbdv: you fwk zvu bbg\nasn: hju une\nyas: pif ejn\ncyr: fwa qpu mpw\nwdt: lka\nmef: bdv\nihs: gua\nbox: tuo\nsqj: ehj\nolv: dlh lcc rpb\nhsh: rnu gix nfq dus\nifc: xup jpr\nnko: you zvu fwk gia\noim: tuo\nfwk: ove dcs hbz gkv cnt frn vzo brh rrt\ndjs: uco bdv nkt\npew: dsq sjy epu\nvka: tvs kow hju\nmbw: amb ulf msa gvw\nmgz: zab xru pui kmj\nlvp: zny mgf\nbxp: hlc mzm\nlgw: epu mcp sjy drp\nmbu: tuo\njdx: dap tei\nboq: lft\nltz: sjy mcp dsq\ncom: nfe\nfll: pqr luf gko\nobk: frk ftn\nvht: zvu gia fwk\nzyh: lgw mfj pew ltz\nhni: xym ggb bkg\nvsy: cdt dac yae\nkfc: gou fpc\nmka: zaw lpm jmg\nuoh: fwa qpu\nbyu: rak mck\npwf: rcr\nrxh: qtx\nzxf: tco wuh\nlvi: ohg kft dqx\nmfj: drp\none: lka\nqsj: pif\ngko: jmg lpm jdx zaw zir\nboe: zvu bbg gia fwk\npum: aps lka tth\ntvs: wci wji zyt dhn hwr vwl wrf ojn rab\nirl: gip\nbqb: kjs qmn lft\nqsl: see hsh\nkyx: hju\nthe: yrq zco xcb uhu kbq\nfob: gzq uzi osb\nnfq: nei wdt azn\nams: afp\ncwr: mzm\ngia: xnn brh hkw hbz irl dcs zuk cnt gkv gbv\nfmh: rxs xpf\nndx: hou uoh qdj vwt\nfpc: hlc nfe\nysn: wjd zuj pum\ncwa: yxm haj gfk\nlfq: kak ujn ehj box\nwth: imd\nhjx: hlb ebx cji aak\nvkn: hxf wax kxq\nafp: dkm lyf\nzgd: hjx\nfph: bao ewp\nriq: uoh hou qdj cyr vwt\najh: akx axr\nqvo: aps lka hlr tth zkr\nvzk: zab xru pui kmj\nwld: haj\nxym: pew mfj vnu\nakx: yae pgu oop cdt dac\nmmq: jzt byu\nnft: sdj byu\nppl: bxp gou fpc\ndkm: yxm haj gfk\nwgp: aps hlr zkr\nvlb: sef\ngou: hlc nfe mzm\nvwe: ams aev\nqpu: you bbg zvu fwk gia\nrho: vwt hou\nhan: ftn frk elr\nswp: dlh rpb\nwji: sar xos vha ums\nsef: wur\njje: szq kfc\nxly: hlc nfe\nlkw: uoh hou cyr\ntvg: vzx uug\ntat: ljj ppg ysn\nfft: olv dyq\ntym: yxm haj\ncqz: gcc nmz\nxbu: haj yxm gfk\nenr: amb\nsjd: iwf\npiz: cuq pcx fph fgc\nkgv: haj yxm\ncwm: tuo\nogu: zxf zab pui\ncxx: elg osd\nqfb: une\nptb: ftb wbn\npui: bsl\nzkr: dkw zrk jzg ryr cxk ufd lfc slu smv cqz bio ptb hxe jev ujb ogt jaf enr yba mbw\npif: vjs ixj\noaw: cir\nqjd: uhu xcb zco yrq\npcx: otd sqj bao ewp\npwt: lkh vzx\nszq: fpc bxp\nlfc: jvd\nhaj: pwf yuo xdb znh aso asf aod kot srf fmh xaz qdl fzl\netc: ing\njdz: fwk gia zvu bbg\nsjq: aps lka hlr tth zkr\ncuq: ewp bao sqj\nqun: cwr fgw fbj\npny: kjs lft qmn\nfwa: gia bbg zvu you\nmgf: fac\nuxl: hni\nvzo: cju xvf fcg lff\nalf: byu sdj\nxvf: pqj mgb isf pqf rxh\ndyq: rpb lcc\nyek: hca hsh\nwcn: rxs\nxcd: bkg ggb\njcv: yxm haj gfk\ngqb: tuo\nrab: hpj jkp\nsrf: efu qsj\nkme: hlr aps\nahr: awd mcy\nljd: tuo\nkmd: mgq\nswz: enh tla\nqnt: sjq gtw\npqj: zzp\nbio: nmz gcc\npbv: hlr tth zkr\ngip: taz\ndus: wdt nei\nvzx: ooc ceb ihw jix\ntii: ovj jna xly\nsve: uoh\nfcg: isf mgb pqj pqf\nirm: piz ohg kft grh\nosd: xlv imk\nftn: ljd mbu izi\nxpf: lne bez hpe wau\ndlh: kow tvs une hju\nboc: zkr hlr\nlke: tuo\nfbf: bbg zvu fwk you\nzuj: hlr lka zkr tth\nkwq: gia bbg\ndac: mef djs\nvcd: nfe\ncju: pqf rxh\nayb: xbu rlf\njna: mzm hlc\nhfg: mzm\najl: fka hpj fhl\ndxs: imk tak\nvwv: kdb xpf\niwf: ytn pgr jdz\nmcy: ytn\nqhv: osb gzq\nove: hni gdl\ngdl: xym zyh\nfhl: vbv ebd\noiu: xmm ing\nfbj: hlc\nlff: isf pqj\nrxs: hpe wau bez\nhxe: vax\nbkg: pew mfj\njaf: nmz huk\nxhd: ggr cir how\nyor: eae\nzpc: qun nik\novj: mzm\nixl: sjq kme gtw\nhlr: bxj bio dkw cxk ryr jzg zrk\ngbv: hni gdl\nkdd: you zvu fwk\nosb: lay zvs kwq fbf\ntfa: tth zkr lka\nqvu: lmn mjn\njdy: ifh qsj efu yas\nnkv: jje\nojn: ahf wov hai nhx bhk\nrfy: nkt\nxmm: ebx aak\njzt: mck rak\nmio: lcc\nfrk: izi oim\nkqf: hlc\nkft: fgc\npqr: zir jdx\nkcx: zny\nytn: fwk gia zvu bbg\nwau: une hju tvs\nljj: wjd pum zuj\njzg: huk gcc\nryr: nik\nxcb: qnt\nuco: fwk bbg you\npqf: xpt ifc\nmgb: zzp ifc\ndiw: fac dxs elg osd\naak: vht nko kdd boe\nvha: fhh vzq qvo boc\npgu: rfy\nphe: mgq asn\nzir: dap bic\nvbv: pbv bik\nfwb: vsy\nipq: swp olv dyq iur\nxlv: pdz gvy wld xob\naai: ixj vjs\nqnf: kcx fjw tvg wqf pcm fry\nsym: aai ejn\nppg: wjd zuj pum\nnak: fbf kwq zvs\nvqp: tuo\nhca: gix rnu\ntla: cnb dkm tym jcv\nxmh: tvs\nbrj: iwf\nohg: pcx fgc fph\nmck: tuo\nbne: zxf\nuug: ceb ooc\nwuh: gia fwk zvu you\nhow: qfb slz vka\nglc: xcb yrq zco\nisf: ifc zzp\nelg: imk xlv wur\nmgq: hju kow\nupa: sdj jzt\nagt: xmm\nkot: phe wsw kmd tur\nftb: ywc jox\nuzi: byz lay kwq fbf\nbrh: wax pvr kxq\naev: afp tla\nats: nso jdo\neae: mio olv iur swp\nfoi: kme\nqdl: arh zal rcr yor\nngp: yxm haj\nyir: enh\ncfh: tuo\nasf: yor arh zal\nvwl: ona ums xos sar\nlyf: yxm gfk\nhlc: sve lce sfj oiu brj zgd wyd byh ajh sjd etc vzk qhv cmu bne\netm: tuo\nzrk: ihs jvd\nfse: nfe mzm\nrus: yek\nnei: zkr tth hlr lka\nizt: tuo\nptn: jzt\nebd: bik one\nrcr: ipq fft\ntxb: ozj\nlkh: ceb ihw jix ayb\nzal: fft\nwpb: how\nooc: rlf\nwjd: tth hlr lka\nona: boc tfa fhh vzq\nqqj: tvs hju\nzco: qnt\nizi: tuo\nhpj: ebd fnj vbv\nrpb: tvs une\nmiw: swz bhg ams\nqte: luf gko\nwpu: vcd xgr jna xly\nawd: pgr jdz\nbyh: akx axr vsy\nfac: imk\nrbx: aps tth zkr lka hlr\ndwc: wpb oaw ryk\nwbn: txb jox\nhly: szq ppl\nsdj: mck lke\nune: qjd dhn rus wrf ojn ajl the ezl\nujn: tuo\nouy: gqb esf izt\nswg: yek\namb: hly gir xfk\ndap: haj yxm\nnnz: ohg piz dqx kft grh\nxfk: ppl kfc\nnik: cwr hfg fgw auy\nnmz: bye\nbic: haj gfk\nenh: jcv tym dkm cnb lyf\npcm: vlb cxx zny\nqnw: wgp pum zuj\ndhn: nhx\ndqx: pcx fgc fph\nskx: aps lka zkr tth\nmpw: gia fwk bbg\nwyd: zxf kmj pui xru\nnso: mjn\nmjd: nft alf upa mmq\ncmu: awd mcy\njdo: mjn lmn jmd\ncxk: ihs ped jvd\ngua: nfe hlc\newp: etm ehj\nfzl: kmd tur wsw\ngkv: jdo qvu wzm\ncnt: lvi irm\nbja: diw cxx zny\nkbq: ixl\nums: qvo boc tfa fhh vzq\nmjn: han pue\nqdj: fwa\nulf: gir hly\ngcc: tii\nsjy: cwm cfh vqp vkw\nkow: ojn nmm wrf vwl qjd mze xci swg xls wth glc tat ypt rab hwr dhn rus zyt the wji ajl\nxjh: fjw fll pcm xfb pwt miw bja vwe rpp pmn kcx pny qte bqb\nogt: vax qun nik\nznt: vsy akx\njox: wxx ozj ize com\nbhg: afp tla\nxnn: wzm jdo ars\nwzm: lmn\npgr: you zvu bbg\nkwb: ngp ogh\nelm: gko ucg luf pqr\ntei: yxm gfk\ngvy: gfk\nryk: cir how\ndkw: nik\nepu: cwm vtp vqp vkw\nvwt: qpu\nhwr: qnw ysn\njjf: pny oka kcx bqb lvp vwe rpp fjw xfb fry pcm imt\ncir: slz xva qfb\nyxm: srf kot cnf aod dwc asf aso qfo wcn znh xdb pwf yuo qeh jdy vwv qdl xaz fmh\njvd: kqf fse\nbyz: zvu bbg you\nrrt: cju xvf lff\nvjs: tvs kow une\nwax: taz\nxdb: yas sym efu qsj\nozj: mzm\nbao: ehj box ujn\npue: ftn\nfgc: lfq bao otd\nhkw: hni gdl\nxob: yxm haj\nsmv: jvd ped\nvnu: sjy\ngir: kfc\nhou: mpw fwa\nlne: kow\nsfj: osb nak uzi\nqmn: ngp kgv\notd: ujn kak box\nqfo: ifh yas\nujb: ftb pka wbn\nped: gua kqf fse\ndcm: gzq nak osb\nhai: ztu\nvns: upa alf\nkjs: ngp kgv\naso: xpf rxs\nrpp: luf pqr gko ucg\nfjw: qmn kwb\nezl: fka jkp fhl\nhuk: wpu tii bye\nmzm: sve rho fob lkw yut riq brj fwb ajh byh zgd mgz etc sjd ndx dcm cmu vzk qhv bne cwe\nzzp: jpr\nahf: skx rbx dqs\nauy: mzm nfe hlc\nxva: kow tvs\nwci: hpj\nbhk: skx ztu rbx\ntur: qqj\nzvu: wms vzo vfi brh mox fdo ove zuk irl vkn hbz\nnkt: you zvu bbg gia\npdz: gfk haj\nfnj: ayn bik pbv\ntco: bbg fwk gia you\njix: cwa\ncwe: mcy\njmd: fuu obk pue\ncji: boe\naod: vya kmd\nkdb: wau lne bez\nxos: vzq\n"
  },
  {
    "path": "exm/aoc/2025/aoc_2025_11_questions.txt",
    "content": "--- Day 11: Reactor ---\n\nYou hear some loud beeping coming from a hatch in the floor of the factory, so you decide to check it out. Inside, you find several large electrical conduits and a ladder.\n\nClimbing down the ladder, you discover the source of the beeping: a large, toroidal reactor which powers the factory above. Some Elves here are hurriedly running between the reactor and a nearby server rack, apparently trying to fix something.\n\nOne of the Elves notices you and rushes over. \"It's a good thing you're here! We just installed a new server rack, but we aren't having any luck getting the reactor to communicate with it!\" You glance around the room and see a tangle of cables and devices running from the server rack to the reactor. She rushes off, returning a moment later with a list of the devices and their outputs (your puzzle input).\n\nFor example:\n\naaa: you hhh\nyou: bbb ccc\nbbb: ddd eee\nccc: ddd eee fff\nddd: ggg\neee: out\nfff: out\nggg: out\nhhh: ccc fff iii\niii: out\n\nEach line gives the name of a device followed by a list of the devices to which its outputs are attached. So, bbb: ddd eee means that device bbb has two outputs, one leading to device ddd and the other leading to device eee.\n\nThe Elves are pretty sure that the issue isn't due to any specific device, but rather that the issue is triggered by data following some specific path through the devices. Data only ever flows from a device through its outputs; it can't flow backwards.\n\nAfter dividing up the work, the Elves would like you to focus on the devices starting with the one next to you (an Elf hastily attaches a label which just says you) and ending with the main output to the reactor (which is the device with the label out).\n\nTo help the Elves figure out which path is causing the issue, they need you to find every path from you to out.\n\nIn this example, these are all of the paths from you to out:\n\n    Data could take the connection from you to bbb, then from bbb to ddd, then from ddd to ggg, then from ggg to out.\n    Data could take the connection to bbb, then to eee, then to out.\n    Data could go to ccc, then ddd, then ggg, then out.\n    Data could go to ccc, then eee, then out.\n    Data could go to ccc, then fff, then out.\n\nIn total, there are 5 different paths leading from you to out.\n\nHow many different paths lead from you to out?\n\n--- Part Two ---\n\nThanks in part to your analysis, the Elves have figured out a little bit about the issue. They now know that the problematic data path passes through both dac (a digital-to-analog converter) and fft (a device which performs a fast Fourier transform).\n\nThey're still not sure which specific path is the problem, and so they now need you to find every path from svr (the server rack) to out. However, the paths you find must all also visit both dac and fft (in any order).\n\nFor example:\n\nsvr: aaa bbb\naaa: fft\nfft: ccc\nbbb: tty\ntty: ccc\nccc: ddd eee\nddd: hub\nhub: fff\neee: dac\ndac: fff\nfff: ggg hhh\nggg: out\nhhh: out\n\nThis new list of devices contains many paths from svr to out:\n\nsvr,aaa,fft,ccc,ddd,hub,fff,ggg,out\nsvr,aaa,fft,ccc,ddd,hub,fff,hhh,out\nsvr,aaa,fft,ccc,eee,dac,fff,ggg,out\nsvr,aaa,fft,ccc,eee,dac,fff,hhh,out\nsvr,bbb,tty,ccc,ddd,hub,fff,ggg,out\nsvr,bbb,tty,ccc,ddd,hub,fff,hhh,out\nsvr,bbb,tty,ccc,eee,dac,fff,ggg,out\nsvr,bbb,tty,ccc,eee,dac,fff,hhh,out\n\nHowever, only 2 paths from svr to out visit both dac and fft.\n\nFind all of the paths that lead from svr to out. How many of those paths visit both dac and fft?\n"
  },
  {
    "path": "exm/aoc/aoc_check_list.txt",
    "content": "https://adventofcode.com/\r\n\r\n 1 coffee\r\n 2 prepare aoc_20xx_yy.adb in LEA\r\n 3 prepare aoc_20xx.gpr in case GNAT is needed\r\n 4 prepare empty mini.txt in Notepad++\r\n ----- Start! -----\r\n 5 open today's aoc web page\r\n 6 download input.txt and have a glimpse on it\r\n 7 read the instructions as quickly as possible...\r\n 8 paste the example into mini.txt\r\n 9 code and train with mini.txt\r\n10 run with input.txt\r\n"
  },
  {
    "path": "exm/aoc/aoc_toolbox.adb",
    "content": "package body AoC_Toolbox is\n\n  procedure GCD_and_Bezout (a, b : in Integer; s, t, the_gcd : out Integer) is\n    --  Finds the GCD and s, t for the\n    --  ` GCD (a, b) = a * s + b * t ` factorization (Bezout theorem).\n    --  Program 1.8, Introduction to number theory, RBJT Allenby & EJ Redfern\n    ta, tb : array (1 .. 3) of Integer;\n    q, r : Integer;\n  begin\n    ta (1) := 1;         tb (1) := 0;\n    ta (2) := 0;         tb (2) := 1;\n    ta (3) := a;         tb (3) := b;\n    while tb (3) /= 0 loop\n      q := ta (3) / tb (3);\n      for i in 1 .. 3 loop\n        r := ta (i) - q * tb (i);\n        ta (i) := tb (i);\n        tb (i) := r;\n      end loop;\n    end loop;\n    s :=       ta (1);\n    t :=       ta (2);\n    the_gcd := ta (3);\n  end GCD_and_Bezout;\n\n  function GCD (a, b : Integer) return Integer is\n    dummy_s, dummy_t, the_gcd : Integer;\n  begin\n    GCD_and_Bezout (a, b, dummy_s, dummy_t, the_gcd);\n    return the_gcd;\n  end GCD;\n\n  function LCM (a, b : Integer) return Integer is\n  begin\n    return abs (a * b) / GCD (a, b);\n  end LCM;\n\n  procedure GCD_and_Bezout_64 (a, b : in Integer_64; s, t, the_gcd : out Integer_64) is\n    --  Finds the GCD and s, t for the\n    --  ` GCD (a, b) = a * s + b * t ` factorization (Bezout theorem).\n    --  Program 1.8, Introduction to number theory, RBJT Allenby & EJ Redfern\n    ta, tb : array (1 .. 3) of Integer_64;\n    q, r : Integer_64;\n  begin\n    ta (1) := 1;         tb (1) := 0;\n    ta (2) := 0;         tb (2) := 1;\n    ta (3) := a;         tb (3) := b;\n    while tb (3) /= 0 loop\n      q := ta (3) / tb (3);\n      for i in 1 .. 3 loop\n        r := ta (i) - q * tb (i);\n        ta (i) := tb (i);\n        tb (i) := r;\n      end loop;\n    end loop;\n    s :=       ta (1);\n    t :=       ta (2);\n    the_gcd := ta (3);\n  end GCD_and_Bezout_64;\n\n  function GCD_64 (a, b : Integer_64) return Integer_64 is\n    dummy_s, dummy_t, the_gcd : Integer_64;\n  begin\n    GCD_and_Bezout_64 (a, b, dummy_s, dummy_t, the_gcd);\n    return the_gcd;\n  end GCD_64;\n\n  function LCM_64 (a, b : Integer_64) return Integer_64 is\n  begin\n    return abs (a * b) / GCD_64 (a, b);\n  end LCM_64;\n\n  function Dist_L1 (a, b : Point) return Natural is\n  begin\n    return\n      abs (a.x - b.x) + abs (a.y - b.y);\n  end Dist_L1;\n\n  function Dist_Max (a, b : Point) return Natural is\n  begin\n    return\n      HAT.Max (abs (a.x - b.x), abs (a.y - b.y));\n  end Dist_Max;\n\n  procedure Rotate (x, y : in out HAT.Real; a : HAT.Real) is\n    use HAT;\n    nx : Real;\n  begin\n    nx := Cos (a) * x - Sin (a) * y;\n    y  := Sin (a) * x + Cos (a) * y;\n    x  := nx;\n  end Rotate;\n\n  function Opposite (d : Direction) return Direction is\n  begin\n    case d is\n      when north => return south;\n      when south => return north;\n      when east  => return west;\n      when west  => return east;\n    end case;\n  end Opposite;\n\n  function Turn_Right (d : Direction) return Direction is\n  begin\n    case d is\n      when north => return east;\n      when south => return west;\n      when east  => return south;\n      when west  => return north;\n    end case;\n  end Turn_Right;\n\n  function Dist_L1_3D (a, b : Point_3D) return Natural is\n  begin\n    return\n      abs (a.x - b.x) + abs (a.y - b.y) + abs (a.z - b.z);\n  end Dist_L1_3D;\n\n  function Dist_L1_3D_R (a, b : Point_3D_R) return HAT.Real is\n    use HAT;\n  begin\n    return\n      abs (a.x - b.x) + abs (a.y - b.y) + abs (a.z - b.z);\n  end Dist_L1_3D_R;\n\n  procedure Skip_till_Space (f : in out HAT.File_Type; times : Positive) is\n    c : Character;\n    use HAT;\n  begin\n    for repeat in 1 .. times loop\n      while not End_Of_File (f) loop\n        Get (f, c);\n        exit when c = ' ';\n      end loop;\n      exit when End_Of_File (f);\n    end loop;\n  end Skip_till_Space;\n\n  function Sgn_64 (i : Integer_64) return Integer_64 is\n  begin\n    if i > 0 then\n      return 1;\n    elsif i < 0 then\n      return -1;\n    else\n      return 0;\n    end if;\n  end Sgn_64;\n\n  function Image (i : Integer_64) return HAT.VString is\n    use HAT;\n    res : VString := +i'Image;\n  begin\n    if i < 0 then\n      return res;\n    else\n      --  Remove the leading ' '.\n      Delete (res, 1, 1);\n      return res;\n    end if;\n  end Image;\n\n  function Deg_2_Rad (a : HAT.Real) return HAT.Real is\n    use HAT;\n  begin\n    return (Pi / 180.0) * a;\n  end Deg_2_Rad;\n\n  function Sim_AND (a, b : Integer_64) return Integer_64 is\n    x : Integer_64 := a;\n    y : Integer_64 := b;\n    res : Integer_64 := 0;\n    m : Integer_64 := 1;\n    x1, y1 : Integer_64;\n  begin\n    if a < 0 or else b < 0 then\n      HAT.Put (\"XOR on negative values!\");\n    end if;\n    while x > 0 or else y > 0 loop\n      x1 := x mod 2;\n      y1 := y mod 2;\n      if x1 = 1 and y1 = 1 then\n        res := res + m;\n      end if;\n      x := x / 2;\n      y := y / 2;\n      m := m * 2;\n    end loop;\n    return res;\n  end Sim_AND;\n\n  function Sim_XOR (a, b : Integer_64) return Integer_64 is\n    x : Integer_64 := a;\n    y : Integer_64 := b;\n    res : Integer_64 := 0;\n    m : Integer_64 := 1;\n    x1, y1 : Integer_64;\n  begin\n    if a < 0 or else b < 0 then\n      HAT.Put (\"XOR on negative values!\");\n    end if;\n    while x > 0 or else y > 0 loop\n      x1 := x mod 2;\n      y1 := y mod 2;\n      if (x1 = 1 or y1 = 1) and then not (x1 = 1 and y1 = 1) then\n        res := res + m;\n      end if;\n      x := x / 2;\n      y := y / 2;\n      m := m * 2;\n    end loop;\n    return res;\n  end Sim_XOR;\n\n  package body Hash_Maps is\n\n    --  Hash map code extended from AoC_2023_15's implementation.\n    --  HASH = Holiday ASCII String Helper :-).\n\n    function HASH (s : HAT.VString) return Natural is\n      h : Natural := 0;\n      use HAT;\n    begin\n      for i in 1 .. Length (s) loop\n        h := ((h + Ord (Element (s, i))) * 17) rem 256;\n      end loop;\n      return h;\n    end HASH;\n\n    procedure Clear (hm : out Hash_Map_Type) is\n    begin\n      for i in hm'Range loop\n        hm (i).slots := 0;\n      end loop;\n    end Clear;\n\n    procedure Insert\n      (hm        : in out Hash_Map_Type;\n       key       : in     HAT.VString;\n       new_value : in     Integer_64;\n       replace   : in     Boolean;      --  Replace existing value ?\n       value     :    out Integer_64)   --  If key exists, we get previous value.\n    is\n      b : constant Natural := HASH (key);\n      new_slots_total : Natural;\n      use HAT;\n    begin\n      for s in 1 .. hm (b).slots loop\n        if hm (b).slot (s).key = key then\n          value := hm (b).slot (s).value;\n          if replace then\n            hm (b).slot (s).value := new_value;\n          end if;\n          return;\n        end if;\n      end loop;\n      --  Append new value.\n      new_slots_total := hm (b).slots + 1;\n      hm (b).slot (new_slots_total).key   := key;\n      hm (b).slot (new_slots_total).value := new_value;\n      hm (b).slots := new_slots_total;\n      value := new_value;\n    end Insert;\n\n    procedure Find\n      (hm              : in out Hash_Map_Type;\n       key             : in     HAT.VString;\n       not_found_value : in     Integer_64;\n       value           :    out Integer_64)\n    is\n      b : constant Natural := HASH (key);\n      use HAT;\n    begin\n      for s in 1 .. hm (b).slots loop\n        if hm (b).slot (s).key = key then\n          value := hm (b).slot (s).value;\n          return;\n        end if;\n      end loop;\n      value := not_found_value;\n    end Find;\n\n  end Hash_Maps;\n\nend AoC_Toolbox;\n"
  },
  {
    "path": "exm/aoc/aoc_toolbox.ads",
    "content": "with HAT, Interfaces;\n\npackage AoC_Toolbox is\n\n  use Interfaces;\n\n  ----------------\n  --  AoC game  --\n  ----------------\n\n  type Part_Type is (part_1, part_2);\n\n  type Data_Type is (mini, input);\n\n  subtype Digit_Type is Natural range 0 .. 9;\n\n  subtype Alpha is Character range 'a' .. 'z';\n  subtype Upcase_Alpha is Character range 'A' .. 'Z';\n\n  subtype Binary is Natural range 0 .. 1;\n\n  ---------------\n  --  Algebra  --\n  ---------------\n\n  --  Greatest Common Denominator\n  --\n  procedure GCD_and_Bezout (a, b : in Integer; s, t, the_gcd : out Integer);\n\n  function GCD (a, b : Integer) return Integer;\n\n  --  Least Common Multiple\n  --\n  function LCM (a, b : Integer) return Integer;\n\n  procedure GCD_and_Bezout_64 (a, b : in Integer_64; s, t, the_gcd : out Integer_64);\n  function GCD_64 (a, b : Integer_64) return Integer_64;\n  function LCM_64 (a, b : Integer_64) return Integer_64;\n\n  ----------------------\n  --  Plane Geometry  --\n  ----------------------\n\n  type Point is record\n    x, y : Integer;\n  end record;\n\n  function Dist_L1 (a, b : Point) return Natural;\n\n  function Dist_Max (a, b : Point) return Natural;\n\n  procedure Rotate (x, y : in out HAT.Real; a : HAT.Real);\n\n  type Direction_or_Nil is (nil, north, east, south, west);\n\n  subtype Direction is Direction_or_Nil range north .. west;\n\n  function Opposite (d : Direction) return Direction;\n\n  function Turn_Right (d : Direction) return Direction;\n\n  -------------------\n  --  3D Geometry  --\n  -------------------\n\n  type Point_3D is record\n    x, y, z : Integer;\n  end record;\n\n  type Point_3D_R is record\n    x, y, z : HAT.Real;\n  end record;\n\n  function Dist_L1_3D (a, b : Point_3D) return Natural;\n\n  function Dist_L1_3D_R (a, b : Point_3D_R) return HAT.Real;\n\n  -----------------------\n  --  Text processing  --\n  -----------------------\n\n  procedure Skip_till_Space (f : in out HAT.File_Type; times : Positive);\n\n  --------------------\n  --  Miscellaneous --\n  --------------------\n\n  function Sgn_64 (i : Integer_64) return Integer_64;\n\n  function Image (i : Integer_64) return HAT.VString;\n\n  function Deg_2_Rad (a : HAT.Real) return HAT.Real;\n\n  --  Simulate AND, XOR for HAC which hasn't modular types...\n  function Sim_AND (a, b : Integer_64) return Integer_64;\n  function Sim_XOR (a, b : Integer_64) return Integer_64;\n\n  ---------------------------------------------\n  --  Hash maps (extended from AoC_2023_15)  --\n  ---------------------------------------------\n\n  package Hash_Maps is\n\n    type Hash_Slot_Type is record\n      key   : HAT.VString;\n      value : Integer_64;\n    end record;\n\n    type Hash_Slot_Array_Type is array (1 .. 2_000) of Hash_Slot_Type;\n\n    type Hash_Box_Type is record\n      slot  : Hash_Slot_Array_Type;\n      slots : Natural;  --  HAC wish: initialized value := 0;\n    end record;\n\n    type Hash_Map_Type is array (0 .. 255) of Hash_Box_Type;\n    --  ^  HAC wish: ideally that type would be private and the\n    --     only publicly visible identifier...\n\n    procedure Clear (hm : out Hash_Map_Type);\n\n    procedure Insert\n      (hm        : in out Hash_Map_Type;\n       key       : in     HAT.VString;\n       new_value : in     Integer_64;\n       replace   : in     Boolean;      --  Replace existing value ?\n       value     :    out Integer_64);  --  If key exists, we get previous value.\n\n    procedure Find\n      (hm              : in out Hash_Map_Type;\n       key             : in     HAT.VString;\n       not_found_value : in     Integer_64;\n       value           :    out Integer_64);\n\n  end Hash_Maps;\n\nend AoC_Toolbox;\n"
  },
  {
    "path": "exm/arguments.adb",
    "content": "with HAT; use HAT;\n\nprocedure Arguments is\nbegin\n  Put (\"Command-line arguments:\");\n  Put (Argument_Count);\n  New_Line (2);\n  Put_Line (\"Argument list:\");\n  Put_Line (\"--------------\");\n  for A in 1 .. Argument_Count loop\n    Put_Line (\"  --> [\" & Argument (A) & ']');\n  end loop;\nend Arguments;\n"
  },
  {
    "path": "exm/attributes.adb",
    "content": "with HAT;\r\n\r\nprocedure Attributes is\r\n\r\n  type Enum is (aa, bb, cc, dd);\r\n  subtype Sub_Enum is Enum range bb .. cc;\r\n\r\n  d : constant Duration := 123.456;\r\n  i : constant Integer := 123;\r\n  r : constant HAT.Real := HAT.Pi;\r\n  b : constant Boolean := True;\r\n  c : constant Character := 'x';\r\n  e : constant Enum := dd;\r\n\r\n  subtype Some_Range is Integer range -123 .. 456;\r\n  subtype A_to_Z is Character range 'A' .. 'Z';\r\n\r\n  dummy_e : Enum;\r\n  dummy_i, sum : Integer;\r\n\r\n  type A is array (Sub_Enum) of HAT.Real;\r\n\r\n  type M is array (-5 .. -2, bb .. dd) of Integer;\r\n\r\n  mm : M;\r\n\r\n  use HAT;\r\n\r\nbegin\r\n  ---------------------------------------------------\r\n  --  If you uncomment any of the following lines  --\r\n  --  you'll get a Constraint_Error on run time:   --\r\n  ---------------------------------------------------\r\n\r\n  --  dummy_i := Some_Range'Succ (Some_Range'Last);\r\n  --  dummy_i := Some_Range'Pred (Some_Range'First);\r\n  --  dummy_e := Enum'Value (\"ff\");\r\n\r\n  --\r\n\r\n  Put_Line (\"Attributes      S = Standard subtype, indicated with '*'\");\r\n  Put_Line (\"==========        or     HAT subtype, indicated with '#'\");\r\n  New_Line;\r\n  Put_Line (\"S'First and S'Last attributes for scalar subtype S\");\r\n  Put_Line (\"--------------------------------------------------\");\r\n  New_Line;\r\n  Put_Line (+\"  * Integer's bounds    : \" & Integer'First               & \" .. \" & Integer'Last);\r\n  Put_Line (+\"  * Natural's bounds    : \" & Natural'First               & \" .. \" & Natural'Last);\r\n  Put_Line (+\"  * Positive's bounds   : \" & Positive'First              & \" .. \" & Positive'Last);\r\n  Put_Line (+\"    Some_Range's bounds : \" & Some_Range'First            & \" .. \" & Some_Range'Last);\r\n  Put_Line (+\"  * Boolean's bounds    : \" & Boolean'First               & \" .. \" & Boolean'Last);\r\n  Put_Line (+\"    A_to_Z's bounds     : \" & A_to_Z'First                & \" .. \" & A_to_Z'Last);\r\n  --  Alternative using VString and the direct concatenation VString & Real:\r\n  Put_Line (+\"  # Real's bounds       : \" & Real'First                  & \" .. \" & Real'Last);\r\n  --  Alternative using String and the 'Image attribute:\r\n  Put_Line  (\"  # Real's bounds       : \" & Real'Image (Real'First)     & \" ..\"  & Real'Image (Real'Last));\r\n  Put_Line  (\"    Enum's bounds       : \" & Enum'Image (Enum'First)     & \" .. \" & Enum'Image (Enum'Last));\r\n  Put_Line  (\"    Sub_Enum's bounds   : \" & Enum'Image (Sub_Enum'First) & \" .. \" & Enum'Image (Sub_Enum'Last));\r\n  New_Line;\r\n  Put_Line (\"S'Pred and S'Succ attributes\");\r\n  Put_Line (\"----------------------------\");\r\n  New_Line;\r\n  Put_Line (+\"  * Integer'Succ (100)                 : \" & Integer'Succ (100));\r\n  Put_Line (+\"  * Integer'Pred (100)                 : \" & Integer'Pred (100));\r\n  Put_Line (+\"    Some_Range'Succ (Some_Range'First) : \" & Some_Range'Succ (Some_Range'First));\r\n  New_Line;\r\n  Put_Line (\"S'Pos and S'Val attributes\");\r\n  Put_Line (\"--------------------------\");\r\n  New_Line;\r\n  Put_Line (+\"  * Boolean'Pos (True)  : \" & Boolean'Pos (True));\r\n  Put_Line (+\"  * Boolean'Val (0)     : \" & Boolean'Val (0));\r\n  Put_Line (+\"  * Character'Pos (' ') : \" & Character'Pos (' '));\r\n  Put_Line (+\"  * Character'Val (65)  : \" & Character'Val (65));\r\n  Put_Line (+\"    Enum'Pos (aa)       : \" & Enum'Pos (aa));\r\n  Put_Line (+\"    Enum'Val (3)        : \" & Enum'Image (Enum'Val (3)));\r\n  New_Line;\r\n  Put_Line (\"S'Image (...) attribute\");\r\n  Put_Line (\"-----------------------\");\r\n  New_Line;\r\n  Put_Line (\"  * Integer'Image (123)      : [\" & Integer'Image (123) & ']');\r\n  Put_Line (\"  # Real'Image (Pi)          : [\" & Real'Image (Pi) & ']');\r\n  Put_Line (\"  * Boolean'Image (True)     : [\" &\r\n    Boolean'Image (\r\n      --  Here we test \"<\" on values of the internal type Strings_as_VStrings.\r\n      Enum'Image (bb) < Enum'Image (cc)\r\n    ) &\r\n    ']'\r\n  );\r\n  Put_Line (\"  * Character'Image ('x')    : [\" & Character'Image ('x') & \"] (purely academic!)\");\r\n  Put_Line (\"  * Duration'Image (123.456) : [\" & Duration'Image (d) & ']');\r\n  Put_Line (\"    Enum'Image (bb)          : [\" & Enum'Image (bb) & ']');\r\n  New_Line;\r\n  Put_Line (\"X'Image attribute\");\r\n  Put_Line (\"-----------------\");\r\n  New_Line;\r\n  Put_Line (\"  i'Image      : [\" & i'Image & ']');\r\n  Put_Line (\"  r'Image      : [\" & r'Image & ']');\r\n  Put_Line (\"  b'Image      : [\" & b'Image & ']');\r\n  Put_Line (\"  c'Image      : [\" & c'Image & ']');\r\n  Put_Line (\"  d'Image      : [\" & d'Image & ']');\r\n  Put_Line (\"  e'Image      : [\" & e'Image & ']');\r\n  New_Line;\r\n  Put_Line (\"S'Value attribute, re-displayed via S'Image for Enum and,\");\r\n  Put_Line (\" otherwise, via \"\"nice\"\" HAT.Image and VString concatenation\");\r\n  Put_Line (\"------------------------------------------------------------\");\r\n  New_Line;\r\n  Put_Line (+\"  * Integer'Value (\"\"1e3\"\")     : [\" & Integer'Value (\"1e3\") & ']');\r\n  Put_Line (+\"  # Real'Value (\"\"1e3\"\")        : [\" & Real'Value (\"1e3\") & ']');\r\n  Put_Line (+\"  * Boolean'Value (\"\"True\"\")    : [\" & Boolean'Value (\"True\") & ']');\r\n  Put_Line (+\"  * Character'Value (\"\"'x'\"\")   : [\" & Character'Value (\"'x'\") & ']');\r\n  Put_Line (+\"  * Duration'Value (\"\"543.21\"\") : [\" & Duration'Value (\"543.21\") & ']');\r\n  Put_Line (+\"    Enum'Value (\"\"dd\"\")         : [\" & Enum'Image (Enum'Value (\"dd\")) & ']');\r\n\r\n  New_Line;\r\n  --  Test Strings_as_VStrings on some operators and HAT overloaded subprograms.\r\n  for x in Enum loop\r\n    Set_Env (Enum'Image (x), +\"Set_to_\" & Enum'Image (x));\r\n  end loop;\r\n  --\r\n  for x in Enum'First .. Enum'Last loop  --  Identical to `for x in Enum loop`\r\n    Put_Line (+\"Env. variable   \" & Enum'Image (x) & \"   has the value   \" & Get_Env (Enum'Image (x)));\r\n  end loop;\r\n  New_Line;\r\n  for x in Enum'Range loop  --  `Enum'Range` is a shortcut for `Enum'First .. Enum'Last`\r\n    Put_Line (+\"Env. variable   \" & Enum'Image (x) & \"   has the value   \" & Get_Env (Enum'Image (x)));\r\n  end loop;\r\n\r\n  New_Line;\r\n  Put_Line (\"A'First, A'Last, A'Range, A'Length attributes for array type A\");\r\n  Put_Line (\"--------------------------------------------------------------\");\r\n  New_Line;\r\n  Put_Line  (\"  * A'First   (should be BB of type Enum) : \" & Enum'Image (A'First));\r\n  Put_Line  (\"  * A'Last    (should be CC of type Enum) : \" & Enum'Image (A'Last));\r\n  Put_Line (+\"  * A'Length  (should be 2) : \" & A'Length);\r\n\r\n  for x in A'Range loop\r\n    Put_Line (+\"Env. variable   \" & Enum'Image (x) & \"   has the value   \" & Get_Env (Enum'Image (x)));\r\n  end loop;\r\n\r\n  New_Line;\r\n  Put_Line (\"M'First (N), M'Last (N), M'Range (N), M'Length (N) attributes\");\r\n  Put_Line (\"---   M = Multidimensional array type, mm = object of type M.\");\r\n  Put_Line (\"-------------------------------------------------------------\");\r\n  New_Line;\r\n  Put_Line (+\"  * M'First (1)  (should be -5) : \" & M'First (1));\r\n  Put_Line (+\"  * mm'Last (1)  (should be -2) : \" & mm'Last (1));\r\n  Put_Line  (\"  * M'First (2)  (should be BB) : \" & Enum'Image (M'First (2)));\r\n  Put_Line  (\"  * mm'Last (2)  (should be DD) : \" & Enum'Image (mm'Last (2)));\r\n\r\n  for i in M'Range (1) loop\r\n    for j in M'Range (2) loop\r\n      mm (i, j) := i * Enum'Pos (j);\r\n    end loop;\r\n  end loop;\r\n\r\n  sum := 0;\r\n  for j in M'Range (2) loop\r\n    for i in M'Range (1) loop\r\n      sum := sum + mm (i, j);\r\n    end loop;\r\n  end loop;\r\n  Put_Line (+\"Sum of elements in the matrix: \" & sum);\r\n\r\nend Attributes;\r\n"
  },
  {
    "path": "exm/auto_complete.adb",
    "content": "--  Algo for auto-complete (e.g. in LEA):\n--  Find_Possible_Declarations in HAC_Sys.Targets.Semantics\n--\n--  Identifier table: hac -d auto_complete.adb\n--\nprocedure Auto_Complete is\n  a : Integer := 0;\n  procedure Sub (b: Boolean) is\n    c : Integer := a;\n  begin\n    --  Here a, c, b are visible\n    c := c + a;\n  end;\n  d : Integer;\nbegin\n  --  Here a, d are visible\n  d := a;\nend Auto_Complete;\n"
  },
  {
    "path": "exm/barnes.adb",
    "content": "--  Puzzle presented by John Barnes in the restaurant \"De Abt\" in Ghent,\n--  the 15th of June 2022, during the Ada-Europe 2022 conference\n--            http://www.ada-europe.org/conference2022/\n--\n--  The question is (from memory):\n--\n--       \"Find the integer (there is only one) with all decimal digits appearing\n--        once and only once, for which the number formed by the first\n--        two digits can be divided by two, the number formed by the\n--        first three digits can be divided by three, and so on.\"\n--\n--  Solution by J-P Rosen, adapted to the HAC subset and added to HAC's regression suite.\n--  The original solution is reproduced as a comment at the bottom of this procedure.\n\nwith HAT;\nwith Interfaces;\n\nprocedure Barnes is\n   use HAT, Interfaces;\n\n   subtype My_Int is Interfaces.Integer_64 range 0 .. 1e11;\n   subtype Digit_Range is My_Int range 1 .. 10;\n   type Digit_String is array (Digit_Range) of My_Int;\n\n   subtype Coeff_Range is My_Int range 0 .. 9;\n\n   Coeff : array (Coeff_Range) of My_Int;\n\n   compiler_regression_test_mode : constant Boolean := Argument_Count > 0;\n\n   procedure Put_Solution (S : Digit_String) is\n      Chars : constant array (Coeff_Range) of Character := \"0123456789\";\n      Res : My_Int := 0;\n   begin\n      if compiler_regression_test_mode then\n         for I in S'Range loop\n            Res := Res * 10 + Character'Pos (Chars (S (I))) - Character'Pos ('0');\n         end loop;\n         if Res /= My_Int'Value (To_String (Argument (1))) then\n            Put_Line (\"   ----> Compiler test failed.\");\n            Set_Exit_Status (1);\n         end if;\n      else\n         Put (\"Solution = \");\n         for I in S'Range loop\n            Put (Chars (S (I)));\n         end loop;\n         New_Line;\n      end if;\n   end Put_Solution;\n\n   function Is_Possible (S : Digit_String; Last : My_Int) return Boolean is\n      Seen : array (Coeff_Range) of Boolean;\n      Accu : My_Int := 0;\n   begin\n      for K in Seen'Range loop\n        Seen (K) := False;\n      end loop;\n      for I in S'First .. Last loop\n         if Seen (S (I)) then\n            return False;\n         end if;\n         Seen (S (I)) := True;\n         Accu := Accu + S (I) * Coeff (Last - I);\n      end loop;\n      return Accu mod Last = 0;\n   end Is_Possible;\n\n   subtype My_Positive_Digit is My_Int range 1 .. 9;\n   subtype My_One_To_Four_Digit is My_Int range 1 .. 4;\n\n   Candidate : Digit_String;\n\n   procedure Try_Combinations is\n      D5 : constant := 5;\n   begin\n      Candidate (5) := D5;\n      --  Small optimizations:\n      --  Last digit is 0 (dividable by 10) => not other digit is 0\n      --  Fifth digit is 5 (dividable by 5 and not a 0)\n      --  Second digit is even => 2, 4, 6, 8\n      for D1 in My_Positive_Digit loop\n         Candidate (1) := D1;\n         for D2 in My_One_To_Four_Digit loop\n            Candidate (2) := 2 * D2;\n            if Is_Possible (Candidate, 2) then\n               for D3 in My_Positive_Digit loop\n                  Candidate (3) := D3;\n                  if Is_Possible (Candidate, 3) then\n                     for D4 in My_Positive_Digit loop\n                        Candidate (4) := D4;\n                        if Is_Possible (Candidate, 4) then\n                           for D6 in My_Positive_Digit loop\n                              Candidate (6) := D6;\n                              if Is_Possible (Candidate, 6) then\n                                 for D7 in My_Positive_Digit loop\n                                    Candidate (7) := D7;\n                                    if Is_Possible (Candidate, 7) then\n                                       for D8 in My_Positive_Digit loop\n                                          Candidate (8) := D8;\n                                          if Is_Possible (Candidate, 8) then\n                                             for D9 in My_Positive_Digit loop\n                                                Candidate (9) := D9;\n                                                if Is_Possible (Candidate, 9) then\n                                                   Candidate (10) := 0;\n                                                   Put_Solution (Candidate);\n                                                   return;\n                                                end if;\n                                             end loop;\n                                          end if;\n                                       end loop;\n                                    end if;\n                                 end loop;\n                              end if;\n                           end loop;\n                        end if;\n                     end loop;\n                  end if;\n               end loop;\n            end if;\n         end loop;\n      end loop;\n   end Try_Combinations;\n\nbegin\n   if not compiler_regression_test_mode then\n      Put_Line (\"Find the integer (there is only one) with all decimal digits appearing\");\n      Put_Line (\"once and only once, for which the number formed by the first\");\n      Put_Line (\"two digits can be divided by two, the number formed by the\");\n      Put_Line (\"first three digits can be divided by three, and so on.\");\n      New_Line;\n   end if;\n   --\n   Coeff (0) := 1;\n   for I in My_Positive_Digit loop\n      Coeff (I) := Coeff (I - 1) * 10;\n   end loop;\n   --\n   Try_Combinations;\nend Barnes;\n\n------------------------------------------------\n--  Original \"full Ada\" program by J-P Rosen  --\n------------------------------------------------\n--\n--\n--  with Ada.Text_IO;\n--  procedure Barnes is\n--     use Ada.Text_Io;\n--\n--     type My_Int is range 0 .. 10**11;\n--     Terminated : exception;\n--     D5         : constant My_Int := 5;\n--     type Digit_String is array (My_Int range <>) of My_Int;\n--     Coeff      : array (My_Int range 0 .. 9) of My_Int;\n--\n--     procedure Put (S : Digit_String) is\n--        Chars : constant array (My_Int range 0 .. 9) of Character := \"0123456789\";\n--     begin\n--        for I in S'Range loop\n--           Put (Chars (S (I)));\n--        end loop;\n--     end Put;\n--\n--     function Is_Possible (S : Digit_String) return Boolean is\n--        Seen : array (My_Int range 0..9) of Boolean := (others => False);\n--        Accu : My_Int := 0;\n--     begin\n--        for I in S'Range loop\n--           if Seen (S(I)) then\n--              return False;\n--           end if;\n--           Seen (S(I)) := True;\n--           Accu := Accu + S (I) * Coeff (S'Last - I);\n--        end loop;\n--        return Accu mod S'Length = 0;\n--     end Is_Possible;\n--\n--  begin\n--     Coeff (0) := 1;\n--     for I in My_Int range 1 .. 9 loop\n--        Coeff (I) := Coeff (I - 1) * 10;\n--     end loop;\n--\n--     -- Small optimizations:\n--     -- Last digit is 0 (dividable by 10) => not other digit is 0\n--     -- Fifth digit is 5 (dividable by 5 and not 0)\n--     -- Second digit is even (hence not 1 or 9)\n--     for D1 in My_Int range 1 .. 9 loop\n--        for D2 in My_Int range 2 .. 8 loop\n--           if Is_Possible ((D1, D2)) then\n--              for D3 in My_Int range 1 .. 9 loop\n--                 if Is_Possible ((D1, D2, D3)) then\n--                    for D4 in My_Int range 1 .. 9 loop\n--                       if Is_Possible ((D1, D2, D3, D4)) then\n--                          for D6 in My_Int range 1 .. 9 loop\n--                             if Is_Possible ((D1, D2, D3, D4, D5, D6)) then\n--                                for D7 in My_Int range 1 .. 9 loop\n--                                   if Is_Possible ((D1, D2, D3, D4, D5, D6, D7)) then\n--                                      for D8 in My_Int range 1 .. 9 loop\n--                                         if Is_Possible ((D1, D2, D3, D4, D5, D6, D7, D8)) then\n--                                            for D9 in My_Int range 1 .. 9 loop\n--                                               if Is_Possible ((D1, D2, D3, D4, D5, D6, D7, D8, D9)) then\n--                                                  Put (\"Solution = \");\n--                                                  Put (Digit_String'(D1, D2, D3, D4, D5, D6, D7, D8, D9, 0));\n--                                                  New_Line;\n--                                                  raise Terminated;\n--                                               end if;\n--                                            end loop;\n--                                         end if;\n--                                      end loop;\n--                                   end if;\n--                                end loop;\n--                             end if;\n--                          end loop;\n--                       end if;\n--                    end loop;\n--                 end if;\n--              end loop;\n--           end if;\n--        end loop;\n--     end loop;\n--  exception\n--     when Terminated =>\n--        null;\n--  end Barnes;\n"
  },
  {
    "path": "exm/binomials.adb",
    "content": "with HAT;\n\nprocedure Binomials is\n\n  function Factorial (n : Natural) return Positive is\n  begin\n    if n = 0 then\n      return 1;\n    else\n      return n * Factorial (n - 1);\n    end if;\n  end Factorial;\n\n  --  Returns the binomial coefficient  /n\\\n  --                                    \\k/\n\n  function Binomial (n, k : Natural) return Positive is\n  begin\n    return Factorial (n) / (Factorial (k) * Factorial (n - k));\n  end Binomial;\n\n  use HAT;\n\nbegin\n  for n in 1 .. 10 loop\n    Put (\"n = \"); Put_Line (n, 0);\n    Put_Line (\"k= binomial (n,k)=\");\n    for k in 1 .. n - 1 loop\n      Put (k, 0); Put (\": \"); Put_Line (Binomial (n, k), 0);\n    end loop;\n    New_Line;\n  end loop;\nend Binomials;\n"
  },
  {
    "path": "exm/bwt.adb",
    "content": "--  Burrows-Wheeler Transform: block-sorting\n--  preprocessing for improving data compression.\n--  This technique is used in the BZip2 format.\n--\n--  https://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transform\n--\n--  HAC example derived from extras/bwt* files in Zip-Ada project.\n--\nwith HAT;\n\nprocedure BWT is\n  use HAT;\n\n  n : constant := 52;\n  default : constant VString := +\"Mary had a little lamb, its fleece was white as snow\";\n\n  subtype Row is String (1 .. n);\n\n  type Table is array (1 .. n) of Row;\n\n  procedure Shell_Sort (b : in out Table) is\n    i, j, step : Integer;\n    step_size : array (1 .. 4) of Integer;\n    stop : Boolean;\n    temp : Row;\n  begin\n    --  'steps' contains decreasing increments for each\n    --  pass. The last pass has increment 1.\n    step_size (4) := 1;\n    for pass in reverse 1 .. 3 loop\n      step_size (pass) := 2 * step_size (pass + 1);\n    end loop;\n  Passes :\n    for pass in 1 .. 4 loop\n      step := step_size (pass);\n      --  Do a straight insertion sort with 'step' as\n      --  an increment instead of 1.\n      i := step + 1;\n      while i <= n loop\n        temp := b (i);\n        j := i;\n        stop := False;\n        while j > step and not stop loop\n          j := j - step;\n          if b (j) > temp then\n            b (j + step) := b (j);\n          else\n            b (j + step) := temp;\n            stop := True;\n          end if;\n        end loop;\n        if not stop then\n          b (1) := temp;\n        end if;\n        i := i + step;\n      end loop;\n    end loop Passes;\n  end Shell_Sort;\n\n  procedure Show (m : Table; message : VString; original : Natural) is\n  begin\n    Put_Line (\"---- BWT Table: \" & message & \" ----\");\n    for i in 1 .. n loop\n      if i = original then\n        Put (\"--original-->\");\n      else\n        Put (\"             \");\n      end if;\n      Put (i, 4);\n      Put (' ');\n      for j in 1 .. n loop\n        Put (m (i)(j));\n      end loop;\n      New_Line;\n    end loop;\n  end Show;\n\n  s, t, u : Row;\n  m : Table;\n  row_index : Positive;\n  line : VString;\n\nbegin\n  --  Put_Line (+\"Enter \" & n & \" characters (until and including '*' position\");\n  --  Put_Line ((n - 1) * '.' & '*');\n  --  Get_Line (line);\n  line := default;\n  --\n  for i in 1 .. n loop\n    s (i) := Element (line, i);\n  end loop;\n  New_Line;\n  --  Fill the matrix\n  for i in 1 .. n loop\n    for j in 1 .. n loop\n      m (i)(j) := Element (line, (1 + (j - 1 + i - 1) mod n));\n    end loop;\n  end loop;\n  --\n  Show (m, +\"unsorted ( (i-1) rotations for row i )\", 1);\n  -----------------\n  --  Transform  --\n  -----------------\n  Shell_Sort (m);\n  for i in 1 .. n loop\n    t (i) := m (i)(n);\n    if m (i) = s then\n      row_index := i;  --  Found row with the message with 0 rotation.\n    end if;\n  end loop;\n  Show (m, +\"sorted\", row_index);\n  --\n  Put_Line (\"BWT output (last column of matrix):\");\n  Put_Line (n * '-');\n  Put_Line (\"t = \" & t);\n  Put_Line (n * '-');\n  Put_Line (+\"Index of row containing the original message is: \" & row_index);\n  --------------------\n  --  De-transform  --\n  --------------------\n  for i in 1 .. n loop\n    for j in 1 .. n loop\n      m (i)(j) := ' ';\n    end loop;\n  end loop;\n  Shift_Insert_Sort :\n  for iter in 1 .. n loop\n    --  Shift columns right\n    for i in 1 .. n loop\n      for j in reverse 2 .. n loop\n        m (i)(j) := m (i)(j - 1);\n      end loop;\n    end loop;\n    --  Insert transformed string t as first column (again and again).\n    --\n    --  The miracle: after iteration #1, t(i) is the correct predecessor\n    --  of the character on sorted partial row i (1 character).\n    --  This gives the full list of pairs.\n    --\n    --  After 2nd sorting (end of iteration #2), t(i) is also the correct\n    --  predecessor each sorted pair.\n    --  We have then the list of all triplets. And so on.\n    --\n    for i in 1 .. n loop\n      m (i)(1) := t (i);\n    end loop;\n    Show (m, +\"insert #\" & iter, 0);\n    Shell_Sort (m);\n    Show (m, +\"sort #\" & iter, 0);\n  end loop Shift_Insert_Sort;\n  --  After iteration n we have a sorted list of all rotated\n  --  versions of the original string. The table is identical\n  --  to the table after encoding.\n  --  The original string is at row 'row_index'.\n  u := m (row_index);\n  --\n  --  Output of table.\n  --\n  Show (m, +\"reconstructed\", row_index);\n  --\n  Put_Line (\"BWT output de-transformed.\");\n  --\n  Put_Line (n * '-');\n  Put_Line (u);\nend BWT;\n"
  },
  {
    "path": "exm/ce_b_2.adb",
    "content": "--  Run-time Constraint_Error following a subtype Range Check\n\nprocedure CE_b_2 is\n  subtype Yes_Men is Boolean range True .. True;\n  i : Yes_Men;\n  j : Boolean := False;\nbegin\n  i := j;\nend CE_b_2; "
  },
  {
    "path": "exm/ce_b_4.adb",
    "content": "--  Run-time Constraint_Error following a array Range Check\n\nprocedure CE_b_4 is\n\n  subtype Yes_Men is Boolean range True .. True;\n\n  key : array (Yes_Men) of Boolean;\n\n  i : Boolean := False;\n\nbegin\n  key (i) := True;\nend CE_b_4;"
  },
  {
    "path": "exm/ce_c_2.adb",
    "content": "--  Run-time Constraint_Error following a subtype Range Check\n\nprocedure CE_c_2 is\n  subtype Alpha is Character range 'A' .. 'Z';\n  i : Alpha;\n  j : Character := 'a';\nbegin\n  i := j;\nend CE_c_2;"
  },
  {
    "path": "exm/ce_c_4.adb",
    "content": "--  Run-time Constraint_Error following a array Range Check\n\nprocedure CE_c_4 is\n\n  subtype Alpha is Character range 'A' .. 'Z';\n  key : array (Alpha) of Boolean;\n  i : Character := 'a';\n  \nbegin\n  key (i) := True;\nend CE_c_4;"
  },
  {
    "path": "exm/ce_e_1.adb",
    "content": "--  Compile-time Constraint_Error following a subtype Range Check\n\nprocedure CE_e_1 is\n\n  type Compression_Method is\n   (Store,\n    --\n    Deflate_Fixed,\n    Deflate_0,\n    Deflate_1,\n    Deflate_2,\n    Deflate_3,\n    Deflate_R,\n    --\n    LZMA_0,\n    LZMA_1,\n    LZMA_2,\n    LZMA_3);\n\n  subtype Deflation_Method is Compression_Method range Deflate_Fixed .. Deflate_R;\n\n  subtype Correct is Deflation_Method range Deflate_1 .. Deflate_3;\n  subtype Wrong   is Deflation_Method range LZMA_0 .. LZMA_3;\n\nbegin\n  null;\nend CE_e_2;"
  },
  {
    "path": "exm/ce_e_2.adb",
    "content": "--  Run-time Constraint_Error following a subtype Range Check\n\nprocedure CE_e_2 is\n\n  type Compression_Method is\n   (Store,\n    Shrink,\n    Reduce_1,\n    Reduce_2,\n    Reduce_3,\n    Reduce_4,\n    --\n    Deflate_Fixed,\n    Deflate_0,\n    Deflate_1,\n    Deflate_2,\n    Deflate_3,\n    Deflate_R,\n    --\n    LZMA_0,\n    LZMA_1,\n    LZMA_2,\n    LZMA_3);\n\n  subtype Reduction_Method is Compression_Method range Reduce_1 .. Reduce_4;\n  subtype Deflation_Method is Compression_Method range Deflate_Fixed .. Deflate_R;\n\n  i : Deflation_Method;\n  j : Compression_Method := Reduce_3;\n  k : Reduction_Method;\n\nbegin\n  i := j;\nend CE_e_2;"
  },
  {
    "path": "exm/ce_e_4.adb",
    "content": "--  Run-time Constraint_Error following a array Range Check\n\nprocedure CE_e_4 is\n\n  type Compression_Method is\n   (Store,\n    Shrink,\n    Reduce_1,\n    Reduce_2,\n    Reduce_3,\n    Reduce_4,\n    --\n    Deflate_Fixed,\n    Deflate_0,\n    Deflate_1,\n    Deflate_2,\n    Deflate_3,\n    Deflate_R,\n    --\n    LZMA_0,\n    LZMA_1,\n    LZMA_2,\n    LZMA_3);\n\n  subtype Reduction_Method is Compression_Method range Reduce_1 .. Reduce_4;\n  subtype Deflation_Method is Compression_Method range Deflate_Fixed .. Deflate_R;\n\n  key : array (Deflation_Method) of Boolean;\n  i : Deflation_Method;\n  j : Compression_Method := Reduce_3;\n  k : Reduction_Method;\n\nbegin\n  key (j) := True;\nend CE_e_4;"
  },
  {
    "path": "exm/ce_i_1.adb",
    "content": "--  Compile-time Constraint_Error following a subtype Range Check\r\n\r\nprocedure CE_i_1 is\r\n  i : Positive;\r\nbegin\r\n  i := -1;\r\nend CE_i_1;\r\n"
  },
  {
    "path": "exm/ce_i_2.adb",
    "content": "--  Run-time Constraint_Error following a subtype Range Check\n\nprocedure CE_i_2 is\n\n  subtype Zero_to_Nine is Integer range 0 .. 9;\n\n  subtype Negative_Temp is Integer range -273 .. -1;\n\n  i : Positive;\n  j : Integer := 1;\n  \nbegin\n  i := -j;\nend CE_i_2; "
  },
  {
    "path": "exm/ce_i_3.adb",
    "content": "--  Compile-time Constraint_Error following an array Range Check\r\n\r\nprocedure CE_i_3 is\r\n  a : array (1 .. 5) of Integer;\r\nbegin\r\n  a (7) := 2;\r\nend CE_i_3;\r\n"
  },
  {
    "path": "exm/ce_i_4.adb",
    "content": "--  Run-time Constraint_Error following a array Range Check\n\nprocedure CE_i_4 is\n\n  subtype Zero_to_Nine is Integer range 0 .. 9;\n\n  key : array (Zero_to_Nine) of Boolean;\n \n  i : Integer := -3;\n \nbegin\n  key (i) := True;\nend CE_i_4;"
  },
  {
    "path": "exm/console_io.adb",
    "content": "--  Demo of Get / Get_Immediate / Get_Line / Skip_Line / Put / Put_Line / New_Line\n--  on the console.\n--  No file involved, unless using:  \"hac console_io.adb <in_file.txt >out_file.txt\"\n\nwith HAT; use HAT;\n\nprocedure Console_IO is\n\n  procedure Test_Get is\n    C1, C2 : Character;\n    I1, I2 : Integer;\n    R1, R2 : Real;\n    V : VString;\n  begin\n    if Get_Needs_Skip_Line then\n      --  Console mode (via the \"hac\" command, or when compiled with a \"full Ada\" compiler).\n      Put (\"Type 2 characters, then Return.\");\n    else\n      --  GUI mode, like from the LEA editor.\n      Put_Line (\"Type 2 characters - one each time!\");\n    end if;\n    Get (C1); Get (C2);\n    if Get_Needs_Skip_Line then Skip_Line; end if;\n    Put_Line (+\"You have typed [\" & C1 & \"] [\" & C2 & \"]\");\n    --\n    if Get_Needs_Skip_Line then\n      Put_Line (\"Type 2 characters. This time there is no need for pressing Return.\");\n      Get_Immediate (C1); Put (+\"[\" & C1 & ']');\n      Get_Immediate (C2); Put (+\"[\" & C2 & ']');\n      New_Line;\n      Put_Line (+\"You have typed [\" & C1 & \"] [\" & C2 & \"]\");\n    end if;\n    --\n    if Get_Needs_Skip_Line then\n      Put (\"Type 2 integers (with a space inbetween), then Return.\");\n    else\n      Put_Line (\"Type 2 integers.\");\n    end if;\n    Get (I1); Get (I2);\n    if Get_Needs_Skip_Line then Skip_Line; end if;\n    Put_Line (+\"You have typed the numbers [\" & I1 & \"] [\" & Image (I2) & \"]\");\n    --\n    if Get_Needs_Skip_Line then\n      Put (\"Type 2 floats, then Return.\");\n    else\n      Put_Line (\"Type 2 floats.\");\n    end if;\n    Get (R1); Get (R2);\n    if Get_Needs_Skip_Line then Skip_Line; end if;\n    Put_Line (+\"You have typed the numbers [\" & R1 & \"] [\" & Image (R2) & \"]\");\n    --\n    Put (\"Type whatever you want, then Return.\");\n    Get_Line (V);\n    Put_Line (\"Congrats, you just typed: [\" & V & ']');\n  end Test_Get;\n\nbegin\n  Put_Line (\"Do we have a real console/terminal ? \");\n  if Get_Needs_Skip_Line then\n    Put_Line (\"Yes! Ada.Text_IO can get multiple inputs from the same line.\");\n    Put_Line (\"Skip_Line (a \"\"Return\"\" keypress) is needed after one or more Get\");\n  else\n    Put_Line (\"No! Perhaps this program is run from LEA ?...\");\n  end if;\n  Put (\"Please Press Return!\");\n  Skip_Line;\n  Put_Line (\"Bravo, you did it!\");\n  New_Line;\n  --\n  Test_Get;\nend Console_IO;\n"
  },
  {
    "path": "exm/covid_19_s.adb",
    "content": "--    ***  This HAC demo is a version of the COVID_19\n--    ***  program in MathPaqs. The program is scaled down for\n--    ***  meeting HAC v.0.074 syntax subset.\n--    ***  We mark the downscaling with \"!\" in comments.\n--    ***\n--    ***  For the original verion in full Ada, see \"covid_19.adb\" @\n--    ***    https://mathpaqs.sourceforge.io/ or\n--    ***    https://github.com/zertovitch/mathpaqs .\n----------------------------------------------------------------------------\n--  \"SEIR\" model for simulating the outbreak of the Coronavirus\n--  disease (COVID-19).\n\n--  This program solves a vectorial ordinary differential equation\n--  (or a system of ordinary differential equations).\n--\n--  * The unknown is a vector containing the values S, E, I, R.\n--    The letters stands for:\n--      S: Susceptible\n--      E: Exposed\n--      I: Infectious\n--      R: Recovered\n--  * There is a propagation of population in the\n--    direction S ---> E ---> I ---> R, plus new\n--    infections:  ^------<---\n--\n--  Related publication:\n--    Nowcasting and forecasting the potential domestic and\n--    international spread of the 2019-nCoV outbreak originating\n--    in Wuhan, China: a modelling study\n--\n--    https://www.thelancet.com/journals/lancet/article/PIIS0140-6736(20)30260-9/fulltext\n--\n--  Simplification here:\n--    - no flights: L_{W,I}, L_{W,C}, ... = 0\n--    - zoonotic force = 0.\n\nwith HAT;\n\nprocedure COVID_19_S is\n\n  use HAT;\n\n  type Status is (Susceptible, Exposed, Infectious, Recovered);\n\n  type Status_Vector is array (Status) of Real;\n\n  --  ! Full Ada: programmable operators (*, +, ...).\n\n  --  ! function \"*\" (l : Real; v : Status_Vector) return Status_Vector is\n  --  !   r : Status_Vector;\n  --  ! begin\n  --  !   for i in v'Range loop r(i) := v(i) * l; end loop;\n  --  !   return r;\n  --  ! end \"*\";\n\n  --  ! function \"+\" (a, b : Status_Vector) return Status_Vector is\n  --  !   r : Status_Vector;\n  --  ! begin\n  --  !   for i in a'Range loop r(i) := a(i) + b(i); end loop;\n  --  !   return r;\n  --  ! end \"+\";\n\n  procedure Times (l : Real; v : Status_Vector; r : out Status_Vector) is\n  begin\n    for i in Status loop r (i) := v (i) * l; end loop;\n  end Times;\n\n  procedure Plus (a, b : Status_Vector; r : out Status_Vector) is\n  begin\n    for i in Status loop r (i) := a (i) + b (i); end loop;\n  end Plus;\n\n  inv_incubation_period : constant Real := 1.0 / 5.2;\n  inv_infective_period  : constant Real := 1.0 / 2.9;\n\n  --  We solve numerically   x' (t) = f (x (t), t)   over the time step h.\n  --\n  procedure Evolution (xt : in out Status_Vector; reproductive_number : Real; h : Real) is\n    --\n    --  ! function f (x : Status_Vector) return Status_Vector is\n    --  ! Full Ada: functions with non-atomic results.\n\n    procedure f (x : Status_Vector; res_f : out Status_Vector) is\n      n, inv_n, s_to_e, e_to_i, nb_infected_over_period, susc_rate : Real;\n      --\n    begin\n      --  Count the population at time t.\n      n := 0.0;\n      for s in Status loop\n        n := n + x (s);\n      end loop;\n      inv_n := 1.0 / n;\n      nb_infected_over_period := x (Infectious) * inv_infective_period;\n      --  Some Susceptible persons get the virus\n      --  from Infectious people and become Exposed.\n      susc_rate := x (Susceptible) * inv_n;  --  As proportion of the population.\n      s_to_e := susc_rate * reproductive_number * nb_infected_over_period;\n      --  Exposed persons become Infectious after incubation.\n      e_to_i := x (Exposed) * inv_incubation_period;\n      --  Infectious people recover after infective period. -> Recovered.\n      --  This rate is already computed: nb_infected_over_period;\n      res_f (Susceptible) := -s_to_e;\n      res_f (Exposed) :=  s_to_e - e_to_i;\n      res_f (Infectious) :=           e_to_i - nb_infected_over_period;\n      res_f (Recovered) :=                    nb_infected_over_period;\n    end f;\n    k1, k2, k3, k4, tmp_a, tmp_b, dbk2, dbk3 : Status_Vector;\n  begin\n    --\n    --  ! Full Ada: sooooo much simpler with operators!\n    --\n    --  !  k1 := f (x               );\n    --  !  k2 := f (x + h * 0.5 * k1);\n    --  !  k3 := f (x + h * 0.5 * k2);\n    --  !  k4 := f (x + h *       k3);\n    --  !  x := x + h * (1.0/6.0) * (k1 + 2.0 * k2 + 2.0 * k3 + k4);\n    --\n    f (xt, k1);\n    --\n    Times (h * 0.5, k1, tmp_a);\n    Plus (xt, tmp_a, tmp_b);      --  tmp_b = xt + h * 0.5 * k1\n    f (tmp_b, k2);\n    --\n    Times (h * 0.5, k2, tmp_a);\n    Plus (xt, tmp_a, tmp_b);      --  tmp_b = xt + h * 0.5 * k2\n    f (tmp_b, k3);\n    --\n    Times (h, k3, tmp_a);\n    Plus (xt, tmp_a, tmp_b);      --  tmp_b = xt + h * k3\n    f (tmp_b, k4);\n    --\n    Times (2.0, k2, dbk2);\n    Times (2.0, k3, dbk3);\n    Plus (k1, dbk2, tmp_a);\n    Plus (tmp_a, dbk3, tmp_b);\n    Plus (tmp_b, k4, tmp_a);      --  tmp_a = (k1 + 2.0 * k2 + 2.0 * k3 + k4)\n    Times (h * (1.0 / 6.0), tmp_a, tmp_b);\n    Plus (xt, tmp_b, tmp_a);\n    xt := tmp_a;\n  end Evolution;\n\n  type Scenario is (No_Lockdown, Lockdown, Lockdown_in_two_Steps);\n\n  procedure Simulation (s : Scenario) is\n    --  ! use Ada.Text_IO, Ada.Integer_Text_IO, PFIO;\n    x : Status_Vector;\n    dt : Real;\n    reproductive_number : Real;\n    n_iter : Integer;\n    out_step : Integer;\n    rf : File_Type;\n    sep : constant Character := ';';\n    --  ! use Ada.Characters.Handling;\n    basic_reproductive_number : constant := 3.5;\n  begin\n    dt := 1.0;\n    n_iter := 365;\n    out_step := 1;\n    --  ! x :=\n    --  !   ( Susceptible => 1_000_000.0,\n    --  !     Exposed     =>         0.0,\n    --  !     Infectious  =>         1.0,  --  Patient 1.\n    --  !     Recovered   =>         0.0\n    --  !   );\n    x (Susceptible) := 1_000_000.0;\n    x (Exposed)     :=         0.0;\n    x (Infectious)  :=         1.0;  --  Patient 1.\n    x (Recovered)   :=         0.0;\n    --  Status numbers at time t = 0.\n\n    Create (rf, \"covid_19_s_\" & To_Lower (+Scenario'Image (s)) & \".csv\");\n    Put (rf, \"t\");\n    for l in Status loop\n      Put (rf, sep);\n      Put (rf, Status'Image (l));\n    end loop;\n    New_Line (rf);\n    for i in 0 .. n_iter loop\n      if i mod out_step = 0 then\n        Put (rf, i);\n        for l in Status loop\n          Put (rf, sep);\n          Put (rf, x (l), 4, 5, 0);\n        end loop;\n        New_Line (rf);\n      end if;\n      case s is\n        when No_Lockdown =>\n          reproductive_number := basic_reproductive_number;\n        when Lockdown =>\n          if i < 40 then\n            reproductive_number := basic_reproductive_number;\n          else\n            reproductive_number := 1.0;\n          end if;\n        when Lockdown_in_two_Steps =>\n          if i < 40 then\n            reproductive_number := basic_reproductive_number;\n          elsif i < 60 then\n            reproductive_number := 2.0;\n          else\n            reproductive_number := 1.0;\n          end if;\n      end case;\n      Evolution (x, reproductive_number, dt);\n    end loop;\n    Close (rf);\n  end Simulation;\n\nbegin\n  Put_Line (\"COVID_19_S Simulation\");\n  Put_Line (\"  -  SEIR prediction model. \");\n  Put_Line (\"Output in : covid*.csv\");\n  for s in Scenario loop\n    Simulation (s);\n  end loop;\n  Put_Line (\"Done\");\nend COVID_19_S;\n"
  },
  {
    "path": "exm/cross_a.adb",
    "content": "--  Example of cross-dependency in bodies\r\n\r\nwith Cross_B;\r\n\r\nwith HAT;\r\n\r\npackage body Cross_A is\r\n\r\n  procedure A (n : Natural) is\r\n    use HAT;\r\n  begin\r\n    if n > 0 then\r\n      Put_Line (\"A: \" & Image (n));\r\n      Cross_B.B (n - 1);\r\n    end if;\r\n  end A;\r\n\r\nend Cross_A;\r\n"
  },
  {
    "path": "exm/cross_a.ads",
    "content": "--  Example of cross-dependency in bodies\r\n\r\npackage Cross_A is\r\n\r\n  procedure A (n : Natural);\r\n\r\nend Cross_A;\r\n"
  },
  {
    "path": "exm/cross_b.adb",
    "content": "--  Example of cross-dependency in bodies\r\n\r\nwith Cross_A;\r\n\r\nwith HAT;\r\n\r\npackage body Cross_B is\r\n\r\n  procedure B (n : Natural) is\r\n    use HAT;\r\n  begin\r\n    if n > 0 then\r\n      Put_Line (\"B: \" & Image (n));\r\n      Cross_A.A (n - 1);\r\n    end if;\r\n  end B;\r\n\r\nend Cross_B;\r\n"
  },
  {
    "path": "exm/cross_b.ads",
    "content": "--  Example of cross-dependency in bodies\r\n\r\npackage Cross_B is\r\n\r\n  procedure B (n : Natural);\r\n\r\nend Cross_B;\r\n"
  },
  {
    "path": "exm/days_1901.adb",
    "content": "--  Prototype developed using HAC [1] and LEA [2], for portable date output of Excel Writer [3].\r\n--\r\n--  [1]: http://hacadacompiler.sf.net/\r\n--  [2]: http://l-e-a.sf.net/\r\n--  [3]: http://excel-writer.sf.net/\r\n\r\nwith HAT; use HAT;\r\n\r\nprocedure Days_1901 is\r\n\r\n  --  1901 is the lowest year supported by Ada.Calendar.\r\n  --  1900 is not a leap year, but Lotus 1-2-3 then Excel consider it as a leap year.\r\n  --  So, with 1901, we skip that issue anyway...\r\n  --\r\n  function Days_since_1901 (y, m, d : Integer) return Integer is\r\n    function Is_leap (y : Integer) return Boolean is\r\n    begin\r\n      if y mod 4 = 0 then\r\n        if y mod 100 = 0 then\r\n          if y mod 400 = 0 then\r\n            return True;\r\n          else\r\n            return False;\r\n          end if;\r\n        else\r\n          return True;\r\n        end if;\r\n      else\r\n        return False;\r\n      end if;\r\n    end Is_leap;\r\n    days_of_previous_months : Integer;\r\n    days_of_previous_years  : Integer;\r\n    y_diff, y_diff_4, y_diff_100, y_diff_400 : Integer;\r\n  begin\r\n    case m is\r\n      when 02 => days_of_previous_months := 31;\r\n      when 03 => days_of_previous_months := 59;\r\n      when 04 => days_of_previous_months := 90;\r\n      when 05 => days_of_previous_months := 120;\r\n      when 06 => days_of_previous_months := 151;\r\n      when 07 => days_of_previous_months := 181;\r\n      when 08 => days_of_previous_months := 212;\r\n      when 09 => days_of_previous_months := 243;\r\n      when 10 => days_of_previous_months := 273;\r\n      when 11 => days_of_previous_months := 304;\r\n      when 12 => days_of_previous_months := 334;\r\n      when others => days_of_previous_months := 0;\r\n    end case;\r\n    if (m > 2) and Is_leap (y) then  --  February has 29 days in leap years.\r\n      days_of_previous_months := days_of_previous_months + 1;\r\n    end if;\r\n    --\r\n    y_diff     := (y - 1)       - 1900;\r\n    y_diff_4   := (y - 1) / 4   - 1900 / 4;\r\n    y_diff_100 := (y - 1) / 100 - 1900 / 100;\r\n    y_diff_400 := (y - 1) / 400 - 1900 / 400;\r\n    --  Add leap years from 1901 (included) to now (excluded).\r\n    days_of_previous_years := 365 * y_diff + y_diff_4 - y_diff_100 + y_diff_400;\r\n    --\r\n    return days_of_previous_years + days_of_previous_months + d - 1;\r\n  end Days_since_1901;\r\n  --\r\nbegin\r\n  for y in 1901 .. 2200 loop\r\n    Put (\"Days from 1/1/1901 to : ... 12/31/\");\r\n    Put (y);\r\n    Put_Line (Days_since_1901 (y, 12, 31));\r\n  end loop;\r\nend Days_1901;\r\n"
  },
  {
    "path": "exm/directories.adb",
    "content": "--  This demo creates a few directories and then deletes them.\n\nwith HAT;\n\nprocedure Directories is\n  use HAT;\nbegin\n  Create_Directory (\"dir_a\");\n  Create_Path (\"dir_b/dir_c/dir_d\");\n  Put (\"Check your current directory and spot \"\"dir_a\"\", \"\"dir_b\"\".\");\n  Skip_Line;\n  Delete_Directory (\"dir_a\");\n  Put_Line (\"\"\"dir_a\"\" has been deleted.\");\n  Delete_Directory (\"dir_b/dir_c/dir_d\");\n  Put_Line (\"\"\"dir_b/dir_c/dir_d\"\" has been deleted.\");\n  Delete_Directory (\"dir_b/dir_c\");\n  Put_Line (\"\"\"dir_b/dir_c\"\" has been deleted.\");\n  Delete_Directory (\"dir_b\");\n  Put_Line (\"\"\"dir_b\"\" has been deleted.\");\nend Directories;\n"
  },
  {
    "path": "exm/doors.adb",
    "content": "--  Special version (for HAC) of https://rosettacode.org/wiki/100_doors#Ada\n\n--        \"There are 100 doors in a row that are all initially closed.\n--         You make 100 passes by the doors.\n--         The first time through, visit every door and toggle the door (if the\n--           door is closed, open it;   if it is open,  close it).\n--         The second time, only visit every 2nd door   (door #2, #4, #6, ...),\n--           and toggle it.\n--         The third time, visit every 3rd door (door #3, #6, #9, ...), etc,\n--           until you only visit the 100th door.\n--\n--   Rosetta Task: Answer the questions:\n--     What state are the doors in after the last pass?\n--     Which are open, which are closed?\n--\n--   Alternate: As noted in https://rosettacode.org/wiki/Talk:100_doors\n--     the only doors that remain open are those whose numbers are perfect squares.\"\n\nwith HAT;\n\nprocedure Doors is\n\n  type Door_State is (Closed, Open);\n\n  last_door : constant := 100;\n  subtype Door_Range is Integer range 1 .. last_door;\n\n  type Door_List is array (Door_Range) of Door_State;\n  the_doors : Door_List;  --  := (others => Closed);\n\nbegin\n  for i in Door_Range loop\n    the_doors (i) := Closed;\n  end loop;\n\n  for i in Door_Range loop\n    for j in Door_Range loop\n      if j mod i = 0 then\n        if the_doors (j) = Closed then\n          the_doors (j) := Open;\n        else\n          the_doors (j) := Closed;\n        end if;\n      end if;\n    end loop;\n  end loop;\n\n  for i in Door_Range loop\n    HAT.Put_Line (\"Door\" & i'Image & \" is \" & the_doors (i)'Image);\n  end loop;\nend Doors;\n"
  },
  {
    "path": "exm/draw_sphere.adb",
    "content": "--  https://rosettacode.org/wiki/Draw_a_sphere\n--  This version is inspired from the ASCII Art C program with\n--  some improvements and explanations.\n\nwith HAT;\n\nprocedure Draw_Sphere is\n\n  use HAT;\n\n  type Point is record\n    x, y, z : Real;\n  end record;\n\n  shades : constant String (1 .. 14) := \"@%&$#XMIeo!*:.\";\n\n  procedure Normalize (x, y, z : Real; pt : out Point) is\n    len : constant Real := Sqrt (x * x + y * y + z * z);\n  begin\n    pt.x := x / len;\n    pt.y := y / len;\n    pt.z := z / len;\n  end Normalize;\n\n  function dot_product (a, b : Point) return Real is\n  begin\n    return a.x * b.x + a.y * b.y + a.z * b.z;\n  end dot_product;\n\n  light : Point;\n\n  procedure Draw_Sphere (r, k : Integer; ambient : Real) is\n    clarity, x, y, z2 : Real;\n    surface_point : Point;\n    shade_index : Integer;\n  begin\n    Normalize (30.0, 30.0, -50.0, light);\n    for i in -r .. r loop\n      x := Real (i) + 0.5;\n      for j in (-2) * r .. 2 * r loop\n        y := Real (j) / 2.0 + 0.5;\n        z2 := Real (r * r) - x * x - y * y;\n        if z2 >= 0.0 then\n          Normalize (x, y, Sqrt (z2), surface_point);\n          clarity := Max (0.0, -dot_product (light, surface_point)) ** k + ambient;\n          shade_index := shades'First +  Integer (clarity * Real (shades'Length));\n          --  Clamp:\n          shade_index := Min (shades'Last, Max (shades'First, shade_index));\n          Put (shades (shade_index));\n        else\n          Put (' ');\n        end if;\n      end loop;\n      New_Line;\n    end loop;\n  end Draw_Sphere;\n\nbegin\n  Draw_Sphere (25, 4, 0.02);\n  Draw_Sphere (16, 2, 0.02);\n  Draw_Sphere  (9, 2, 0.05);\n  Draw_Sphere  (4, 3, 0.10);\nend Draw_Sphere;\n"
  },
  {
    "path": "exm/e.cmd",
    "content": "@echo off\n\necho (Re-)building HAC\ncd..\ngprbuild -P hac.gpr hac\ncd exm\nset hacbuild=done\n\nif \"%1\"==\"\" goto gallery\n\nrem Try without extension\nif exist %1.adb ..\\hac -v2 %1.adb %2 %3 %4 %5 %6 %7 %8 %9\nif exist %1.adb goto fin\n\nrem Try with extension\n..\\hac -v2 %1 %2 %3 %4 %5 %6 %7 %8 %9\ngoto fin\n\n:gallery\n\n..\\hac gallery.adb\n\n:fin"
  },
  {
    "path": "exm/echo.adb",
    "content": "--  Example from command-line:  hac echo.adb <echo.adb >echo.txt\n\nwith HAT; use HAT;\n\nprocedure Echo is\n  s : VString;\nbegin\n  Put_Line (\"Type your messages (\"\"STOP!\"\" or Ctrl-Z to stop):\");\n  while not End_Of_File loop\n    Get_Line (s);\n    --  Exit door if program run from a console without Ctrl-Z :\n    exit when s = \"STOP!\";\n    Put_Line (\"This is the echo...  [\" & s & ']');\n  end loop;\nend Echo;\n"
  },
  {
    "path": "exm/einmaleins.adb",
    "content": "--  Example of use, just written \"live\" using the\n--  LEA editor, during a homeschooling session.\n\nwith HAT; use HAT;\n\nprocedure Einmaleins is\n  x, y : Integer;\nbegin\n  x := 2 + Rand (7);  --  Random, 2 to 9\n  y := 2 + Rand (7);  --  Random, 2 to 9\n  --\n  if Rnd < 0.5 then\n    x := x * 10;\n  else\n    y := y * 10;\n  end if;\n  --\n  Put (x, 0); Put (\" * \"); Put (y, 0); Put (\" = \"); Put (x * y, 0);\nend Einmaleins;\n"
  },
  {
    "path": "exm/embed_text.adb",
    "content": "--  This tool reads a text file and writes\n--  an Ada package with its contents.\n--\n--  https://www.reddit.com/r/ada/comments/1l3i9wl/embedding_a_text_file_in_an_ada_exe/\n\nwith HAT;\n\nprocedure Embed_Text is\n  use HAT;\n  s, pkg : VString;\n  f1, f2 : File_Type;\n  lines : Natural := 0;\n  c : Character;\n  type Output_Mode is (hac, full_ada);\n  output : Output_Mode := hac;\nbegin\n  if Argument_Count < 2 then\n    Put_Line (\"Embed_Text reads a text file and writes an Ada package with its contents.\");\n    Put_Line (\"Usage - \");\n    Put_Line (\"from HAC:              hac embed_text.adb TEXT_FILE Ada_Package_Name [-h] [-f]\");\n    Put_Line (\"built as executable:       embed_text     TEXT_FILE Ada_Package_Name [-h] [-f]\");\n    New_Line;\n    Put_Line (\"Produces: ada_package_name.ads, ada_package_name.adb, demo_ada_package_name.adb\");\n    New_Line;\n    Put_Line (\"Options: -h : produce sources for HAC, with HAT package (default)\");\n    Put_Line (\"         -f : produce sources for \"\"full Ada\"\", with Ada.* packages\");\n    return;\n  end if;\n  Open (f1, Argument (1));\n  pkg := Argument (2);\n  for i in 3 .. Argument_Count loop\n    if Argument (i) = \"-h\" then\n      output := hac;\n    elsif Argument (i) = \"-f\" then\n      output := full_ada;\n    end if;\n  end loop;\n  Create (f2, To_Lower (pkg) & \".adb\");\n  Put_Line (f2, \"package body \" & pkg & \" is\");\n  Put_Line (f2, \"  procedure Fill_Contents (text : out Embedded_Text) is\");\n  case output is\n    when hac      =>\n      Put_Line (f2, \"    use HAT;\");\n    when full_ada => \n      Put_Line (f2, \"    use Ada.Strings.Unbounded;\");\n      Put_Line (f2, \"    function \"\"+\"\" (S : String) return Unbounded_String renames To_Unbounded_String;\");\n  end case;\n  Put_Line (f2, \"  begin\");\n  while not End_Of_File (f1) loop\n    lines := lines + 1;\n    Get_Line (f1, s);\n    Put (f2, +\"    text (\" & lines & \") := +\"\"\");\n    for i in 1 .. Length (s) loop\n      c := Element (s, i);\n      if c = '\"' then\n        Put (f2, \"\"\"\"\"\");\n      else\n        Put (f2, c);\n      end if;\n    end loop;\n    Put_Line (f2, \"\"\";\");\n  end loop;\n  Close (f1);\n  Put_Line (f2,  \"  end Fill_Contents;\");\n  Put_Line (f2,  \"end \" & pkg & \";\");\n  Close (f2);\n  Create (f2, To_Lower (pkg) & \".ads\");\n  case output is\n    when hac      =>\n      Put_Line (f2,  \"with HAT;\");\n    when full_ada =>\n      Put_Line (f2,  \"with Ada.Strings.Unbounded;\");\n  end case;\n  Put_Line (f2,  \"package \" & pkg & \" is\");\n  Put (f2, +\"  type Embedded_Text is array (1 .. \" & lines & \") of \");\n  case output is\n    when hac      =>\n      Put_Line (f2,  \"HAT.VString;\");\n    when full_ada =>\n      Put_Line (f2,  \"Ada.Strings.Unbounded.Unbounded_String;\");\n  end case;\n  Put_Line (f2,  \"  procedure Fill_Contents (text : out Embedded_Text);\");\n  Put_Line (f2,  \"end \" & pkg & \";\");\n  Close (f2);\n  Create (f2, \"demo_\" & To_Lower (pkg) & \".adb\");\n  case output is\n    when hac      =>\n      Put_Line (f2,  \"with HAT;\");\n    when full_ada =>\n      Put_Line (f2,  \"with Ada.Strings.Unbounded, Ada.Text_IO;\");\n  end case;\n  Put_Line (f2,  \"with \" & pkg & ';');\n  Put_Line (f2,  \"procedure Demo_\" & pkg & \" is\");\n  Put_Line (f2,  \"  e : \" & pkg & \".Embedded_Text;\");\n  Put_Line (f2,  \"begin\");\n  Put_Line (f2,  \"  \" & pkg & \".Fill_Contents (e);\");\n  Put_Line (f2,  \"  for l in e'Range loop\");\n  case output is\n    when hac      =>\n      Put_Line (f2,  \"    HAT.Put_Line (e (l));\");\n    when full_ada =>\n      Put_Line (f2,  \"    Ada.Text_IO.Put_Line (Ada.Strings.Unbounded.To_String (e (l)));\");\n  end case;\n  Put_Line (f2,  \"  end loop;\");\n  Put_Line (f2,  \"end Demo_\" & pkg & ';');\n  Close (f2);\nend Embed_Text;\n"
  },
  {
    "path": "exm/env.adb",
    "content": "--  System's Environment Variables: Set & Get.\n\nwith HAT;\n\nprocedure Env is\n  use HAT;\n  path, path_v : VString;\nbegin\n  path   := Get_Env (\"PATH\");   --  String argument\n  path_v := Get_Env (+\"PATH\");  --  VString argument\n  --\n  Put_Line (\"The PATH (to happiness) is : \" & path);\n  if path /= path_v then\n    Put_Line (\"Uh ?\");\n  end if;\n  Set_Env (\"HAC_Rules\", \"Good Day, Ladies and Gentlemen!\");\n  New_Line;\n  Put_Line (\n    \"Important message from the environment variables: \" &\n    Get_Env (\"HAC_Rules\")\n  );\nend Env;\n"
  },
  {
    "path": "exm/existence.adb",
    "content": "with HAT; use HAT;\n\nprocedure Existence is\n  procedure Check (Name : VString) is\n    procedure Tell (Existing : Boolean; As : VString) is\n    begin\n      Put (Name);\n      if Existing then\n        Put (\" exists \");\n      else\n        Put (\" does not exist \");\n      end if;\n      Put_Line (+\"as \" & As);\n    end Tell;\n  begin\n    Tell (Exists (Name), +\"anything in the file system\");\n    Tell (Directory_Exists (Name), +\"a directory\");\n    Tell (File_Exists (Name), +\"a file\");\n  end Check;\nbegin\n  Check (+\"existence.adb\");\n  Check (+\"aoc\");\nend Existence;\n"
  },
  {
    "path": "exm/file_append.adb",
    "content": "--  This demo creates a file in multiple steps, via the Append procedure.\n\nwith HAT;\n\nprocedure File_Append is\n  use HAT;\n  f : File_Type;\n  n : constant VString := To_VString (\"file_append.txt\");\nbegin\n  Create (f, n);\n  Put_Line (f, \"0\");\n  Close (f);\n  --\n  for i in 1 .. 9 loop\n    Append (f, n);\n    Put_Line (f, i, 0);\n    Close (f);\n  end loop;\nend File_Append;\n"
  },
  {
    "path": "exm/file_copy.adb",
    "content": "--  This demo reads a text file (itself) and writes\n--  its contents in another text file.\n--\n--  NB: for copying a file (of any kind) with a single command,\n--  you can use Copy_File. See binary copy at the end of this demo.\n\nwith HAT;\n\nprocedure File_Copy is\n  use HAT;\n  s : VString;\n  f1, f2 : File_Type;\nbegin\n  Put_Line (\"Line-by-line text copy\");\n  Open (f1, \"file_copy.adb\");\n  Create (f2, \"file_copy.txt\");\n  while not End_Of_File (f1) loop\n    Get_Line (f1, s);\n    Put_Line (f2, s);\n  end loop;\n  Close (f1);\n  Close (f2);\n  --\n  Put_Line (\"Binary copy\");\n  --  It's an opportunity to test some Ada.Directories-like subprograms.\n  --\n  Copy_File (\"file_copy.adb\", \"file_copy_bin_$$.txt\");\n  if Exists (\"file_copy_bin.txt\") then\n    Delete_File (\"file_copy_bin.txt\");\n  end if;\n  Rename (\"file_copy_bin_$$.txt\", \"file_copy_bin.txt\");\nend File_Copy;\n"
  },
  {
    "path": "exm/file_read.adb",
    "content": "--  This demo reads a text file (itself) and displays\n--  its contents on the console.\n\nwith HAT;\n\nprocedure File_Read is\n  use HAT;\n  s : VString;\n  f : File_Type;\nbegin\n  Open (f, \"file_read.adb\");\n  while not End_Of_File (f) loop\n    Get_Line (f, s);\n    Put_Line (s);\n  end loop;\n  Close (f);\nend File_Read;\n"
  },
  {
    "path": "exm/fill_drive.adb",
    "content": "--  This script is useful for clearing the unused space of a drive.\n--  Typically, you have deleted sensitive data files, but you would like to\n--  prevent recovery of those file contents, but you would still like to\n--  keep other files (so, you avoid a new formatting or wipeout of the drive).\n\nwith HAT; use HAT;\n\nprocedure Fill_Drive is\n  f : File_Type;\nbegin\n  Create (f, \"garbage_delete_me.txt\");\n  loop\n    Put_Line (f, \"Bla bla bla bla bla bla and more bla bla bla bla bla!\");\n    --  TBD: randomized version.\n  end loop;\nend Fill_Drive;\n"
  },
  {
    "path": "exm/gallery.adb",
    "content": "--  We launch new instances of HAC (possibly from HAC itself, too).\n--  Usage: hac gallery.adb\n\nwith HAT; use HAT;\n\nprocedure Gallery is\n\n  procedure Launch_Demos is\n\n    procedure Shell (command : VString; echo : Boolean) is\n    begin\n      if echo then\n        Put_Line (\"Executing: [\" & command & ']');\n      end if;\n      Shell_Execute (command);\n    end Shell;\n\n    procedure Launch_HAC (Ada_file_name : VString) is\n      dummy : Character;\n    begin\n      Shell (\n        +\"..\" & Directory_Separator & \"hac -v2 \" & Ada_file_name,\n        False\n      );\n      Put (\"--- Press any key to continue in the HAC gallery...\");\n      Get_Immediate (dummy);\n      New_Line;\n    end Launch_HAC;\n\n    procedure Build_HAC is\n    begin\n      if Get_Env (\"hacbuild\") = \"done\" then\n        return;\n      end if;\n      Put_Line (\"(Re-)building HAC, in case the present program isn't run from HAC...\");\n      Shell (+\"gprbuild -p -P ..\" & Directory_Separator & \"hac\", True);\n    end Build_HAC;\n\n  begin\n    Build_HAC;  --  Redundant if this program is itself run through HAC.\n    --\n    Launch_HAC (+\"hello.adb\");\n    Launch_HAC (+\"attributes.adb\");\n    Launch_HAC (+\"maze_gen.adb\");\n    Launch_HAC (+\"strings_demo.adb\");\n    Launch_HAC (+\"env.adb\");\n    Launch_HAC (+\"arguments.adb arg1 arg2 \"\"arg 3 ...\"\" arg4\");\n    Launch_HAC (+\"ackermann.adb\");\n    Launch_HAC (+\"anti_primes.adb\");\n    Launch_HAC (+\"doors.adb\");\n    Launch_HAC (+\"hofstadter.adb\");\n    Launch_HAC (+\"mandelbrot.adb\");\n    Launch_HAC (+\"shell_sort.adb\");\n    Launch_HAC (+\"merge_sort.adb\");\n    Launch_HAC (+\"days_1901.adb\");\n    Launch_HAC (+\"shell.adb\");\n    Launch_HAC (+\"file_read.adb\");\n    Launch_HAC (+\"existence.adb\");\n    Launch_HAC (+\"timing.adb\");\n    Launch_HAC (+\"bwt.adb\");\n    Launch_HAC (+\"unit_a.adb\");\n    --  The following demos write files.\n    Launch_HAC (+\"file_copy.adb\");\n    Launch_HAC (+\"three_lakes_s.adb\");\n    Launch_HAC (+\"covid_19_s.adb\");\n  end Launch_Demos;\n\nbegin\n  Launch_Demos;\nend Gallery;\n"
  },
  {
    "path": "exm/hac_exm.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the examples of the HAC project ( https://sf.net/projects/hacadacompiler/ ).\n--\n--  These examples give (or should give...) the same output on a real\n--  Ada compiler as when compiled and run by HAC.\n--\n--  Build me with \"gprbuild -P hac_exm\", or open me with GNAT Studio.\n--  \n\nproject HAC_Exm is\n\n   type HAC_Build_Mode_Type is (\"Debug\", \"Fast\");\n   HAC_Build_Mode : HAC_Build_Mode_Type := external (\"HAC_Build_Mode\", \"Debug\");\n\n   for Main use\n      --\n      --  1) HAC and GNAT OK (correct Ada, same output)\n      --\n     (\"ackermann.adb\",\n      \"arguments.adb\",\n      \"anti_primes.adb\",\n      \"attributes.adb\",\n      \"barnes.adb\",                 --  John Barnes' Ada-Europe 2022 puzzle\n      \"binomials.adb\",\n      \"bwt.adb\",\n      \"console_io.adb\",\n      \"covid_19_s.adb\",\n      \"days_1901.adb\",\n      \"doors.adb\",                  --  Rosetta Code\n      \"draw_sphere.adb\",            --  Rosetta Code\n      \"echo.adb\",\n      \"einmaleins.adb\",\n      \"embed_text.adb\",\n      \"env.adb\",\n      \"existence.adb\",\n      \"file_append.adb\",\n      \"file_copy.adb\",\n      \"file_read.adb\",\n      \"fill_drive.adb\",\n      \"hello.adb\",\n      \"hello_big.adb\",\n      \"gallery.adb\",\n      \"hilbert_curve.adb\",          --  PDF demo, Rosetta Code\n      \"hofstadter.adb\",\n      \"koch_curve.adb\",             --  PDF demo, Rosetta Code\n      \"mandelbrot.adb\",\n      \"maze_gen.adb\",               --  Maze generator from Rosetta Code\n      \"md2html.adb\",                --  Markdown to HTML converter\n      \"merge_sort.adb\",\n      \"names_in_boxes.adb\",\n      \"native.adb\",                 --  Example that works also for native targets.\n      \"peano_curve.adb\",            --  PDF demo, Rosetta Code\n      \"pdf_hello.adb\",              --  PDF demo\n      \"prc.adb\",\n      \"random.adb\",\n      \"record_code_gen.adb\",\n      \"remarks.adb\",\n      \"series.adb\",\n      \"shell_sort.adb\",\n      \"shell.adb\",\n      \"strings_demo.adb\",\n      \"sudoku_sample.adb\",\n      \"tasks_01.adb\",\n      \"tasks_02.adb\",\n      \"three_lakes_s.adb\",\n      \"timing.adb\",\n      \"triangles_overlap.adb\",      --  Rosetta Code\n      \"unit_a.adb\");\n\n      --\n      --  2) * GNAT OK\n      --     * HAC KO (feature not yet supported)\n      --  \n      --  \"overloading.adb\"\n      --\n      --  3) * GNAT OK\n      --     * HAC KO (crash)\n      --\n      --  4) * GNAT OK (detects correctly incorrect Ada code)\n      --     * HAC KO (compiles instead of outputting a compilation error; likely a Pascal-ism)\n      --     See places with \"!!\" in the parser code.\n      --  \n      --\n      --  5) Code wrong, incomplete, HAC showing wrong output, or whatever - to be sorted...\n      --\n      --  \"dinersmo.adb\",\n      --  \"din_sm.adb\",\n      --  \"din_ws.adb\",\n      --  \"newrace.adb\",\n      --  \"pgm0.adb\",\n      --  \"pgm1.adb\",\n      --  \"pgm2.adb\",\n      --  \"race.adb\",\n      --  \"racedead.adb\"\n\n   case HAC_Build_Mode is\n      when \"Debug\" => for Object_Dir use \"../obj/debug\";\n      when \"Fast\"  => for Object_Dir use \"../obj/fast\";\n   end case;\n\n   for Source_Dirs use (\".\", \"../src\", \"pdf\", \"tasking\");\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";  --  Flips by default the \"-p\" switch\n\n   package Pretty_Printer is\n      for Default_Switches (\"ada\") use (\"-i2\");\n   end Pretty_Printer;\n\n   Compiler_Common_Options :=\n     (\"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n      \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n      \"-gnatwcijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n      \"-gnatf\",  --  Full errors. Verbose details, all undefined references\n      \"-gnatq\",  --  Don't quit, try semantics, even if parse errors\n      \"-gnatQ\",  --  Don't quit, write ali/tree file even if compile errors\n      \"-g\",            --  Generate debugging information\n      --\n      \"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",       --  Style: check x:no extra parens\n      \"-gnatye\",       --  Style: check e:end/exit labels present\n      \"-gnatytc\");     --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   Debug_Options :=\n     (\"-gnata\",         --  Assertions enabled\n      \"-gnato\",         --  Enable overflow checking in STRICT mode\n      \"-gnatVa\",        --  Enable all validity checking options\n      \"-fstack-check\",\n      \"-fno-inline\");\n\n   Fast_Options :=\n     (\"-Ofast\",\n      \"-gnatpn\");\n   \n   package Compiler is\n      case HAC_Build_Mode is\n         when \"Debug\" => for Default_Switches (\"ada\") use Compiler_Common_Options & Debug_Options;\n         when \"Fast\"  => for Default_Switches (\"ada\") use Compiler_Common_Options & Fast_Options;\n      end case;\n   end Compiler;\n\n   package Binder is\n      case HAC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-Es\");\n         when \"Fast\" =>\n      end case;\n   end Binder;\n\n   package Linker is\n      case HAC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-g\");\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use (\"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-g\", \"-j0\");\n   end Builder;\n\nend HAC_Exm;\n"
  },
  {
    "path": "exm/hello.adb",
    "content": "with HAT;\r\n\r\nprocedure Hello is\r\nbegin\r\n  HAT.Put (\"Hello world!\");\r\nend Hello;\r\n"
  },
  {
    "path": "exm/hello_big.adb",
    "content": "with HAT;\r\n\r\nprocedure Hello_Big is\r\n  use HAT;\r\n  f : Real := 0.0;\r\nbegin\r\n  Put (\"Hello\");\r\n  Put_Line (\" world! I am the program file: \" & Command_Name);\r\n  Put_Line (\r\n        \"          i     i ** 2     2 ** i      2.0 ** i      2.0 ** f\");\r\n  Put_Line (\r\n        \"-------------------------------------------------------------\");\r\n  for i in 1 .. 10 loop\r\n    Put (i, 11);\r\n    Put (i ** 2, 11);\r\n    Put (2 ** i, 11);\r\n    Put (2.0 ** i, 11, 2, 0);       --  Fore, Aft, Exp.\r\n    f := f + 1.0;\r\n    Put_Line (2.0 ** f,  5, 3, 4);  --  Fore, Aft, Exp.\r\n  end loop;\r\nend Hello_Big;\r\n"
  },
  {
    "path": "exm/hofstadter.adb",
    "content": "--  Hofstadter Female and Male sequences\n--  Code taken from:\n--  http://rosettacode.org/wiki/Mutual_recursion#Ada\n--\n\nwith HAT;\n\nprocedure Hofstadter is\n\n  function M (N : Integer) return Integer;\n\n  function F (N : Integer) return Integer is\n  begin\n    if N = 0 then\n      return 1;\n    else\n      return N - M (F (N - 1));\n    end if;\n  end F;\n\n  function M (N : Integer) return Integer is\n  begin\n    if N = 0 then\n      return 0;\n    else\n      return N - F (M (N - 1));\n    end if;\n  end M;\n\n  --  F(n) is not equal to M(n) if and only if n+1 is a Fibonacci number.\n  --  https://oeis.org/A005378\n\n  function Fibonacci (N : Integer) return Integer is\n  begin\n    if N = 0 then\n      return 0;\n    elsif N = 1 then\n      return 1;\n    else\n      return Fibonacci (N - 1) + Fibonacci (N - 2);\n    end if;\n  end Fibonacci;\n\n  n_max : constant := 35;\n  dig_it : constant := 3;\n\n  is_fibo : array (0 .. n_max) of Boolean;\n  fn : Integer;\n\n  use HAT;\n\nbegin\n  Put_Line (\"Hofstadter Female and Male sequences (mutual recursion)\");\n  for n in 0 .. n_max - 1 loop\n    is_fibo (n) := False;\n  end loop;\n  for n in 0 .. n_max - 1 loop\n    fn := Fibonacci (n);\n    exit when fn > is_fibo'Last;\n    is_fibo (fn) := True;\n  end loop;\n  Put (\"n =     \");\n  for n in 0 .. n_max - 1 loop Put (n, dig_it); end loop;\n  New_Line;\n  Put_Line (\"        \" & n_max * dig_it * '_');\n  Put_Line (\"Is n+1  \");\n  Put (\"Fibo ?  \");\n  for n in 0 .. n_max - 1 loop\n    Put ((dig_it - 1) * ' ');\n    if is_fibo (n + 1) then\n      Put ('Y');\n    else\n      Put (' ');\n    end if;\n  end loop;\n  New_Line;\n  Put (\"F:      \");\n  for n in 0 .. n_max - 1 loop Put (F (n), dig_it); end loop;\n  New_Line;\n  Put (\"M:      \");\n  for n in 0 .. n_max - 1 loop Put (M (n), dig_it); end loop;\n  New_Line;\n  Put (\"F = M   \");\n  for n in 0 .. n_max - 1 loop\n    Put ((dig_it - 1) * ' ');\n    if F (n) /= M (n) then\n      Put ('N');\n    else\n      Put (' ');\n    end if;\n  end loop;\n  New_Line;\nend Hofstadter;\n"
  },
  {
    "path": "exm/mandelbrot.adb",
    "content": "with HAT;\n\nprocedure Mandelbrot is\n\n  use HAT;\n\n  --  NB: there is a complete Complex package in the Ada library:\n  --  Ada.Numerics.Generic_Complex_Types.\n\n  type Complex is record\n    Re, Im : Real;\n  end record;\n\n  --  function Sqr (c: Complex) return Complex is\n  --  !! functions with non-standard return types not yet available for HAC.\n\n  procedure Sqr (c : in out Complex) is\n    res : Complex;\n  begin\n    res.Re := c.Re ** 2 - c.Im ** 2;\n    res.Im := 2.0 * c.Re * c.Im;\n    c := res;\n  end Sqr;\n\n  --  !!  Programmable operators (like \"+\") are not yet available for HAC.\n  procedure Add (c : in out Complex; added : Complex) is\n  begin\n    c.Re := c.Re + added.Re;\n    c.Im := c.Im + added.Im;\n  end Add;\n\n  function Square_Modulus (c : Complex) return Real is\n  begin\n    return c.Re ** 2 + c.Im ** 2;\n  end Square_Modulus;\n\n  --\n\n  function Mandelbrot_Iterate (z0 : Complex; max_iter : Integer) return Integer is\n    z : Complex;\n  begin\n    z.Re := 0.0;\n    z.Im := 0.0;\n    for i in 1 .. max_iter loop\n      Sqr (z);\n      Add (z, z0);\n      if Square_Modulus (z) > 4.0 then\n        return i;\n      end if;\n    end loop;\n    return max_iter;\n  end Mandelbrot_Iterate;\n\n  --  Display the Mandelbrot set for a given area, in \"ASCII art\".\n  --\n  procedure Mandelzoom (x_min, y_min, x_max, y_max : Real) is\n    c_max : constant := 98;\n    r_max : constant := 20;\n    i_max : constant := 24;\n    aart : constant String (1 .. i_max) := \"0123456789abcdefghijklm \";\n    --                                         here we give up ----^\n    z0 : Complex;\n    width  : constant Real := x_max - x_min;\n    height : constant Real := y_max - y_min;\n  begin\n    for r in 0 .. r_max loop\n      for c in 0 .. c_max loop\n        z0.Re := x_min + (width  / Real (c_max) * Real (c));\n        z0.Im := y_min + (height / Real (r_max) * Real (r));\n        Put (aart (Mandelbrot_Iterate (z0, i_max)));\n      end loop;\n      New_Line;\n    end loop;\n  end Mandelzoom;\n\nbegin\n  Mandelzoom (-2.2, -1.0, 0.6, 1.0);\nend Mandelbrot;\n"
  },
  {
    "path": "exm/mathe_kal/2022/mathe_plus_2022_02.adb",
    "content": "--  https://www.mathekalender.de/wp/de/kalender/aufgaben/2022-02-de/\n--\n--  Brute-Force-Methode zum Raestsel \"Bogenmatik\"\n--\n--  a*5 = Punkte pro Treffer im weissen Ring.\n--  b*5 = Punkte pro Treffer im violetten Ring.\n--  c*5 = Punkte pro Treffer im gelben Ring.\n--  d*5 = Punkte pro Treffer im Zentrum.\n\nwith HAT;\n\nprocedure Mathe_Plus_2022_02 is\n  lim : constant := 22;\n  use HAT;\nbegin\n  for a in 1 .. lim loop\n    for b in a + 1 .. lim + 1 loop\n      for c in b + 1 .. lim + 2 loop\n        for d in c + 1 .. lim + 3 loop\n          if    3 * a +     b +             d = 25  --  125 Punkte gesamt.\n            and         2 * b +     c + 2 * d = 46  --  230 Punkte gesamt.\n            and   a +       b + 2 * c +     d = 37  --  185 Punkte gesamt.\n          then\n            HAT.Put_Line\n              (+\"Moeglichkeit: \" &\n               a * 5 & \", \" & b * 5 & \", \" & c * 5 & \", \" & d * 5);\n          end if;\n        end loop;\n      end loop;\n    end loop;\n  end loop;\nend Mathe_Plus_2022_02;\n"
  },
  {
    "path": "exm/mathe_kal/2022/mathe_plus_2022_04.adb",
    "content": "--  https://www.mathekalender.de/wp/de/kalender/aufgaben/2022-04-de/\n--\n--  Brute-Force-Methode um Raestsels \"Geschenkeversand\"\n--  Moeglichkeit Nr 4 (\"Fuer jede Anfangsreihe von Geschenken mit einer\n--  ungeraden Anzahl von ordentlich verpackten Geschenken\") zu testen.\n--  Das Programm ist kein Beweis, dass es immer geht, aber man sieht,\n--  dass dieselbe Muster immer wieder kommen, von '-' getrennt.\n--\n--    P = ordentlich verpackt\n--    D = Verpackungsmaterial beschaedigt\n--\n--  Fuer die anderen Moeglichkeiten gibt es Gegenbeispiele:\n--    PPPP hat keine Loesung aber gilt fuer Nr 1, 3, 7, 8, 9.\n--    PDP hat keine Loesung aber gilt mindestens fuer Nr 2, 5, 6.\n--    PPDDD hat keine Loesung aber gilt mindestens fuer Nr 10.\n\nwith HAT;\n\nprocedure Mathe_Plus_2022_04 is\n\n  verbose : constant Boolean := True;\n\n  subtype Test_String is String (1 .. 10);\n\n  s : Test_String;\n\n  successes, failures : Natural := 0;\n\n  use HAT;\n\n  procedure Solve is\n    run : Test_String := s;\n    --\n    procedure Flip (i : Integer) is\n    begin\n      if i in run'Range then\n        case run (i) is\n          when 'P' => run (i) := 'D';\n          when 'D' => run (i) := 'P';\n          when others => null;\n        end case;\n      end if;\n    end Flip;\n    --\n    Ps, Ds, done : Boolean;\n  begin\n    if verbose then\n      Put_Line (+run & \" <------\");\n    end if;\n    for count in 1 .. run'Length * 2 loop\n      Ps := False;\n      Ds := False;\n      for i in run'Range loop\n        case run (i) is\n          when 'P' =>\n            --  Simple choice: just choose the first 'P' on the line.\n            Ps := True;\n            Flip (i - 1);\n            Flip (i + 1);\n            run (i) := '-';  --  Send gift number i.\n            exit;\n          when 'D' =>\n            Ds := True;\n          when others =>\n            null;\n        end case;\n      end loop;\n      if verbose then\n        Put_Line (run);\n      end if;\n      done := not (Ps or Ds);\n      --  ^ done = True: no more gifts in either state: line is empty.\n      exit when done;\n    end loop;\n    if done then\n      successes := successes + 1;\n    else\n      failures := failures + 1;\n    end if;\n  end Solve;\n\n  procedure Test\n    (start : Positive; number_of_Ps : Natural; length : Positive) is\n  begin\n    if number_of_Ps = 0 then\n      for i in start .. length loop\n        s (i) := 'D';\n      end loop;\n      for i in length + 1 .. s'Last loop\n        s (i) := ' ';\n      end loop;\n      Solve;\n    else\n      if start + number_of_Ps - 1 < length then\n        s (start) := 'D';\n        Test (start + 1, number_of_Ps, length);\n      end if;\n      s (start) := 'P';\n      Test (start + 1, number_of_Ps - 1, length);\n    end if;\n  end;\nbegin\n  --  Test all setups up to a certain\n  --  length and with an odd number of 'P'.\n  for length in 1 .. s'Length loop\n    for np in 1 .. length loop\n      if np mod 2 = 1 then\n        Test (1, np, length);\n      end if;\n    end loop;\n  end loop;\n  Put_Line (+\"successes . . \" & successes);\n  Put_Line (+\"failures  . . \" & failures);\nend Mathe_Plus_2022_04;\n"
  },
  {
    "path": "exm/mathe_kal/2022/mathe_plus_2022_09.adb",
    "content": "--  https://www.mathekalender.de/wp/de/kalender/aufgaben/2022-09-de/\r\n\r\nwith HAT;\r\n\r\nprocedure Mathe_Plus_2022_09 is\r\n\r\n  type Gift is (warm_socks, candle, bobble_hat, flute, woolen_sweater);\r\n\r\n  size, joy : array (Gift) of Positive;\r\n\r\n  type Child is (Nasti, Manu, Jona, Uli);\r\n\r\n  list : array (Child, 1 .. 5) of Gift;\r\n\r\n  total_size : Natural;\r\n  total_joy : array (Child) of Natural;\r\n\r\n  use HAT;\r\n\r\nbegin\r\n  size (warm_socks)     := 2;\r\n  size (candle)         := 4;\r\n  size (bobble_hat)     := 6;\r\n  size (flute)          := 24;\r\n  size (woolen_sweater) := 16;\r\n\r\n  joy (warm_socks)     := 4;\r\n  joy (candle)         := 5;\r\n  joy (bobble_hat)     := 8;\r\n  joy (flute)          := 20;\r\n  joy (woolen_sweater) := 10;\r\n\r\n  list (Nasti, 1) := flute;\r\n  list (Nasti, 2) := woolen_sweater;\r\n  list (Nasti, 3) := bobble_hat;\r\n  list (Nasti, 4) := candle;\r\n  list (Nasti, 5) := warm_socks;\r\n\r\n  list (Manu, 1) := warm_socks;\r\n  list (Manu, 2) := candle;\r\n  list (Manu, 3) := bobble_hat;\r\n  list (Manu, 4) := woolen_sweater;\r\n  list (Manu, 5) := flute;\r\n\r\n  list (Jona, 1) := warm_socks;\r\n  list (Jona, 2) := bobble_hat;\r\n  list (Jona, 3) := candle;\r\n  list (Jona, 4) := flute;\r\n  list (Jona, 5) := woolen_sweater;\r\n\r\n  list (Uli, 1) := flute;\r\n  list (Uli, 2) := bobble_hat;\r\n  list (Uli, 3) := candle;\r\n  list (Uli, 4) := warm_socks;\r\n  list (Uli, 5) := woolen_sweater;\r\n\r\n  for c in Child loop\r\n    Put (Child'Image (c) & \"     \");\r\n  end loop;\r\n  New_Line;\r\n\r\n  for bag_size in 2 .. 52 loop\r\n    for c in Child loop\r\n      total_size    := 0;\r\n      total_joy (c) := 0;\r\n      for i in 1 .. 5 loop\r\n        if total_size + size (list (c, i)) <= bag_size then\r\n          --  In the bag!\r\n          total_size    := total_size    + size (list (c, i));\r\n          total_joy (c) := total_joy (c) + joy  (list (c, i));\r\n        end if;\r\n      end loop;\r\n      Put (total_joy (c), 8);\r\n    end loop;\r\n    Put (\"   \" & Boolean'Image (total_joy (Jona) >= total_joy (Manu)));\r\n    New_Line;\r\n  end loop;\r\nend Mathe_Plus_2022_09;\r\n"
  },
  {
    "path": "exm/mathe_kal/2022/mkp_2022.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the Mathe Kalender Plus examples.\n--  Some programs work with both HAC and \"full Ada\" compilers like,\n--  GNAT some (titled *_full_ada.adb) work only with \"full Ada\".\n--  \nproject MKP_2022 is\n\n   for Source_Dirs use (\n     \".\",\n     \"../../../src\"   --  GNAT's access to the HAT package.\n   );\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";\n\n   type AoC_Build_Mode_Type is\n      (\"Debug\",\n       \"Fast\"\n      );\n   AoC_Build_Mode : AoC_Build_Mode_Type := external (\"AoC_Build_Mode\", \"Debug\");\n\n   for Main use (\n     \"mathe_plus_2022_09\",\n     \"mathe_plus_2022_04\",\n     \"mathe_plus_2022_02\"\n   );\n   \n   case AoC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"obj_debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"obj_fast\";\n   end case;\n\n   Common_Options := (\n     \"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n     \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n     \"-gnatwCijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n     \"-gnatf\",  --  Full errors. Verbose details, all undefined references\n     \"-gnatq\",  --  Don't quit, try semantics, even if parse errors\n     \"-gnatQ\",  --  Don't quit, write ali/tree file even if compile errors\n     --\n     \"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n     \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n     \"-gnatyx\",       --  Style: check x:no extra parens\n     --  \"-gnatye\",   --  Style: check e:end/exit labels present\n     \"-gnatytc\"       --  Style: check t:token separation rules, c:comment format (two spaces)\n   );\n\n   Fast_Options := (\n     \"-O3\",\n     \"-funroll-loops\", \"-fpeel-loops\", \"-funswitch-loops\",\n     \"-ftracer\", \"-fweb\", \"-frename-registers\",\n     \"-ftree-vectorize\", \"-fipa-cp-clone\", \"-fgcse-after-reload\"\n   );\n\n   Debug_Options  := (\n     --  \"-gnateV\",  --  Validity check for parameters, GNAT > 4.6, redundant with -gnatVim ?\n     \"-gnatVa\",  --  Turn on all validity checking options\n     \"-gnato\",   --  Enable overflow checking in STRICT (-gnato1) mode\n     \"-g\", \n     \"-fno-inline\", \"-fstack-check\"\n   );\n\n   package Compiler is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use Common_Options & Debug_Options ;\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use Common_Options & Fast_Options & (\"-gnatpn\", \"-ffunction-sections\");\n      end case;\n   end Compiler;\n\n   package Linker is\n      case AoC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-g\");\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use (\"-g\", \"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use (\"-Es\");\n   end Binder;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\nend MKP_2022;\n"
  },
  {
    "path": "exm/maze_gen.adb",
    "content": "--  Special version (for HAC) of\n--  http://rosettacode.org/wiki/Maze_generation#Ada\n\nwith HAT;\n\nprocedure Maze_Gen is\n\n  type Direction is (North, South, West, East);\n\n  type Cell_Walls is array (Direction) of Boolean;\n\n  type Cells is record\n    Walls   : Cell_Walls;\n    Visited : Boolean;\n  end record;\n\n  Height : constant := 15;\n  Width  : constant := 24;\n\n  type Maze_Grid is array (1 .. Height, 1 .. Width) of Cells;\n\n  type Point is record\n    Row, Col : Integer;\n  end record;\n\n  type Maze_Type is record\n    Start : Point;\n    Grid  : Maze_Grid;\n  end record;\n\n  function Opposite (D : Direction) return Direction is\n  begin\n    case D is\n      when North => return South;\n      when South => return North;\n      when East  => return West;\n      when West  => return East;\n    end case;\n  end Opposite;\n\n  procedure Move (P : in out Point; D : Direction; Valid_Move : out Boolean) is\n  begin\n    Valid_Move := False;\n    case D is\n      when North =>\n        if P.Row > 1 then\n          Valid_Move := True;\n          P.Row      := P.Row - 1;\n        end if;\n      when East =>\n        if P.Col < Width then\n          Valid_Move := True;\n          P.Col      := P.Col + 1;\n        end if;\n      when West =>\n        if P.Col > 1 then\n          Valid_Move := True;\n          P.Col      := P.Col - 1;\n        end if;\n      when South =>\n        if P.Row < Height then\n          Valid_Move := True;\n          P.Row      := P.Row + 1;\n        end if;\n    end case;\n  end Move;\n\n  function Val (I : Integer) return Direction is  --  ! Full Ada: use 'Val(...)\n  begin\n    case I is\n      when 0      => return North;\n      when 1      => return South;\n      when 2      => return West;\n      when others => return East;\n    end case;\n  end Val;\n\n  procedure Depth_First_Algorithm (Maze : in out Maze_Grid; P : Point) is\n    --  https://en.wikipedia.org/wiki/Maze_generation_algorithm\n    Next_P          : Point;\n    Next_D          : Direction;\n    Valid_Direction : Boolean;\n    Checked_Wall    : array (Direction) of Boolean;\n    All_Checked     : Boolean;\n  begin\n    for D in Direction loop  --  ! Full Ada \":= (others => False)\"\n      Checked_Wall (D) := False;\n    end loop;\n    --  Mark as visited:\n    Maze (P.Row, P.Col).Visited := True;\n    loop\n      --  Use random direction:\n      loop\n        Next_D := Val (HAT.Rand (3));\n        exit when not Checked_Wall (Next_D);  --  At least one wall is unchecked.\n      end loop;\n      Next_P := P;\n      Move (Next_P, Next_D, Valid_Direction);\n      if Valid_Direction then\n        if not Maze (Next_P.Row, Next_P.Col).Visited then\n          --  Connect the two cells by breaking the wall.\n          Maze (P.Row, P.Col).Walls (Next_D) := False;\n          Maze (Next_P.Row, Next_P.Col).Walls (Opposite (Next_D)) := False;\n          --  Recurse from next cell.\n          Depth_First_Algorithm (Maze, Next_P);\n        end if;\n      end if;\n      Checked_Wall (Next_D) := True;  --  Neighbour is either visited or invalid.\n      --\n      All_Checked := True;\n      for D in Direction loop\n        All_Checked := All_Checked and Checked_Wall (D);\n      end loop;\n      --  Neighbours in all directions are either visited\n      --  (either from here, or previously visited), or invalid:\n      exit when All_Checked;\n      --  Continue until there is no unvisited neighbour left.\n    end loop;\n  end Depth_First_Algorithm;\n\n  procedure Initialize (Maze : in out Maze_Type) is\n    All_Walls : Cell_Walls;\n    use HAT;\n  begin\n    for D in Direction loop\n      All_Walls (D) := True;\n    end loop;\n    --  ! Full Ada: initialized record.\n    for i in 1 .. Height loop\n      for j in 1 .. Width loop\n        Maze.Grid (i, j).Walls := All_Walls;\n        Maze.Grid (i, j).Visited := False;\n      end loop;\n    end loop;\n    --  Choose starting cell\n    Maze.Start.Row := Rand (1_000_000) mod Height + 1;\n    Maze.Start.Col := Rand (1_000_000) mod Width + 1;\n    Put_Line\n       (+\"Height: \" & Height & \", Width: \" & Width);\n    Put_Line\n       (+\"Starting generation at \" &\n        Maze.Start.Row & \", \" & Maze.Start.Col & \" (marked with an X)\");\n    Depth_First_Algorithm (Maze.Grid, Maze.Start);\n  end Initialize;\n\n  procedure Put_Grid (Item : Maze_Type) is\n    use HAT;\n    H_Bar : array (Boolean) of VString;\n    V_Bar : array (Boolean) of Character;\n    S_Cell : array (Boolean) of VString;\n    Line : VString;\n  begin\n    H_Bar (False) := +\"   +\";\n    H_Bar (True)  := +\"---+\";\n    V_Bar (False) := ' ';\n    V_Bar (True)  := '|';\n    S_Cell (False) := +\"   \";\n    S_Cell (True)  := +\" X \";\n    --  North border of top row:\n    Line := +\"+\";\n    for Col in 1 .. Width loop\n      Line := Line & H_Bar (Item.Grid (1, Col).Walls (North));\n    end loop;\n    Put_Line (Line);\n    --  All rows:\n    for Row in 1 .. Height loop\n      --  West border of leftmost column:\n      Line := +\"\" & V_Bar (Item.Grid (Row, 1).Walls (West));\n      --  All columns:\n      for Col in 1 .. Width loop\n        Line := Line & S_Cell (Row = Item.Start.Row and Col = Item.Start.Col)\n                     & V_Bar (Item.Grid (Row, Col).Walls (East));\n      end loop;\n      Put_Line (Line);\n      --  South border of current row:\n      Line := +\"+\";\n      for Col in 1 .. Width loop\n        Line := Line & H_Bar (Item.Grid (Row, Col).Walls (South));\n      end loop;\n      Put_Line (Line);\n    end loop;\n  end Put_Grid;\n\n  My_Maze : Maze_Type;\n\nbegin\n  Initialize (My_Maze);\n  Put_Grid (My_Maze);\nend Maze_Gen;\n"
  },
  {
    "path": "exm/md2html.adb",
    "content": "--  MD2HTML - a Markdown to HTML converter.\n--\n--  Useful for viewing Markdown files offline.\n\nwith HAT;\n\nprocedure MD2HTML is\n\n  use HAT;\n\n  f1, f2 : File_Type;\n\n  type List_Descriptor is record\n    indent  : Positive;\n    ordered : Boolean;\n  end record;\n\n  list_top : Natural := 0;\n  list_stack : array (1 .. 10) of List_Descriptor;\n\n  bold, italic, underline, strikethrough : Boolean := False;\n\n  procedure Process (s : VString; indent : Positive) is\n\n    function Is_Separator (c : Character) return Boolean is\n    begin\n      case c is\n        when ' ' | ',' | ';' | '.' =>\n          return True;\n        when others =>\n          return False;\n      end case;\n    end Is_Separator;\n\n    function Process_Content (ct : VString) return VString is  --  Assumption: ct is never empty.\n      r : VString;\n      c, cp1, cp2 : Character := ' ';\n      item : Boolean := False;\n      ordered : Boolean;\n    begin\n      for i in 1 .. Length (ct) loop\n        c := Element (ct, i);\n        case cp1 is\n          when '*' | '_' | '~' | '-' =>\n            if c = cp1 then\n              --  \"**, \"__\", \"~~\"\n              case cp1 is\n                when '*' =>\n                  bold := not bold;\n                  if bold then r := r & \"<b>\"; else r := r & \"</b>\"; end if;\n                when '_' =>\n                  underline := not underline;\n                  if underline then r := r & \"<u>\"; else r := r & \"</u>\"; end if;\n                when '~' =>\n                  strikethrough := not strikethrough;\n                  if strikethrough then r := r & \"<s>\"; else r := r & \"</s>\"; end if;\n                when others =>\n                  r := r & cp1;\n              end case;\n            elsif cp2 /= cp1 then\n              if c = ' ' and cp2 = ' ' then\n                if i = 2 and then (cp1 = '-' or cp1 = '*') then\n                  --  \" * item\"\n                  item := True;\n                  ordered := False;\n                else\n                  r := r & cp1;\n                end if;\n              elsif Is_Separator (cp2) and then (cp1 = '*' or cp1 = '_') then\n                --  \" *x\"\n                if not italic then r := r & \"<i>\"; end if;\n                italic := True;\n              elsif Is_Separator (c) and then (cp1 = '*' or cp1 = '_') then\n                --  \"x* \"\n                if italic then r := r & \"</i>\"; end if;\n                italic := False;\n              else\n                r := r & cp1;\n              end if;\n            elsif cp2 = cp1 then\n              --  \"**x\": treated at previous step.\n              null;\n            else\n              r := r & cp1;\n            end if;\n          when others =>\n            r := r & cp1;\n        end case;\n        cp2 := cp1;\n        cp1 := c;\n      end loop;\n      if item then\n        r := \"<li>\" & r;\n        if list_top = 0 or else indent > list_stack (list_top).indent then\n          list_top := list_top + 1;\n          list_stack (list_top).indent  := indent;\n          list_stack (list_top).ordered := ordered;\n          if ordered then\n            r := \"<ol>\" & r;\n          else\n            r := \"<ul>\" & r;\n          end if;\n        end if;\n      end if;\n      return r;\n    end Process_Content;\n\n    hc : Integer := 0;\n    i : Positive := 1;\n    r : VString;\n  begin\n    if Length (s) = 0 then\n      bold          := False;\n      italic        := False;\n      underline     := False;\n      strikethrough := False;\n      return;\n    end if;\n\n    --  Headings\n    while Element (s, i) = '#' loop\n      hc := hc + 1;\n      i := i + 1;\n    end loop;\n    if hc > 0 then\n      r := r & \"<h\" & hc & '>';\n    end if;\n\n    r := r & Process_Content (Slice (s, 1 + hc, Length (s)) & ' ');\n\n    while list_top > 0 and then indent < list_stack (list_top).indent loop\n      if list_stack (list_top).ordered then\n        r := \"</ol>\" & r;\n      else\n        r := \"</ul>\" & r;\n      end if;\n      list_top := list_top - 1;\n    end loop;\n\n    if hc > 0 then\n      r := r & \"</h\" & hc & '>';\n    end if;\n    Put_Line (f2, r);\n\n  end Process;\n\n  s : VString;\n\nbegin\n  if Argument_Count = 0 then\n    Open (f1, \"../readme.md\");\n  else\n    Open (f1, Argument (1));\n  end if;\n  Create (f2, \"output.html\");\n  Put_Line (f2, \"<html><body><font face=\"\"Calibri, Arial, Geneva, Helvetica\"\">\");\n  while not End_Of_File (f1) loop\n    Get_Line (f1, s);\n    for indent in 1 .. Length (s) loop\n      if Element (s, indent) /= ' ' then\n        Process (Slice (s, indent, Length (s)), indent);\n        exit;\n      end if;\n    end loop;\n  end loop;\n  Close (f1);\n  Put_Line (f2, \"</font></body></html>\");\n  Close (f2);\nend MD2HTML;\n"
  },
  {
    "path": "exm/merge_sort.adb",
    "content": "with HAT;\r\n\r\nprocedure Merge_Sort is\r\n\r\n  procedure Merge is\r\n\r\n    subtype Vector is String (1 .. 26);\r\n    v                : Vector;\r\n    temp_array       : Vector;\r\n    max              : Integer;\r\n    cur_length       : Integer;\r\n    m                : Integer;\r\n    left, top_left   : Integer;\r\n    right, top_right : Integer;\r\n\r\n    c2 : String (1 .. 3);\r\n\r\n    use HAT;\r\n\r\n  begin\r\n    v := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n    c2 := \" rl\";\r\n    max := 26;\r\n    Put_Line (\"Merge Sort\");\r\n    New_Line;\r\n    Put_Line (\"String at start:\");\r\n    Put_Line (\"----------------\");\r\n    Put_Line (v);\r\n    New_Line;\r\n    --\r\n    cur_length := 1;\r\n    while cur_length < max loop  --  New phase\r\n      temp_array := v;\r\n      for k in 1 .. 26 loop\r\n        Put (temp_array (k));\r\n        Put (c2 (1));\r\n      end loop;\r\n      New_Line;\r\n      left := 1;\r\n      m := 1;\r\n      while left <= max loop  --  Find pair of subarrays\r\n        right := left + cur_length;\r\n        top_left := right;\r\n        if top_left > max then\r\n          top_left := max + 1;\r\n        end if;\r\n        top_right := right + cur_length;\r\n        if top_right > max then\r\n          top_right := max + 1;\r\n        end if;\r\n        --  Merge subarrays\r\n        --  Go until one subarray runs out\r\n        while left < top_left and right < top_right loop\r\n          if temp_array (left) <= temp_array (right) then\r\n            v (m)  := temp_array (left);\r\n            Put (v (m));\r\n            Put (c2 (2));\r\n            left  := left + 1;\r\n          else\r\n            v (m)  := temp_array (right);\r\n            Put (v (m));\r\n            Put (c2 (3));\r\n            right := right + 1;\r\n          end if;\r\n          m := m + 1;\r\n        end loop;\r\n        --  Now \"copy tail\" of whichever subarray remains\r\n        while left < top_left loop\r\n          v (m) := temp_array (left);\r\n          Put (v (m));\r\n          Put (c2 (2));\r\n          m    := m + 1;\r\n          left := left + 1;\r\n        end loop;\r\n        while right < top_right loop\r\n          v (m)  := temp_array (right);\r\n          Put (v (m));\r\n          Put (c2 (3));\r\n          right := right + 1;\r\n          m     := m + 1;\r\n        end loop;\r\n        left := top_right;\r\n      end loop;\r\n      New_Line;\r\n      --  Now double size of subarrays and go back for next phase\r\n      cur_length := cur_length * 2;\r\n    end loop;\r\n    New_Line;\r\n    Put_Line (\"Result of Merge Sort:\");\r\n    Put_Line (\"---------------------\");\r\n    Put_Line (v);\r\n  end Merge;\r\n\r\nbegin\r\n  Merge;\r\nend Merge_Sort;\r\n"
  },
  {
    "path": "exm/names_in_boxes.adb",
    "content": "--  https://stackoverflow.com/questions/61719343/storing-and-using-strings-of-varying-length-ada\n\nwith HAT; use HAT;\n\nprocedure Names_in_Boxes is\n\n  Max : constant := 100;\n  type Names_List is array (1 .. Max) of VString;\n\n  procedure Object_Catcha (N : out Integer) is\n  begin\n    Put (\"Enter amount of objects: \");\n    Get (N);\n    --  Console vs. GUI input:\n    if Get_Needs_Skip_Line then Skip_Line; else New_Line; end if;\n  end Object_Catcha;\n\n  procedure Names_Catcha (Names : out Names_List; N : in Integer) is\n  begin\n    for I in 1 .. N loop\n      Put (+\"Object \" & I & \": \");\n      Get_Line (Names (I));\n    end loop;\n  end Names_Catcha;\n\n  procedure Space_Box (Names : in Names_List; N : in Integer) is\n  begin\n    Put_Line (N * \"+-----------+     \");\n    for I in 1 .. N loop\n      Put (\"| \" & Names (I) & (10 - Length (Names (I))) * ' ' & '|');\n      if I < N then\n        Put (\"<>---\");\n      end if;\n    end loop;\n    New_Line;\n    Put_Line (N * \"+-----------+     \");\n  end Space_Box;\n\n  --  \"Global\" variables, unknown to\n  --  Object_Catcha, Names_Catcha, Space_Box:\n  N : Integer;\n  Names : Names_List;\n\nbegin\n  Object_Catcha (N);\n  if N > Max then\n    Put_Line (+\"Too many objects! Maximum is \" & Max);\n  else\n    Put_Line (\"Enter the name of the objects: \");\n    Names_Catcha (Names, N);\n    Space_Box (Names, N);\n  end if;\nend Names_in_Boxes;\n"
  },
  {
    "path": "exm/native.adb",
    "content": "--  Summary of what can be done with\n--  compilation for native targets.\n--  Currently (v.0.26): not much!\n--\n--  Command sample:\n--  hac -tamd64_windows_console_fasm exm/native.adb\n\nwith HAT;\n\nprocedure Native is\n  use HAT;\n  --  a : Integer;\nbegin\n  --  a := 1;  --  Variables: TBD.\n  Put_Line (\"Hello ...\");\n  Put_Line (\"... world!\");\n  --  12345 in various forms:\n  Put_Line (12000 + 340 + 5 * 1);\n  Put_Line (12355 * (13 - 12) - 20 / (1414 / 707));\n  Put_Line (2469 * 5);\n  Put_Line (61725 / 5);\nend Native;\n"
  },
  {
    "path": "exm/not_working/din_sm.adb",
    "content": "with HAT; use HAT;\r\n\r\nprocedure Din_SM is\r\n    task SCREEN is\r\n      entry SEIZE;\r\n      entry RELEASE;\r\n    end SCREEN;\r\n    task DIJKSTRA is\r\n      entry GIVE_BIRTH;\r\n    end DIJKSTRA;\r\n    task HOPPER is\r\n      entry GIVE_BIRTH;\r\n    end HOPPER;\r\n    task SAMMET is\r\n      entry GIVE_BIRTH;\r\n    end SAMMET;\r\n    task GEHANI is\r\n      entry GIVE_BIRTH;\r\n    end GEHANI;\r\n    task CHOPSTICK1 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK1;\r\n    task CHOPSTICK2 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK2;\r\n    task CHOPSTICK3 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK3;\r\n    task CHOPSTICK4 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK4;\r\n  NO_MEALS : integer := 3;\r\n  task body DIJKSTRA is\r\n       LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          SCREEN.SEIZE;\r\n          PUT(\"Eddy Dijkstra living and breathing\");\r\n          NEW_LINE;\r\n          SCREEN.RELEASE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK1.PICKUP;\r\n        CHOPSTICK2.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        SCREEN.SEIZE;\r\n        PUT(\"Eddy Dijkstra eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 1 and 2\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        delay LENGTH_OF_MEAL;\r\n        SCREEN.SEIZE;\r\n        PUT(\"Eddy Dijkstra done\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        CHOPSTICK1.PUTDOWN;\r\n        CHOPSTICK2.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      SCREEN.SEIZE;\r\n      PUT(\"Eddy Dijkstra burp\");\r\n      NEW_LINE;\r\n      SCREEN.RELEASE;\r\n    end DIJKSTRA;\r\n   task body HOPPER is\r\n        LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          SCREEN.SEIZE;\r\n          PUT(\" Gracie Hopper living and breathing\");\r\n          NEW_LINE;\r\n          SCREEN.RELEASE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK2.PICKUP;\r\n        CHOPSTICK3.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        SCREEN.SEIZE;\r\n        PUT(\" Gracie Hopper eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 2 and 3\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        delay LENGTH_OF_MEAL;\r\n        SCREEN.SEIZE;\r\n        PUT(\" Gracie Hopper done\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        CHOPSTICK2.PUTDOWN;\r\n        CHOPSTICK3.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      SCREEN.SEIZE;\r\n      PUT(\" Gracie Hopper burp\");\r\n      NEW_LINE;\r\n      SCREEN.RELEASE;\r\n    end HOPPER;\r\n    task body SAMMET is\r\n        LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          SCREEN.SEIZE;\r\n          PUT(\"  Jeannie Sammet living and breathing\");\r\n          NEW_LINE;\r\n          SCREEN.RELEASE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK3.PICKUP;\r\n        CHOPSTICK4.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        SCREEN.SEIZE;\r\n        PUT(\"  Jeannie Sammet eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 3 and 4\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        delay LENGTH_OF_MEAL;\r\n        SCREEN.SEIZE;\r\n        PUT(\"  Jeannie Sammet done\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        CHOPSTICK3.PUTDOWN;\r\n        CHOPSTICK4.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      SCREEN.SEIZE;\r\n      PUT(\"  Jeannie Sammet burp\");\r\n      NEW_LINE;\r\n      SCREEN.RELEASE;\r\n    end SAMMET;\r\n  task body GEHANI is\r\n        LENGTH_OF_MEAL : FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          SCREEN.SEIZE;\r\n          PUT(\"   Narain Gehani living and breathing\");\r\n          NEW_LINE;\r\n          SCREEN.RELEASE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK1.PICKUP;\r\n        CHOPSTICK4.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        SCREEN.SEIZE;\r\n        PUT(\"   Narain Gehani eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 1 and 4\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        delay LENGTH_OF_MEAL;\r\n        SCREEN.SEIZE;\r\n        PUT(\"   Narain Gehani done\");\r\n        NEW_LINE;\r\n        SCREEN.RELEASE;\r\n        CHOPSTICK1.PUTDOWN;\r\n        CHOPSTICK4.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      SCREEN.SEIZE;\r\n      PUT(\"   Narain Gehani burp\");\r\n      NEW_LINE;\r\n      SCREEN.RELEASE;\r\n    end GEHANI;\r\n  task body SCREEN is\r\n    begin\r\n      loop\r\n        select\r\n          accept SEIZE;\r\n          accept RELEASE;\r\n        or\r\n          terminate;\r\n        end select;\r\n      end loop;\r\n    end SCREEN;\r\n  task body CHOPSTICK1 is\r\n    begin\r\n      loop\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK1;\r\n  task body CHOPSTICK2 is\r\n    begin\r\n      loop\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK2;\r\n  task body CHOPSTICK3 is\r\n    begin\r\n      loop\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK3;\r\n  task body CHOPSTICK4 is\r\n    begin\r\n      loop\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK4;\r\nbegin\r\n  DIJKSTRA.GIVE_BIRTH;\r\n  HOPPER.GIVE_BIRTH;\r\n  SAMMET.GIVE_BIRTH;\r\n  GEHANI.GIVE_BIRTH;\r\nend Din_SM;\r\n"
  },
  {
    "path": "exm/not_working/din_ws.adb",
    "content": "with HAT; use HAT;\r\n\r\nprocedure Din_WS is\r\n    task DIJKSTRA is\r\n      entry GIVE_BIRTH;\r\n    end DIJKSTRA;\r\n    task HOPPER is\r\n      entry GIVE_BIRTH;\r\n    end HOPPER;\r\n    task SAMMET is\r\n      entry GIVE_BIRTH;\r\n    end SAMMET;\r\n    task GEHANI is\r\n      entry GIVE_BIRTH;\r\n    end GEHANI;\r\n    task CHOPSTICK1 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK1;\r\n    task CHOPSTICK2 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK2;\r\n    task CHOPSTICK3 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK3;\r\n    task CHOPSTICK4 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK4;\r\n  NO_MEALS : integer := 5;\r\n  task body DIJKSTRA is\r\n       LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          PUT(\"Eddy Dijkstra living and breathing\");\r\n          NEW_LINE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK1.PICKUP;\r\n        CHOPSTICK2.PICKUP;\r\n        LENGTH_OF_MEAL := Float(RANDOM(9)) + 1.0;\r\n        PUT(\"Eddy Dijkstra eating meal\"); PUT(x, 2);\r\n        PUT(\" with chopsticks 1 and 2\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL, 2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        delay LENGTH_OF_MEAL;\r\n        PUT(\"Eddy Dijkstra done\");\r\n        NEW_LINE;\r\n        CHOPSTICK1.PUTDOWN;\r\n        CHOPSTICK2.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      PUT(\"Eddy Dijkstra burp\");\r\n      NEW_LINE;\r\n    end DIJKSTRA;\r\n   task body HOPPER is\r\n        LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          PUT(\" Gracie Hopper living and breathing\");\r\n          NEW_LINE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK2.PICKUP;\r\n        CHOPSTICK3.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        PUT(\" Gracie Hopper eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 2 and 3\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        delay LENGTH_OF_MEAL;\r\n        PUT(\" Gracie Hopper done\");\r\n        NEW_LINE;\r\n        CHOPSTICK2.PUTDOWN;\r\n        CHOPSTICK3.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      PUT(\" Gracie Hopper burp\");\r\n      NEW_LINE;\r\n    end HOPPER;\r\n    task body SAMMET is\r\n        LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          PUT(\"  Jeannie Sammet living and breathing\");\r\n          NEW_LINE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK3.PICKUP;\r\n        CHOPSTICK4.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        PUT(\"  Jeannie Sammet eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 3 and 4\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        delay LENGTH_OF_MEAL;\r\n        PUT(\"  Jeannie Sammet done\");\r\n        NEW_LINE;\r\n        CHOPSTICK3.PUTDOWN;\r\n        CHOPSTICK4.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      PUT(\"  Jeannie Sammet burp\");\r\n      NEW_LINE;\r\n    end SAMMET;\r\n  task body GEHANI is\r\n        LENGTH_OF_MEAL : FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          PUT(\"   Narain Gehani living and breathing\");\r\n          NEW_LINE;\r\n        end GIVE_BIRTH;\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK1.PICKUP;\r\n        CHOPSTICK4.PICKUP;\r\n        LENGTH_OF_MEAL := RANDOM(9) + 1;\r\n        PUT(\"   Narain Gehani eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 1 and 4\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        delay LENGTH_OF_MEAL;\r\n        PUT(\"   Narain Gehani done\");\r\n        NEW_LINE;\r\n        CHOPSTICK1.PUTDOWN;\r\n        CHOPSTICK4.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      PUT(\"   Narain Gehani burp\");\r\n      NEW_LINE;\r\n    end GEHANI;\r\n  task body CHOPSTICK1 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n        or\r\n          terminate;\r\n        end select;\r\n      end loop;\r\n    end CHOPSTICK1;\r\n  task body CHOPSTICK2 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n         or\r\n          terminate;\r\n        end select;\r\n     end loop;\r\n    end CHOPSTICK2;\r\n  task body CHOPSTICK3 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n        or\r\n          terminate;\r\n        end select;\r\n      end loop;\r\n    end CHOPSTICK3;\r\n  task body CHOPSTICK4 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n          accept PUTDOWN;\r\n        or\r\n          terminate;\r\n        end select;\r\n      end loop;\r\n    end CHOPSTICK4;\r\nbegin\r\n  DIJKSTRA.GIVE_BIRTH;\r\n  HOPPER.GIVE_BIRTH;\r\n  SAMMET.GIVE_BIRTH;\r\n  GEHANI.GIVE_BIRTH;\r\nend Din_WS;\r\n"
  },
  {
    "path": "exm/not_working/dinersmo.adb",
    "content": "with HAT; use HAT;\r\n\r\nprocedure dinersmo is\r\n\r\n    SCREEN: SEMAPHORE := 1;\r\n\r\n    -- task SCREEN is\r\n    --    entry WAIT;\r\n    --    entry SIGNAL;\r\n    -- end SCREEN;\r\n\r\n    task DIJKSTRA is\r\n      entry GIVE_BIRTH;\r\n    end DIJKSTRA;\r\n\r\n    task HOPPER is\r\n      entry GIVE_BIRTH;\r\n    end HOPPER;\r\n\r\n    task SAMMET is\r\n      entry GIVE_BIRTH;\r\n    end SAMMET;\r\n\r\n    task GEHANI is\r\n      entry GIVE_BIRTH;\r\n    end GEHANI;\r\n\r\n    task CHOPSTICK1 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK1;\r\n\r\n    task CHOPSTICK2 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK2;\r\n\r\n    task CHOPSTICK3 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK3;\r\n\r\n    task CHOPSTICK4 is\r\n      entry PICKUP;\r\n      entry PUTDOWN;\r\n    end CHOPSTICK4;\r\n\r\n\r\n\r\n  NO_MEALS : integer := 5;\r\n\r\n\r\n\r\n  task body DIJKSTRA is\r\n       LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n\r\n        accept GIVE_BIRTH do\r\n          WAIT(SCREEN);\r\n          PUT(\"Eddy Dijkstra living and breathing\");\r\n          NEW_LINE;\r\n          SIGNAL(SCREEN);\r\n        end GIVE_BIRTH;\r\n\r\n      for x in 1..NO_MEALS loop\r\n\r\n        CHOPSTICK1.PICKUP;\r\n        CHOPSTICK2.PICKUP;\r\n\r\n        LENGTH_OF_MEAL := RANDOM(10);\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\"Eddy Dijkstra eating meal\"); PUT(x, 2);\r\n        PUT(\" with chopsticks 1 and 2\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL, 2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        delay LENGTH_OF_MEAL;\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\"Eddy Dijkstra done\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        CHOPSTICK1.PUTDOWN;\r\n        CHOPSTICK2.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n\r\n      WAIT(SCREEN);\r\n      PUT(\"Eddy Dijkstra burp\");\r\n      NEW_LINE;\r\n      SIGNAL(SCREEN);\r\n\r\n    end DIJKSTRA;\r\n\r\n   task body HOPPER is\r\n        LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          WAIT(SCREEN);\r\n          PUT(\" Gracie Hopper living and breathing\");\r\n          NEW_LINE;\r\n          SIGNAL(SCREEN);\r\n        end GIVE_BIRTH;\r\n\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK2.PICKUP;\r\n        CHOPSTICK3.PICKUP;\r\n\r\n        LENGTH_OF_MEAL := RANDOM(10);\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\" Gracie Hopper eating meal\"); PUT(x, 2);\r\n        PUT(\" with chopsticks 2 and 3\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL, 2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        delay LENGTH_OF_MEAL;\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\" Gracie Hopper done\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        CHOPSTICK2.PUTDOWN;\r\n        CHOPSTICK3.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      WAIT(SCREEN);\r\n      PUT(\" Gracie Hopper burp\");\r\n      NEW_LINE;\r\n      SIGNAL(SCREEN);\r\n    end HOPPER;\r\n\r\n    task body SAMMET is\r\n        LENGTH_OF_MEAL: FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          WAIT(SCREEN);\r\n          PUT(\"  Jeannie Sammet living and breathing\");\r\n          NEW_LINE;\r\n          SIGNAL(SCREEN);\r\n        end GIVE_BIRTH;\r\n\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK3.PICKUP;\r\n        CHOPSTICK4.PICKUP;\r\n\r\n        LENGTH_OF_MEAL := RANDOM(10);\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\"  Jeannie Sammet eating meal\"); PUT(x, 2);\r\n        PUT(\" with chopsticks 3 and 4\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL, 2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        delay LENGTH_OF_MEAL;\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\"  Jeannie Sammet done\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        CHOPSTICK3.PUTDOWN;\r\n        CHOPSTICK4.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      WAIT(SCREEN);\r\n      PUT(\"  Jeannie Sammet burp\");\r\n      NEW_LINE;\r\n      SIGNAL(SCREEN);\r\n    end SAMMET;\r\n\r\n  task body GEHANI is\r\n        LENGTH_OF_MEAL : FLOAT;\r\n    begin\r\n        accept GIVE_BIRTH do\r\n          WAIT(SCREEN);\r\n          PUT(\"   Narain Gehani living and breathing\");\r\n          NEW_LINE;\r\n          SIGNAL(SCREEN);\r\n        end GIVE_BIRTH;\r\n\r\n      for x in 1..NO_MEALS loop\r\n        CHOPSTICK1.PICKUP;\r\n        CHOPSTICK4.PICKUP;\r\n\r\n        LENGTH_OF_MEAL := RANDOM(10);\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\"   Narain Gehani eating meal\"); PUT(x:2);\r\n        PUT(\" with chopsticks 1 and 4\");\r\n        PUT(\" for\"); PUT(LENGTH_OF_MEAL:2); PUT(\" seconds\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        delay LENGTH_OF_MEAL;\r\n\r\n        WAIT(SCREEN);\r\n        PUT(\"   Narain Gehani done\");\r\n        NEW_LINE;\r\n        SIGNAL(SCREEN);\r\n\r\n        CHOPSTICK1.PUTDOWN;\r\n        CHOPSTICK4.PUTDOWN;\r\n        delay 5.0;\r\n      end loop;\r\n      WAIT(SCREEN);\r\n      PUT(\"   Narain Gehani burp\");\r\n      NEW_LINE;\r\n      SIGNAL(SCREEN);\r\n    end GEHANI;\r\n\r\n -- task body SCREEN is\r\n --   begin\r\n --     loop\r\n --       select\r\n --         accept WAIT;\r\n --       or\r\n --         terminate;\r\n --       end select;\r\n --       accept SIGNAL;\r\n --     end loop;\r\n --   end SCREEN;\r\n\r\n  task body CHOPSTICK1 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n        or\r\n          terminate;\r\n        end select;\r\n        accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK1;\r\n\r\n  task body CHOPSTICK2 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n        or\r\n          terminate;\r\n        end select;\r\n        accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK2;\r\n\r\n  task body CHOPSTICK3 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n        or\r\n          terminate;\r\n        end select;\r\n        accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK3;\r\n\r\n  task body CHOPSTICK4 is\r\n    begin\r\n      loop\r\n        select\r\n          accept PICKUP;\r\n        or\r\n          terminate;\r\n        end select;\r\n        accept PUTDOWN;\r\n      end loop;\r\n    end CHOPSTICK4;\r\n\r\nbegin\r\n  DIJKSTRA.GIVE_BIRTH;\r\n  HOPPER.GIVE_BIRTH;\r\n  SAMMET.GIVE_BIRTH;\r\n  GEHANI.GIVE_BIRTH;\r\nend dinersmo;\r\n"
  },
  {
    "path": "exm/not_working/newrace.adb",
    "content": "with HAT; use HAT;   -- CS159-10 Instructor: Arthur Vargas Lopes\r\n                     -- Fall 1990\r\nprocedure newrace is\r\ntask SCREEN is\r\n        entry WAITME;\r\n        ENTRY SIGNALME;\r\nend SCREEN;\r\ntask BUBBLE_SORT is\r\nend BUBBLE_SORT;\r\ntask SELECT_S_SORT is\r\nend SELECT_S_SORT;\r\ntask body SCREEN is\r\n  n : integer;\r\nbegin\r\n  n := 0;\r\n  loop\r\n     select\r\n       when n = 0 =>\r\n          accept WAITME do\r\n            n := 1;\r\n          end WAITME;\r\n     or\r\n       when n = 1 =>\r\n          accept SIGNALME do\r\n            n := n - 1;\r\n          end SIGNALME;\r\n     or\r\n        terminate;\r\n     end select;\r\n   end loop;\r\nend SCREEN;\r\ntask body SELECT_S_SORT is\r\n    B : STRING(0..25);\r\n    I,J : INTEGER;\r\n    procedure SWAP(X, Y : in INTEGER) is\r\n        temp : character;\r\n    begin\r\n                                        SCREEN.WAITME; CURSORAT(2,X+14);\r\n                                        PUT(\"X\"); CURSORAT(2,Y+14);\r\n                                        PUT(\"Y\");\r\n                                        SCREEN.SIGNALME;\r\n        temp := b(x);\r\n        b(x) := b(y);\r\n        b(y) := temp;                   SCREEN.WAITME; CURSORAT(3,X+14);\r\n                                        PUT(b(x)); CURSORAT(3,Y+14);\r\n                                        PUT(b(y));\r\n                                        CURSORAT(2,X+14); PUT(\" \");\r\n                                        CURSORAT(2,Y+14); PUT(\" \");\r\n                                        SCREEN.SIGNALME;\r\n    end SWAP;\r\n begin\r\n       SCREEN.WAITME;CURSORAT(3,1); PUT(\"Selection:\");SCREEN.SIGNALME;\r\n       B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n       for k in 0..25 loop\r\n           CURSORAT(3,k+14);\r\n           put(b(k));\r\n       end loop;\r\n       for i in 0..24 loop       SCREEN.WAITME; CURSORAT(2,50);\r\n                                 PUT(\"I: \"); PUT(I);  SCREEN.SIGNALME;\r\n         for j in (i+1)..25 loop    SCREEN.WAITME; CURSORAT(3,50);\r\n                                    PUT(\"J: \"); PUT(J);  SCREEN.SIGNALME;\r\n           if B(I) > B(J) then\r\n             SWAP(I,J);\r\n           end if;\r\n         end loop;\r\n       end loop;\r\nend SELECT_S_SORT;\r\n\r\ntask body BUBBLE_SORT is\r\n    B : STRING(0..25);\r\n    I,J : INTEGER;\r\n    procedure SWAP(X, Y : in INTEGER) is\r\n        temp : character;\r\n    begin\r\n        SCREEN.WAITME; CURSORAT(6,X+14); PUT(\"X\"); CURSORAT(6,Y+14);\r\n        PUT(\"Y\"); SCREEN.SIGNALME;\r\n        temp := b(x);\r\n        b(x) := b(y);\r\n        b(y) := temp;\r\n        SCREEN.WAITME; CURSORAT(7,X+14); PUT(b(x)); CURSORAT(7,Y+14);\r\n        PUT(b(y)); CURSORAT(6,X+14);\r\n        PUT(\" \"); CURSORAT(6,Y+14); PUT(\" \"); SCREEN.SIGNALME;\r\n    end SWAP;\r\nbegin\r\n       SCREEN.WAITME;CURSORAT(7,1); PUT(\"Bubble:\"); SCREEN.SIGNALME;\r\n       B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n       for k in 0..25 loop\r\n           SCREEN.WAITME;CURSORAT(7,k+14);\r\n           put(b(k));    SCREEN.SIGNALME;\r\n       end loop;\r\n       I:= 25;\r\n       while (I > 0) loop                CURSORAT(6,50); PUT(\"I: \"); PUT(I);\r\n         J:= 0;\r\n         while (J < I) loop              CURSORAT(7,50); PUT(\"J: \"); PUT(J);\r\n           if B(J) > B(J+1) then\r\n             SWAP(J,J+1);\r\n           end if;\r\n           J:= J+1;\r\n         end loop;\r\n         I:= I-1;\r\n       end loop;\r\nend BUBBLE_SORT;\r\n\r\nbegin\r\nend newrace;\r\n"
  },
  {
    "path": "exm/not_working/overloading.adb",
    "content": "--  This example contains a feature that is missing in HAC (at least v.0.01)\n\nwith HAT; use HAT;\n\nprocedure Overloading is\n\n  function A (i : Integer) return Integer is\n  begin\n    return i + 1;\n  end A;\n\n  function A (r : Real) return Integer is\n  begin\n    return Integer (r) + 2;\n  end A;\n\nbegin\n  Put (A (0));    --  Should be 1\n  Put (A (0.0));  --  Should be 2\nend Overloading;\n"
  },
  {
    "path": "exm/not_working/pgm0.adb",
    "content": "with HAT; use HAT;\r\n\r\nprocedure PGM0 is\r\n\r\n  TASK TELLER IS\r\n     ENTRY MAKE_DEP(CUST_ID : INTEGER;\r\n                    AMOUNT  : Real);\r\n  END TELLER;\r\n\r\n  TASK CUST_C;\r\n  TASK CUST_B;\r\n  TASK CUST_A;\r\n\r\n  TYPE CUST_RECORD IS\r\n    RECORD\r\n      ID      : INTEGER;\r\n      BALANCE : Real;\r\n    END RECORD;\r\n\r\n  ACCOUNT : ARRAY (1 .. 5) OF CUST_RECORD;\r\n\r\n  procedure Show is\r\n  begin\r\n    for i in account'Range loop\r\n      Put_Line (+\"#\" & i & \"; ID: \" & account (i).ID & \"; balance: \" & account (i).balance);\r\n    end loop;\r\n    New_Line;\r\n  end;\r\n\r\n  TASK BODY CUST_C IS\r\n  BEGIN\r\n    TELLER.MAKE_DEP (435,75.50);\r\n  END CUST_C;\r\n\r\n  TASK BODY CUST_B IS\r\n  BEGIN\r\n    TELLER.MAKE_DEP (878,100.0);\r\n  END CUST_B;\r\n\r\n  TASK BODY CUST_A IS\r\n  BEGIN\r\n    TELLER.MAKE_DEP (354,50.00);\r\n  END CUST_A;\r\n\r\n  TASK BODY TELLER IS\r\n  BEGIN\r\n    ACCOUNT (1).ID      := 125;\r\n    ACCOUNT (1).BALANCE := 400.50;\r\n    ACCOUNT (2).ID      := 354;\r\n    ACCOUNT (2).BALANCE := 75.33;\r\n    ACCOUNT (3).ID      := 435;\r\n    ACCOUNT (3).BALANCE := 137.95;\r\n    ACCOUNT (4).ID      := 878;\r\n    ACCOUNT (4).BALANCE := 557.00;\r\n    ACCOUNT (5).ID      := 589;\r\n    ACCOUNT (5).BALANCE := 235.75;\r\n    Show;\r\n\r\n    LOOP\r\n      SELECT\r\n        ACCEPT MAKE_DEP (CUST_ID : INTEGER;\r\n                         AMOUNT  : Real) DO\r\n           for I in account'Range loop\r\n             IF ACCOUNT(I).ID = CUST_ID THEN\r\n                ACCOUNT(I).BALANCE :=\r\n                   ACCOUNT(I).BALANCE\r\n                   + AMOUNT;\r\n               Show;\r\n               exit;\r\n             END IF;\r\n           END LOOP;\r\n        END MAKE_DEP;\r\n      OR\r\n        TERMINATE;\r\n      END SELECT;\r\n    END LOOP;\r\n  END TELLER;\r\n\r\nBEGIN\r\n   NULL;\r\nEND;\r\n"
  },
  {
    "path": "exm/not_working/pgm1.adb",
    "content": "with HAT; use HAT;\r\n\r\nPROCEDURE PGM1 IS\r\n\r\n  TASK STD_1;\r\n  TASK STD_2;\r\n  TASK STD_3;\r\n\r\n  TASK TEACHER IS\r\n    ENTRY CHECK_GRADE (STDNT :     INTEGER;\r\n                       GRADE : OUT INTEGER);\r\n  END TEACHER;\r\n\r\n  TASK BODY STD_1 IS\r\n    MY_GRADE : INTEGER;\r\n  BEGIN\r\n    TEACHER.CHECK_GRADE (1, MY_GRADE);\r\n  END STD_1;\r\n\r\n  TASK BODY STD_2 IS\r\n    MY_GRADE : INTEGER;\r\n  BEGIN\r\n    TEACHER.CHECK_GRADE (2, MY_GRADE);\r\n  END STD_2;\r\n\r\n  TASK BODY STD_3 IS\r\n    MY_GRADE : INTEGER;\r\n  BEGIN\r\n    TEACHER.CHECK_GRADE (3, MY_GRADE);\r\n  END STD_3;\r\n\r\n  TASK BODY TEACHER IS\r\n    CLASS_GRADES : ARRAY (1 .. 4) OF INTEGER;\r\n    I : INTEGER;\r\n  BEGIN\r\n    CLASS_GRADES (1) := 35;\r\n    CLASS_GRADES (2) := 97;\r\n    CLASS_GRADES (3) := 85;\r\n    CLASS_GRADES (4) := 77;\r\n    ACCEPT CHECK_GRADE\r\n      (STDNT : INTEGER;\r\n       GRADE : OUT INTEGER) \r\n    DO\r\n      I := STDNT;\r\n      GRADE := CLASS_GRADES(I);\r\n    END CHECK_GRADE;\r\n  END TEACHER;\r\n\r\nBEGIN\r\n  NULL;\r\nEND PGM1;\r\n"
  },
  {
    "path": "exm/not_working/pgm2.adb",
    "content": "with HAT; use HAT;\r\n\r\nPROCEDURE PGM2 IS\r\n\r\n  POINT1   : INTEGER := 10;\r\n  POINT2   : INTEGER := -10;\r\n  POINT3   : INTEGER := -20;\r\n  POINT4   : INTEGER := 0;\r\n  POINT5   : INTEGER := 100;\r\n  FINISHED : INTEGER;\r\n\r\n  TASK CALCULATOR IS\r\n     ENTRY GET_LENGTH(POINTA, POINTB : INTEGER;\r\n                      LENGTH : OUT INTEGER);\r\n     ENTRY GET_MIDPOINT(POINTA, POINTB : INTEGER;\r\n                        POINTC : OUT INTEGER);\r\n     ENTRY DONE;\r\n     ENTRY ACK;\r\n  END CALCULATOR;\r\n\r\n  TASK GEOM_A;\r\n\r\n  TASK GEOM_B;\r\n\r\n  TASK GEOM_C;\r\n\r\n  TASK BODY GEOM_A IS\r\n     LENGTH   : INTEGER;\r\n     MIDPOINT : INTEGER;\r\n  BEGIN\r\n     CALCULATOR.GET_LENGTH(POINT2,POINT1,LENGTH);\r\n     CALCULATOR.GET_MIDPOINT(POINT1,POINT5,MIDPOINT);\r\n     CALCULATOR.ACK;\r\n  END GEOM_A;\r\n\r\n  TASK BODY GEOM_B IS\r\n     LENGTH   : INTEGER;\r\n     MIDPOINT : INTEGER;\r\n  BEGIN\r\n     CALCULATOR.GET_MIDPOINT(POINT2,POINT3,MIDPOINT);\r\n     CALCULATOR.GET_MIDPOINT(POINT3,POINT5,MIDPOINT);\r\n     CALCULATOR.ACK;\r\n  END GEOM_B;\r\n\r\n  TASK BODY GEOM_C IS\r\n     LENGTH   : INTEGER;\r\n     MIDPOINT : INTEGER;\r\n  BEGIN\r\n     CALCULATOR.GET_MIDPOINT(POINT1,POINT4,MIDPOINT);\r\n     CALCULATOR.GET_LENGTH(POINT5,POINT2,LENGTH);\r\n     CALCULATOR.GET_MIDPOINT(POINT4,POINT1,MIDPOINT);\r\n     CALCULATOR.ACK;\r\n  END GEOM_C;\r\n\r\n  TASK BODY CALCULATOR IS\r\n  BEGIN\r\n     FINISHED := 0;\r\n     LOOP\r\n        SELECT\r\n           ACCEPT GET_LENGTH(POINTA, POINTB : INTEGER;\r\n                             LENGTH : OUT INTEGER) DO\r\n              LENGTH := POINTB - POINTA;\r\n           END GET_LENGTH;\r\n        OR\r\n           ACCEPT GET_MIDPOINT(POINTA, POINTB : INTEGER;\r\n                               POINTC : OUT INTEGER) DO\r\n              POINTC := (POINTA + POINTB) / 2;\r\n           END GET_MIDPOINT;\r\n        OR\r\n           ACCEPT ACK DO\r\n              FINISHED := FINISHED + 1;\r\n           END ACK;\r\n        OR\r\n           WHEN FINISHED = 3 =>\r\n              ACCEPT DONE DO\r\n                 NULL;\r\n              END DONE;\r\n        OR\r\n           TERMINATE;\r\n        END SELECT;\r\n     END LOOP;\r\n  END CALCULATOR;\r\n\r\nBEGIN\r\n   CALCULATOR.DONE;\r\n   PUT(\"POINT1 = \"); PUT_LINE(POINT1);\r\n   PUT(\"POINT2 = \"); PUT_LINE(POINT2);\r\n   PUT(\"POINT3 = \"); PUT_LINE(POINT3);\r\n   PUT(\"POINT4 = \"); PUT_LINE(POINT4);\r\n   PUT(\"POINT5 = \"); PUT_LINE(POINT5);\r\nEND PGM2;\r\n"
  },
  {
    "path": "exm/not_working/race.adb",
    "content": "with HAT; use HAT;\r\n\r\nprocedure RACE is\r\n------------------------------------------------------------------------------\r\n-- Sort race demonstration program for THE AVL PARALLEL MONITORING           -\r\n-- WITH                                SmallAda Version 2.0.                 -\r\n------------------------------------------------------------------------------\r\nSTIME : FLOAT;\r\ntask BUBBLE_SORT is\r\n  entry S(r : in INTEGER; t : in FLOAT);\r\n  entry X;\r\nend BUBBLE_SORT;\r\n\r\ntask INSERT_SORT is\r\n  entry S(r : in INTEGER; t : in FLOAT);\r\n  entry X;\r\nend INSERT_SORT;\r\n\r\ntask SHELL_SORT is\r\n  entry S(r : in INTEGER; t : in FLOAT);\r\n  entry X;\r\nend SHELL_SORT;\r\n\r\ntask SCREEN is\r\n  entry P(X,Y : in INTEGER; C : in CHARACTER);\r\n  entry place(who : integer);\r\n  entry conclude;\r\nend SCREEN;\r\n\r\ntask body SCREEN is\r\n  position : integer := 0;\r\nbegin\r\nloop\r\n  select\r\n    accept P(X,Y : in INTEGER; C : in CHARACTER) do\r\n      CURSORAT(X,Y);\r\n      PUT(C);\r\n    end P;\r\n  or\r\n    accept place(who : integer) do\r\n      CURSORAT(who,50);\r\n      IF POSITION = 0 THEN\r\n         PUT(\"FIRST\");\r\n      ELSIF POSITION = 1 THEN\r\n         PUT(\"SECOND\");\r\n      ELSE\r\n         PUT(\"LAST\");\r\n         CURSORAT(18,1);\r\n      END IF;\r\n      POSITION := POSITION + 1;\r\n    end place;\r\n  or\r\n    when position = 3 =>\r\n        accept conclude;\r\n  or\r\n    terminate ;\r\n  end select ;\r\nend loop;\r\nend SCREEN;\r\n\r\ntask body SHELL_SORT is\r\n  B          : STRING(0..25);\r\n  TEMP       : CHARACTER;\r\n  I\r\n ,J\r\n ,STEP       : INTEGER;\r\n  STEPSIZE   : array(1..4) OF INTEGER;\r\n  STOP       : BOOLEAN;\r\n  ROW        : INTEGER;\r\n  STIME      : FLOAT;\r\nbegin\r\n  B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n  -- Accept call from \"main\"\r\n  accept S(r : in INTEGER; t : in FLOAT) do\r\n    ROW   := r;\r\n    STIME := t;\r\n  end S;\r\n  for k in 0..25 loop\r\n    SCREEN.P(ROW,14+k,B(k));\r\n  end loop;\r\n  -- 'steps' contains decreasing increments for each\r\n  -- pass. The last pass has increment 1.\r\n  STEPSIZE(4) := 1;\r\n  for PASS in reverse 1..3 loop\r\n    STEPSIZE(PASS):= 2*STEPSIZE(PASS+1);\r\n  end loop;\r\n\r\n  delay STIME - CLOCK;\r\n  for PASS in 1..4 loop\r\n    STEP := STEPSIZE(PASS);\r\n    -- Do a straight insertion sort with 'step' as\r\n    -- an increment instead of 1.\r\n    I := STEP;\r\n    while (I <= 25) loop\r\n      TEMP := B(I);\r\n      J    := I;\r\n      STOP := FALSE;\r\n      while (J > STEP-1) and (STOP /= TRUE) loop\r\n        J := J - STEP;\r\n        if B(J) > TEMP then\r\n          B(J+STEP) := B(J);\r\n          SCREEN.P(ROW, 14+J, TEMP);\r\n        else\r\n          B(J+STEP) := TEMP;\r\n          STOP := TRUE;\r\n        end if;\r\n        SCREEN.P(ROW,14+(J+STEP),B(J+STEP));\r\n      end loop;\r\n      if (not STOP) then\r\n        B(0) := TEMP;\r\n        SCREEN.P(ROW,14,B(0));\r\n      end if;\r\n      I := I + STEP;\r\n    end loop;\r\n  end loop; -- for pass in 1..npass\r\n  SCREEN.PLACE(ROW);\r\nend SHELL_SORT;\r\n\r\ntask body BUBBLE_SORT is\r\n  B     : STRING(0..25);\r\n  TEMP  : CHARACTER;\r\n  I, J  : INTEGER;\r\n  ROW   : INTEGER;\r\n  STIME : FLOAT;\r\nbegin\r\n  B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n  -- Accept call from \"main\"\r\n  accept S(r : in INTEGER; t : in FLOAT) do\r\n    ROW := r;\r\n    STIME := t;\r\n  end S;\r\n  for k in 0..25 loop\r\n    SCREEN.P(ROW,14+k,B(k));\r\n  end loop;\r\n  delay STIME - CLOCK;\r\n  I:= 25;\r\n  while (I > 0) loop\r\n    J:= 0;\r\n    while (J < I) loop\r\n      if B(J) > B(J+1) then\r\n        TEMP:= B(J+1);\r\n        B(J+1):= B(J);\r\n        B(J):= TEMP;\r\n        SCREEN.P(ROW,14+J  ,B(J  ));\r\n        SCREEN.P(ROW,14+J+1,B(J+1));\r\n      end if;\r\n      J:= J+1;\r\n    end loop;\r\n    I:= I-1;\r\n  end loop;\r\n  SCREEN.PLACE(ROW);\r\nend BUBBLE_SORT;\r\n\r\ntask body INSERT_SORT is\r\n  B     : STRING(0..25);\r\n  TEMP  : CHARACTER;\r\n  J     : INTEGER;\r\n  STOP  : BOOLEAN;\r\n  ROW   : INTEGER;\r\n  STIME : FLOAT;\r\nBEGIN\r\n  B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n  -- Accept call from \"main\"\r\n  accept S(r : in INTEGER; t : in FLOAT) do\r\n    ROW   := r;\r\n    STIME := t;\r\n  end S;\r\n  for k in 0..25 loop\r\n    SCREEN.P(ROW,14+k,B(k));\r\n  end loop;\r\n  delay STIME - CLOCK;\r\n  for I in 0..25 loop\r\n    TEMP := B(I);\r\n    J    := I;\r\n    STOP := FALSE;\r\n    while (J > 0) and (not STOP) loop\r\n      J := J - 1;\r\n      if (B(J) > TEMP) then\r\n        B(J+1):= B(J);\r\n      else\r\n        B(J+1):= TEMP;\r\n        STOP  := TRUE;\r\n      end if;\r\n      SCREEN.P(ROW, 14+(J+1) ,B(J+1));\r\n    end loop;\r\n    if (not STOP) then\r\n      B(0) := TEMP;\r\n      SCREEN.P(ROW ,14 ,B(0));\r\n    end if;\r\n  end loop;\r\n  SCREEN.PLACE(ROW);\r\nend INSERT_SORT;\r\n\r\nbegin\r\n  CURSORAT(3,1);\r\n  PUT(\"Bubble:\");\r\n  CURSORAT(5,1);\r\n  PUT(\"Insertion:\");\r\n  CURSORAT(7,1);\r\n  PUT(\"Shell:\");\r\n  STIME := CLOCK + 10.0;\r\n  -- Start Bubble\r\n  BUBBLE_SORT.S(3,STIME);\r\n  -- Start Insert\r\n  INSERT_SORT.S(5,STIME);\r\n  -- Start Shell\r\n  SHELL_SORT.S(7,STIME);\r\n  -- Wait until the \"race\" finish\r\n  SCREEN.conclude;\r\nend RACE;\r\n"
  },
  {
    "path": "exm/not_working/racedead.adb",
    "content": "with HAT; use HAT;\r\n\r\nprocedure RACEDead is\r\n------------------------------------------------------------------------------\r\n-- Sort race demonstration program for THE AVL PARALLEL MONITORING           -\r\n-- WITH                                SmallAda Version 2.0.                 -\r\n------------------------------------------------------------------------------\r\n   STIME : FLOAT;\r\n   task BUBBLE_SORT is\r\n     entry S(r : in INTEGER; t : in FLOAT);\r\n     entry X;\r\n   end BUBBLE_SORT;\r\n\r\n   task INSERT_SORT is\r\n     entry S(r : in INTEGER; t : in FLOAT);\r\n     entry X;\r\n   end INSERT_SORT;\r\n\r\n   task SHELL_SORT is\r\n     entry S(r : in INTEGER; t : in FLOAT);\r\n     entry X;\r\n   end SHELL_SORT;\r\n\r\n   task SCREEN is\r\n     entry P(X,Y : in INTEGER; C : in CHARACTER);\r\n   end SCREEN;\r\n   task body SCREEN is\r\n\r\n\r\n   begin\r\n     loop\r\n       select\r\n       accept P(X,Y : in INTEGER;\r\n                  C : in CHARACTER) do\r\n         CURSORAT(X,Y);\r\n         PUT(C);\r\n       end P;\r\n       end select ;\r\n     end loop;\r\n   end SCREEN;\r\n\r\n   task body BUBBLE_SORT is\r\n    B : STRING(0..5);\r\n    TEMP : CHARACTER;\r\n    I,J : INTEGER;\r\n    ROW : INTEGER;\r\n    STIME : FLOAT;\r\n   begin\r\n       B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n       accept S(r : in INTEGER; t : in FLOAT) do\r\n         ROW := r;\r\n         STIME := t;\r\n       end S;\r\n       for k in 0..5 loop SCREEN.P(ROW,14+k,B(k)); end loop;\r\n       delay STIME - CLOCK;\r\n       I:= 5;\r\n       while (I > 0) loop\r\n         J:= 0;\r\n         while (J < I) loop\r\n           if B(J) > B(J+1) then\r\n             TEMP:= B(J+1);\r\n             B(J+1):= B(J);\r\n             B(J):= TEMP;\r\n             SCREEN.P(ROW,14+J  ,B(J  ));\r\n             SCREEN.P(ROW,14+J+1,B(J+1));\r\n           end if;\r\n           J:= J+1;\r\n         end loop;\r\n         I:= I-1;\r\n       end loop;\r\n       accept X;\r\n   end BUBBLE_SORT;\r\n\r\n\r\n   task body INSERT_SORT is\r\n     B : STRING(0..5);\r\n     TEMP : CHARACTER;\r\n     J : INTEGER;\r\n     STOP : BOOLEAN;\r\n     ROW : INTEGER;\r\n     STIME : FLOAT;\r\n   BEGIN\r\n     B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n     accept S(r : in INTEGER; t : in FLOAT) do\r\n       ROW := r;\r\n       STIME := t;\r\n     end S;\r\n     for k in 0..5 loop SCREEN.P(ROW,14+k,B(k)); end loop;\r\n     delay STIME - CLOCK;\r\n     for I in 0..5 loop\r\n       TEMP := B(I); J:= I; STOP := FALSE;\r\n       while (J > 0) and (not STOP) loop\r\n         J := J - 1;\r\n         if (B(J) > TEMP) then\r\n            B(J+1):= B(J);\r\n         else\r\n            B(J+1):= TEMP;\r\n            STOP := TRUE;\r\n         end if;\r\n         SCREEN.P(ROW, 14+(J+1) ,B(J+1));\r\n       end loop;\r\n       if (not STOP) then\r\n          B(0):= TEMP;\r\n          SCREEN.P(ROW ,14 ,B(0));\r\n       end if;\r\n     end loop;\r\n     accept X;\r\n  end INSERT_SORT;\r\n\r\n\r\n   task body SHELL_SORT is\r\n     B : STRING(0..5);\r\n     TEMP : CHARACTER;\r\n     I,J,STEP : INTEGER;\r\n     STEPSIZE : array(1..4) OF INTEGER;\r\n     STOP : BOOLEAN;\r\n     ROW : INTEGER;\r\n     STIME : FLOAT;\r\n\r\n   begin\r\n     B := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n     accept S(r : in INTEGER; t : in FLOAT) do\r\n       ROW := r;\r\n       STIME := t;\r\n     end S;\r\n     for k in 0..5 loop SCREEN.P(ROW,14+k,B(k)); end loop;\r\n                    -- 'steps' contains decreasing increments for each\r\n                    -- pass. The last pass has increment 1.\r\n     STEPSIZE(4) := 1;\r\n     for PASS in reverse 1..3 loop\r\n         STEPSIZE(PASS):= 2*STEPSIZE(PASS+1);\r\n     end loop;\r\n\r\n     delay STIME - CLOCK;\r\n     for PASS in 1..4 loop\r\n       STEP := STEPSIZE(PASS);\r\n                    -- Do a straight insertion sort with 'step' as\r\n                    -- an increment instead of 1.\r\n       I:= STEP;\r\n       while (I <= 5) loop\r\n         TEMP := B(I); J:= I; STOP:= FALSE;\r\n         while (J > STEP-1) and (STOP /= TRUE) loop\r\n           J := J - STEP;\r\n           if B(J) > TEMP then\r\n              B(J+STEP):= B(J);\r\n              SCREEN.P(ROW, 14+J, TEMP);\r\n           else\r\n              B(J+STEP):= TEMP;\r\n              STOP:= TRUE;\r\n           end if;\r\n           SCREEN.P(ROW, 14+(J+STEP) ,B(J+STEP));\r\n         end loop;\r\n         if (not STOP) then\r\n            B(0):= TEMP;\r\n            SCREEN.P(ROW, 14 ,B(0));\r\n         end if;\r\n         I := I + STEP;\r\n       end loop;\r\n     end loop; -- for pass in 1..npass\r\n     accept X;\r\n   end SHELL_SORT;\r\n\r\nbegin\r\n\r\n  CURSORAT(3,1); PUT(\"Bubble:\");\r\n  CURSORAT(5,1); PUT(\"Insertion:\");\r\n  CURSORAT(7,1); PUT(\"Shell:\");\r\n\r\n  STIME := CLOCK + 10.0;\r\n\r\n  BUBBLE_SORT.S(3,STIME);\r\n  INSERT_SORT.S(5,STIME);\r\n  SHELL_SORT.S(7,STIME);\r\n\r\n  BUBBLE_SORT.X;\r\n  INSERT_SORT.X;\r\n  SHELL_SORT.X;\r\nend RACEDead;\r\n"
  },
  {
    "path": "exm/not_working/roland_01.adb",
    "content": "--  Submitted by Roland Coghetto - thanks\r\n--\r\n--  ** HAC Bug as of 21-Mar-2019: the BEGIN .. END block\r\n--     below (even without DECLARE) seems to corrupt the stack.\r\n--  See comments @ procedure Block_statement in HAC.Parser.\r\n\r\nwith HAT; use HAT;\r\n\r\nprocedure Roland_01 is\r\n  a:integer:= 1234;\r\nbegin\r\n  put(\"a = \");\r\n  put(a);\r\n  new_line;\r\n  put(\"[p1]\");\r\n  declare\r\n    aa: integer; -- := 1;\r\n  begin\r\n    put(\"[p2]\");\r\n    new_line;\r\n    put_line(\"BEGIN BLOC 1\");\r\n    put(\"aa = \");\r\n    --  put(aa);  --  BUG\r\n    new_line;\r\n    put_line(\"END BLOC 1\");\r\n  end;\r\n  new_line;\r\n  put_line(\"OUT 1\");\r\n  put(\"a = \");\r\n  put(a);\r\n  new_line;\r\n  put_line(\"OUT 2\");\r\nend Roland_01;\r\n"
  },
  {
    "path": "exm/pack_list.adb",
    "content": "--  Turn a list of integers (one per row), like\n--      ...\n--      791\n--      690\n--      960\n--      939\n--      549\n--      ...\n--  into a packed format with 10 items per line, separated by commas, like:\n--      ...\n--      791,  690,  960,  939,  549,  855,  911,  933,  911,  945,  --   40 ..  49\n--      974,  755,  846,  762,  761,  571,  677,  763,  760,  759,  --   50 ..  59\n--      754,  494,  552,  537,  577,  692,  786,  788,  788,  790,  --   60 ..  69\n--      ...\n\nwith HAT;\n\nprocedure Pack_List is\n  use HAT;\n  s : VString;\n  f, g : File_Type;\n  i : Natural := 0;\n  x : Natural;\nbegin\n  Open   (f, \"list.txt\");\n  Create (g, \"packed_list.txt\");\n  while not End_Of_File (f) loop\n    Get (f, x);\n    Put (g, x, 4);\n    Put (g, \", \");\n    i := i + 1;\n    if i mod 10 = 0 then\n      Put (g, \" --  \");\n      Put (g, i - 10, 3);\n      Put (g, \" .. \");\n      Put (g, i - 1, 3);\n      New_Line (g);\n    end if; \n  end loop;\n  Close (f);\n  Close (g);\nend Pack_List;\n"
  },
  {
    "path": "exm/pdf/hac_pdf_out.adb",
    "content": "package body HAC_PDF_Out is\n\n  use HAT;\n\n  procedure Set_A4_Portrait (r : out Rectangle) is\n  begin\n    r.x_min  := 0.0;\n    r.y_min  := 0.0;\n    r.width  := 21.0 * one_cm;\n    r.height := 29.7 * one_cm;\n  end Set_A4_Portrait;\n\n  procedure Set_A4_Landscape (r : out Rectangle) is\n  begin\n    r.x_min  := 0.0;\n    r.y_min  := 0.0;\n    r.width  := 29.7 * one_cm;\n    r.height := 21.0 * one_cm;\n  end Set_A4_Landscape;\n\n  procedure Init (pdf : in out PDF_Out_File) is\n    A4_portrait : Rectangle;\n    cm_2_5_margins : Margins_Type;\n  begin\n    Set_A4_Portrait (A4_portrait);\n    --\n    cm_2_5_margins.left   := cm_2_5;\n    cm_2_5_margins.right  := cm_2_5;\n    cm_2_5_margins.top    := cm_2_5;\n    cm_2_5_margins.bottom := cm_2_5;\n    --\n    pdf.is_created     := False;\n    pdf.is_closed      := False;\n    pdf.file_index     := 1;\n    pdf.file_name      := Null_VString;\n    pdf.format         := PDF_1_3;\n    pdf.zone           := nowhere;\n    pdf.text_switch    := graphics;\n    pdf.last_page      := 0;\n    pdf.current_line   := 1;  --  Mostly for Ada.Text_IO compatibility\n    pdf.current_col    := 1;  --  Mostly for Ada.Text_IO compatibility\n    pdf.page_box       := A4_portrait;\n    pdf.maximum_box    := A4_portrait;\n    pdf.page_margins   := cm_2_5_margins;\n    pdf.objects        := 1;\n    pdf.current_font   := Helvetica;\n    pdf.font_size      := 11.0;\n    pdf.line_spacing   := 1.2;\n    pdf.stream_obj_buf := Null_VString;\n    pdf.ext_font_name  := Null_VString;\n    pdf.doc_title      := Null_VString;\n    pdf.doc_author     := Null_VString;\n    pdf.doc_subject    := Null_VString;\n    pdf.doc_keywords   := Null_VString;\n    pdf.doc_creator    := Null_VString;\n  end Init;\n\n  procedure W (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    HAT.Put (pdf.pdf_file, s);\n    pdf.file_index := pdf.file_index + Length (s);\n  end W;\n\n  function NL return Character is begin return Character'Val (10); end NL;\n\n  procedure WL (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    W (pdf, s & NL);\n  end WL;\n\n  procedure No_Nowhere (pdf : in out PDF_Out_File) is\n  begin\n    if pdf.zone = nowhere then\n      New_Page (pdf);\n    end if;\n  end No_Nowhere;\n\n  --  Delayed output, for internal PDF's \"stream\" object\n\n  procedure Wd (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    No_Nowhere (pdf);\n    pdf.stream_obj_buf := pdf.stream_obj_buf & s;\n  end Wd;\n\n  procedure WLd (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    Wd (pdf, s & NL);\n  end WLd;\n\n  --  External stream index\n\n  function Buffer_index (pdf : PDF_Out_File) return Natural is\n  begin\n    return pdf.file_index - pdf.start_index;\n  end Buffer_index;\n\n  function Img_I (p : Integer) return VString is\n  begin\n    return HAT.Image (p);\n  end Img_I;\n\n  function Img_R (x : Real) return VString is\n    im : VString := HAT.Image (x);\n  begin\n    if Slice (im, 1, 2) = \"0.\" then\n      im := Slice (im, 2, Length (im));\n    elsif Slice (im, 1, 3) = \"-0.\" then\n      im := '-' & Slice (im, 3, Length (im));\n    end if;\n    if im = \".0\" then\n      return +\"0\";\n    end if;\n    if Slice (im, Length (im) - 1, Length (im)) = \".0\" then\n      return Slice (im, 1, Length (im) - 2);  --  Return as integer\n    end if;\n    return im;\n  end Img_R;\n\n  --  function \"+\"(P1, P2 : Point) return Point is\n  --  begin\n  --    return (P1.x + P2.x, P1.y + P2.y);\n  --  end \"+\";\n  --\n  --  function \"*\"(f : Real; P : Point) return Point is\n  --  begin\n  --    return (f * P.x, f * P.y);\n  --  end \"*\";\n  --\n  --  function \"+\"(P : Point; r : Rectangle) return Rectangle is\n  --  begin\n  --    return (P.x + r.x_min, P.y + r.y_min, r.width, r.height);\n  --  end \"+\";\n  --\n  --  function \"*\"(f : Real; r : Rectangle) return Rectangle is\n  --  begin\n  --    return (r.x_min, r.y_min, f * r.width, f * r.height);\n  --  end \"*\";\n\n  function X_Max (r : Rectangle) return Real is\n  begin\n    return r.x_min + r.width;\n  end X_Max;\n\n  function Y_Max (r : Rectangle) return Real is\n  begin\n    return r.y_min + r.height;\n  end Y_Max;\n\n  type Abs_Rel_Mode is (absolute, relative);\n\n  function Img_P (p : Point) return VString is\n  begin\n    return Img_R (p.x) & ' ' & Img_R (p.y);\n  end Img_P;\n\n  function Img_Rect (box : Rectangle; mode : Abs_Rel_Mode) return VString is\n  begin\n    case mode is\n      when absolute =>\n        return Img_R (box.x_min) & ' ' & Img_R (box.y_min) & ' ' &\n               Img_R (X_Max (box)) & ' ' & Img_R (Y_Max (box)) & ' ';\n      when relative =>\n        return Img_R (box.x_min) & ' ' & Img_R (box.y_min) & ' ' &\n               Img_R (box.width) & ' ' & Img_R (box.height) & ' ';\n    end case;\n  end Img_Rect;\n\n  procedure New_fixed_index_object (pdf : in out PDF_Out_File; idx : PDF_Index_Type) is\n  begin\n    pdf.object_offset (idx) := Buffer_index (pdf);\n    WL (pdf, Img_I (Integer (idx)) & \" 0 obj\");\n  end New_fixed_index_object;\n\n  procedure New_object (pdf : in out PDF_Out_File) is\n  begin\n    pdf.objects := pdf.objects + 1;\n    New_fixed_index_object (pdf, pdf.objects);\n  end New_object;\n\n  function producer return VString is\n  begin\n    return +\"HAC_PDF_Out, a version of Ada PDF Writer (http://apdf.sf.net/), \" &\n            \"stripped down for the HAC Ada Compiler language subset.\";\n  end producer;\n\n  procedure Write_PDF_header (pdf : in out PDF_Out_File) is\n    sig : String (1 .. 8);\n  begin\n    pdf.is_created := True;\n    pdf.start_index := pdf.file_index;\n    case pdf.format is\n      when PDF_1_3 =>\n        WL (pdf, +\"%PDF-1.3\");\n        sig (1) := Character'Val (16#25#);\n        sig (2) := Character'Val (16#C2#);\n        sig (3) := Character'Val (16#A5#);\n        sig (4) := Character'Val (16#C2#);\n        sig (5) := Character'Val (16#B1#);\n        sig (6) := Character'Val (16#C3#);\n        sig (7) := Character'Val (16#AB#);\n        sig (8) := Character'Val (10);\n        W (pdf, +sig);\n    end case;\n    WL (pdf, \"%  --  Produced by \" & producer);\n  end Write_PDF_header;\n\n  procedure New_substream (pdf : in out PDF_Out_File) is\n  begin\n    pdf.stream_obj_buf := Null_VString;\n  end New_substream;\n\n  procedure Finish_substream (pdf : in out PDF_Out_File) is\n  begin\n    WL (pdf, +\"  << /Length\" & Integer'Image (Length (pdf.stream_obj_buf)) & \" >>\");\n    --  Length could be alternatively stored in next object,\n    --  so we wouldn't need to buffer the stream - see 7.3.10, Example 3.\n    --  But we prefer the buffered version, which could be compressed in a future version\n    --  of this package.\n    WL (pdf, +\"stream\");\n    WL (pdf, pdf.stream_obj_buf);\n    WL (pdf, +\"endstream\");\n  end Finish_substream;\n\n  --  Internal - test page for experimenting PDF constructs (and how Adobe Reader reacts to them)\n  --\n  procedure Test_Page (pdf : in out PDF_Out_File) is\n  begin\n    WLd (pdf, +\"10 10 200 200 re S\"); -- rectangle, stroke\n    WLd (pdf, +\"  BT\");            --  Begin Text object (9.4). Text matrix and text line matrix:= I\n    WLd (pdf, +\"    /Ada_PDF_Std_Font_Helvetica 24 Tf\");   --  F1 font, 24 pt size (9.3 Text State Parameters and Operators)\n    WLd (pdf, +\"    0.5 0 0 rg\");  --  red, nonstroking colour (Table 74)\n    WLd (pdf, +\"    0.25 G\");     --  25% gray stroking colour (Table 74)\n    WLd (pdf, +\"    2 Tr\");        --  Tr: Set rendering mode as \"Fill, then stroke text\" (Table 106)\n    WLd (pdf, +\"    20 539 Td\");\n    WLd (pdf, +\"    (Hello World !) Tj\"); -- Tj: Show a text string (9.4.3 Text-Showing Operators)\n    WLd (pdf, +\"    16 TL\");       --  TL: set text leading (distance between lines, 9.3.5)\n    WLd (pdf, +\"    T*\");          --  T*: Move to the start of the next line (9.4.2)\n    WLd (pdf, +\"    20 20 200 200 re S\"); -- rectangle, stroke (within text region)\n    WLd (pdf, +\"    /Ada_PDF_Std_Font_Helvetica-Oblique 12 Tf\");\n    WLd (pdf, +\"    0 Tr\");        --  Tr: Set rendering mode as default: \"Fill text\" (Table 106)\n    WLd (pdf, +\"    0 g\");         --  black (default)\n    WLd (pdf, +\"    (Subtitle here.) Tj T*\");\n    WLd (pdf, +\"  ET\");           --  End Text\n    WLd (pdf, +\"30 30 200 200 re S\"); -- rectangle, stroke\n    WLd (pdf, +\"  BT\");\n    WLd (pdf, +\"    5 5 Td (Second text chunk here.) Tj T*\");\n    WLd (pdf, +\"  ET\");\n    WLd (pdf, +\"40 40 240 240 re S\"); -- rectangle, stroke\n    WLd (pdf, +\"15 15 Td (Text chunk not within BT/ET.) Tj\");\n  end Test_Page;\n\n  function test_page_mode return Boolean is begin return False; end test_page_mode;\n\n  package Fonts is\n\n    function Standard_Font_Name (f : Standard_Font_Type) return VString;\n\n    --  Font dictionary name within a page\n    --\n    function Font_Dictionary_Name (font_name : VString) return VString;\n\n    --  Font dictionary name within a page, for standard fonts\n    --  Example: /Ada_PDF_Std_Font_Courier-Oblique\n    --\n    function Standard_Font_Dictionary_Name (f : Standard_Font_Type) return VString;\n\n    --  Output font dictionary (resource for last page)\n    --\n    procedure Font_Dictionary (pdf : in out PDF_Out_File);\n\n    --  function Current_Font_Name (pdf : PDF_Out_File) return VString;\n\n    function Current_Font_Dictionary_Name (pdf : PDF_Out_File) return VString;\n\n  end Fonts;\n\n  procedure Insert_PDF_Font_Selection_Code (pdf : in out PDF_Out_File) is\n  begin\n    Insert_Text_PDF_Code (pdf,\n      Fonts.Current_Font_Dictionary_Name (pdf) &\n      ' ' & Img_R (pdf.font_size) & \" Tf \" &  --  Tf: 9.3 Text State Parameters and Operators\n      Img_R (pdf.font_size * pdf.line_spacing) & \" TL\"  --  TL: set text leading (9.3.5)\n    );\n  end Insert_PDF_Font_Selection_Code;\n\n  procedure Font (pdf : in out PDF_Out_File; f : Standard_Font_Type) is\n  begin\n    pdf.current_font := f;\n    Insert_PDF_Font_Selection_Code (pdf);\n  end Font;\n\n  procedure Font_Size (pdf : in out PDF_Out_File; size : Real) is\n  begin\n    pdf.font_size := size;\n    Insert_PDF_Font_Selection_Code (pdf);\n  end Font_Size;\n\n  procedure Line_Spacing (pdf : in out PDF_Out_File; factor : Real) is\n  begin\n    pdf.line_spacing := factor;\n    Insert_PDF_Font_Selection_Code (pdf);\n  end Line_Spacing;\n\n  procedure Line_Spacing_Pt (pdf : in out PDF_Out_File; pt : Real) is\n  begin\n    pdf.line_spacing := pt / pdf.font_size;\n    --  !! This assumes that the font size is in Point (pt) units.\n    Insert_PDF_Font_Selection_Code (pdf);\n  end Line_Spacing_Pt;\n\n  procedure Begin_text (pdf : in out PDF_Out_File) is\n  begin\n    WLd (pdf,  +\"  BT\");  --  Begin Text object (9.4.1, Table 107)\n  end Begin_text;\n\n  procedure End_text (pdf : in out PDF_Out_File) is\n  begin\n    WLd (pdf,  +\"  ET\");\n  end End_text;\n\n  procedure Flip_to (pdf : in out PDF_Out_File; new_state : Text_or_graphics) is\n  begin\n    No_Nowhere (pdf);\n    --  WLd(pdf,  \" % Text_or_graphics before: \" & pdf.text_switch'Image);\n    if pdf.text_switch /= new_state then\n      pdf.text_switch := new_state;\n      case new_state is\n        when text     => Begin_text (pdf);\n        when graphics => End_text (pdf);\n      end case;\n    end if;\n    --  WLd(pdf,  \" % Text_or_graphics after: \" & pdf.text_switch'Image);\n  end Flip_to;\n\n  function pages_idx return Integer is begin return 1; end pages_idx;\n\n  procedure New_Page (pdf : in out PDF_Out_File) is\n  begin\n    if pdf.zone /= nowhere then\n      Finish_Page (pdf);\n    end if;\n    pdf.last_page := pdf.last_page + 1;\n    pdf.current_line := 1;\n    pdf.current_col := 1;\n    --  PDF_Out.Images.Clear_local_resource_flags (pdf);\n    --\n    --  Page descriptor object:\n    --\n    New_object (pdf);\n    pdf.page_idx (pdf.last_page) := pdf.objects;\n    --  Table 30 (7.7.3.3 Page Objects) for options\n    WL (pdf, +\"  <</Type /Page\");\n    WL (pdf, +\"    /Parent \" & Img_I (pages_idx) & \" 0 R\");\n    --  Contents stream object is object number n+1 (our choice):\n    WL (pdf, +\"    /Contents \" & Img_I (Integer (pdf.objects + 1)) & \" 0 R\");\n    --  Resources: a dictionary containing any resources required by the page.\n    --  Resources object is object number n+2 (our choice):\n    WL (pdf, +\"    /Resources \" & Img_I (Integer (pdf.objects + 2)) & \" 0 R\");\n    WL (pdf, +\"    /MediaBox [\" & Img_Rect (pdf.page_box, absolute) & ']');\n    WL (pdf, +\"  >>\");\n    WL (pdf, +\"endobj\");\n    --  Page contents object:\n    --\n    New_object (pdf);\n    New_substream (pdf);\n    if test_page_mode then\n      Test_Page (pdf);\n    else\n      pdf.zone := in_page;\n      Insert_PDF_Font_Selection_Code (pdf);\n      pdf.zone := in_header;\n      --  No dispatching in the HAC version -> no custom header!\n      Page_Header (pdf);\n    end if;\n    pdf.zone := in_page;\n    Text_XY (pdf, pdf.page_margins.left, Y_Max (pdf.page_box) - pdf.page_margins.top);\n  end New_Page;\n\n  procedure Finish_Page (pdf : in out PDF_Out_File) is\n\n    --  appended_object_idx : PDF_Index_Type;\n\n  begin\n    if pdf.zone = nowhere then\n      return;  --  We are already \"between pages\"\n    end if;\n    if test_page_mode then\n      null;  --  Nothing to do anymore with test page\n    else\n      pdf.zone := in_footer;\n      --  No dispatching in the HAC version -> no custom  footer!\n      Page_Footer (pdf);\n      Flip_to (pdf, graphics);\n    end if;\n    pdf.zone := nowhere;\n    Finish_substream (pdf);\n    WL (pdf, +\"endobj\");  --  end of page contents.\n    --  Resources Dictionary (7.8.3) for the page just finished:\n    New_object (pdf);\n    WL (pdf, +\"<<\");\n    --  Font resources:\n    Fonts.Font_Dictionary (pdf);\n    --  appended_object_idx := pdf.objects + 1;  --  Images contents to be appended after this object\n    --  Image resources:\n    WL (pdf, +\"  /XObject <<\");\n    --  Image_List (pdf);\n    WL (pdf, +\"  >>\");\n    WL (pdf, +\">>\");\n    WL (pdf, +\"endobj\");  --  end of Resources\n    --  PDF_Out.Images.Insert_unloaded_local_images (pdf);\n  end Finish_Page;\n\n  procedure Put_Real (pdf  : in out PDF_Out_File;\n                      num  : in Real\n            )\n  is\n  begin\n    Put_Str (pdf, Image (num));\n  end Put_Real;\n\n  procedure Put_Int (pdf   : in out PDF_Out_File;\n                     num   : in Integer\n            )\n  is\n  begin\n    Put_Str (pdf, Image (num));\n  end Put_Int;\n\n  procedure Put_Str (pdf : in out PDF_Out_File; str : VString) is\n  begin\n    if test_page_mode then\n      null;  --  Nothing to do (test page instead)\n    else\n      Insert_Text_PDF_Code (pdf, '(' & str & \") Tj\");\n    end if;\n  end Put_Str;\n\n  procedure Put_Line (pdf : in out PDF_Out_File; str : VString) is\n  begin\n    Put_Str (pdf, str);\n    New_Line (pdf);\n  end Put_Line;\n\n  procedure New_Line (pdf : in out PDF_Out_File) is\n    Spacing : constant := 1;\n  begin\n    pdf.current_line := pdf.current_line + 1;\n    pdf.current_col := 1;\n    if test_page_mode then\n      null;  --  Nothing to do (test page instead)\n    else\n      for i in 1 .. Spacing loop\n        Insert_Text_PDF_Code (pdf, +\"T*\");\n      end loop;\n    end if;\n  end New_Line;\n\n  procedure Text_XY (pdf : in out PDF_Out_File; x, y : Real) is\n  begin\n    Flip_to (pdf, text);\n    --  The following explicit End_text, Begin_text are just\n    --  for resetting the text matrices (hence, position and orientation).\n    End_text (pdf);\n    Begin_text (pdf);\n    Insert_PDF_Code (pdf, Img_R (x) & ' ' & Img_R (y) & \" Td\");  --  Td: 9.4.2 Text-Positioning Operators\n    pdf.current_line := 1;\n    pdf.current_col := 1;\n  end Text_XY;\n\n  procedure Put_XY (pdf : in out PDF_Out_File; x, y : Real; str : VString) is\n  begin\n    Text_XY (pdf, x, y);\n    Put_Str (pdf, str);\n  end Put_XY;\n\n  function Col (pdf : in PDF_Out_File) return Positive is\n  begin\n    return pdf.current_col;\n  end Col;\n\n  function Line (pdf : in PDF_Out_File) return Positive is\n  begin\n    return pdf.current_line;\n  end Line;\n\n  function Page (pdf : in PDF_Out_File) return Natural is\n  begin\n    return Natural (pdf.last_page);  --  Issue if Integer is 16-bit and last_page > 2**15-1\n  end Page;\n\n  procedure Color (pdf : in out PDF_Out_File; c : Color_Type) is\n  begin\n    Insert_PDF_Code (pdf, Img_R (c.red) & ' ' & Img_R (c.green) & ' ' & Img_R (c.blue) & \" rg\");\n    --  rg = nonstroking colour (Table 74)\n  end Color;\n\n  procedure Stroking_Color (pdf : in out PDF_Out_File; c : Color_Type) is\n  begin\n    Insert_PDF_Code (pdf, Img_R (c.red) & ' ' & Img_R (c.green) & ' ' & Img_R (c.blue) & \" RG\");\n    --  RG = nonstroking colour (Table 74)\n  end Stroking_Color;\n\n  procedure Text_Rendering_Mode (pdf : in out PDF_Out_File; r : Rendering_Mode) is\n  begin\n    Insert_Text_PDF_Code (pdf, Img_I (Integer (Rendering_Mode'Pos (r))) & \" Tr\");\n    --  Tr = Set rendering mode (Table 106)\n  end Text_Rendering_Mode;\n\n  function Image_name (i : Positive) return VString is\n  begin\n    return \"/Ada_PDF_Img\" & Img_I (i);\n  end Image_name;\n\n  --  procedure Image (pdf : in out PDF_Out_File; file_name : String; target : Rectangle) is\n  --    image_index : Positive;  --  Index in the list of images\n  --  begin\n  --    No_Nowhere (pdf);\n  --    PDF_Out.Images.Image_ref (pdf, file_name, image_index);\n  --    Insert_Graphics_PDF_Code (pdf, \"q \" &\n  --      Img (target.width) & \" 0 0 \" & Img (target.height) &\n  --      ' ' & Img (target.x_min) & ' ' & Img (target.y_min) & \" cm \" &  --  cm: Table 57\n  --      Image_name (image_index) & \" Do Q\"\n  --    );\n  --  end Image;\n  --\n  --  function Get_pixel_dimensions (image_file_name : String) return Rectangle is\n  --  begin\n  --    return PDF_Out.Images.Get_pixel_dimensions (image_file_name);\n  --  end Get_pixel_dimensions;\n\n  -----------------------\n  --  Vector graphics  --\n  -----------------------\n\n  procedure Line_Width (pdf : in out PDF_Out_File; width : Real) is\n  begin\n    Insert_Graphics_PDF_Code (pdf, Img_R (width) & \" w\");\n  end Line_Width;\n\n  procedure Single_Line (pdf : in out PDF_Out_File; from, to : Point) is\n  begin\n    Insert_Graphics_PDF_Code (pdf,\n      Img_R (from.x) & ' ' & Img_R (from.y) & \" m \" &\n      Img_R (to.x) & ' ' & Img_R (to.y) & \" l s\"\n    );\n  end Single_Line;\n\n  --    Table 59 - Path Construction Operators (8.5.2)\n  --    Table 60 - Path-Painting Operators (8.5.3.1)\n\n  function inside_path_rule_char (r : Inside_path_rule) return Character is\n  begin\n    case r is\n      when nonzero_winding_number => return ' ';\n      when even_odd               => return '*';\n    end case;\n  end inside_path_rule_char;\n\n  function path_drawing_operator (m : Path_Rendering_Mode) return Character is\n  begin\n    case m is\n      when fill             => return 'F';\n      when stroke           => return 'S';\n      when fill_then_stroke => return 'B';\n    end case;\n  end path_drawing_operator;\n\n  procedure Draw (pdf : in out PDF_Out_File; what : Rectangle; rendering : Path_Rendering_Mode) is\n  begin\n    Insert_Graphics_PDF_Code (pdf, Img_Rect (what, relative) & \" re \" & path_drawing_operator (rendering));\n  end Draw;\n\n  procedure Move (pdf : in out PDF_Out_File; to : Point) is\n  begin\n    Insert_Graphics_PDF_Code (pdf, Img_P (to) & \" m\");  --  m operator (Table 59)\n  end Move;\n\n  procedure Line_To (pdf : in out PDF_Out_File; to : Point) is\n  begin\n    Insert_Graphics_PDF_Code (pdf, Img_P (to) & \" l\");\n  end Line_To;\n\n  procedure Cubic_Bezier (pdf : in out PDF_Out_File; control_1, control_2 : Point; to : Point) is\n  begin\n    Insert_Graphics_PDF_Code (\n      pdf,\n      Img_P (control_1) & ' ' &\n      Img_P (control_2) & ' ' &\n      Img_P (to) & \" c\"\n    );\n  end Cubic_Bezier;\n\n  procedure Finish_Path (\n    pdf        : in out PDF_Out_File;\n    close_path :        Boolean;\n    rendering  :        Path_Rendering_Mode;  --  fill, stroke, or both\n    rule       :        Inside_path_rule\n  )\n  is\n    cmd : VString;\n  begin\n    cmd := +path_drawing_operator (rendering) & inside_path_rule_char (rule);\n    if close_path then\n      cmd := To_Lower (cmd);\n    end if;\n    --  Insert the s, S, f, f*, b, b*, B, B* of Table 60 - Path-Painting Operators (8.5.3.1)\n    if cmd = \"s*\" or cmd = \"S*\" or cmd = \"F \" or cmd = \"F*\" then\n      Insert_Graphics_PDF_Code (pdf, +\"n\");  --  End the path object without filling or stroking it.\n    else\n      Insert_Graphics_PDF_Code (pdf, cmd);\n    end if;\n  end Finish_Path;\n\n  -----------------------------\n  --  Direct code insertion  --\n  -----------------------------\n\n  procedure Insert_PDF_Code (pdf : in out PDF_Out_File; code : VString) is\n  begin\n    WLd (pdf, \"    \" & code);  --  Indentation is just cosmetic...\n  end Insert_PDF_Code;\n\n  procedure Insert_Text_PDF_Code (pdf : in out PDF_Out_File; code : VString) is\n  begin\n    Flip_to (pdf, text);\n    Insert_PDF_Code (pdf, code);\n  end Insert_Text_PDF_Code;\n\n  procedure Insert_Graphics_PDF_Code (pdf : in out PDF_Out_File; code : VString) is\n  begin\n    Flip_to (pdf, graphics);\n    Insert_PDF_Code (pdf, code);\n  end Insert_Graphics_PDF_Code;\n\n  --  Table 317 - Entries in the document information dictionary (14.3.3)\n\n  procedure Title (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    pdf.doc_title := s;\n  end Title;\n\n  procedure Author (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    pdf.doc_author := s;\n  end Author;\n\n  procedure Subject (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    pdf.doc_subject := s;\n  end Subject;\n\n  procedure Keywords (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    pdf.doc_keywords := s;\n  end Keywords;\n\n  procedure Creator_Application (pdf : in out PDF_Out_File; s : VString) is\n  begin\n    pdf.doc_creator := s;\n  end Creator_Application;\n\n  procedure Page_Header (pdf : in out PDF_Out_File) is\n  begin\n    null;  --  Default header is empty.\n  end Page_Header;\n\n  procedure Page_Footer (pdf : in out PDF_Out_File) is\n  begin\n    null;  --  Default footer is empty.\n  end Page_Footer;\n\n  procedure Set_Left_Margin (pdf : out PDF_Out_File; pts : Real) is\n  begin\n    pdf.page_margins.left := pts;\n  end Set_Left_Margin;\n\n  function Get_Left_Margin (pdf : PDF_Out_File) return Real is\n  begin\n    return pdf.page_margins.left;\n  end Get_Left_Margin;\n\n  procedure Set_Right_Margin (pdf : out PDF_Out_File; pts : Real) is\n  begin\n    pdf.page_margins.right := pts;\n  end Set_Right_Margin;\n\n  function Get_Right_Margin (pdf : PDF_Out_File) return Real is\n  begin\n    return pdf.page_margins.right;\n  end Get_Right_Margin;\n\n  procedure Set_Top_Margin (pdf : out PDF_Out_File; pts : Real) is\n  begin\n    pdf.page_margins.top := pts;\n  end Set_Top_Margin;\n\n  function Get_Top_Margin (pdf : PDF_Out_File) return Real is\n  begin\n    return pdf.page_margins.top;\n  end Get_Top_Margin;\n\n  procedure Set_Bottom_Margin (pdf : out PDF_Out_File; pts : Real) is\n  begin\n    pdf.page_margins.bottom := pts;\n  end Set_Bottom_Margin;\n\n  function Get_Bottom_Margin (pdf : PDF_Out_File) return Real is\n  begin\n    return pdf.page_margins.bottom;\n  end Get_Bottom_Margin;\n\n  procedure Set_Margins (pdf : out PDF_Out_File; new_margins : Margins_Type) is\n  begin\n    pdf.page_margins := new_margins;\n  end Set_Margins;\n\n  procedure Get_Margins (pdf : PDF_Out_File; result : out Margins_Type) is\n  begin\n    result := pdf.page_margins;\n  end Get_Margins;\n\n  procedure Page_Setup (pdf : in out PDF_Out_File; layout : Rectangle) is\n    mb_x_min, mb_y_min, mb_x_max, mb_y_max : Real;\n  begin\n    pdf.page_box := layout;\n    mb_x_min := Min (pdf.maximum_box.x_min, layout.x_min);\n    mb_y_min := Min (pdf.maximum_box.y_min, layout.y_min);\n    mb_x_max := Max (X_Max (pdf.maximum_box), X_Max (layout));\n    mb_y_max := Max (Y_Max (pdf.maximum_box), Y_Max (layout));\n    --\n    pdf.maximum_box.x_min  := mb_x_min;\n    pdf.maximum_box.y_min  := mb_y_min;\n    pdf.maximum_box.width  := mb_x_max - mb_x_min;\n    pdf.maximum_box.height := mb_y_max - mb_y_min;\n  end Page_Setup;\n\n  procedure Layout (pdf : PDF_Out_File; result : out Rectangle) is\n  begin\n    result := pdf.page_box;\n  end Layout;\n\n  procedure Reset (\n    pdf        : in out PDF_Out_File;\n    PDF_format :        PDF_type\n  )\n  is\n  begin\n    Init (pdf);\n    --  Check if we are trying to re-use a half-finished object (ouch!):\n    --  if pdf.is_created and not pdf.is_closed then\n    --    null;  --  !!  raise PDF_stream_not_closed;\n    --  end if;\n    pdf.format := PDF_format;\n    --  Set a default title (replaced when procedure Title is called).\n    --  In Adobe Reader, this content can be copied to the clipboard.\n    pdf.doc_title := +\"Document created with: \" & producer;\n  end Reset;\n\n  procedure Finish (pdf : in out PDF_Out_File) is\n\n    info_idx, cat_idx : PDF_Index_Type;\n\n    procedure Info is\n    begin\n      New_object (pdf);\n      info_idx := pdf.objects;\n      WL (pdf, +\"  << /Producer (\" & producer & ')');\n      WL (pdf, +\"     /Title (\" & To_String (pdf.doc_title) & ')');\n      WL (pdf, +\"     /Author (\" & To_String (pdf.doc_author) & ')');\n      WL (pdf, +\"     /Subject (\" & To_String (pdf.doc_subject) & ')');\n      WL (pdf, +\"     /Keywords (\" & To_String (pdf.doc_keywords) & ')');\n      WL (pdf, +\"     /Creator (\" & To_String (pdf.doc_creator) & ')');\n      WL (pdf, +\"  >>\");\n      WL (pdf, +\"endobj\");\n    end Info;\n\n    procedure Pages_dictionary is\n    begin\n      New_fixed_index_object (pdf, pages_idx);\n      WL (pdf, +\"  << /Type /Pages\");\n      W (pdf,  +\"     /Kids [\");\n      for p in 1 .. pdf.last_page loop\n        W (pdf, Img_I (pdf.page_idx (p)) & \" 0 R \");\n      end loop;\n      WL (pdf, +\"]\");\n      if pdf.last_page > 0 then\n        WL (pdf, \"     /Count \" & Img_I (pdf.last_page));\n      end if;\n      WL (pdf, \"     /MediaBox [\" & Img_Rect (pdf.maximum_box, absolute) & ']'\n      );\n      --  7.7.3.3 Page Objects - MediaBox\n      --  Boundaries of the physical medium on which the page shall be displayed or printed\n      --  7.7.3.4 Inheritance of Page Attributes\n      --  Global page size, lower-left to upper-right, measured in points\n      --  Bounding box of all pages\n      WL (pdf, +\"  >>\");\n      WL (pdf, +\"endobj\");\n    end Pages_dictionary;\n\n    procedure Catalog_dictionary is\n    begin\n      New_object (pdf);\n      cat_idx := pdf.objects;\n      WL (pdf, +\"  << /Type /Catalog\");\n      WL (pdf, +\"     /Pages \" & Img_I (pages_idx) & \" 0 R\");\n      if pdf.last_page > 0 then\n        --  Open the document on page 1, fit the\n        --  entire page within the window (Table 151):\n        WL (pdf, +\"     /OpenAction [\" & Img_I (pdf.page_idx (1)) & \" 0 R /Fit]\");\n      end if;\n      WL (pdf, +\"  >>\");\n      WL (pdf, +\"endobj\");\n    end Catalog_dictionary;\n\n    procedure Trailer is\n    begin\n      WL (pdf, +\"trailer\");\n      WL (pdf, +\"  << /Root \" & Img_I (cat_idx) & \" 0 R\");\n      WL (pdf, +\"     /Size \" & Img_I (pdf.objects + 1));\n      WL (pdf, +\"     /Info \" & Img_I (info_idx) & \" 0 R\");\n      WL (pdf, +\"  >>\");\n    end Trailer;\n\n    xref_offset : Natural;\n\n    procedure XRef is\n      s10 : VString;\n    begin\n      xref_offset := Buffer_index (pdf);\n      WL (pdf, +\"xref\");\n      WL (pdf, +\"0 \" & Img_I (pdf.objects + 1));\n      WL (pdf, +\"0000000000 65535 f \");\n      for i in 1 .. pdf.objects loop\n        s10 := Image (pdf.object_offset (i));\n        while Length (s10) < 10 loop\n          s10 := '0' & s10;\n        end loop;\n        WL (pdf, s10 & \" 00000 n \");  --   <-- the trailing space is needed!\n      end loop;\n    end XRef;\n\n  begin\n    if pdf.last_page = 0 then\n      --  No page ? Then make quickly a blank page.\n      New_Page (pdf);\n    end if;\n    Finish_Page (pdf);\n    Info;\n    Pages_dictionary;\n    Catalog_dictionary;\n    XRef;\n    Trailer;\n    WL (pdf, +\"startxref\"); -- offset of xref\n    WL (pdf, Img_I (Integer (xref_offset)));\n    WL (pdf, +\"%%EOF\");\n    --  PDF_Out.Images.Clear_image_directory (pdf);\n    pdf.is_closed := True;\n  end Finish;\n\n  ----------------------\n  -- Output to a file --\n  ----------------------\n\n  procedure Create (\n    pdf        : in out PDF_Out_File;\n    file_name  :        VString\n  )\n  is\n  begin\n    Reset (pdf, PDF_1_3);\n    HAT.Create (pdf.pdf_file, file_name);\n    pdf.file_name := file_name;\n    Write_PDF_header (pdf);\n  end Create;\n\n  procedure Close (pdf : in out PDF_Out_File) is\n  begin\n    Finish (pdf);\n    if pdf.file_name /= \"nul\" then  --  Test needed for OA 7.2.2 (Close raises Use_Error)\n      HAT.Close (pdf.pdf_file);\n    end if;\n  end Close;\n\n  function Is_Open (pdf : in PDF_Out_File) return Boolean is\n  begin\n    return HAT.Is_Open (pdf.pdf_file);\n  end Is_Open;\n\n  function one_cm   return Real is begin return 28.346456692913385826771653543307; end one_cm; -- = 72.0 / 2.54;\n  function cm_2_5   return Real is begin return 70.866141732283464566929133858268; end cm_2_5; -- = one_cm * 2.5;\n  function one_inch return Real is begin return 72.0; end one_inch;\n\n  --  !! HAC Bug: presence of subpackage body is not checked !\n\n  package body Fonts is\n\n    --  9.6.2.2  Standard Type 1 Fonts (Standard 14 Fonts)\n    function Standard_Font_Name (f : Standard_Font_Type) return VString is\n    begin  --  Code generation: see pw_work.xls, Fonts (Std)\n      case f is\n        when Courier                 => return +\"Courier\";\n        when Courier_Bold            => return +\"Courier-Bold\";\n        when Courier_Bold_Oblique    => return +\"Courier-BoldOblique\";\n        when Courier_Oblique         => return +\"Courier-Oblique\";\n        when Helvetica               => return +\"Helvetica\";\n        when Helvetica_Bold          => return +\"Helvetica-Bold\";\n        when Helvetica_Bold_Oblique  => return +\"Helvetica-BoldOblique\";\n        when Helvetica_Oblique       => return +\"Helvetica-Oblique\";\n        when Symbol                  => return +\"Symbol\";\n        when Times_Bold              => return +\"Times-Bold\";\n        when Times_Bold_Italic       => return +\"Times-BoldItalic\";\n        when Times_Italic            => return +\"Times-Italic\";\n        when Times_Roman             => return +\"Times-Roman\";\n        when Zapf_Dingbats           => return +\"ZapfDingbats\";\n      end case;\n    end Standard_Font_Name;\n\n    function Font_Dictionary_Name (font_name : VString) return VString is\n    begin\n      return \"/Ada_PDF_Font_\" & font_name;\n    end Font_Dictionary_Name;\n\n    function Standard_Font_Dictionary_Name (f : Standard_Font_Type) return VString is\n    begin\n      return \"/Ada_PDF_Std_Font_\" & Standard_Font_Name (f);\n    end Standard_Font_Dictionary_Name;\n\n    --  7.8.3 Resource Dictionaries (any resources required by a page).\n    --  Table 33: Font: A dictionary that maps resource names to font dictionaries.\n    --\n    procedure Font_Dictionary (pdf : in out PDF_Out_File) is\n    begin\n      WL (pdf, +\"  /Font <<\");  --  font dictionary\n      for f in Standard_Font_Type loop\n        WL (pdf,\n          +\"    \" & Standard_Font_Dictionary_Name (f) &\n          \" << /Type /Font /Subtype /Type1 /BaseFont /\" & Standard_Font_Name (f) &\n          --  7.9.2.2 Text String Type: \"PDFDocEncoding can encode all of\n          --  the ISO Latin 1 character set and is documented in Annex D.\"\n          --  PDFDocEncoding is recognized by the Chrome PDF viewer on Windows but...\n          --  *isn't* by Adobe Reader X, on Windows! So we resort to another ISO\n          --  Latin 1 superset: WinAnsiEncoding = Windows Code Page 1252 (Table D.1).\n          \" /Encoding /WinAnsiEncoding \" &\n          \" >>\"\n        );\n      end loop;\n      WL (pdf, +\"    >>\");\n    end Font_Dictionary;\n\n    function Current_Font_Dictionary_Name (pdf : PDF_Out_File) return VString is\n    begin\n      if pdf.current_font in Standard_Font_Type then\n        return Standard_Font_Dictionary_Name (pdf.current_font);\n      else\n        return Font_Dictionary_Name (pdf.ext_font_name);\n      end if;\n    end Current_Font_Dictionary_Name;\n\n  end Fonts;\n\nend HAC_PDF_Out;\n"
  },
  {
    "path": "exm/pdf/hac_pdf_out.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC_PDF_OUT - A low level package for writing Adobe Acrobat PDF (*) files.\n--\n--  HAC_PDF_OUT is a stripped-down version of PDF_OUT ( http://apdf.sf.net/ )\n--  for successful compilation with HAC (HAC Ada Compiler) v.0.1.\n--\n--  Elements of PDF_OUT removed in HAC_PDF_OUT are:\n--\n--    - Object-oriented type extension (tagged type for PDF stream).\n--        PDF Files are the only supported PDF streams.\n--    - Object.method notation\n--    - Default values in records, replaced by explicit initialization.\n--    - Inclusion of raster images.\n--    - User-defined exceptions (PDF_stream_not_created, ...).\n--    - User-defined operators (\"+\", ...).\n--    - Indefinite page table and offset table.\n--\n-------------------------------------------------------------------------------------\n\n--  Legal licensing note:\n\n--  Copyright (c) 2014 .. 2022 Gautier de Montmollin\n\n--  Permission is hereby granted, free of charge, to any person obtaining a copy\n--  of this software and associated documentation files (the \"Software\"), to deal\n--  in the Software without restriction, including without limitation the rights\n--  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n--  copies of the Software, and to permit persons to whom the Software is\n--  furnished to do so, subject to the following conditions:\n\n--  The above copyright notice and this permission notice shall be included in\n--  all copies or substantial portions of the Software.\n\n--  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n--  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n--  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n--  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n--  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n--  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n--  THE SOFTWARE.\n\n--  NB: this is the MIT License, as found 12-Sep-2007 on the site\n--  http://www.opensource.org/licenses/mit-license.php\n\n--  (*) All Trademarks mentioned are properties of their respective owners.\n-------------------------------------------------------------------------------------\n--\n--  Follow these steps to create a PDF document stream:\n--\n--  1. Create\n--\n--  2. | Put(pdf, data),\n--     | New_Line(pdf), ... : other \"Text_IO\"-like (full list below)\n--     | Image(pdf, ...)    : raster images [disabled for the HAC version]\n--     | Move/Line/...      : vector graphics\n--     | New_Page(pdf)\n--\n--  3. Close\n--\n--  4. (PDF_Out_String only) function Contents returns the full .pdf\n--\n--  Header and footer are set up by overriding the corresponding methods.\n--\n--  Note: the standard PDF measurement unit is a \"point\", set as 1/72 inch.\n--\n--  All technical references are to PDF 1.7 format, ISO 32000-1:2008 standard\n--  http://www.adobe.com/devnet/pdf/pdf_reference.html\n--\n--------------------------------------------------------------------------\n\nwith HAT;\n\npackage HAC_PDF_Out is\n\n  type PDF_type is (\n    PDF_1_3 -- PDF 1.3\n  );\n\n  subtype Real is HAT.Real;\n\n  type Point is record\n    x, y : Real;\n  end record;\n\n  --  procedure Add (P1, P2 : Point; result : out Point);\n  --\n  --  procedure Scale_Point (f : Real; P : Point; result : out Point);\n\n  type Rectangle is record\n    x_min, y_min,\n    width, height : Real;\n  end record;\n\n  --  procedure Translate (P : Point; r : Rectangle; result : out Rectangle);\n  --\n  --  --  Scaling. r.x_min and r.y_min are preserved.\n  --  procedure Scale_Rectangle (f : Real; r : Rectangle; result : out Rectangle);\n\n  function X_Max (r : Rectangle) return Real;\n  function Y_Max (r : Rectangle) return Real;\n\n  subtype PDF_Index_Type is Integer;\n\n  subtype Offset_Index_Type is PDF_Index_Type range 1 .. 1000;\n\n  type Offset_table is array (Offset_Index_Type) of Natural;\n\n  subtype Page_Index_Type is PDF_Index_Type range 1 .. 1000;\n\n  type Page_table is array (Page_Index_Type) of PDF_Index_Type; -- object ID's of pages\n\n  type Page_zone is (nowhere, in_page, in_header, in_footer);\n  type Text_or_graphics is (text, graphics);\n\n  type Margins_Type is record\n    left, right, top, bottom : Real;\n  end record;\n\n  type Font_Type is\n     ( --  The 14 standard fonts\n      Courier,\n      Courier_Bold,\n      Courier_Bold_Oblique,\n      Courier_Oblique,\n      Helvetica,\n      Helvetica_Bold,\n      Helvetica_Bold_Oblique,\n      Helvetica_Oblique,\n      Symbol,\n      Times_Bold,\n      Times_Bold_Italic,\n      Times_Italic,\n      Times_Roman,\n      Zapf_Dingbats,\n      --  Fonts imported into the PDF document\n      External_Font\n     );\n\n  subtype Standard_Font_Type is Font_Type range Courier .. Zapf_Dingbats;\n\n  --  !! Should be private (in a future version of HAC)\n\n  type PDF_Out_File is record\n    pdf_file       : HAT.File_Type;\n    file_index     : Natural;\n    file_name      : HAT.VString;\n    start_index    : Natural;\n    is_created     : Boolean;\n    is_closed      : Boolean;\n    format         : PDF_type;\n    zone           : Page_zone;\n    text_switch    : Text_or_graphics;\n    last_page      : PDF_Index_Type;\n    current_line   : Positive;\n    current_col    : Positive;\n    page_idx       : Page_table;\n    page_box       : Rectangle;\n    maximum_box    : Rectangle;\n    page_margins   : Margins_Type;\n    objects        : PDF_Index_Type;\n    object_offset  : Offset_table;\n    stream_obj_buf : HAT.VString;\n    current_font   : Font_Type;\n    font_size      : Real;\n    line_spacing   : Real;\n    ext_font_name  : HAT.VString;\n    doc_title      : HAT.VString;  --  Document information (14.3.3)\n    doc_author     : HAT.VString;  --  Document information (14.3.3)\n    doc_subject    : HAT.VString;  --  Document information (14.3.3)\n    doc_keywords   : HAT.VString;  --  Document information (14.3.3)\n    doc_creator    : HAT.VString;  --  Document information (14.3.3) : creator application\n  end record;\n\n  procedure Init (pdf : in out PDF_Out_File);\n\n  ----------------------------\n  -- (2) Document contents: --\n  ----------------------------\n\n  procedure Put_Real (pdf  : in out PDF_Out_File;\n                      num  : in Real\n            );\n  procedure Put_Int (pdf   : in out PDF_Out_File;\n                     num   : in Integer\n            );\n  procedure Put_Str (pdf : in out PDF_Out_File; str : HAT.VString);\n  --\n  procedure Put_Line (pdf : in out PDF_Out_File; str : HAT.VString);\n  --\n  procedure New_Line (pdf : in out PDF_Out_File);\n  procedure New_Page (pdf : in out PDF_Out_File);\n  --  Call to Finish_Page is optional, but can be necessary in some circumstances,\n  --  for instance for displaying the footer correctly before changing page\n  --  orientation or margins for the following pages.\n  procedure Finish_Page (pdf : in out PDF_Out_File);\n  --\n  procedure Text_XY (pdf : in out PDF_Out_File; x, y : Real);\n  procedure Put_XY (pdf : in out PDF_Out_File; x, y : Real; str : HAT.VString);\n\n  function Col (pdf : in PDF_Out_File) return Positive;\n  function Line (pdf : in PDF_Out_File) return Positive;\n  function Page (pdf : in PDF_Out_File) return Natural;\n\n  --  Select one of the Adobe PDF standard fonts.\n  --  The encoding is on 8 bits and follows the \"Windows Code Page 1252\"\n  --  encoding (called WinAnsiEncoding in the PDF standard).\n  --  See Annex D, especially \"Table D.1 - Latin-text encodings\" for details.\n  procedure Font (pdf : in out PDF_Out_File; f : Standard_Font_Type);\n\n  --  Set the font size.\n  --  In general the size is a scale factor (see Table 105, Tf operator).\n  --  For standard fonts the unit seems to be the Point (pt).\n  procedure Font_Size (pdf : in out PDF_Out_File; size : Real);\n\n  procedure Line_Spacing (pdf : in out PDF_Out_File; factor : Real);  --  as multiple of font size\n  procedure Line_Spacing_Pt (pdf : in out PDF_Out_File; pt : Real);   --  in Point (pt) units\n\n  --------------\n  --  Colors  --\n  --------------\n\n  --  0.0 = minimum intensity\n  --  1.0 = maximum intensity.\n  subtype Color_Value is Real;  --  range 0.0 .. 1.0;\n\n  type Color_Type is record\n    red, green, blue : Color_Value;\n  end record;\n\n  procedure Color (pdf : in out PDF_Out_File; c : Color_Type);\n  procedure Stroking_Color (pdf : in out PDF_Out_File; c : Color_Type);\n\n  type Rendering_Mode is (\n    fill, stroke, fill_then_stroke, invisible,\n    --  Same, but also add text to path for clipping.\n    fill_and_add_to_path,\n    stroke_and_add_to_path,\n    fill_then_stroke_and_add_to_path,\n    add_to_path\n  );\n\n  procedure Text_Rendering_Mode (pdf : in out PDF_Out_File; r : Rendering_Mode);\n\n  -----------------------\n  --  Vector graphics  --\n  -----------------------\n\n  procedure Line_Width (pdf : in out PDF_Out_File; width : Real);\n\n  --  Draw a single line segment:\n  procedure Single_Line (pdf : in out PDF_Out_File; from, to : Point);\n\n  subtype Path_Rendering_Mode is Rendering_Mode range fill .. fill_then_stroke;\n\n  --  Draw simple figures.\n  --  Rectangle:\n  procedure Draw (pdf : in out PDF_Out_File; what : Rectangle; rendering : Path_Rendering_Mode);\n\n  --  Paths:\n\n  type Inside_path_rule is (nonzero_winding_number, even_odd);\n  --  Rule to determine how to fill areas within a (non-trivial) path.\n  --  See 8.5.3.3.2 and 8.5.3.3.3 of PDF specification\n\n  procedure Move    (pdf : in out PDF_Out_File; to : Point);\n  procedure Line_To (pdf : in out PDF_Out_File; to : Point);\n  procedure Cubic_Bezier (pdf : in out PDF_Out_File; control_1, control_2 : Point; to : Point);\n  --  All lines and curves and the eventual filling inside the path\n  --  will be drawn when path is completed, with Finish_Path:\n\n  procedure Finish_Path (\n    pdf        : in out PDF_Out_File;\n    close_path :        Boolean;\n    rendering  :        Path_Rendering_Mode;  --  fill, stroke, or both\n    rule       :        Inside_path_rule\n  );\n\n  ------------\n  --  Misc  --\n  ------------\n\n  --  In the likely case some PDF feature is not yet implemented in\n  --  this package, you can insert direct PDF code - at your own risk ;-).\n  --\n  --  NB: the state the PDF machine is either in text-writing\n  --  mode, or graphics mode. To make outputs compliant with the PDF\n  --  standard, if you want to insert graphics code, please\n  --  use the Insert_Graphics_PDF_Code below. For text-related stuff,\n  --  use Insert_Text_PDF_Code.\n  --\n  procedure Insert_PDF_Code (pdf : in out PDF_Out_File; code : HAT.VString);\n\n  --  This is for direct text PDF code insertion (text-writing mode\n  --  will be switched on). In PDF language these are the T... commands.\n  --\n  procedure Insert_Text_PDF_Code (pdf : in out PDF_Out_File; code : HAT.VString);\n\n  --  This is for direct graphics PDF code insertion (text-writing mode\n  --  will be switched off for the graphics output).\n  --\n  procedure Insert_Graphics_PDF_Code (pdf : in out PDF_Out_File; code : HAT.VString);\n\n  --  Document information\n  procedure Title (pdf : in out PDF_Out_File; s : HAT.VString);\n  procedure Author (pdf : in out PDF_Out_File; s : HAT.VString);\n  procedure Subject (pdf : in out PDF_Out_File; s : HAT.VString);\n  procedure Keywords (pdf : in out PDF_Out_File; s : HAT.VString);\n  procedure Creator_Application (pdf : in out PDF_Out_File; s : HAT.VString);\n\n  ------------------\n  --  Page layout --\n  ------------------\n\n  --  You need to override the Header and Footer methods\n  --  for setting up your custom header and footer. By default they do nothing.\n  procedure Page_Header (pdf : in out PDF_Out_File);\n  procedure Page_Footer (pdf : in out PDF_Out_File);\n\n  --  They have to be called before New_Page in order to influence the next page.\n  --  For the first page, call them before any output (typically right after Create).\n  --\n  procedure Set_Left_Margin (pdf : out PDF_Out_File; pts : Real);\n  function Get_Left_Margin (pdf : PDF_Out_File) return Real;\n  procedure Set_Right_Margin (pdf : out PDF_Out_File; pts : Real);\n  function Get_Right_Margin (pdf : PDF_Out_File) return Real;\n  procedure Set_Top_Margin (pdf : out PDF_Out_File; pts : Real);\n  function Get_Top_Margin (pdf : PDF_Out_File) return Real;\n  procedure Set_Bottom_Margin (pdf : out PDF_Out_File; pts : Real);\n  function Get_Bottom_Margin (pdf : PDF_Out_File) return Real;\n\n  --  Some distances in Points\n\n  function one_cm   return Real;\n  function cm_2_5   return Real;\n  function one_inch return Real;\n\n  procedure Set_Margins (pdf : out PDF_Out_File; new_margins : Margins_Type);\n  procedure Get_Margins (pdf : PDF_Out_File; result : out Margins_Type);\n\n  procedure Set_A4_Portrait (r : out Rectangle);\n  procedure Set_A4_Landscape (r : out Rectangle);\n\n  procedure Page_Setup (pdf : in out PDF_Out_File; layout : Rectangle);\n\n  procedure Layout (pdf : PDF_Out_File; result : out Rectangle);\n\n  procedure Create (\n    pdf        : in out PDF_Out_File;\n    file_name  :        HAT.VString\n  );\n\n  procedure Close (pdf : in out PDF_Out_File);\n\n  function Is_Open (pdf : in PDF_Out_File) return Boolean;\n\nprivate\n\n  function Image_name (i : Positive) return HAT.VString;\n  procedure New_object (pdf : in out PDF_Out_File);\n  procedure WL (pdf : in out PDF_Out_File; s : HAT.VString);\n\nend HAC_PDF_Out;\n"
  },
  {
    "path": "exm/pdf/hilbert_curve.adb",
    "content": "--  https://rosettacode.org/wiki/Hilbert_curve#Ada\n--  Author: Jesper Quorning\n--\n--  This version is adapted to HAC's Ada subset.\n\nwith HAT;\nwith HAC_PDF_Out;\n\nprocedure Hilbert_Curve is\n\n   use HAT, HAC_PDF_Out;\n\n   Page_Length : constant := 500.0;\n   Corner_X    : constant := 50.0;\n   Corner_Y    : constant := 300.0;\n\n   type Rule_Type is (A, B, C, D);\n\n   PDF   : HAC_PDF_Out.PDF_Out_File;\n   First : Boolean;\n\n   procedure Hilbert (Order  : in Natural;\n                      Rule   : in Rule_Type;\n                      Length : in HAC_PDF_Out.Real;\n                      X, Y   : in HAC_PDF_Out.Real)\n   is\n      L : constant HAC_PDF_Out.Real := Length / 4.0;\n      P : Point;\n   begin\n      if Order = 0 then\n         P.x := Corner_X + X;\n         P.y := Corner_Y + Y;\n         if First then\n            First := False;\n            Move (PDF, P);\n         else\n            Line_To (PDF, P);\n         end if;\n      else\n         case Rule is\n            when A =>\n               Hilbert (Order - 1, D, 2.0 * L, X - L, Y + L);\n               Hilbert (Order - 1, A, 2.0 * L, X - L, Y - L);\n               Hilbert (Order - 1, A, 2.0 * L, X + L, Y - L);\n               Hilbert (Order - 1, B, 2.0 * L, X + L, Y + L);\n            when B =>\n               Hilbert (Order - 1, C, 2.0 * L, X + L, Y - L);\n               Hilbert (Order - 1, B, 2.0 * L, X - L, Y - L);\n               Hilbert (Order - 1, B, 2.0 * L, X - L, Y + L);\n               Hilbert (Order - 1, A, 2.0 * L, X + L, Y + L);\n            when C =>\n               Hilbert (Order - 1, B, 2.0 * L, X + L, Y - L);\n               Hilbert (Order - 1, C, 2.0 * L, X + L, Y + L);\n               Hilbert (Order - 1, C, 2.0 * L, X - L, Y + L);\n               Hilbert (Order - 1, D, 2.0 * L, X - L, Y - L);\n            when D =>\n               Hilbert (Order - 1, A, 2.0 * L, X - L, Y + L);\n               Hilbert (Order - 1, D, 2.0 * L, X + L, Y + L);\n               Hilbert (Order - 1, D, 2.0 * L, X + L, Y - L);\n               Hilbert (Order - 1, C, 2.0 * L, X - L, Y - L);\n         end case;\n      end if;\n   end Hilbert;\n\n   procedure Hilbert_Page (Order : Natural; Color : Color_Type) is\n   begin\n      First := True;\n      Stroking_Color (PDF, Color);\n      Hilbert (Order, A, Page_Length, Page_Length / 2.0, Page_Length / 2.0);\n      Finish_Path (PDF, False,\n                        stroke,\n                        nonzero_winding_number);\n   end Hilbert_Page;\n\n   a4p, back : Rectangle;\n   black, violet, green : Color_Type;\n\nbegin\n   HAC_PDF_Out.Create (PDF, +\"hilbert-curve.pdf\");\n   Set_A4_Portrait (a4p);\n   Page_Setup (PDF, a4p);\n   black.red   := 0.0;\n   black.green := 0.0;\n   black.blue  := 0.0;\n   violet.red   := 0.9;\n   violet.green := 0.1;\n   violet.blue  := 0.8;\n   green.red   := 0.0;\n   green.green := 0.9;\n   green.blue  := 0.0;\n\n   for depth in reverse 1 .. 7 loop\n      Color (PDF, black);\n      back.x_min  := Corner_X;\n      back.y_min  := Corner_Y;\n      back.width  := Page_Length;\n      back.height := Page_Length;\n      Draw (PDF, back, fill);\n\n      if depth = 7 then\n         Line_Width (PDF, 1.0);\n      else\n         Line_Width (PDF, 2.0);\n      end if;\n      Hilbert_Page (depth,     violet);\n      Hilbert_Page (depth - 1, green);\n\n      if depth > 1 then\n         New_Page (PDF);\n      end if;\n   end loop;\n\n   HAC_PDF_Out.Close (PDF);\nend Hilbert_Curve;\n"
  },
  {
    "path": "exm/pdf/koch_curve.adb",
    "content": "--  http://www.rosettacode.org/wiki/Koch_curve#Ada\n--  Author: Jesper Quorning\n--\n--  This version is adapted to HAC's Ada subset.\n\nwith HAC_PDF_Out;\nwith HAT;\n\nprocedure Koch_Curve is\n\n   use HAC_PDF_Out, HAT;\n\n   subtype My_Real is HAC_PDF_Out.Real;\n   subtype Angle_Deg  is My_Real;\n   subtype Level_Type is Integer range 0 .. 7;\n\n   Vertex_Length : constant := 400.0;\n   Purple : Color_Type;\n   Corner : Point;\n\n   procedure Draw_Image (Level : Level_Type) is\n\n      Current   : Point;\n      Direction : Angle_Deg  := 60.0;\n      Doc       : PDF_Out_File;\n\n      My_Layout  : Rectangle;\n      My_Margins : Margins_Type;\n\n      Deg_To_Rad : constant := 0.01745329251994329576923690768489;  --  Pi / 180\n\n      procedure Koch (Level : Level_Type; Vertex_Length : My_Real) is\n         Move, Abs_Point : Point;\n      begin\n         if Level = 0 then\n            Move.x := Vertex_Length * Sin (Direction * Deg_To_Rad);\n            Move.y := Vertex_Length * Cos (Direction * Deg_To_Rad);\n            Current.x := Current.x + Move.x;\n            Current.y := Current.y + Move.y;\n            Abs_Point.x := Corner.x + Current.x;\n            Abs_Point.y := Corner.y + Current.y;\n            Line_To (Doc, Abs_Point);\n         else\n            Koch (Level - 1, Vertex_Length / 3.0);  Direction := Direction -  60.0;\n            Koch (Level - 1, Vertex_Length / 3.0);  Direction := Direction + 120.0;\n            Koch (Level - 1, Vertex_Length / 3.0);  Direction := Direction -  60.0;\n            Koch (Level - 1, Vertex_Length / 3.0);\n         end if;\n      end Koch;\n\n   begin\n      Current.x := 0.0;\n      Current.y := 0.0;\n      --\n      Create (Doc, +\"koch_\" & Character'Val (Character'Pos ('0') + Level) & \".pdf\");\n      Creator_Application (Doc, +\"Koch_Curve\");\n      Title (Doc, +\"Koch snowflake curve drawn with HAC_PDF_Out\");\n      Author (Doc, +\"Niels Fabian Helge von Koch\");\n      Subject (Doc, +\"Koch snowflake curve with recursion level\" & Level_Type'Image (Level));\n      Keywords (Doc, +\"Koch, snowflake, curve, fractal\");\n      Set_A4_portrait (My_Layout);\n      Page_Setup (Doc, My_Layout);\n      My_Margins.left   := cm_2_5;\n      My_Margins.right  := one_cm;\n      My_Margins.top    := one_cm;\n      My_Margins.bottom := one_cm;\n      Set_Margins (Doc, My_Margins);\n      Color (Doc, Purple);\n      Move (Doc, Corner);\n      for Count in 1 .. 3 loop\n         Koch (Level, Vertex_Length);\n         Direction := Direction + 120.0;\n      end loop;\n      Finish_Path (Doc, True, fill, even_odd);\n      Close (Doc);\n   end Draw_Image;\n\nbegin\n   Purple.red   := 0.35;\n   Purple.green := 0.0;\n   Purple.blue  := 0.25;\n   --\n   Corner.x := 90.0;\n   Corner.y := 580.0;\n   --\n   for Level in Level_Type loop\n      Draw_Image (Level);\n   end loop;\nend Koch_Curve;\n"
  },
  {
    "path": "exm/pdf/pdf_hello.adb",
    "content": "with HAC_PDF_Out;\nwith HAT;\n\nprocedure PDF_Hello is\n  use HAC_PDF_Out, HAT;\n\n  pdf : PDF_Out_File;\n\n  c1, c2, black : Color_Type;\n\nbegin\n  Create (pdf, +\"hello.pdf\");\n  Creator_Application (pdf, +\"PDF_Hello\");\n  Keywords (pdf, +\"Hello, World, HAC, PDF\");\n  Put_Line (pdf, +\"Hello world !\");\n  New_Line (pdf);\n  Put_Line (pdf, +\"This PDF document was created by...\");\n  Font (pdf, Helvetica);\n  Text_Rendering_Mode (pdf, fill_then_stroke);\n  --  The following can be done in a more compact way with\n  --  a \"full Ada\" compiler: pdf.Stroking_Color ((0.0, 0.3, 0.1));\n  c1.red   := 0.0;\n  c1.green := 0.3;\n  c1.blue  := 0.1;\n  Stroking_Color (pdf, c1);\n  c2.red   := 0.1;\n  c2.green := 0.5;\n  c2.blue  := 0.2;\n  Color (pdf, c2);\n  Font_Size (pdf, 36.0);\n  New_Line (pdf);\n  Put_Line (pdf, +\"HAC\");\n  Font_Size (pdf, 18.0);\n  Put_Line (pdf, +\"HAC Ada Compiler\");\n  Close (pdf);\nend PDF_Hello;\n"
  },
  {
    "path": "exm/pdf/peano_curve.adb",
    "content": "--  https://rosettacode.org/wiki/Peano_curve#Ada\n--  Author: Jesper Quorning\n--\n--  This version is adapted to HAC's Ada subset.\n\nwith HAT;\nwith HAC_PDF_Out;\n\nprocedure Peano_Curve is\n\n   use HAT, HAC_PDF_Out;\n\n   Filename   : constant String (1 .. 15) := \"peano-curve.pdf\";\n   Scale      : constant := 2.1;\n   Line_W     : constant := 2.5;\n   Corner_X   : constant := 150.0;\n   Corner_Y   : constant := 50.0;\n   Background : Color_Type;\n   Frame      : Rectangle;\n   PDF        : PDF_Out_File;\n\n   type Coord is record\n      X, Y : Natural;\n   end record;\n\n   procedure Transform (left, right : Coord; scale_right : Natural; result : out Coord) is\n   begin\n      result.X := left.X + scale_right * right.X;\n      result.Y := left.Y + scale_right * right.Y;\n   end Transform;\n\n   procedure Peano (Pos : Coord; Length : Positive; I1, I2 : Integer) is\n      len : constant Integer := Length / 3;\n      pt, new_pos : Coord;\n      pdf_pt : Point;\n   begin\n      if Length = 1 then\n         pdf_pt.x := Corner_X + Scale * (HAC_PDF_Out.Real (3 * Pos.X));\n         pdf_pt.y := Corner_Y + Scale * (HAC_PDF_Out.Real (3 * Pos.Y));\n         Line_To (PDF, pdf_pt);\n      else\n         pt.X := 2 * I1;      pt.Y := 2 * I1;      Transform (Pos, pt, len, new_pos); Peano (new_pos, len, I1,     I2);\n         pt.X := I1 - I2 + 1; pt.Y := I1 + I2;     Transform (Pos, pt, len, new_pos); Peano (new_pos, len, I1,     1 - I2);\n         pt.X := 1;           pt.Y := 1;           Transform (Pos, pt, len, new_pos); Peano (new_pos, len, I1,     1 - I2);\n         pt.X := I1 + I2;     pt.Y := I1 - I2 + 1; Transform (Pos, pt, len, new_pos); Peano (new_pos, len, 1 - I1, 1 - I2);\n         pt.X := 2 * I2;      pt.Y := 2 - 2 * I2;  Transform (Pos, pt, len, new_pos); Peano (new_pos, len, I1,     I2);\n         pt.X := 1 + I2 - I1; pt.Y := 2 - I1 - I2; Transform (Pos, pt, len, new_pos); Peano (new_pos, len, I1,     I2);\n         pt.X := 2 - 2 * I1;  pt.Y := 2 - 2 * I1;  Transform (Pos, pt, len, new_pos); Peano (new_pos, len, I1,     I2);\n         pt.X := 2 - I1 - I2; pt.Y := 1 + I2 - I1; Transform (Pos, pt, len, new_pos); Peano (new_pos, len, 1 - I1, I2);\n         pt.X := 2 - 2 * I2;  pt.Y := 2 * I2;      Transform (Pos, pt, len, new_pos); Peano (new_pos, len, 1 - I1, I2);\n      end if;\n   end Peano;\n\n   procedure Draw_Peano (order : Natural) is\n      black : Color_Type;\n      pt : Coord;\n      pdf_pt : Point;\n   begin\n      black.red   := 0.0;\n      black.green := 0.0;\n      black.blue  := 0.0;\n      Stroking_Color (PDF, black);\n      Line_Width (PDF, Line_W);\n      pdf_pt.x := Corner_X;\n      pdf_pt.y := Corner_Y;\n      Move (PDF, pdf_pt);\n      pt.X := 0;\n      pt.Y := 0;\n      Peano (pt, 3**order, 0, 0);\n      Finish_Path (PDF, False,\n                        stroke,\n                        nonzero_winding_number);\n   end Draw_Peano;\n\n   a4p : Rectangle;\n\nbegin\n   Background.red   := 0.827;\n   Background.green := 0.816;\n   Background.blue  := 0.016;\n\n   Frame.x_min  := 10.0;\n   Frame.y_min  := 10.0;\n   Frame.width  := 820.0;\n   Frame.height := 575.0;\n\n   HAC_PDF_Out.Create (PDF, +Filename);\n   Set_A4_Landscape (a4p);\n   Page_Setup (PDF, a4p);\n\n   for order in reverse 1 .. 4 loop\n      Color (PDF, Background);\n      Draw (PDF, Frame, fill);\n\n      Draw_Peano (order);\n      if order > 1 then\n         New_Page (PDF);\n      end if;\n   end loop;\n\n   HAC_PDF_Out.Close (PDF);\nend Peano_Curve;\n"
  },
  {
    "path": "exm/permutations.adb",
    "content": "--  Show all permutations of a certain range.\n\nwith HAT;\n\nprocedure Permutations is\n\n  subtype Some_Range is Integer range 1 .. 4;\n\n  x : array (Some_Range) of Some_Range;\n\n  procedure Fill (from : Some_Range) is\n    ok : Boolean;\n    use HAT;\n  begin\n    for value in Some_Range loop\n      ok := True;\n      for i in 1 .. from - 1 loop\n        ok := ok and then not (x (i) = value);\n      end loop;\n      if ok then\n        x (from) := value; \n        if from = Some_Range'Last then\n          for i in Some_Range loop\n            Put (Image (x (i)));\n          end loop;\n          New_Line;\n        else\n          Fill (from + 1);\n        end if;\n      end if;\n    end loop;\n  end;\n\nbegin\n  Fill (1);\nend Permutations;\n"
  },
  {
    "path": "exm/pkg_1.adb",
    "content": "package body Pkg_1 is\r\n\r\n  -------------------------------------------------\r\n  --  Sub-packages defined only in Pkg_1's body  --\r\n  -------------------------------------------------\r\n\r\n  package Sub_Pkg_3 is\r\n  end Sub_Pkg_3;\r\n\r\n  package Sub_Pkg_4 is\r\n    function F return Integer;\r\n    --\r\n    package Spec_which_doesnt_need_any_body is\r\n      subtype Ha is Integer;\r\n    end Spec_which_doesnt_need_any_body;\r\n    --\r\n    --  package Spec_which_needs_a_body_1 is\r\n    --    procedure Ho_1;\r\n    --  end Spec_which_needs_a_body_1;\r\n    --\r\n    --  !! HAC bug: doesn't check for missing body !!\r\n  end Sub_Pkg_4;\r\n\r\n  type Some_Useless_Type is record\r\n    useless_1 : Integer;\r\n    useless_2 : VS;       --  Defined in the spec\r\n    useless_3 : PA;       --  Defined in the spec, private part\r\n  end record;\r\n\r\n  package body Sub_Pkg_4 is\r\n\r\n    package Spec_which_needs_a_body_2 is\r\n      procedure Ho2;\r\n    end Spec_which_needs_a_body_2;\r\n\r\n    package body Spec_which_needs_a_body_2 is\r\n      procedure Ho2 is begin HAT.Put (\"[Ho2] \"); end Ho2;\r\n    end Spec_which_needs_a_body_2;\r\n\r\n    --  !! HAC bug: doesn't check for missing body !!\r\n\r\n    function F return Integer is\r\n      variable_local_to_F : Some_Useless_Type;\r\n    begin\r\n      Spec_which_needs_a_body_2.Ho2;\r\n      variable_local_to_F.useless_3 := PA'Last;\r\n      return 656 + variable_local_to_F.useless_3;  --  Should be 666.\r\n    end F;\r\n\r\n  end Sub_Pkg_4;\r\n\r\n  -------------------\r\n  --  Other stuff  --\r\n  -------------------\r\n\r\n  procedure Proc_in_body;\r\n\r\n  procedure Proc_in_body is\r\n  begin\r\n    null;\r\n  end Proc_in_body;\r\n\r\n  procedure Proc_1 (par_1 : Integer; par_2 : out HAT.Real) is\r\n    x, y : PB;\r\n\r\n    package Inner_pkg is\r\n      use HAT;\r\n      procedure Ho_ho_ho;\r\n      public_message : constant VString := +\"This is public\";\r\n    private\r\n      private_message : constant VString := +\"Ho ho \";\r\n    end Inner_pkg;\r\n\r\n    some_garbage_1 : Integer;\r\n\r\n    package body Inner_pkg is\r\n      use HAT;\r\n      body_message : constant VString := +\"ho!\";\r\n      procedure Ho_ho_ho is\r\n      begin\r\n        x.field_2 := private_message & body_message;\r\n      end Ho_ho_ho;\r\n    end Inner_pkg;\r\n\r\n    some_garbage_2 : Integer;\r\n\r\n    use Inner_pkg;\r\n    use HAT;\r\n\r\n  begin\r\n    Inner_pkg.Ho_ho_ho;\r\n    Ho_ho_ho;\r\n    y := x;\r\n    Put_Line (y.field_2);\r\n    --  Put_Line (Inner_pkg.body_message);        --  Compilation should fail if uncommented.\r\n    --  Put_Line (Inner_pkg.private_message);     --  Compilation should fail if uncommented.\r\n    Put_Line (public_message);\r\n    par_2 := Real (Sub_Pkg_4.F) + 0.123456;\r\n  end Proc_1;\r\n\r\n  -------------------------------------------------\r\n  --  Sub-packages defined only in Pkg_1's spec  --\r\n  -------------------------------------------------\r\n\r\n  package body Sub_Pkg_2 is\r\n\r\n    procedure Proc_2 (message : VString) is\r\n      use HAT;  --  !!  Should not be necessary (clause already in spec)\r\n    begin\r\n      Put_Line (\"Hello from Sub_Pkg_2.Proc_2: \" & message);\r\n    end Proc_2;\r\n\r\n  end Sub_Pkg_2;\r\n\r\nend Pkg_1;\r\n"
  },
  {
    "path": "exm/pkg_1.ads",
    "content": "with HAT;\r\n\r\npackage Pkg_1 is\r\n\r\n  subtype A is Integer;\r\n\r\n  subtype B0 is A;\r\n  subtype B is Pkg_1.A;\r\n\r\n  subtype C is B range 0 .. 1000;\r\n\r\n  package Sub_Pkg_1 is\r\n\r\n    subtype D is C range 1 .. 100;\r\n\r\n  end Sub_Pkg_1;\r\n\r\n  subtype E is Sub_Pkg_1.D range 2 .. 10;\r\n\r\n  procedure Proc_1 (par_1 : Integer; par_2 : out HAT.Real);\r\n\r\n  package Sub_Pkg_2 is\r\n\r\n    use HAT;\r\n\r\n    procedure Proc_2 (message : VString);\r\n\r\n  end Sub_Pkg_2;\r\n\r\n  subtype VS is HAT.VString;\r\n\r\nprivate\r\n\r\n  subtype PA is E;\r\n\r\n  type PB is record\r\n    field_1 : PA;\r\n    field_2 : HAT.VString;\r\n  end record;\r\n\r\nend Pkg_1;\r\n"
  },
  {
    "path": "exm/pkg_2.ads",
    "content": "with Pkg_1;\r\n\r\npackage Pkg_2 is\r\n\r\n  subtype F is Pkg_1.E;\r\n\r\n  use Pkg_1.Sub_Pkg_1;\r\n\r\n  subtype G is D range 22 .. 99;\r\n\r\nend Pkg_2;\r\n"
  },
  {
    "path": "exm/pkg_demo.adb",
    "content": "--  Demo of many library-level packages.\r\n--  Minimum HAC version: HAC 0.0999 10-Apr-2022.\r\n--\r\n--  HAC and GNAT figure out all the source files\r\n--  that are needed for the build.\r\n--\r\n--  The X* packages are generated by Pkg_Demo_Gen (file pkg_demo_gen.adb).\r\n--\r\n--      X_Pkg_Test_S depends on X_Pkg_Test_S1, X_Pkg_Test_S2, ...\r\n--      X_Pkg_Test_S1 depends on X_Pkg_Test_S11, X_Pkg_Test_S12, ...\r\n--      ...\r\n\r\nwith HAT;\r\n\r\nwith X_Pkg_Demo_S,  --  Dependencies always declared in specs\r\n     X_Pkg_Demo_M,  --  Dependencies declared in specs or bodies (randomly)\r\n     X_Pkg_Demo_B;  --  Dependencies always declared in bodies\r\n\r\nprocedure Pkg_Demo is\r\n\r\n  use HAT;\r\n\r\n  procedure Failure (Msg : VString) is\r\n  begin\r\n    Put_Line (+\"Failure in test: [\" & Msg & ']');\r\n    Set_Exit_Status (1);  --  Compiler test failed.\r\n  end Failure;\r\n\r\n  procedure Assert (Msg : VString; Check : in Boolean) is\r\n    --  Similar to RM 11.4.2 but without raising an exception.\r\n  begin\r\n    if not Check then Failure (Msg & \", assertion\"); end if;\r\n  end Assert;\r\n\r\nbegin\r\n  if Argument_Count = 0 then\r\n    Put_Line (+\"Specs:  \" & X_Pkg_Demo_S.Do_it); \r\n    Put_Line (+\"Mixed:  \" & X_Pkg_Demo_M.Do_it); \r\n    Put_Line (+\"Bodies: \" & X_Pkg_Demo_B.Do_it); \r\n  else\r\n    Assert (+\"Specs\",  X_Pkg_Demo_S.Do_it = \"[S][S1][S11][S12][S13][S2][S21][S22][S23][S3][S31][S32][S33]\"); \r\n    Assert (+\"Mixed\",  X_Pkg_Demo_M.Do_it = \"[M][M1][M11][M12][M13][M2][M21][M22][M23][M3][M31][M32][M33]\"); \r\n    Assert (+\"Bodies\", X_Pkg_Demo_B.Do_it = \"[B][B1][B11][B12][B13][B2][B21][B22][B23][B3][B31][B32][B33]\"); \r\n  end if;\r\nend Pkg_Demo;\r\n"
  },
  {
    "path": "exm/pkg_demo_gen.adb",
    "content": "--  Testing library-level packages.\r\n--  Pkg_Demo_Gen creates the packages for Pkg_Demo.\r\n--\r\n--  The command `hac pkg_demo_gen.adb delete` will\r\n--  delete those packages.\r\n\r\nwith HAT;\r\n\r\nprocedure Pkg_Demo_Gen is\r\n\r\n  --  This type controls the location of WITH's in\r\n  --  packages further in the dependency tree.\r\n  --\r\n  type Test_Mode is (all_in_spec, mixed, all_in_bodies);\r\n\r\n  use HAT;\r\n\r\n  max_depth : constant := 2;\r\n  children  : constant := 3;\r\n\r\n  procedure Generate (prefix : VString; depth : Natural; mode : Test_Mode) is\r\n    f : File_Type;\r\n    name : constant VString := \"X_Pkg_Demo_\" & prefix;\r\n    file_name : constant VString := To_Lower (name);\r\n    subtype Child_Range is Integer range 1 .. children;\r\n    with_in_spec : array (Child_Range) of Boolean;\r\n  begin\r\n    if Argument_Count > 0 and then Argument (1) = \"delete\" then\r\n      Delete_File (file_name & \".adb\");\r\n      Delete_File (file_name & \".ads\");\r\n    else\r\n      for child in Child_Range loop\r\n        case mode is\r\n          when all_in_spec   => with_in_spec (child) := True;\r\n          when mixed         => with_in_spec (child) := Rnd > 0.5;\r\n          when all_in_bodies => with_in_spec (child) := False;\r\n        end case;\r\n      end loop;\r\n      --\r\n      for is_body in Boolean loop\r\n        if is_body then\r\n          Create (f, file_name & \".adb\");\r\n        else\r\n          Create (f, file_name & \".ads\");\r\n        end if;\r\n        Put_Line (f, \"--  File generated by Pkg_Demo_Gen. This is needed for Pkg_Demo.\");\r\n        Put_Line (f, \"--\");\r\n        if depth < max_depth then\r\n          New_Line (f);\r\n          for child in Child_Range loop\r\n            if is_body xor with_in_spec (child) then\r\n              Put_Line (f, \"with \" & name & Image (child) & ';');\r\n            end if;\r\n          end loop;\r\n        end if;\r\n        if not is_body then\r\n          New_Line (f);\r\n          Put_Line (f, \"with HAT; use HAT;\");\r\n        end if;\r\n        New_Line (f);\r\n        Put (f, \"package \");\r\n        if is_body then\r\n          Put (f, \"body \");\r\n        end if;\r\n        Put_Line (f, name & \" is\");\r\n        New_Line (f);\r\n        Put (f, \"  function Do_it return VString\");\r\n        if is_body then\r\n          Put_Line (f, \"  is\");\r\n          Put_Line (f, \"  begin\");\r\n          Put_Line (f, \"    return +\"\"[\" & prefix & \"]\"\"\");\r\n          if depth < max_depth then\r\n            --  Now the funny part...\r\n            for child in Child_Range loop\r\n              Put_Line (f, \"   & \" & name & Image (child) & \".Do_it\");\r\n            end loop;\r\n          end if;\r\n          Put_Line (f, \"    ;\");\r\n          Put_Line (f, \"  end Do_it;\");\r\n        else\r\n          Put_Line (f, ';');\r\n        end if;\r\n        New_Line (f);\r\n        Put_Line (f, \"end \" & name & ';');\r\n        Close (f);\r\n        --\r\n      end loop;\r\n    end if;\r\n    if depth < max_depth then\r\n      --  Now the funny part...\r\n      for child in Child_Range loop\r\n        Generate (prefix & Image (child), depth + 1, mode);\r\n      end loop;\r\n    end if;\r\n  end Generate;\r\n\r\n  abbr : array (Test_Mode) of Character;\r\n\r\nbegin\r\n  abbr (all_in_spec)   := 'S';\r\n  abbr (mixed)         := 'M';\r\n  abbr (all_in_bodies) := 'B';\r\n\r\n  for mode in Test_Mode loop\r\n    Generate (+abbr (mode), 0, mode);\r\n  end loop;\r\nend Pkg_Demo_Gen;\r\n"
  },
  {
    "path": "exm/prc.adb",
    "content": "--  Demo of modularity with packages.\r\n\r\nwith HAT;\r\nwith Pkg_1, Pkg_2;\r\nwith Cross_A, Cross_B;\r\n\r\nprocedure Prc is\r\n\r\n  x : Pkg_1.A;\r\n\r\n  use Pkg_1;\r\n\r\n  y : B;\r\n  z : Pkg_1.E;\r\n\r\n  t : constant Pkg_2.G := Pkg_2.G'Last;\r\n\r\n  r : HAT.Real;\r\n\r\n  use HAT;\r\n\r\n  package Local_Namespace is\r\n    procedure Hi;\r\n    --\r\n    package Loc_SubPkg_1 is\r\n      abc : Integer;\r\n    end Loc_SubPkg_1;\r\n    --\r\n    package Loc_SubPkg_1b is\r\n      abc : Integer;\r\n    end Loc_SubPkg_1b;\r\n    --\r\n    package Loc_SubPkg_2 is\r\n      procedure Jedi_2;\r\n    end Loc_SubPkg_2;\r\n    --\r\n  end Local_Namespace;\r\n\r\n  package body Local_Namespace is\r\n    --\r\n    procedure Hi is\r\n    begin\r\n      Put_Line (\"Hi!\");\r\n    end Hi;\r\n    --\r\n    package body Loc_SubPkg_1 is\r\n      --  Superfluous, but admitted as local package.\r\n      --  For library level it would be rejected: Ada RM 7.2 (4))\r\n    end Loc_SubPkg_1;\r\n    --\r\n    --  Loc_SubPkg_3 (spec & body) is fully\r\n    --  contained in Loc_SubPkg_1's body!\r\n    --\r\n    package Loc_SubPkg_3 is\r\n      procedure Jedi_3;\r\n    end Loc_SubPkg_3;\r\n    --\r\n    package body Loc_SubPkg_3 is\r\n      --  !! HAC bug: doesn't check for missing body !!\r\n      procedure Jedi_3 is\r\n      begin\r\n        Put (\"[Jedi 3] \");\r\n      end Jedi_3;\r\n    end Loc_SubPkg_3;\r\n    --\r\n    package body Loc_SubPkg_2 is\r\n      procedure Jedi_2 is\r\n      begin\r\n        Loc_SubPkg_3.Jedi_3;\r\n        Put (\"[Jedi 2] \");\r\n      end Jedi_2;\r\n    end Loc_SubPkg_2;\r\n    --\r\n  end Local_Namespace;\r\n\r\n  procedure Hi_Hi is\r\n    use Local_Namespace;\r\n  begin\r\n    Loc_SubPkg_2.Jedi_2;\r\n    Hi;\r\n  end Hi_Hi;\r\n\r\n  procedure Hi_Hi_2 is\r\n    use Local_Namespace;\r\n    use Loc_SubPkg_2;\r\n  begin\r\n    Jedi_2;\r\n    Hi;\r\n  end Hi_Hi_2;\r\n\r\nbegin\r\n  x := 0;\r\n  y := 0;\r\n  z := 2;\r\n  Put (t, 0);\r\n  New_Line;\r\n  Proc_1 (x, r);\r\n  Put (r, 0, 7, 0);\r\n  New_Line;\r\n  Sub_Pkg_2.Proc_2 (+\"Hey man\");\r\n  Cross_A.A (5);\r\n  Cross_B.B (5);\r\n  --\r\n  Local_Namespace.Loc_SubPkg_2.Jedi_2;\r\n  Local_Namespace.Hi;\r\n  Hi_Hi;\r\n  Hi_Hi_2;\r\nend Prc;\r\n"
  },
  {
    "path": "exm/random.adb",
    "content": "--  Pseudo-Random Generation: Rand (discrete) and Rnd (continuous)\n\nwith HAT;\n\nprocedure Random is\n\n  use HAT;\n\n  procedure Discrete (iterations : Integer) is\n    faces : constant := 6;\n    histogram : array (1 .. faces) of Integer;\n    r, t : Integer;\n  begin\n    for f in 1 .. faces loop\n      histogram (f) := 0;\n    end loop;\n    for it in 1 .. iterations loop\n      r := 1 + Rand (5);\n      histogram (r) := histogram (r) + 1;\n    end loop;\n    --  Any error should be detected by range checks.\n    t := 0;\n    for f in 1 .. faces loop\n      t := t + histogram (f);\n    end loop;\n    if t /= iterations then\n      Put_Line (+\"*** ERROR: total = \" & t);\n      Skip_Line;\n    end if;\n    for f in 1 .. faces loop\n      Put (+\"  Dice face \" & f & ':');\n      Put (Real (histogram (f)) / Real (iterations), 2, 5, 0);\n      Put_Line (+\", #occurences: \" & histogram (f));\n    end loop;\n  end Discrete;\n\n  procedure Continuous (iterations : Integer) is\n    in_disc : Integer := 0;\n  begin\n    for it in 1 .. iterations loop\n      if Rnd ** 2 + Rnd ** 2 <= 1.0 then\n        in_disc := in_disc + 1;\n      end if;\n    end loop;\n    Put (\"  Monte-Carlo estimation of pi: \");\n    Put_Line (4.0 * Real (in_disc) / Real (iterations));\n  end Continuous;\n\n  it : Integer;\n\nbegin\n  for dec in 3 .. 7 loop\n    Put_Line (+\"======= Iterations: 10 ** \" & dec);\n    it := 10 ** dec;\n    Discrete (it);\n    Continuous (it);\n  end loop;\nend Random;\n"
  },
  {
    "path": "exm/record_code_gen.adb",
    "content": "--  Code generation example for Ada records\n\nwith HAT;\n\nprocedure Record_Code_Gen is\n  use HAT;\n  type Typ is (ints, floats);\n  type Field is (a, b);\n  --\n  function Typ_Of (f : Field) return Typ is\n  begin\n    case f is\n      when a => return ints;\n      when b => return floats;\n    end case;\n  end Typ_Of;\n  --\n  f_ada : File_Type;\n  t : Typ;\nbegin\n  --  Write a simple Ada record:\n  Create (f_ada, \"$_simple_ada_record_snippet.ads\");\n  Put_Line (f_ada, \"  type T1 is record\");\n  for f in Field loop\n    t := Typ_Of (f);\n    Put_Line\n      (f_ada,\n       To_Lower (+\"    \" & f'Image & \" : \" & t'Image & ';'));\n  end loop;\n  Put_Line (f_ada, \"  end record;\");\n  Close (f_ada);\n  --\n  --  Here, other forms: C header, records in records vs.\n  --  flat representation, record of arrays, conversion functions\n  --  for the records, ...\nend Record_Code_Gen;\n"
  },
  {
    "path": "exm/remarks.adb",
    "content": "--  Remarks (warnings and notes) emitted by the HAC compiler.\n--\n--  Command sample:\n--\n--  for HAC:         hac -c     -rkruv remarks.adb\n--  for GNAT:        gcc -c -gnatwkruv remarks.adb\n\nwith Interfaces;\n\nprocedure Remarks is\n\n  use Interfaces;\n  use Interfaces;       --  Note:    \"use\" clause already applied (...) [-rr]\n  a  : Integer;         --  Note:    variable \"a\" is not referenced [-ru]\n  type B is (x, y);     --  Note:    type \"B\" is not referenced [-ru]\n  procedure C is null;  --  Note:    procedure \"C\" is not referenced [-ru]\n  d : Integer := 123;   --  Note:    variable \"d\" is not referenced [-ru]\n                        --  Note:    variable \"d\" is not modified, could be declared constant [-rk]\n  e : Integer;          --  Note:    variable \"e\" is never read [-ru]\n  f : Integer := 123;   --  Note:    variable \"f\" is never read [-ru]\n  g : Integer := 123;   --  Note:    variable \"g\" is not modified, could be declared constant [-rk]\n  h : Integer;          --  Warning: variable \"h\" is read but never written [-rv]\n  type A0 is (x0, y0);  --  Note:    item \"y0\" is not referenced [-ru]\n  b0 : A0 := x0;        --  Note:    variable \"b0\" is not referenced [-ru]\n                        --  Note:    variable \"b0\" is not modified, could be declared constant [-rk]\n\n  procedure Missing_Read_Writes   --  Note:    procedure \"Missing_Read_Writes\" is not referenced [-ru]\n    (a1 : in     Integer;         --  Note:    parameter \"a1\" is not referenced [-ru]\n     b1 : in out Integer;         --  Note:    parameter \"b1\" is not referenced [-ru]\n     c1 :    out Integer;         --  Warning: parameter \"c1\" is never written [-rv]\n                                  --  Note:    parameter \"c1\" is not referenced [-ru]\n     d1 :    out Integer;         --  Warning: parameter \"d1\" is read but never written [-rv]\n     e1 :    out Integer)         --  `e1` is written -> compiler is happy.\n  is\n  begin\n    if d1 = 5 then null; end if;  --  Warning: parameter \"d1\" is read but not written at this point [-rv]\n    if e1 = 5 then null; end if;  --  Warning: parameter \"e1\" is read but not written at this point [-rv]\n    e1 := 2;\n  end Missing_Read_Writes;\n\n  procedure OK_Read_Writes   --  Note: procedure \"OK_Read_Writes\" is not referenced [-ru]\n    (a2 : in     Integer;\n     b2 : in out Integer;    --  Note: parameter \"b2\" is not referenced [-ru]\n     c2 :    out Integer)\n  is\n  begin\n    c2 := a2;  --  `c2` is written, `a2` is read, so the compiler is happy about `a2` and `c2`.\n  end OK_Read_Writes;\n\n  function Useless return Integer is  --  Note: function \"Useless\" is not referenced [-ru]\n  begin\n    return 5;\n  end Useless;\n\n  --  Example appeared @\n  --     https://www.reddit.com/r/ada/comments/1ezm9d6/the_variable_may_not_be_initialized/\n\n  type Array_Of_Naturals is array (1 .. 5) of Natural;\n\n  function Max_Array (A : Array_Of_Naturals) return Natural is\n    Max : Natural;\n  begin\n    for I in A'Range loop\n      if A (I) > Max then  --  Warning: variable \"Max\" is read before it is ever written [-rv]\n        Max := A (I);\n      end if;\n    end loop;\n    return Max;\n  end Max_Array;\n\n  function Max_Array_2 (A : Array_Of_Naturals) return Natural is\n    Max_2 : Natural;\n    Further_Iteration : Boolean := False;\n  begin\n    for I in A'Range loop\n      if Further_Iteration then\n        if A (I) > Max_2 then  --  Warning: variable \"Max_2\" may be read before it is ever written [-rv]\n          --\n          --  ^ The warning is softer than for Max: when there is a condition\n          --    within a loop, we are not sure this is the first iteration.\n          --    Then, we cannot be sure that Max_2 is not initialized.\n          --    In this example, Max_2 is actually initialized on the first iteration.\n          Max_2 := A (I);\n        end if;\n      else\n        Max_2 := 0;\n        Further_Iteration := True;\n      end if;\n    end loop;\n    return Max_2;\n  end Max_Array_2;\n\n  procedure Tom (Condition : Boolean; J : out Integer) is\n     I : Integer;\n  begin\n     if Condition then\n        J := I;  --  Warning: variable \"I\" is read but not written at this point [-rv]\n     end if;\n  end Tom;\n\n  procedure Cases is\n    type ABC is (a, b, c);\n    x : constant ABC := a;\n  begin\n    case x is\n      when a => null;\n      when b => null;\n      when c => null;\n      when others => null;  --  Note: \"when others\" is redundant here: all values are already explicitly covered [-rr]\n    end case;\n  end;\n\nbegin\n  e := 0;\n  f := g + h;  --  Warning: variable \"h\" is read but not written at this point [-rv]\n  Cases;\nend Remarks;\n"
  },
  {
    "path": "exm/series.adb",
    "content": "with HAT;\n\nprocedure Series is\n  use HAT;\n  max_x : constant := 30;\n  sum : Real := 0.0;\n  x : constant Real := 0.8;\nbegin\n  Put_Line (+\"x = \" & x);\n  Put_Line (+\"sum:  1 + x + x^2 + ... + x^n:\");\n  for n in 0 .. max_x loop\n    sum := sum + x ** n;\n    Put_Line (+\"n = \" & n & \"; sum = \" & sum);\n  end loop;\n  Put_Line (+\"n -> infinity; sum = \" & 1.0 / (1.0 - x));\nend Series;\n"
  },
  {
    "path": "exm/shell.adb",
    "content": "with HAT; use HAT;\n\nprocedure Shell is\n  type OS_Kind is (Nixux, Windoze);\n  k : OS_Kind;\n  r : Integer;\n  f : File_Type;\n  --\n  procedure Pipe_Test (with_result, with_output : Boolean) is\n    line, contents : VString;\n    out_name : constant VString := +\"output.lst\";\n    secret_command : constant VString :=\n      +\"echo This is the ultra-secret message for testing I/O pipe\";\n    piped_secret_command : constant VString := secret_command & '>' & out_name;\n  begin\n    Put (\"Testing outward pipe (command>something). With result parameter: \");\n    Put (with_result);\n    Put (\". With output parameter: \");\n    Put (with_output);\n    Put_Line (\".\");\n    if with_output then\n      if with_result then\n        Shell_Execute (secret_command, r, contents);\n      else\n        Shell_Execute (secret_command, contents);\n      end if;\n      Put_Line (+\"  --> Contents output VString are: [\" & contents & ']');\n    else\n      if with_result then\n        Shell_Execute (piped_secret_command, r);\n      else\n        Shell_Execute (piped_secret_command);\n      end if;\n      Put (+\"  --> Contents of file \" & out_name & \" are: [\");\n      Open (f, out_name);\n      while not End_Of_File (f) loop\n        Get_Line (f, line);\n        Put_Line (line);\n      end loop;\n      Close (f);\n      Put_Line (']');\n    end if;\n    if with_result and r /= 0 then\n      Put_Line (+\"Result of echo command is not 0: \" & r);\n    end if;\n    New_Line;\n  end Pipe_Test;\n  --\n  procedure Produce_Errors (command : VString) is\n  begin\n    Shell_Execute (command, r);\n    Put_Line (\n      +\"Result of command \"\"\" & command &\n      \"\"\" should be not 0. Returned value is: \" & r\n    );\n    if k = Nixux then\n      --  WEXITSTATUS\n      Put_Line (+\"  POSIX: filtered exit code is: \" & r / 256 mod 256);\n    end if;\n    New_Line;\n  end Produce_Errors;\nbegin\n  if Index (Get_Env (\"OS\"), \"Windows\") > 0 then\n    k := Windoze;\n  else\n    k := Nixux;\n  end if;\n  --\n  Set_Env (\"HAC_Rules\", \"Good Day, Ladies and Gentlemen!\");\n  --\n  case k is\n    when Nixux   => Shell_Execute (\"echo The env. var. is set... [$HAC_Rules]\", r);\n    when Windoze => Shell_Execute (\"echo The env. var. is set... [%HAC_Rules%]\", r);\n  end case;\n  if r /= 0 then\n    Put_Line (+\"Result of echo command is not 0: \" & r);\n  end if;\n  --\n  for w_res in Boolean loop\n    for w_out in Boolean loop\n      Pipe_Test (w_res, w_out);\n    end loop;\n  end loop;\n  Produce_Errors (+\"Command_Impossible\");\n  Produce_Errors (+\"exit 123\");\nend Shell;\n"
  },
  {
    "path": "exm/shell_sort.adb",
    "content": "with HAT;  --  SmallAda: CS159-10 - FAll/1990 - Arthur Vargas Lopes\r\n\r\nprocedure Shell_Sort is\r\n\r\n  use HAT;\r\n\r\n  procedure Shell is\r\n    b : String (1 .. 26);\r\n    i, j, step : Integer;\r\n    step_size : array (1 .. 4) of Integer;\r\n    stop : Boolean;\r\n    temp : Character;\r\n  begin\r\n    b := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\r\n    Put_Line (\"Shell Sort\");\r\n    New_Line;\r\n    Put_Line (\"String at start:\");\r\n    Put_Line (\"----------------\");\r\n    Put_Line (b);\r\n    New_Line;\r\n    --  Put_Line(B);\r\n    --  'steps' contains decreasing increments for each\r\n    --  pass. The last pass has increment 1.\r\n    step_size (4) := 1;\r\n    for pass in reverse 1 .. 3 loop\r\n      step_size (pass) := 2 * step_size (pass + 1);\r\n    end loop;\r\n    for pass in 1 .. 4 loop\r\n      --  cursorat(14,45);\r\n      Put (\"Pass: \"); Put (pass);\r\n      New_Line;\r\n      step := step_size (pass);\r\n      Put (\"Step: \"); Put (step);\r\n      New_Line;\r\n        --  Do a straight insertion sort with 'step' as\r\n        --  an increment instead of 1.\r\n      i := step + 1;\r\n      while i <= 26 loop\r\n        --  cursorat(15,45);\r\n        New_Line;\r\n        Put (\"I:    \"); Put (i); New_Line;\r\n        temp := b (i);\r\n        j := i;\r\n        stop := False;\r\n        while j > step and not stop loop\r\n          j := j - step;\r\n          --  cursorat(16,45); put(\"J:    \"); put(J);\r\n          if b (j) > temp then\r\n            b (j + step) := b (j);\r\n            --  cursorat(15,14+j);\r\n            Put (temp);\r\n          else\r\n            b (j + step) := temp;\r\n            stop := True;\r\n          end if;\r\n          --  CursorAt(15,14+(j+step)); Put(b(j+step));\r\n        end loop;\r\n        if not stop then\r\n          b (1) := temp;\r\n          --  CursorAt(15,14+0);\r\n          Put (temp);\r\n        end if;\r\n        i := i + step;\r\n      end loop;\r\n      New_Line;\r\n    end loop; -- for pass in 1..npass\r\n    New_Line;\r\n    Put_Line (\"Result of Shell Sort:\");\r\n    Put_Line (\"---------------------\");\r\n    Put_Line (b);\r\n  end Shell;\r\n\r\nbegin\r\n  Shell;\r\n  --  New_Line;\r\n  --  PUT(\"Press enter to proceed...\");\r\n  --  GET(ch);\r\nend Shell_Sort;\r\n"
  },
  {
    "path": "exm/strings_demo.adb",
    "content": "with HAT; use HAT;\n\nprocedure Strings_demo is\n  s1, s2, s4, s4_s4 : VString;\n  --\n  n : constant := 10;\n  type Str_Vector is array (1 .. n) of VString;\n  type Bi_Vector is record\n    A, B : Str_Vector;\n  end record;\n  --\n  procedure A_to_B (BV : in out Bi_Vector) is\n  begin\n    BV.B := BV.A;\n  end A_to_B;\n  --\n  procedure Reverso (SV : in out Str_Vector) is\n    SV2 : Str_Vector;\n  begin\n    for i in 1 .. n loop\n      SV2 (n - i + 1) := SV (i);\n    end loop;\n    SV := SV2;\n  end Reverso;\n  --\n  procedure Show (SV : in Str_Vector) is\n  begin\n    for i in 1 .. n loop\n      Put_Line (SV (i));\n    end loop;\n  end Show;\n  --\n  procedure Slice_Show (v : VString) is\n    l : constant Integer := Length (v);\n    c : Character;\n    row : VString;\n  begin\n    for i in reverse 1 .. l loop\n      Put_Line (Slice (v, 1, i));\n    end loop;\n    --\n    for i in 1 .. l loop\n      Put ((i - 1) * ' ');\n      Put_Line (Slice (v, i, l));\n    end loop;\n    --\n    for i in 1 .. l loop\n      row := +\"\";\n      for j in 1 .. l loop\n        if i = j then\n          c := Element (v, i);\n        elsif abs (i - j) = 1 then\n          c := ' ';\n        else\n          c := '_';\n        end if;\n        row := row & c;\n      end loop;\n      Put_Line (row);\n    end loop;\n  end Slice_Show;\n  --\n  procedure Up_Low (v : VString) is\n    row : VString;\n    c : Character;\n  begin\n    Put_Line (v);\n    New_Line;\n    Put_Line (To_Upper (v));\n    Put_Line (To_Lower (v));\n    New_Line;\n    for i in 1 .. Length (v) loop\n      row := +\"\";\n      for j in 1 .. Length (v) loop\n        c := Element (v, j);\n        if i = j then\n          row := row & To_Upper (c);\n        else\n          row := row & To_Lower (c);\n        end if;\n      end loop;\n      Put_Line (row);\n    end loop;\n  end Up_Low;\n\n  s3 : constant VString := +\" world\";\n  ZZ : Bi_Vector;\n  padded : VString;\n  Str3 : constant String (6 .. 8) := \"But\";\n  v_char : VString;\nbegin\n  s2 := +\"Hello\";             --  Convert from literal string, copy to s2.\n  v_char := +'.';             --  Convert from Character\n  s1 := s2;                   --  Copy VString to VString\n  s4 := s1 & s3;              --  Concatenation VString & VString\n  Put_Line (5 * (s1 & ' '));  --  Multiplication, and Concatenation with Character\n  for i in 1 .. 4 loop Put (v_char & s1); end loop; New_Line;\n  padded := +\"   \" & '\"' & s1 & \"\"\"    \";\n  New_Line;\n  Put_Line (\"->\" & padded & \"<- original\");\n  Put_Line (\"->\" & Trim_Left (padded)  & \"<-  Trim_Left\");\n  Put_Line (\"->\" & Trim_Right (padded) & \"<-  Trim_Right\");\n  Put_Line (\"->\" & Trim_Both (padded)  & \"<-  Trim_Both\");\n  s4 := \"---> \"\"\" & s4 & '\"';\n  Put_Line (s4);\n  Put_Line (\">> \" & s4 & ' ' & '!' & \" <<\");\n  s4 := +\"abc\" & 'd' & \"ef\";\n  --\n  for i in 1 .. n loop\n    ZZ.A (i) := +\"\";\n    for j in 1 .. n loop\n      if j = i then\n        ZZ.A (i) := ZZ.A (i) & '*';\n      else\n        ZZ.A (i) := ZZ.A (i) & '.';\n      end if;\n    end loop;\n  end loop;\n  --\n  A_to_B (ZZ);\n  --\n  Show (ZZ.B);\n  Reverso (ZZ.B);\n  Show (ZZ.B);\n  --\n  Slice_Show (+\"What's happening to this string?!\");\n  Up_Low (+\"Upside Down\");\n  --\n  Put_Line (+\"  [\" & (-123) & \"]  [\" & 123 & \"]  [\" & Real (Pi) & ']');\n  Put_Line (123 & (+\" & Right VString\"));\n  Put_Line (Real (-456.0) & (+\" & Right VString\"));\n  Put_Line (Real (-456.0e9) & (+\" & Right VString\"));\n  Put_Line (Real (456.0e11) & (+\" & Right VString\"));\n  Put_Line (Real (456.0e66) & (+\" & Right VString\"));\n  Put_Line (Real (456.789e13) & (+\" & Right VString\"));\n  Put_Line (Real (4.56789e13) & (+\" & Right VString\"));\n  Put_Line (Real (4.56789e14) & (+\" & Right VString\"));\n  Put_Line (Real (4.56789e15) & (+\" & Right VString\"));\n  Put_Line (Real (1.79769313486232E+307) & (+\" & Right VString\"));\n  Put_Line (\"Integer: Image...        \" & Image (456789));\n  Put_Line (\"Real: Image...           \" & Image (Real (456789.0)));\n  Put_Line (\"Real: Image...           \" & Image (Real (4.56789e10)));\n  Put_Line (\"Real: Image attribute...\"  & Real'Image (4.56789e10));\n  Put_Line (Float_Value   (+\"456.789e13\"));  --  Ada.Text_IO display of the Real number\n  Put_Line (Integer_Value (+\"456\"));         --  Ada.Text_IO display of the Integer number\n  Put (Str3); Put (\"! \");\n  s1 := +Str3;\n  Put_Line (s1 & \"!!\");\n  Put (\"Heads: \"); for i in 1 .. 10 loop Put (Head (+\"Head...\", i)); end loop;\n  New_Line;\n  Put (\"Tails: \"); for i in 1 .. 10 loop Put (Tail (+\"...Tail\", i)); end loop;\n  New_Line (2);\n  Put_Line (\"----------- Strings_demo: That's all folks, the show is over! -----------\");\n  New_Line (3);\n  Put_Line ('.');\n  --\n  --  Quick tests. More systematic tests can be found in:  test/strings.adb\n  --\n  if s2 /= To_VString (\"Hello\") then\n    --  `To_VString (\"Hello\")` and `+\"Hello\"` are identical function calls.\n    Put (\"Ooops?\");\n  end if;\n  if +Str3 /= To_VString (Str3) then\n    --  `To_VString (s3)` and `+s3` are identical function calls.\n    Put (\"Ooops?\");\n  end if;\n  if +'x' /= To_VString ('x') then\n    --  `To_VString ('x')` and `+'x'` are identical function calls.\n    Put (\"Ooops?\");\n  end if;\n  if s4 /= +\"abcdef\" then  --  Comparison VString to VString\n    Put (\"Ooops?\");\n  end if;\n  if s4 /=  \"abcdef\" then  --  Comparison VString to String_Literal\n    Put (\"Ooops?\");\n  end if;\n  if Length (s4) /= 6 then\n    Put (\"Ooops?\");\n  end if;\n  s4_s4 := s4 & s4;  --  abcdefabcdef\n                     --  123456789012\n  if Index (s4_s4, +\"cd\") /= 3 or\n     Index (s4_s4,  \"cd\") /= 3 or\n     Index (s4_s4,  'c')  /= 3\n  then\n    Put (\"[Index] Ooops?\");\n  end if;\n  if Index (s4_s4, +\"cd\", 4) /= 9 or\n     Index (s4_s4,  \"cd\", 4) /= 9 or\n     Index (s4_s4,  'c', 4)  /= 9\n  then\n    Put (\"[Index, From] Ooops?\");\n  end if;\n  if Index_Backward (s4_s4, +\"cd\") /= 9 or\n     Index_Backward (s4_s4,  \"cd\") /= 9 or\n     Index_Backward (s4_s4,  'c')  /= 9\n  then\n    Put (\"[Index_Backward] Ooops?\");\n  end if;\n  if Index_Backward (s4_s4, +\"cd\", 8) /= 3 or\n     Index_Backward (s4_s4,  \"cd\", 8) /= 3 or\n     Index_Backward (s4_s4,  'c', 8)  /= 3\n  then\n    Put (\"[Index_Backward, From] Ooops?\");\n  end if;\n  --\n  if Starts_With (+\"package\", 'q')     then Put (\"Ooops?\"); end if;\n  if Starts_With (+\"package\",  \"proc\") then Put (\"Ooops?\"); end if;\n  if Starts_With (+\"package\", +\"proc\") then Put (\"Ooops?\"); end if;\n  if not Starts_With (+\"package\",  \"pack\") then Put (\"Ooops?\"); end if;\n  if not Starts_With (+\"package\", +\"pack\") then Put (\"Ooops?\"); end if;\n  --\n  if Ends_With (+\"package\", 'f')     then Put (\"Ooops?\"); end if;\n  if Ends_With (+\"package\",  \"proc\") then Put (\"Ooops?\"); end if;\n  if Ends_With (+\"package\", +\"proc\") then Put (\"Ooops?\"); end if;\n  if not Ends_With (+\"package\",  \"age\") then Put (\"Ooops?\"); end if;\n  if not Ends_With (+\"package\", +\"age\") then Put (\"Ooops?\"); end if;\nend Strings_demo;\n"
  },
  {
    "path": "exm/sudoku_sample.adb",
    "content": "with Sudokus;\nwith HAT;\n\nprocedure Sudoku_Sample is\n\n  use Sudokus;\n\n  grand_total : Technique_Count;\n\n  procedure Solve_from_Strings (s : Sudo_Strings; name : HAT.VString; verbosity_level : Natural) is\n    p : Sudo_Pack;\n    h : Sudo_Help;\n  begin\n    Convert_Data (s, p, h);\n    Solve (p, h, name, verbosity_level);\n    Cumulate (grand_total, p.total);\n  end Solve_from_Strings;\n\n  easy,\n  less_easy,\n  hard,\n  very_hard,\n  hidden_double_1,\n  hidden_triple_1 : Sudo_Strings;\n\n  use HAT;\n\nbegin\n  Put_Line\n    (\"Increase parameter `verbosity_level` for getting more details about \" &\n     \"the Sudoku resolution.\");\n  New_Line;\n\n  Zero (grand_total);\n\n  --  Spotting only naked singles is sufficient on this one.\n  easy (1) := +\"1   83 57\";\n  easy (2) := +\"9 27     \";\n  easy (3) := +\"  5   34 \";\n  easy (4) := +\"5   7  8 \";\n  easy (5) := +\"4  9 1  5\";\n  easy (6) := +\" 1  5   6\";\n  easy (7) := +\" 57   8  \";\n  easy (8) := +\"     87 4\";\n  easy (9) := +\"24 16   9\";\n  Solve_from_Strings (easy, +\"Easy 1         \", 1);\n\n  --  One round needs to spot only hidden singles;\n  --  the rest is solved by handling naked singles.\n  easy (1) := +\"1459  2 8\";\n  easy (2) := +\" 3   5 91\";\n  easy (3) := +\"2  3    7\";\n  easy (4) := +\" 2    1 6\";\n  easy (5) := +\"    6    \";\n  easy (6) := +\"4 1    8 \";\n  easy (7) := +\"3    4  2\";\n  easy (8) := +\"65 1   7 \";\n  easy (9) := +\"9 4  7513\";\n  Solve_from_Strings (easy, +\"Easy 2         \", 1);\n\n  --  One round needs to spot doubles on rows.\n  less_easy (1) := +\"7 8  4  3\";\n  less_easy (2) := +\"   8   9 \";\n  less_easy (3) := +\"   7  8 2\";\n  less_easy (4) := +\"     7941\";\n  less_easy (5) := +\"         \";\n  less_easy (6) := +\"1745     \";\n  less_easy (7) := +\"9 6  3   \";\n  less_easy (8) := +\" 4   6   \";\n  less_easy (9) := +\"8  4  5 9\";\n  Solve_from_Strings (less_easy, +\"Less easy 1a   \", 1);\n\n  --  Same puzzle, but first row is filled a bit more...\n  --  No multiple spotting is needed for solving it.\n  less_easy (1) := +\"7 8  4 53\";\n  Solve_from_Strings (less_easy, +\"Less easy 1b   \", 1);\n\n  less_easy (1) := +\" 8  2    \";\n  less_easy (2) := +\"4 7 536  \";\n  less_easy (3) := +\" 6    4  \";\n  less_easy (4) := +\"  49    2\";\n  less_easy (5) := +\"2       7\";\n  less_easy (6) := +\"7    59  \";\n  less_easy (7) := +\"  6    9 \";\n  less_easy (8) := +\"  547 3 1\";\n  less_easy (9) := +\"    1  4 \";\n  Solve_from_Strings (less_easy, +\"Less easy 2    \", 1);\n\n  less_easy (1) := +\"8  9     \";\n  less_easy (2) := +\"   5  18 \";\n  less_easy (3) := +\"      236\";\n  less_easy (4) := +\"  7 31   \";\n  less_easy (5) := +\" 1     4 \";\n  less_easy (6) := +\"   74 9  \";\n  less_easy (7) := +\"729      \";\n  less_easy (8) := +\" 64  8   \";\n  less_easy (9) := +\"     6  7\";\n  Solve_from_Strings (less_easy, +\"Less easy 3    \", 1);\n\n  --  This one has a {13} {13} hidden\n  --  double on first row at round 6.\n  less_easy (1) := +\" 7    2 6\";\n  less_easy (2) := +\" 9  16  4\";\n  less_easy (3) := +\"5  3    7\";\n  less_easy (4) := +\"      4  \";\n  less_easy (5) := +\"9  6 1  8\";\n  less_easy (6) := +\"  3      \";\n  less_easy (7) := +\"6    7  1\";\n  less_easy (8) := +\"7  58  4 \";\n  less_easy (9) := +\"2 9    7 \";\n  Solve_from_Strings (less_easy, +\"Less easy 4    \", 1);\n\n  less_easy (1) := +\"6  1     \";\n  less_easy (2) := +\"  869  2 \";\n  less_easy (3) := +\"  23   5 \";\n  less_easy (4) := +\"3     9  \";\n  less_easy (5) := +\"8   7   3\";\n  less_easy (6) := +\"  1     8\";\n  less_easy (7) := +\" 7   18  \";\n  less_easy (8) := +\" 4  862  \";\n  less_easy (9) := +\"     5  6\";\n  Solve_from_Strings (less_easy, +\"Less easy 5    \", 1);\n\n  less_easy (1) := +\"1  4 7 9 \";\n  less_easy (2) := +\"3 8 51   \";\n  less_easy (3) := +\" 6       \";\n  less_easy (4) := +\"4 6    3 \";\n  less_easy (5) := +\"7       1\";\n  less_easy (6) := +\" 3    4 7\";\n  less_easy (7) := +\"       1 \";\n  less_easy (8) := +\"   38 5 4\";\n  less_easy (9) := +\" 7 5 9  8\";\n  Solve_from_Strings (less_easy, +\"Less easy 6    \", 1);\n\n  --  This one is tricky near the end.\n  less_easy (1) := +\"81 5 4 72\";\n  less_easy (2) := +\"   1 7 48\";\n  less_easy (3) := +\"   8 3195\";\n  less_easy (4) := +\"298741563\";\n  less_easy (5) := +\"   239481\";\n  less_easy (6) := +\"1  685927\";\n  less_easy (7) := +\"981376254\";\n  less_easy (8) := +\" 2 958716\";\n  less_easy (9) := +\"576412839\";\n  Solve_from_Strings (less_easy, +\"Less easy 7    \", 1);\n\n  --  https://www.youtube.com/watch?v=8dNHOyzH-gc\n  hard (1) := +\" 2      5\";\n  hard (2) := +\"  4 7   1\";\n  hard (3) := +\"    3    \";\n  hard (4) := +\" 7  2 9  \";\n  hard (5) := +\"4     3  \";\n  hard (6) := +\"   6    8\";\n  hard (7) := +\" 56    1 \";\n  hard (8) := +\"   3  7 2\";\n  hard (9) := +\"9  8     \";\n  Solve_from_Strings (hard, +\"Hard 1         \", 1);\n\n  --  https://www.youtube.com/watch?v=9LiOg4BnmVU\n  hard (1) := +\"56 1   3 \";\n  hard (2) := +\"9   2 6  \";\n  hard (3) := +\" 1      2\";\n  hard (4) := +\"  36  7 9\";\n  hard (5) := +\"    8   4\";\n  hard (6) := +\" 5       \";\n  hard (7) := +\"    3    \";\n  hard (8) := +\"    4    \";\n  hard (9) := +\" 27 6  13\";\n  Solve_from_Strings (hard, +\"Hard 2         \", 1);\n\n  --  https://www.youtube.com/watch?v=4GVyBiFUNws\n  hard (1) := +\" 8  2 56 \";\n  hard (2) := +\"   1    7\";\n  hard (3) := +\"         \";\n  hard (4) := +\" 5  9 4 8\";\n  hard (5) := +\"  78    3\";\n  hard (6) := +\" 9  1  5 \";\n  hard (7) := +\"2 4   8  \";\n  hard (8) := +\" 6  85   \";\n  hard (9) := +\"   2  1  \";\n  Solve_from_Strings (hard, +\"Hard 3         \", 1);\n\n  --  This one is tricky due to locked cells that\n  --  are well hidden to the human. In that case,\n  --  it is about the digit 4 on last row, that\n  --  can be only within the bottom, center box.\n  --  Then 4 can't be in any cell of that box that\n  --  isn't on the last row.\n  hard (1) := +\"1 76 2   \";\n  hard (2) := +\"2 5 3 4  \";\n  hard (3) := +\"3    9  2\";\n  hard (4) := +\"  4 2  5 \";\n  hard (5) := +\"87    264\";\n  hard (6) := +\"52  8 7  \";\n  hard (7) := +\"   2    7\";\n  hard (8) := +\"  2 7 1  \";\n  hard (9) := +\"7    8325\";\n  Solve_from_Strings (hard, +\"Hard 4         \", 1);\n\n  hidden_double_1 (1) := +\"    6    \";  --  {47} {47}:  hidden double\n  hidden_double_1 (2) := +\"    42736\";  --  in the first two cells\n  hidden_double_1 (3) := +\"  673  4 \";\n  hidden_double_1 (4) := +\" 94    68\";\n  hidden_double_1 (5) := +\"    964 7\";\n  hidden_double_1 (6) := +\"6 7 5 923\";\n  hidden_double_1 (7) := +\"1      85\";\n  hidden_double_1 (8) := +\" 6  8 271\";\n  hidden_double_1 (9) := +\"  5 1  94\";\n  Solve_from_Strings (hidden_double_1, +\"Hidden double 1\", 1);\n\n  hidden_triple_1 (1) := +\"9  7     \";\n  hidden_triple_1 (2) := +\"  34   5 \";\n  hidden_triple_1 (3) := +\"  7 3 1  \";\n  hidden_triple_1 (4) := +\"3    94  \";\n  hidden_triple_1 (5) := +\"2  8 6  3\";\n  hidden_triple_1 (6) := +\"  83    9\";\n  hidden_triple_1 (7) := +\"  1 8 2  \";\n  hidden_triple_1 (8) := +\" 4   36  \";\n  hidden_triple_1 (9) := +\"     7  5\";\n  Solve_from_Strings (hidden_triple_1, +\"Hidden triple 1\", 1);\n\n  --  https://www.youtube.com/watch?v=T4OdkQMmyu8\n  --  Stalls at round 7, equivalent to t = 7:37\n  --  From comment at t= 8:30: \"a computer has\n  --  to go on a brute force way\".\n  very_hard (1) := +\" 8 1    7\";\n  very_hard (2) := +\"   5   26\";\n  very_hard (3) := +\"  27 4  3\";\n  very_hard (4) := +\"     1  4\";\n  very_hard (5) := +\"1        \";\n  very_hard (6) := +\"  42     \";\n  very_hard (7) := +\"      6 8\";\n  very_hard (8) := +\"7 1  3   \";\n  very_hard (9) := +\"  54  9  \";\n  Solve_from_Strings (very_hard, +\"Very hard 1    \", 1);\n\n  Show_Total (grand_total, +\"Techniques used for all puzzles:\");\n\nend Sudoku_Sample;\n"
  },
  {
    "path": "exm/sudokus.adb",
    "content": "package body Sudokus is\n\n  function Count (s : Sudoset) return Natural is\n    res : Natural := 0;\n  begin\n    for i in Sudigit loop\n      if s (i) then\n        res := res + 1;\n      end if;\n    end loop;\n    return res;\n  end Count;\n\n  function Count_Solved (u : Grid) return Natural is\n    total : Natural := 0;\n  begin\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if u (i, j).solved then\n          total := total + 1;\n        end if;\n      end loop;\n    end loop;\n    return total;\n  end Count_Solved;\n\n  function Is_Solved (u : Grid) return Boolean is\n  begin\n    return Count_Solved (u) = 81;\n  end Is_Solved;\n\n  procedure Find_Box_Base (i, j : Sudigit; base_i, base_j : out Sudigit) is\n    zone_i, zone_j : Natural;\n  begin\n    zone_i := (i - 1) / 3;\n    zone_j := (j - 1) / 3;\n    base_i := zone_i * 3 + 1;\n    base_j := zone_j * 3 + 1;\n  end Find_Box_Base;\n\n  function Is_Valid (u : Grid) return Boolean is\n    set, empty : Sudoset;\n    v : Sudigit;\n    base_i, base_j : Sudigit;\n    use HAT;\n  begin\n    for num in Sudigit loop\n      empty (num) := False;\n    end loop;\n    for i in Sudigit loop\n      set := empty;\n      --  Check row:\n      for j in Sudigit loop\n        if u (i, j).solved then\n          v := u (i, j).value;\n          if set (v) then\n            Put_Line (+\"Invalid row \" & i & \"; duplicate value \" & v);\n            return False;\n          end if;\n          set (v) := True;\n        end if;\n      end loop;\n    end loop;\n    --\n    for j in Sudigit loop\n      set := empty;\n      --  Check column:\n      for i in Sudigit loop\n        if u (i, j).solved then\n          v := u (i, j).value;\n          if set (v) then\n            Put_Line (+\"Invalid column \" & j & \"; duplicate value \" & v);\n            return False;\n          end if;\n          set (v) := True;\n        end if;\n      end loop;\n    end loop;\n    --\n    for bi in 0 .. 2 loop\n      for bj in 0 .. 2 loop\n        set := empty;\n        base_i := bi * 3 + 1;\n        base_j := bj * 3 + 1;\n        --  Check box:\n        for i in base_i .. base_i + 2 loop\n          for j in base_j .. base_j + 2 loop\n            if u (i, j).solved then\n              v := u (i, j).value;\n              if set (v) then\n                Put_Line\n                  (+\"Invalid box \" & (1 + bi * 3 + bj) &\n                    \"; duplicate value \" & v);\n                return False;\n              end if;\n              set (v) := True;\n            end if;\n          end loop;\n        end loop;\n      end loop;\n    end loop;\n    return True;\n  end Is_Valid;\n\n  procedure Adapt_Sets (u : in out Grid; i, j : Sudigit) is\n    num : Sudigit;\n    base_i, base_j : Sudigit;\n  begin\n    if u (i, j).solved then\n      num := u (i, j).value;\n      for k in Sudigit loop\n        --  Disable row:\n        u (i, k).set (num) := False;\n        --  Disable column:\n        u (k, j).set (num) := False;\n        Find_Box_Base (i, j, base_i, base_j);\n        --  Disable square:\n        for ii in base_i .. base_i + 2 loop\n          for jj in base_j .. base_j + 2 loop\n            u (ii, jj).set (num) := False;\n          end loop;\n        end loop;\n      end loop;\n    else\n      HAT.Put_Line (\"Cell i, j is not solved!\");  --  !! Full Ada: raise some exception\n    end if;\n  end Adapt_Sets;\n\n  procedure Adapt_All_Sets (u : in out Grid) is\n  begin\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if u (i, j).solved then\n          Adapt_Sets (u, i, j);\n        end if;\n      end loop;\n    end loop;\n  end Adapt_All_Sets;\n\n  procedure Mark_Solution (u : in out Grid; i, j, num : Sudigit) is\n  begin\n    u (i, j).value := num;\n    u (i, j).solved := True;\n    Adapt_Sets (u, i, j);\n    for n in Sudigit loop\n      u (i, j).set (n) := False;\n    end loop;\n  end Mark_Solution;\n\n  ------------------------------------\n  --  ===  Solving techniques  ===  --\n  ------------------------------------\n\n  ---------------------------------------------------------------\n  --  Singles. Some cells have only one possibility.           --\n  --  This case is called \"single\". It can be either \"naked\",  --\n  --  when the only possibility is alone, or \"hidden\" when     --\n  --  the possibility in question is not alone in its cell     --\n  --  but is nowhere else in a house (row, column or box).     --\n  --  When a single is found, the cell is solved.              --\n  ---------------------------------------------------------------\n\n  --  The \"naked single\" case is the most simple case to solve when\n  --  the possibilities for each cell are counted: the cell (i, j)\n  --  has only one possible digit. Note that for humans, this case\n  --  is not easily identifiable visually.\n  --\n  procedure Handle_Naked_Singles\n    (u       : in out Grid;\n     verbose : in     Boolean;\n     found   :    out Natural)\n  is\n    procedure Handle_Naked_Single (i, j : Sudigit) is\n      the_number : Sudigit;\n      use HAT;\n    begin\n      if Count (u (i, j).set) = 1 then\n        found := found + 1;\n        for num in Sudigit loop\n          if u (i, j).set (num) then\n            Mark_Solution (u, i, j, num);\n            the_number := num;\n            exit;\n          end if;\n        end loop;\n        if verbose then\n          Put_Line\n            (+\"Found naked single at pos \" &\n             i & ',' & j  & \": digit: \" & the_number);\n        end if;\n      end if;\n    end Handle_Naked_Single;\n  begin\n    found := 0;\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if not u (i, j).solved then\n          Handle_Naked_Single (i, j);\n        end if;\n      end loop;\n    end loop;\n  end Handle_Naked_Singles;\n\n  procedure Handle_Hidden_Singles\n    (u       : in out Grid;\n     verbose : in     Boolean;\n     found   :    out Natural)\n  is\n    procedure Handle_Hidden_Single (i, j : Sudigit) is\n      base_i, base_j : Sudigit;\n      ok : Boolean;\n      use HAT;\n    begin\n      Find_Box_Base (i, j, base_i, base_j);\n      for num in Sudigit loop\n        if u (i, j).set (num) then\n          --  Check row:\n          ok := True;\n          for jj in Sudigit loop\n            if jj /= j then\n              --  Check that the digit is NOT possible elsewhere on the row.\n              ok := ok and not u (i, jj).set (num);\n              exit when not ok;\n            end if;\n          end loop;\n          if ok then\n            if verbose then\n              Put_Line\n                (+\"Found hidden single (row) at pos \" &\n                 i & ',' & j  & \": digit: \" & num);\n            end if;\n          else\n            --  Check column:\n            ok := True;\n            for ii in Sudigit loop\n              if ii /= i then\n                --  Check that the digit is NOT possible elsewhere on the column.\n                ok := ok and not u (ii, j).set (num);\n                exit when not ok;\n              end if;\n            end loop;\n            if ok then\n              if verbose then\n                Put_Line\n                  (+\"Found hidden single (column) at pos \" &\n                   i & ',' & j  & \": digit: \" & num);\n              end if;\n            end if;\n          end if;\n          if not ok then\n            --  Check box:\n            ok := True;\n            Box_Row :\n            for ii in base_i .. base_i + 2 loop\n              for jj in base_j .. base_j + 2 loop\n                if ii /= i or else j /= jj then\n                  --  Check that the digit is NOT possible elsewhere in the box.\n                  ok := ok and not u (ii, jj).set (num);\n                  exit Box_Row when not ok;\n                end if;\n              end loop;\n            end loop Box_Row;\n            if ok then\n              if verbose then\n                Put_Line\n                  (+\"Found hidden single (box) at pos \" &\n                   i & ',' & j  & \": digit: \" & num);\n              end if;\n            end if;\n          end if;\n          if ok then\n            found := found + 1;\n            Mark_Solution (u, i, j, num);\n            exit;\n          end if;\n        end if;\n      end loop;\n    end Handle_Hidden_Single;\n  begin\n    found := 0;\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if not u (i, j).solved then\n          Handle_Hidden_Single (i, j);\n        end if;\n      end loop;\n    end loop;\n  end Handle_Hidden_Singles;\n\n  --------------------\n  --  Locked cells  --\n  --------------------\n\n  procedure Handle_Locked_Cells_Outside_Boxes\n    (u       : in out Grid;\n     verbose : in     Boolean;\n     found   :    out Natural)\n  is\n    procedure Handle_Locked_Cells_Outside_A_Box (i, j : Sudigit) is\n      base_i, base_j : Sudigit;\n      ok_row, ok_col, any_cell : Boolean;\n      use HAT;\n    begin\n      Find_Box_Base (i, j, base_i, base_j);\n      for num in Sudigit loop\n        if u (i, j).set (num) then\n          --  Check if `num` is only on a row / column within its box:\n          ok_row := True;\n          ok_col := True;\n          for ii in base_i .. base_i + 2 loop\n            for jj in base_j .. base_j + 2 loop\n              if u (ii, jj).set (num) then\n                ok_col := ok_col and jj = j;\n                ok_row := ok_row and ii = i;\n              end if;\n            end loop;\n          end loop;\n          --  We have found that `num` is possible only on a row within the box.\n          --  Then, it cannot be on that row outside the box.\n          any_cell := False;\n          if ok_row then\n            for jj in Sudigit loop\n              if jj not in base_j .. base_j + 2 and then u (i, jj).set (num) then\n                found := found + 1;\n                u (i, jj).set (num) := False;\n                any_cell := True;\n              end if;\n            end loop;\n            if verbose and then any_cell then\n              Put_Line\n                (+\"Found locked cells on row \" & i &\n                 \" *outside* of box with edge \" & base_i & ',' & base_j &\n                  \"; digit: \" & num);\n            end if;\n          end if;\n          --  We have found that `num` is possible only on a column within the box.\n          --  Then, it cannot be on that column outside the box.\n          any_cell := False;\n          if ok_col then\n            for ii in Sudigit loop\n              if ii not in base_i .. base_i + 2 and then u (ii, j).set (num) then\n                found := found + 1;\n                u (ii, j).set (num) := False;\n                any_cell := True;\n              end if;\n            end loop;\n            if verbose and then any_cell  then\n              Put_Line\n                (+\"Found locked cells on column \" & j &\n                 \" *outside* of box with edge \" & base_i & ',' & base_j &\n                  \"; digit: \" & num);\n            end if;\n          end if;\n        end if;\n      end loop;\n    end Handle_Locked_Cells_Outside_A_Box;\n  begin\n    found := 0;\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if not u (i, j).solved then\n          Handle_Locked_Cells_Outside_A_Box (i, j);\n        end if;\n      end loop;\n    end loop;\n  end Handle_Locked_Cells_Outside_Boxes;\n\n  procedure Handle_Locked_Cells_Inside_Boxes\n    (u       : in out Grid;\n     verbose : in     Boolean;\n     found   :    out Natural)\n  is\n    procedure Handle_Locked_Cells_Inside_A_Box (i, j : Sudigit) is\n      base_i, base_j : Sudigit;\n      ok_row, ok_col, any_cell_row, any_cell_col : Boolean;\n      use HAT;\n    begin\n      Find_Box_Base (i, j, base_i, base_j);\n      for num in Sudigit loop\n        if u (i, j).set (num) then\n          --  Check if `num` is only on a row / column within its box:\n          ok_row := True;\n          for jj in Sudigit loop\n            if jj not in base_j .. base_j + 2 then\n              --  Row i, but outside the box\n              if u (i, jj).set (num) then\n                ok_row := False;\n                exit;\n              end if;\n            end if;\n          end loop;\n          --\n          ok_col := True;\n          for ii in Sudigit loop\n            if ii not in base_i .. base_i + 2 then\n              --  Column j, but outside the box\n              if u (ii, j).set (num) then\n                ok_col := False;\n                exit;\n              end if;\n            end if;\n          end loop;\n          --\n          any_cell_row := False;\n          any_cell_col := False;\n          for ii in base_i .. base_i + 2 loop\n            for jj in base_j .. base_j + 2 loop\n              --  We have found that on the whole row, `num` is possible only within the box.\n              --  Then, it cannot be on another row inside the box.\n              if ok_row and then i /= ii and then u (ii, jj).set (num) then\n                found := found + 1;\n                u (ii, jj).set (num) := False;\n                any_cell_row := True;\n              end if;\n              --  We have found that on the whole column, `num` is possible only within the box.\n              --  Then, it cannot be on another column inside the box.\n              if ok_col and then j /= jj and then u (ii, jj).set (num) then\n                found := found + 1;\n                u (ii, jj).set (num) := False;\n                any_cell_col := True;\n              end if;\n            end loop;\n          end loop;\n          --\n          if verbose then\n            if any_cell_row then\n              Put_Line\n                (+\"Found locked cells on row \" & i &\n                 \" *inside* of box with edge \" & base_i & ',' & base_j &\n                  \"; digit: \" & num);\n            end if;\n            if any_cell_col then\n              Put_Line\n                (+\"Found locked cells on column \" & j &\n                 \" *inside* of box with edge \" & base_i & ',' & base_j &\n                  \"; digit: \" & num);\n            end if;\n          end if;\n        end if;\n      end loop;\n    end Handle_Locked_Cells_Inside_A_Box;\n  begin\n    found := 0;\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if not u (i, j).solved then\n          Handle_Locked_Cells_Inside_A_Box (i, j);\n        end if;\n      end loop;\n    end loop;\n  end Handle_Locked_Cells_Inside_Boxes;\n\n  ------------------------------\n  --  Multiple possibilities  --\n  ------------------------------\n\n  --  TBD: Handle_Naked_Multiples\n\n  procedure Handle_Hidden_Multiples\n    (u       : in out Grid;\n     multi   : in     Sudigit;\n     h       : in out Sudo_Help;\n     verbose : in     Boolean;\n     found   :    out Natural)\n  is\n    procedure Single_Row (i : Sudigit) is\n      procedure Check_Sequence (s : Sequence_Type) is\n        --  Example: we check if the *triple* {2, 5, 6}\n        --  appears, partially or fully, only in *three*\n        --  cells in a house, possibly with other digits.\n        --  In that case, the said other digits can be\n        --  removed as possibilities in those three cells.\n        match_count : Natural;\n        ok : Boolean;\n        has_multiple : Sudoset;\n        mask, appears : Sudoset := h.empty;\n        is_set, is_set_new : Boolean;\n        something_removed : Boolean;\n        selected_digit : Sudigit;\n        use HAT;\n      begin\n        for seq in 1 .. multi loop  --  ex.: (2, 5, 6 => True, others => False)\n          mask (s (seq)) := True;\n        end loop;\n        match_count := 0;\n        has_multiple := h.empty;\n        for jj in Sudigit loop\n          ok := False;\n          for seq in 1 .. multi loop\n            selected_digit := s (seq);\n            if u (i, jj).set (selected_digit) then\n              appears (selected_digit) := True;\n              ok := True;\n            end if;\n          end loop;\n          if ok then\n            match_count := match_count + 1;\n            has_multiple (jj) := True;\n          end if;\n        end loop;\n        if match_count <= multi\n          and then Count (appears) = multi  --  Ensure all considered digits appear at least once\n        then\n          for j in Sudigit loop\n            if has_multiple (j) then\n              something_removed := False;\n              --  In the cells containing the hidden multiple,\n              --  we keep only the digits of the multiple\n              --  and remove the other digits.\n              for d in Sudigit loop\n                is_set := u (i, j).set (d);\n                is_set_new := is_set and mask (d);\n                u (i, j).set (d) := is_set_new;\n                if is_set_new /= is_set then\n                  something_removed := True;\n                end if;\n              end loop;\n              if something_removed then\n                found := found + 1;\n                if verbose then\n                  Put\n                    (+\"Found hidden multiple on a row at pos \" &\n                     i & ',' & j  & \": digits:\");\n                  for seq in 1 .. multi loop\n                    if u (i, j).set (s (seq)) then\n                      Put (s (seq), 2);\n                    else\n                      Put (+\" (\" & s (seq) & ')');\n                    end if;\n                  end loop;\n                  New_Line;\n                end if;\n              end if;\n            end if;\n          end loop;\n        end if;\n      end Check_Sequence;\n\n    begin\n      --  Check all sequences. E.g., for multi = 2:\n      --  {1, 2}, {1, 3}, {2, 3}, {1, 4}, {2, 4}, {3, 4}, ...\n      for combi in 1 .. h.max_combi (multi) loop\n        Check_Sequence (h.table (multi, combi));\n      end loop;\n    end Single_Row;\n\n    procedure Single_Column (j : Sudigit) is\n      procedure Check_Sequence (s : Sequence_Type) is\n        match_count : Natural;\n        ok : Boolean;\n        has_multiple : Sudoset;\n        mask, appears : Sudoset := h.empty;\n        is_set, is_set_new : Boolean;\n        something_removed : Boolean;\n        selected_digit : Sudigit;\n        use HAT;\n      begin\n        for seq in 1 .. multi loop\n          mask (s (seq)) := True;\n        end loop;\n        match_count := 0;\n        has_multiple := h.empty;\n        for i in Sudigit loop\n          ok := False;\n          for seq in 1 .. multi loop\n            selected_digit := s (seq);\n            if u (i, j).set (selected_digit) then\n              appears (selected_digit) := True;\n              ok := True;\n            end if;\n          end loop;\n          if ok then\n            match_count := match_count + 1;\n            has_multiple (i) := True;\n          end if;\n        end loop;\n        if match_count <= multi\n          and then Count (appears) = multi\n        then\n          for i in Sudigit loop\n            if has_multiple (i) then\n              something_removed := False;\n              for d in Sudigit loop\n                is_set := u (i, j).set (d);\n                is_set_new := is_set and mask (d);\n                u (i, j).set (d) := is_set_new;\n                if is_set_new /= is_set then\n                  something_removed := True;\n                end if;\n              end loop;\n              if something_removed then\n                found := found + 1;\n                if verbose then\n                  Put\n                    (+\"Found hidden multiple on a column at pos \" &\n                     i & ',' & j  & \": digits:\");\n                  for seq in 1 .. multi loop\n                    if u (i, j).set (s (seq)) then\n                      Put (s (seq), 2);\n                    else\n                      Put (+\" (\" & s (seq) & ')');\n                    end if;\n                  end loop;\n                  New_Line;\n                end if;\n              end if;\n            end if;\n          end loop;\n        end if;\n      end Check_Sequence;\n\n    begin\n      for combi in 1 .. h.max_combi (multi) loop\n        Check_Sequence (h.table (multi, combi));\n      end loop;\n    end Single_Column;\n\n    procedure Single_Box (base_i, base_j : Sudigit) is\n      procedure Check_Sequence (s : Sequence_Type) is\n        match_count : Natural;\n        ok : Boolean;\n        has_multiple : array (0 .. 2, 0 .. 2) of Boolean;\n        mask, appears : Sudoset := h.empty;\n        is_set, is_set_new : Boolean;\n        something_removed : Boolean;\n        selected_digit : Sudigit;\n        use HAT;\n      begin\n        for seq in 1 .. multi loop\n          mask (s (seq)) := True;\n        end loop;\n        match_count := 0;\n        for i in has_multiple'Range (1) loop\n          for j in has_multiple'Range (2) loop\n            has_multiple (i, j) := False;\n          end loop;\n        end loop;\n        for i in base_i .. base_i + 2 loop\n          for j in base_j .. base_j + 2 loop\n            ok := False;\n            for seq in 1 .. multi loop\n              selected_digit := s (seq);\n              if u (i, j).set (selected_digit) then\n                appears (selected_digit) := True;\n                ok := True;\n              end if;\n            end loop;\n            if ok then\n              match_count := match_count + 1;\n              has_multiple (i - base_i, j - base_j) := True;\n            end if;\n          end loop;\n        end loop;\n        if match_count <= multi\n          and then Count (appears) = multi\n        then\n          for i in base_i .. base_i + 2 loop\n            for j in base_j .. base_j + 2 loop\n              if has_multiple (i - base_i, j - base_j) then\n                something_removed := False;\n                for d in Sudigit loop\n                  is_set := u (i, j).set (d);\n                  is_set_new := is_set and mask (d);\n                  u (i, j).set (d) := is_set_new;\n                  if is_set_new /= is_set then\n                    something_removed := True;\n                  end if;\n                end loop;\n                if something_removed then\n                  found := found + 1;\n                  if verbose then\n                    Put\n                      (+\"Found hidden multiple in a box at pos \" &\n                       i & ',' & j  & \": digits:\");\n                    for seq in 1 .. multi loop\n                      if u (i, j).set (s (seq)) then\n                        Put (s (seq), 2);\n                      else\n                        Put (+\" (\" & s (seq) & ')');\n                      end if;\n                    end loop;\n                    New_Line;\n                  end if;\n                end if;\n              end if;\n            end loop;\n          end loop;\n        end if;\n      end Check_Sequence;\n\n    begin\n      for combi in 1 .. h.max_combi (multi) loop\n        Check_Sequence (h.table (multi, combi));\n      end loop;\n    end Single_Box;\n\n  begin\n    found := 0;\n    for ij in Sudigit loop\n      Single_Row (ij);\n      Single_Column (ij);\n    end loop;\n    for box_i in 0 .. 2 loop\n      for box_j in 0 .. 2 loop\n        Single_Box (box_i * 3 + 1, box_j * 3 + 1);\n      end loop;\n    end loop;\n  end Handle_Hidden_Multiples;\n\n  function Technique_Image (t : Resolution_Technique) return HAT.VString is\n    use HAT;\n  begin\n    case t is\n      when naked_single            => return +\"naked single(s)\";\n      when hidden_single           => return +\"hidden single(s)\";\n      when locked_cell_outside_box => return +\"locked cell(s), outside boxe(s)\";\n      when locked_cell_inside_box  => return +\"locked cell(s), inside boxe(s)\";\n      when hidden_double           => return +\"hidden double(s)\";\n      when hidden_triple           => return +\"hidden triple(s)\";\n      when hidden_quadruple        => return +\"hidden quadruple(s)\";\n      when hidden_quintuple        => return +\"hidden quintuple(s)\";\n      when hidden_sextuple         => return +\"hidden sextuple(s)\";\n      when hidden_septuple         => return +\"hidden septuple(s)\";\n      when hidden_octuple          => return +\"hidden octuple(s)\";\n    end case;\n  end Technique_Image;\n\n  procedure Zero (count : out Technique_Count) is\n  begin\n    for t in Resolution_Technique loop\n      count (t) := 0;\n    end loop;\n  end Zero;\n\n  function Sum (count : Technique_Count) return Natural is\n    s : Natural := 0;\n  begin\n    for t in Resolution_Technique loop\n      s := s + count (t);\n    end loop;\n    return s;\n  end Sum;\n\n  procedure Cumulate\n    (total      : in out Technique_Count;\n     additional :        Technique_Count)\n  is\n  begin\n    for t in Resolution_Technique loop\n      total (t) := total (t) + additional (t);\n    end loop;\n  end Cumulate;\n\n  procedure Show_Total (total : Technique_Count; title : HAT.VString) is\n    use HAT;\n  begin\n    Put_Line (title);\n    for t in Resolution_Technique loop\n      if total (t) > 0 then\n        Put_Line (+\"   found: \" & total (t) & ' ' & Technique_Image (t));\n      end if;\n    end loop;\n    New_Line;\n  end Show_Total;\n\n  procedure Show (u : Grid; title : HAT.VString) is\n    min_poss : Natural := Natural'Last;\n    poss : Natural;\n    use HAT;\n  begin\n    Put_Line (title);\n    Put_Line (Length (title) * '=');\n    New_Line;\n    Put_Line (+\"Grid, \" & Count_Solved (u) & \" digits set         Possibilities\");\n    New_Line;\n    for i in Sudigit loop\n      for j in Sudigit loop\n        if j mod 3 = 1 then\n          Put ('|');\n        else\n          Put (' ');\n        end if;\n        if u (i, j).solved then\n          Put (u (i, j).value, 0);\n        else\n          Put ('_');\n        end if;\n      end loop;\n      Put (\"|         \");\n      for j in Sudigit loop\n        if j mod 3 = 1 then\n          Put ('|');\n        else\n          Put (' ');\n        end if;\n        if u (i, j).solved then\n          Put ('_');\n        else\n          poss := Count (u (i, j).set);\n          Put (poss, 0);\n          min_poss := Min (min_poss, poss);\n        end if;\n      end loop;\n      Put_Line ('|');\n      if i = 3 or else i = 6 then\n        Put_Line (\":-----+-----+-----:         :-----+-----+-----:\");\n      end if;\n    end loop;\n    New_Line;\n    if min_poss in Sudigit then\n      Put_Line (+\"                            Minimum: \" & min_poss);\n    end if;\n  end Show;\n\n  procedure Show_Detailed_Possibilities (u : Grid) is\n    use HAT;\n  begin\n    for i in Sudigit loop\n      for j in Sudigit loop\n        for num in Sudigit loop\n          if u (i, j).set (num) then\n            Put (num, 0);\n          else\n            Put ('.');\n          end if;\n        end loop;\n        if j mod 3 = 0 then\n          Put ('|');\n        else\n          Put (' ');\n        end if;\n      end loop;\n      New_Line;\n      if i mod 3 = 0 then\n        Put_Line (90 * '-');\n      end if;\n    end loop;\n  end Show_Detailed_Possibilities;\n\n  procedure Resolution_Round\n    (pack            : in out Sudo_Pack;\n     help            : in out Sudo_Help;\n     title           : in     HAT.VString;\n     verbosity_level : in     Natural)\n  is\n    found : Technique_Count;\n\n    procedure Handle_Techniques is\n      single_hit_verbosity : constant Boolean := verbosity_level > 4;\n    begin\n      Handle_Naked_Singles (pack.u, single_hit_verbosity, found (naked_single));\n      if found (naked_single) > 0 then\n        return;\n      end if;\n      --  We search more complicated possibilities,\n      --  only when none for the less complicated was found.\n      Handle_Hidden_Singles (pack.u, single_hit_verbosity, found (hidden_single));\n      if found (hidden_single) > 0 then\n        return;\n      end if;\n      Handle_Locked_Cells_Outside_Boxes\n        (pack.u, single_hit_verbosity, found (locked_cell_outside_box));\n      if found (locked_cell_outside_box) > 0 then\n        return;\n      end if;\n      Handle_Locked_Cells_Inside_Boxes\n        (pack.u, single_hit_verbosity, found (locked_cell_inside_box));\n      if found (locked_cell_inside_box) > 0 then\n        return;\n      end if;\n      for t in hidden_double .. hidden_octuple loop\n        Handle_Hidden_Multiples\n          (pack.u,\n           2 + Resolution_Technique'Pos (t)\n             - Resolution_Technique'Pos (hidden_double),\n           help,\n           single_hit_verbosity,\n           found (t));\n        if found (t) > 0 then\n          return;\n        end if;\n      end loop;\n    end Handle_Techniques;\n\n    use HAT;\n\n  begin\n    Zero (found);\n    Handle_Techniques;\n    pack.stalling := Sum (found) = 0;\n    if verbosity_level > 1 then\n      if pack.stalling then\n        Put_Line (\"Stalling. Search abandoned.\");\n        if verbosity_level > 2 then\n          Show_Detailed_Possibilities (pack.u);\n        end if;\n      end if;\n      if verbosity_level > 2 or else Is_Solved (pack.u) then\n        Show (pack.u, title);\n        if verbosity_level > 3 then\n          Show_Detailed_Possibilities (pack.u);\n        end if;\n      end if;\n      if verbosity_level > 2 then\n        Show_Total (found, +\"Techniques used in this round:\");\n      end if;\n    end if;\n    Cumulate (pack.total, found);\n  end Resolution_Round;\n\n  procedure Solve\n    (pack            : in out Sudo_Pack;\n     help            : in out Sudo_Help;\n     name            : in     HAT.VString;\n     verbosity_level : in     Natural)\n  is\n    use HAT;\n  begin\n    Adapt_All_Sets (pack.u);\n    case verbosity_level is\n      when 0 =>\n        null;  --  Completely silent, except for errors.\n      when 1 =>\n        Put (\"Puzzle: \" & name & \" - \");\n      when others =>\n        New_Line;\n        Show (pack.u, \"> > > > Initial board for: \" & name);\n        if verbosity_level > 3 then\n          Show_Detailed_Possibilities (pack.u);\n        end if;\n    end case;\n    if not Is_Valid (pack.u) then\n      Put_Line (\"Initial board is invalid!\");\n      return;\n    end if;\n    --\n    for round in 1 .. Sudigit'Last * Sudigit'Last loop\n      Resolution_Round\n        (pack, help, +\"After round \" & round & \" for \" & name, verbosity_level);\n      exit when pack.stalling or else Is_Solved (pack.u);\n    end loop;\n    --\n    if verbosity_level > 1 then\n      Show_Total (pack.total, +\"Totals of techniques used:\");\n    end if;\n    if not Is_Valid (pack.u) then\n      Put_Line (\"Solution or current state is invalid!\");\n      return;\n    end if;\n    if verbosity_level = 1 then\n      if pack.stalling then\n        Put_Line\n          (\"** stalling **, algorithm not smart enough,\" &\n           \" or too few digits set in puzzle!\");\n      elsif Is_Solved (pack.u) then\n        Put_Line (\"solved and checked.\");\n      else\n        Put_Line (\"Neither solved nor unsolved ?!\");\n      end if;\n    end if;\n  end Solve;\n\n  procedure Initialize (pack : out Sudo_Pack) is\n  begin\n    Zero (pack.total);\n    pack.stalling := False;\n  end Initialize;\n\n  procedure Initialize_Helper (help : out Sudo_Help) is\n    i_shifted, bits_1 : Natural;\n    comb_index : Positive;\n  begin\n    for num in Sudigit loop\n      help.full (num) := True;\n      help.empty (num) := False;\n      help.max_combi (num) := 0;\n    end loop;\n    --\n    for i in 1 .. (2 ** Sudigit'Last) - 1 loop\n      i_shifted := i;\n      bits_1 := 0;\n      for d in Sudigit loop\n        if i_shifted mod 2 = 1 then\n          bits_1 := bits_1 + 1;\n        end if;\n        i_shifted := i_shifted / 2;\n      end loop;\n      --  For bits_1 = 3 (say), we have found a new\n      --  combination with 3 digits which correspond to\n      --  the position of the bit in the binary\n      --  representation of i.\n      help.max_combi (bits_1) := help.max_combi (bits_1) + 1;\n      i_shifted := i;\n      comb_index := 1;\n      for d in Sudigit loop\n        if i_shifted mod 2 = 1 then\n          help.table (bits_1, help.max_combi (bits_1))(comb_index) := d;\n          comb_index := comb_index + 1;\n        end if;\n        i_shifted := i_shifted / 2;\n      end loop;\n    end loop;\n    --  Some table outputs:\n    --\n    --  HAT.Put_Line (\"Combinations:\");\n    --  for d in 1 .. Sudigit'Last - 1 loop\n    --    HAT.Put (\"For\");\n    --    HAT.Put (d, 2);\n    --    HAT.Put_Line (help.max_combi (d));  --  = Binomial (9, d)\n    --  end loop;\n    --\n    --  HAT.Put_Line (\"All doubles:\");\n    --  for i in 1 .. help.max_combi (2) loop\n    --    for j in 1 .. 2 loop\n    --      HAT.Put (help.table (2, i)(j), 2);\n    --    end loop;\n    --    HAT.New_Line;\n    --  end loop;\n    --\n    --  HAT.Put_Line (\"All triples:\");\n    --  for i in 1 .. help.max_combi (3) loop\n    --    for j in 1 .. 3 loop\n    --      HAT.Put (help.table (3, i)(j), 2);\n    --    end loop;\n    --    HAT.New_Line;\n    --  end loop;\n  end Initialize_Helper;\n\n  procedure Convert_Data\n    (s    : in     Sudo_Strings;\n     pack : in out Sudo_Pack;\n     help : in out Sudo_Help)\n  is\n    procedure Convert_String (i : Sudigit; s : HAT.VString) is\n      c : Character;\n      use HAT;\n    begin\n      for j in Sudigit loop\n        c := Element (s, j);\n        case c is\n          when ' ' =>\n            pack.u (i, j).solved := False;\n            pack.u (i, j).set := help.full;\n          when '1' .. '9' =>\n            pack.u (i, j).solved := True;\n            pack.u (i, j).set := help.empty;\n            pack.u (i, j).value := Ord (c) - Ord ('0');\n          when others =>\n            Put_Line (\"Data Error!\");  --  !! Full Ada: raise some exception\n        end case;\n      end loop;\n    end Convert_String;\n\n  begin\n    Initialize (pack);\n    Initialize_Helper (help);\n    for i in Sudigit loop\n      Convert_String (i, s (i));\n    end loop;\n  end Convert_Data;\n\nend Sudokus;\n"
  },
  {
    "path": "exm/sudokus.ads",
    "content": "--  This package explores ways to solve a Sudoku\n--  in a human-friendly way, that is *without* resorting\n--  to brute force by using recursion.\n\nwith HAT;\n\npackage Sudokus is\n\n  subtype Sudigit is Integer range 1 .. 9;\n\n  type Sudoset is array (Sudigit) of Boolean;\n\n  function Count (s : Sudoset) return Natural;\n\n  type Cell is record\n    solved : Boolean;\n    value  : Sudigit;\n    set    : Sudoset;\n  end record;\n\n  type Grid is array (Sudigit, Sudigit) of Cell;\n\n  function Count_Solved (u : Grid) return Natural;\n\n  function Is_Solved (u : Grid) return Boolean;\n\n  function Is_Valid (u : Grid) return Boolean;\n\n  --  Once a cell (i, j) is solved, we need to remove\n  --  the digit in the possibility sets of the row i,\n  --  the column j and the 3x3 box containing (i, j).\n  --\n  procedure Adapt_Sets (u : in out Grid; i, j : Sudigit);\n\n  procedure Adapt_All_Sets (u : in out Grid);\n\n  --  We associate combinations of possible Sudigits\n  --  with the binary representation of numbers.\n  --  Example: if we want to consider digits 2 and 4,\n  --  the number associated is 2 ** 1 + 2 ** 3 = 10.\n  --\n  --           ----- Binary ----- |#Sudigits = count\n  --  Decimal: Bit :  >987654321< |of binary '1's   |Sequence:\n  ------------------------------------------------------------\n  --        1         >        1<           1       | 1\n  --        2         >       10<           1       | 2\n  --        3         >       11<           2       | 1, 2\n  --        4         >      100<           1       | 3\n  --        5         >      101<           2       | 1, 3\n  --        6         >      110<           2       | 2, 3\n  --        7         >      111<           3       | 1, 2, 3\n  --        8         >     1000<           1       | 4\n  --        9         >     1001<           2       | 1, 4\n  --  >>>> 10         >     1010<           2       | 2, 4\n  --       11         >     1011<           3       | 1, 2, 4\n\n  type Sequence_Type is array (Sudigit) of Sudigit;\n\n  type Combination_Table is array (Sudigit, 1 .. 126) of Sequence_Type;\n\n  --  Say c is of type Combination_Table. Then, in the example above,\n  --  we see that the pair {2, 4} is the 5th combination with two Sudigits.\n  --  Then c (2, 5)(1) = 2 and c (2, 5)(2) = 4.\n\n  type Max_Combinations_Type is array (Sudigit) of Natural;\n\n  --  The data in the following record is invariant and independent of puzzles.\n\n  type Sudo_Help is record\n    full      : Sudoset;\n    empty     : Sudoset;\n    table     : Combination_Table;\n    max_combi : Max_Combinations_Type;\n  end record;\n\n  -------------------------------------------------------\n  --  Organization of different resolution techniques  --\n  -------------------------------------------------------\n\n  type Resolution_Technique is\n    (naked_single,\n     hidden_single,\n     locked_cell_outside_box,\n     locked_cell_inside_box,\n     hidden_double,\n     hidden_triple,\n     hidden_quadruple,\n     hidden_quintuple,\n     hidden_sextuple,\n     hidden_septuple,\n     hidden_octuple);\n\n  function Technique_Image (t : Resolution_Technique) return HAT.VString;\n\n  type Technique_Count is array (Resolution_Technique) of Natural;\n\n  procedure Zero (count : out Technique_Count);\n\n  procedure Cumulate\n    (total      : in out Technique_Count;\n     additional :        Technique_Count);\n\n  procedure Show_Total (total : Technique_Count; title : HAT.VString);\n\n  --  Output of a grid on console.\n\n  procedure Show_Detailed_Possibilities (u : Grid);\n\n  type Sudo_Pack is record\n    u        : Grid;\n    total    : Technique_Count;\n    stalling : Boolean;\n  end record;\n\n  procedure Resolution_Round\n    (pack            : in out Sudo_Pack;\n     help            : in out Sudo_Help;\n     title           : in     HAT.VString;\n     verbosity_level : in     Natural);\n\n  procedure Solve\n    (pack            : in out Sudo_Pack;\n     help            : in out Sudo_Help;\n     name            : in     HAT.VString;\n     verbosity_level : in     Natural);\n\n  --  Input of puzzles as strings.\n\n  type Sudo_Strings is array (Sudigit) of HAT.VString;\n\n  procedure Convert_Data\n    (s    : in     Sudo_Strings;\n     pack : in out Sudo_Pack;\n     help : in out Sudo_Help);\n\nend Sudokus;\n"
  },
  {
    "path": "exm/tasking/tasks_01.adb",
    "content": "--  Here is the simplest case of tasking you can imagine: just\r\n--  a bunch of tasks running in parallel, without communication\r\n--  between them.\r\n\r\nwith HAT;\r\n\r\nprocedure Tasks_01 is\r\n\r\n  task T1;\r\n  task T2;\r\n\r\n  task body T1 is\r\n  begin\r\n    for i in 1 .. 4 loop\r\n      HAT.Put_Line (\"  [1] I am T1\");\r\n      delay 0.01;\r\n    end loop;\r\n  end T1;\r\n\r\n  task body T2 is\r\n  begin\r\n    for i in 1 .. 6 loop\r\n      HAT.Put_Line (\"  [2]   I am T2\");\r\n      delay 0.01;\r\n    end loop;\r\n  end T2;\r\n\r\nbegin\r\n  for i in 1 .. 3 loop\r\n    HAT.Put_Line (\"I am the main procedure\");\r\n    delay 0.01;\r\n  end loop;\r\nend Tasks_01;\r\n"
  },
  {
    "path": "exm/tasking/tasks_02.adb",
    "content": "--  Was originally Test2 in SmallAda\r\n\r\nwith HAT;\r\n\r\nprocedure Tasks_02 is\r\n\r\n  compiler_regression_test_mode : constant Boolean := HAT.Argument_Count > 0;\r\n  verbose : constant Boolean := not compiler_regression_test_mode;\r\n\r\n  procedure Selective_Put_Line (M : HAT.VString) is\r\n  begin\r\n    if verbose then\r\n      HAT.Put_Line (M);\r\n    end if;\r\n  end Selective_Put_Line;\r\n\r\n  task T1;\r\n  task T2 is\r\n    entry Hereza_Num (V1 : Integer);\r\n    entry Gimmea_Num (V2 : out Integer);\r\n  end T2;\r\n\r\n  the_answer : constant := 42;\r\n\r\n  use HAT;\r\n\r\n  task body T1 is\r\n    iii : Integer;\r\n  begin\r\n    Selective_Put_Line (5 * \"Task T1 starting... \");\r\n    iii := the_answer;\r\n    Selective_Put_Line (+\"iii = \" & iii);\r\n    T2.Hereza_Num (iii);\r\n  end T1;\r\n\r\n  task body T2 is\r\n    jjj : Integer;\r\n  begin\r\n    Selective_Put_Line (5 * \"Task T2 starting... \");\r\n    jjj := 0;\r\n    Selective_Put_Line (+\"jjj = \" & jjj);\r\n    accept Hereza_Num (V1 : Integer) do\r\n      jjj := V1;\r\n    end Hereza_Num;\r\n    Selective_Put_Line (+\"jjj = \" & jjj);\r\n    accept Gimmea_Num (V2 : out Integer) do\r\n      V2 := jjj;\r\n    end Gimmea_Num;\r\n  end T2;\r\n\r\n  Mmm : Integer := 99;\r\n\r\nbegin\r\n  Selective_Put_Line (+\"[Main] ---------- Test with Tasks.\");\r\n  Selective_Put_Line (+\"[Main] [point 1] mmm = \" & Mmm);\r\n  T2.Gimmea_Num (Mmm);\r\n  Selective_Put_Line (+\"[Main] ---------- At this point, tasks are done.\");\r\n  Selective_Put_Line (+\"[Main] [point 2] mmm = \" & Mmm);\r\n  Selective_Put_Line (+\"[Main] Done.\");\r\n  if compiler_regression_test_mode and then Mmm /= the_answer then\r\n    Put_Line (\"   ----> Compiler test failed.\");\r\n    Set_Exit_Status (1);\r\n  end if;\r\nend Tasks_02;\r\n"
  },
  {
    "path": "exm/three_lakes_s.adb",
    "content": "--    ***  This HAC demo is a version of the Three_Lakes\n--    ***  program in MathPaqs. The program is scaled down for\n--    ***  meeting HAC v.0.072 syntax subset.\n--    ***  We mark the downscaling with \"!\" in comments.\n--    ***\n--    ***  For the original verion in full Ada, see \"three_lakes.adb\" @\n--    ***    https://mathpaqs.sourceforge.io/ or\n--    ***    https://github.com/zertovitch/mathpaqs .\n----------------------------------------------------------------------------\n--  This program solves a vectorial ordinary differential equation\n--  (or a system of ordinary differential equations).\n--\n--  * The unknown is a vector containing the levels of three lakes.\n--  * The lakes are connected by two channels.\n--  * There is an initial condition: the levels at t = 0.\n--  * Boundary conditions take the form of natural inflows into the lakes,\n--    and a single, controlled outflow out of one of the lakes.\n--\n--  Related publication:\n--    Evolution simulee des niveaux dans le systeme des Trois-Lacs,\n--    F. & G. de Montmollin,\n--    Bulletin de la Societe vaudoise des sciences naturelles.\n--    88.2: 121-129, ISSN 0037-9603, 2002\n--\n--  Related post:\n--    https://gautiersblog.blogspot.com/2020/05/the-three-lakes-problem.html\n--\n\nwith HAT;\n--  ! with Ada.Text_IO,\n--  !      Ada.Integer_Text_IO,\n--  !      Ada.Numerics.Generic_Elementary_Functions;\n\nprocedure Three_Lakes_S is\n\n  --  ! type Real is digits 15;\n\n  --  ! package PFIO is new Ada.Text_IO.Float_IO (Real);\n  --  ! package PFEF is new Ada.Numerics.Generic_Elementary_functions (Real);\n\n  use HAT;\n\n  type Lake is (Morat, Neuchatel, Bienne);\n\n  type Lake_Vector is array (Lake) of Real;\n\n  --  ! Full Ada: programmable operators (*, +, ...).\n\n  --  ! function \"*\" (l : Real; v : Lake_Vector) return Lake_Vector is\n  --  !   r : Lake_Vector;\n  --  ! begin\n  --  !   for i in v'Range loop r(i) := v(i) * l; end loop;\n  --  !   return r;\n  --  ! end \"*\";\n\n  --  ! function \"+\" (a, b : Lake_Vector) return Lake_Vector is\n  --  !   r : Lake_Vector;\n  --  ! begin\n  --  !   for i in a'Range loop r(i) := a(i) + b(i); end loop;\n  --  !   return r;\n  --  ! end \"+\";\n\n  procedure Times (l : Real; v : Lake_Vector; r : out Lake_Vector) is\n  begin\n    for i in Lake loop r (i) := v (i) * l; end loop;\n  end Times;\n\n  procedure Plus (a, b : Lake_Vector; r : out Lake_Vector) is\n  begin\n    for i in Lake loop r (i) := a (i) + b (i); end loop;\n  end Plus;\n\n  function Sign (i : Real) return Real is\n  begin\n    if    i < 0.0 then  return -1.0;\n    elsif i = 0.0 then  return  0.0;\n    else                return  1.0;\n    end if;\n  end Sign;\n\n  --  ! ivs: constant Lake_Vector:=\n  --  !    (Morat     => 1.0 / 2.2820e7,\n  --  !     Neuchatel => 1.0 / 2.1581e8,\n  --  !     Bienne    => 1.0 / 4.0870e7);\n  --\n  --  ! Full Ada: aggregates\n\n  ivs : Lake_Vector;\n\n  procedure Init_Sensitivity is\n  begin\n    ivs (Morat)     := 1.0 / 2.2820e7;\n    ivs (Neuchatel) := 1.0 / 2.1581e8;\n    ivs (Bienne)    := 1.0 / 4.0870e7;\n  end Init_Sensitivity;\n\n  --  We solve numerically   x' (t) = f (x (t), t)   over the time step h.\n  --\n  procedure Evolution (x : in out Lake_Vector; q_e : Lake_Vector; q_sb, h : Real) is\n    --\n    --  ! function f (x : Lake_Vector) return Lake_Vector is\n    --  ! Full Ada: functions with non-atomic results.\n\n    procedure f (x : Lake_Vector; res_f : out Lake_Vector) is\n      q_tr_mn, q_tr_nb : Real;\n      --\n      procedure Flux_tansfert is\n        --  ! use PFEF;\n      begin\n        q_tr_mn :=\n          --  Canal de la Broye: Morat -> Neuchatel.\n          Sign (x (Morat) - x (Neuchatel)) *                           --  sens d'ecoulement\n          15.223 *                                                      --  facteur de debit\n          (((x (Morat) + x (Neuchatel)) * 0.5 - 426.0)**1.868) *   --  effet du niveau moyen\n          ((abs (x (Morat) - x (Neuchatel)))**0.483);       --  effet de la diff. de niveaux\n        --\n        q_tr_nb :=\n          --  Canal de la Thielle: Neuchatel -> Bienne.\n          Sign (x (Neuchatel) - x (Bienne)) *                          --  sens d'ecoulement\n          18.582 *                                                      --  facteur de debit\n          (((x (Neuchatel) + x (Bienne)) * 0.5 - 426.0)**2.511) *  --  effet du niveau moyen\n          ((abs (x (Neuchatel) - x (Bienne)))**0.482);      --  effet de la diff. de niveaux\n      end Flux_tansfert;\n    begin\n      Flux_tansfert;\n      res_f (Morat) := (q_e (Morat)     - q_tr_mn) * ivs (Morat);\n      res_f (Neuchatel) := (q_e (Neuchatel) + q_tr_mn - q_tr_nb) * ivs (Neuchatel);\n      res_f (Bienne) := (q_e (Bienne)              + q_tr_nb - q_sb) * ivs (Bienne);\n    end f;\n    k1, k2, k3, k4, tmp_a, tmp_b, dbk2, dbk3 : Lake_Vector;\n  begin\n    --  Runge-Kutta, Order 4\n    --\n    --  ! Full Ada: sooooo much simpler with operators!\n    --\n    --  !  k1 := f (x               );\n    --  !  k2 := f (x + h * 0.5 * k1);\n    --  !  k3 := f (x + h * 0.5 * k2);\n    --  !  k4 := f (x + h *       k3);\n    --  !  x := x + h * (1.0/6.0) * (k1 + 2.0 * k2 + 2.0 * k3 + k4);\n    --\n    f (x, k1);\n    --\n    Times (h * 0.5, k1, tmp_a);\n    Plus (x, tmp_a, tmp_b);      --  tmp_b = x + h * 0.5 * k1\n    f (tmp_b, k2);\n    --\n    Times (h * 0.5, k2, tmp_a);\n    Plus (x, tmp_a, tmp_b);      --  tmp_b = x + h * 0.5 * k2\n    f (tmp_b, k3);\n    --\n    Times (h, k3, tmp_a);\n    Plus (x, tmp_a, tmp_b);      --  tmp_b = x + h * k3\n    f (tmp_b, k4);\n    --\n    Times (2.0, k2, dbk2);\n    Times (2.0, k3, dbk3);\n    Plus (k1, dbk2, tmp_a);\n    Plus (tmp_a, dbk3, tmp_b);\n    Plus (tmp_b, k4, tmp_a);     --  tmp_a = (k1 + 2.0 * k2 + 2.0 * k3 + k4)\n    Times (h * (1.0 / 6.0), tmp_a, tmp_b);\n    Plus (x, tmp_b, tmp_a);\n    x := tmp_a;\n  end Evolution;\n\n  procedure Simulation (sim_output : VString) is\n    --  ! use Ada.Text_IO, Ada.Integer_Text_IO, PFIO;\n    x, q_e : Lake_Vector;\n    q_sb, h : Real;\n    n_iter : Integer;\n    out_step : Integer;\n    rf : File_Type;\n    sep : constant Character := ';';\n  begin\n    h := 3600.0;\n    n_iter := 24 * 20;\n    out_step := 3;\n\n    --  ! x := (Morat => 428.2, Neuchatel => 429.0, Bienne => 429.4);  --  Lake levels at time t = 0.\n    --  ! q_e := (Morat => 40.0, Neuchatel => 70.0, Bienne => 100.0);  --  Inflows (could be dynamic).\n    x (Morat)     := 428.2;\n    x (Neuchatel) := 429.0;\n    x (Bienne)    := 429.4;\n    q_e (Morat)     := 40.0;\n    q_e (Neuchatel) := 70.0;\n    q_e (Bienne)    := 100.0;\n    q_sb := 200.0;                                               --  Outflow (could be dynamic).\n\n    Create (rf, sim_output);\n    Put (rf, \"t\");\n    for l in Lake loop\n      Put (rf, sep);\n      Put (rf, Lake'Image (l));\n    end loop;\n    New_Line (rf);\n    for i in 0 .. n_iter loop\n      if i mod out_step = 0 then\n        Put (rf, i);\n        for l in Lake loop\n          Put (rf, sep);\n          Put (rf, x (l), 4, 5, 0);\n        end loop;\n        New_Line (rf);\n      end if;\n      Evolution (x, q_e, q_sb, h);\n    end loop;\n    Close (rf);\n  end Simulation;\n\n  sim_output : constant VString := +\"3_lakes_s.csv\";\n\nbegin\n  Put_Line (\"Three_Lakes_S Simulation\");\n  Put_Line (\"  -  predicting the levels of 3 interconnected lakes.\");\n  Put_Line (\"Output in : \" & sim_output);\n  Init_Sensitivity;\n  Simulation (sim_output);\n  Put_Line (\"Done\");\nend Three_Lakes_S;\n"
  },
  {
    "path": "exm/timing.adb",
    "content": "with HAT;\n\nprocedure Timing is\n  use HAT;\n\n  procedure Simple is\n    T1 : constant Time := Clock;\n    T2 : Time;\n    D : Duration;\n    Day_Secs, Day_Mins : Integer;\n  begin\n    Put_Line (Image (T1));\n    Day_Secs := Integer (Seconds (T1));\n    Day_Mins := Day_Secs / 60;\n    Put_Line (\n      +\"More in detail... : Year = \" & Year (T1) &\n      \", Month = \" & Month (T1) &\n      \", Day = \" & Day (T1) &\n      \", Hour = \" & Day_Mins / 60 &\n      \", Minutes = \" & Day_Mins mod 60 &\n      \", Seconds = \" & Day_Secs mod 60\n      );\n    Put_Line (\"Waiting 3 seconds...\");\n    delay 1.0 + 4.0 * 0.5;  --  HAC interpreter can be interrupted during the \"delay\" statement.\n    T2 := Clock;\n    Put_Line (Image (T2));\n    D := T2 - T1 + 0.0 * 1.234;\n    Put_Line (Image (D));\n    D := D + 1.0;\n    D := D - 2.0 * 0.5;\n    Put_Line (Image (D));\n  end Simple;\n\nbegin\n  Simple;\nend Timing;\n"
  },
  {
    "path": "exm/triangles_overlap.adb",
    "content": "--  https://rosettacode.org/wiki/Determine_if_two_triangles_overlap\n--  This version is adapted to HAC's Ada subset.\n\nwith HAT;\n\nprocedure Triangles_Overlap is\n\n  use HAT;\n\n  subtype Vertex is Natural range 0 .. 2;\n  --  ^ Full Ada: type Vertex is mod 3;  (we simulate that with a range and explicit \"mod 3\"s)\n  type Point is array (1 .. 2) of Real;\n  type Triangle is array (Vertex) of Point;\n\n  function Same_Side (A, B, M, N : Point) return Boolean is\n  \n    function Z_of_Cross_Product_AB_AU (U : Point) return Real is\n    begin\n      return\n        (B (2) - A (2)) * (U (1) - A (1)) -\n        (B (1) - A (1)) * (U (2) - A (2));\n    end Z_of_Cross_Product_AB_AU;\n    \n  begin\n    --  If the Z-value of AB^AM and AB^AN have the same sign, or one or both is 0,\n    --  then the segment MN doesn't intersect the line containing segment AB.\n    return Z_of_Cross_Product_AB_AU (M) * Z_of_Cross_Product_AB_AU (N) >= 0.0;\n  end Same_Side;\n\n  function In_Side (t1, t2 : Triangle) return Boolean is\n    cond_1, cond_2 : Boolean;\n  begin\n    --  Simulate Ada 2012's \"for all v in Vertex =>\":\n    cond_1 := True;\n    for v1 in Vertex loop\n      --  Simulate Ada 2012's \"for some v2 in Vertex =>\":\n      cond_2 := False;\n      for v2 in Vertex loop\n        cond_2 := cond_2 or Same_Side (t1 ((v1 + 1) mod 3), t1 ((v1 + 2) mod 3), t1 (v1), t2 (v2));\n      end loop;\n      cond_1 := cond_1 and cond_2;\n    end loop;\n    return cond_1;\n  end In_Side;\n\n  function Overlap (t1, t2 : Triangle) return Boolean is\n  begin\n    return In_Side (t1, t2) and then In_Side (t2, t1);\n  end Overlap;\n\n  procedure To_Triangle (r1, r2, r3, r4, r5, r6 : Real; t : out Triangle) is\n  begin\n    t (0)(1) := r1;\n    t (0)(2) := r2;\n    t (1)(1) := r3;\n    t (1)(2) := r4;\n    t (2)(1) := r5;\n    t (2)(2) := r6;\n  end To_Triangle;\n\n  procedure Show (T1, T2 : Triangle) is\n  begin\n    Put_Line (Boolean'Image (Overlap (T1, T2)));  --  !!  Overlap (T1, T2)'Image not accepted by HAC ??\n  end Show;\n\n  t1, t2 : Triangle;\n\nbegin\n  To_Triangle (0.0, 0.0, 5.0, 0.0, 0.0, 5.0, t1); To_Triangle   (0.0, 0.0,  5.0,  0.0,  0.0, 6.0, t2); Show (t1, t2);\n  To_Triangle (0.0, 0.0, 0.0, 5.0, 5.0, 0.0, t1); To_Triangle   (0.0, 0.0,  0.0,  5.0,  5.0, 0.0, t2); Show (t1, t2);\n  To_Triangle (0.0, 0.0, 5.0, 0.0, 0.0, 5.0, t1); To_Triangle (-10.0, 0.0, -5.0,  0.0, -1.0, 6.0, t2); Show (t1, t2);\n  To_Triangle (0.0, 0.0, 5.0, 0.0, 2.5, 5.0, t1); To_Triangle   (0.0, 4.0,  2.5, -1.0,  5.0, 4.0, t2); Show (t1, t2);\n  To_Triangle (0.0, 0.0, 1.0, 1.0, 0.0, 2.0, t1); To_Triangle   (2.0, 1.0,  3.0,  0.0,  3.0, 2.0, t2); Show (t1, t2);\n  To_Triangle (0.0, 0.0, 1.0, 1.0, 0.0, 2.0, t1); To_Triangle   (2.0, 1.0,  3.0, -2.0,  3.0, 4.0, t2); Show (t1, t2);\n  To_Triangle (0.0, 0.0, 1.0, 0.0, 0.0, 1.0, t1); To_Triangle   (1.0, 0.0,  2.0,  0.0,  1.0, 1.0, t2); Show (t1, t2);\nend Triangles_Overlap;\n"
  },
  {
    "path": "exm/unit_a.adb",
    "content": "with Unit_B, Unit_C, HAT;\n\n--  GNAT compilation: gnatmake unit_a -I..\\src\n--  \"src\" is for getting the HAT package.\n\nprocedure Unit_A is\n  v : Integer;\n  a_msg : HAT.VString;\n\n  use HAT;\n\n  procedure X is\n  begin\n    Put (\"(x>\");\n    a_msg := +\"A\";\n    Unit_B (v, +\"b\", +\"B\");\n    v := v * 3;\n    Put (\"<x)\");\n  end X;\n\nbegin\n  Put_Line (\"Unit_A: demo of modularity features for subprograms.\");\n  Put_Line (\"------\");\n  Put_Line (\"  NB: the program and its output are nonsensical, but\");\n  Put_Line (\"  the output should be identical on all Ada implementations.\");\n  New_Line;\n  Put_Line (\"----[begin]----\");\n  v := 10101;\n  a_msg := +\"a\";\n  HAT.Put (+\"(a\" & a_msg & \">\");\n  for i in 1 .. 2 loop\n    Put (Image (Unit_C (+\"u\", +\"U\", v)));\n  end loop;\n  X;\n  Unit_B (v, +\"b\", +\"B\");\n  X;\n  HAT.Put (v, 0);\n  HAT.Put (\"<A\" & a_msg & \")\");\n  New_Line;\n  Put_Line (\"----[end]------\");\nend Unit_A;\n"
  },
  {
    "path": "exm/unit_b.adb",
    "content": "with Unit_C, Unit_E, Unit_F;\n\nprocedure Unit_B (n : in out Integer; title_1, title_2 : HAT.VString) is\n  use HAT;\n  b_msg : VString := +\"b\";\n  --\n  procedure Y is\n  begin\n    Put (\"(y>\");\n    Put (Image (Unit_C (+\"c\", +\"C\", n)));\n    HAT.Put (\"<y)\");\n    b_msg := +\"B\";\n  end Y;\n  procedure Y2 is\n  begin\n    Y;\n  end Y2;\nbegin\n  Put (+\"(\" & title_1 & b_msg & n & \">\");\n  Put (Image (Unit_C (+\"s\", +\"S\", n)));\n  Y2;\n  HAT.Put (+\"<\" & title_2 & b_msg & \")\");\n  Unit_E;\n  if n /= 777 then\n    Unit_F;\n  end if;\n  n := n * 2;\nend Unit_B;\n"
  },
  {
    "path": "exm/unit_b.ads",
    "content": "with HAT;\n\nprocedure Unit_B (n : in out Integer; title_1, title_2 : HAT.VString);\n"
  },
  {
    "path": "exm/unit_c.adb",
    "content": "with HAT;\n\nuse HAT;\n\nfunction Unit_C (title_1, title_2 : VString; n : Integer) return Real is\n  c_msg : VString;\n  procedure Z is\n  begin\n   c_msg := +\".C\";\n   Put (+\"z[\" & n & \"]\");\n  end Z;\nbegin\n  c_msg := +\".c\";\n  Put (+\"(\" & title_1 & c_msg & \">\");\n  Z;\n  Put (+\"<\" & title_2 & c_msg & \")\");\n  return Real (n);\nend Unit_C;\n"
  },
  {
    "path": "exm/unit_e.adb",
    "content": "with Unit_C;\nwith HAT;\n\nprocedure Unit_E is\n  use HAT;\nbegin\n  Put (Unit_C\n    (+\"Unit_C called from Unit_E\",\n     +\"Said otherwise: Unit_E calls Unit_C\",\n     123));\nend Unit_E;\n"
  },
  {
    "path": "exm/unit_f.adb",
    "content": "with Unit_B;\n\nprocedure Unit_F is\n  x : Integer := 777;\n  use HAT;  --  WITH'ed in unit_f.ads.\nbegin\n  Unit_B (x, +\" {Unit_B called from Unit_F} \", +\" {Value: 777} \");\n  Unit_G;  --  WITH'ed in unit_f.ads.\nend Unit_F;\n"
  },
  {
    "path": "exm/unit_f.ads",
    "content": "with Unit_G, HAT;\n\nprocedure Unit_F;\n"
  },
  {
    "path": "exm/unit_g.adb",
    "content": "with HAT;\n\nprocedure Unit_G is\nbegin\n  HAT.Put (\"__(G)__\");\nend Unit_G;\n"
  },
  {
    "path": "exm/unit_g.ads",
    "content": "procedure Unit_G;\n"
  },
  {
    "path": "fast.cmd",
    "content": "gprbuild %1 -P hac -XHAC_Build_Mode=Fast -XHAC_OS=Win64\n"
  },
  {
    "path": "hac.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the HAC project:\n--\n--      Home page:     http://hacadacompiler.sf.net/\n--      Project page:  http://sf.net/projects/hacadacompiler/\n--      Mirror:        https://github.com/zertovitch/hac\n--      Alire crate:   https://alire.ada.dev/crates/hac\n--\n--  Build me with \"gprbuild -P hac\", or \"gnatmake -P hac\",\n--  or open me with GNAT Studio.\n--\nproject HAC is\n\n   type HAC_Build_Mode_Type is\n     (\"Debug\",\n      \"Fast\",\n      \"Small\",\n      \"Small_Unchecked\",  --  Smallest size, at the price of less safety. Not for the release binary!\n      \"Profiling\");\n\n   HAC_Build_Mode : HAC_Build_Mode_Type := external (\"HAC_Build_Mode\", \"Debug\");\n\n   type HAC_OS_Kind is (\"Any\", \"Linux\", \"MacOSX\", \"Win32\", \"Win64\");\n\n   HAC_OS : HAC_OS_Kind := external (\"HAC_OS\", \"Any\");\n\n   for Main use\n     (\"hac.adb\",         --  Principal command-line tool\n      \"hac_mini.adb\",    --  Minimal version of hac.adb\n      \"hac_multi.adb\");  --  Parallel demo with many compilations\n\n   case HAC_Build_Mode is\n      when \"Debug\"           => for Object_Dir use \"obj/debug\";\n      when \"Fast\"            => for Object_Dir use \"obj/fast\";\n      when \"Small\"           => for Object_Dir use \"obj/small\";\n      when \"Small_Unchecked\" => for Object_Dir use \"obj/small_unchecked\";\n      when \"Profiling\"       => for Object_Dir use \"obj/profiling\";\n   end case;\n\n   for Source_Dirs use\n     (\"src\", \"src/apps\", \"src/compile\", \"src/compile/emit\", \"src/execute\", \"src/manage\");\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";  --  Flips by default the \"-p\" switch\n\n   package Pretty_Printer is\n      for Default_Switches (\"ada\") use (\"-i2\");\n   end Pretty_Printer;\n\n   type HAC_Styles_Checks_Type is (\"Off\", \"On\");\n\n   HAC_Styles_Checks : HAC_Styles_Checks_Type := external (\"HAC_Styles_Checks\", \"On\");\n\n   Compiler_Common_Options :=\n     (\"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n      \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n      \"-gnatwcijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n      \"-gnatf\",   --  Full errors. Verbose details, all undefined references\n      \"-gnatq\",   --  Don't quit, try semantics, even if parse errors\n      \"-gnatQ\",   --  Don't quit, write ali/tree file even if compile errors\n      \"-g\");      --  Generate debugging information\n\n   Style_Checks :=\n     (\"-gnatyaknpr\",  --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n      \"-gnatybfhiu\",  --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n      \"-gnatyx\",      --  Style: check x:no extra parens\n      \"-gnatye\",      --  Style: check e:end/exit labels present\n      \"-gnatytc\");    --  Style: check t:token separation rules, c:comment format (two spaces)\n\n   case HAC_Styles_Checks is\n      when \"Off\" => null;\n      when \"On\"  => Compiler_Common_Options := Compiler_Common_Options & Style_Checks;\n   end case;\n\n   Compiler_Debug_Options :=\n     (\"-gnata\",         --  Assertions enabled\n      \"-gnato\",         --  Enable overflow checking in STRICT mode\n      \"-gnatVa\",        --  Enable all validity checking options\n      \"-fstack-check\",\n      \"-fno-inline\") &\n     Compiler_Common_Options;\n\n   Compiler_Fast_Options :=\n     (\"-O2\",\n      \"-gnatpn\",\n      \"-fipa-cp-clone\",\n      \"-fgcse-after-reload\",\n      \"-funroll-loops\",\n      \"-fpeel-loops\",\n      \"-funswitch-loops\",\n      \"-ftracer\", \"-fweb\",\n      \"-ftree-vectorize\",\n      \"-frename-registers\",\n      \"-ffunction-sections\",\n      \"-fdata-sections\") &\n     Compiler_Common_Options;\n\n   Compiler_Small_Options :=\n     (\"-Os\"\n      --  Commented out: see remark in Check_No_Extra_Symbol.\n      --  \"-ffunction-sections\"\n      --  \"-fdata-sections\"\n      ) &\n     Compiler_Common_Options;\n\n   Compiler_Profiling_Options :=\n     (\"-O2\",\n      \"-gnatp\",\n      \"-fno-inline\",\n      \"-pg\") &\n     Compiler_Common_Options;\n\n   package Compiler is\n      case HAC_Build_Mode is\n         when \"Fast\"            =>\n           for Default_Switches (\"ada\") use Compiler_Fast_Options;\n         when \"Small\"           =>\n           for Default_Switches (\"ada\") use Compiler_Small_Options;\n         when \"Small_Unchecked\" =>\n           for Default_Switches (\"ada\") use Compiler_Small_Options & (\"-gnatp\");\n         when \"Profiling\"       =>\n           for Default_Switches (\"ada\") use Compiler_Profiling_Options;\n         when \"Debug\"           =>\n           for Default_Switches (\"ada\") use Compiler_Debug_Options;\n           for Local_Configuration_Pragmas use project'Project_Dir & \"debug.pra\";\n      end case;\n   end Compiler;\n\n   Binder_Common_Options := ();\n\n   case HAC_OS is\n      when \"Linux\" =>\n         Binder_Common_Options := Binder_Common_Options & \"-static\";  --  Ensures a consistent run-time library\n      when others  =>\n   end case;\n\n   package Binder is\n      --  -Es: Store tracebacks in exception occurrences, and enable symbolic tracebacks\n      for Default_Switches (\"ada\") use Binder_Common_Options & (\"-Es\");\n   end Binder;\n\n   Linker_Common_Options := (\"-g\");\n\n   case HAC_OS is\n      when \"Linux\" =>\n         Linker_Common_Options := Linker_Common_Options & \"-static\";  --  Ensures a consistent run-time library\n      when \"Win64\" =>\n         Linker_Common_Options :=\n            Linker_Common_Options & (\"obj/hac_icon.rbj\");\n      when \"MacOSX\" =>\n         Linker_Common_Options :=\n            Linker_Common_Options & (\"-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib\");\n            --  To overcome \"ld: library not found for -lSystem\"\n      when others  =>\n   end case;\n\n   Linker_Small_Options :=\n     Linker_Common_Options & (\"-Wl,--gc-sections\");\n\n   package Linker is\n      case HAC_Build_Mode is\n         when \"Debug\" =>\n           for Default_Switches (\"ada\") use Linker_Common_Options;\n         when \"Profiling\" =>\n           for Default_Switches (\"ada\") use Linker_Small_Options & (\"-pg\");\n         when \"Fast\" | \"Small\" | \"Small_Unchecked\" =>\n           for Default_Switches (\"ada\") use Linker_Small_Options;\n      end case;\n   end Linker;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-j0\");\n   end Builder;\n\n   package Ide is\n      for Default_Switches (\"adacontrol\") use (\"-f\", \"test/verif_hac.aru\", \"-r\");\n   end Ide;\n\nend HAC;\n"
  },
  {
    "path": "profiling.cmd",
    "content": "call go17\n\ngprbuild -P hac -XHAC_Build_Mode=Profiling -XHAC_OS=Win32\n\ncd exm\\aoc\\2022\n..\\..\\..\\hac -c -v2 aoc_2022_21.adb \n\ncopy gmon.out ..\\..\\..\ndel gmon.out\ncd ..\\..\\..\ngprof hac.exe >hac_profile.txt\n"
  },
  {
    "path": "readme.md",
    "content": "# HAC - HAC Ada Compiler\n\nHAC is perhaps the first open-source (albeit very\npartial) Ada compiler fully programmed in Ada itself.\n\n**Complete description in: `doc/hac.txt`**\n\n### Command-line flavor:\n\nIf you are impatient: in Alire (https://alire.ada.dev/),\ndo \"alr get hac\", then \"alr run\" from the hac* directory.\n\nAlternatively: have GNAT installed (https://www.adacore.com/download),\nthen, on your preferred command-line interpreter:\n\n```\n  gnatmake -P hac\n\n  cd exm\n  ../hac gallery.adb\n```\n\n(if `gnatmake` doesn't work, try `gprbuild`;\n for Windows, '\\\\' is meant in place of '/' )\n\n### Editor / pre-built flavor:\n\nOr, if you don't want to touch the command-line at all for playing\nwith HAC, you can download and use LEA (http://l-e-a.sf.net/).\n\n### Examples\nYou'll find hundreds of examples in the `exm` directory and\nits subdirectories.\n\nHere is the famous Hello World! File `hello.adb`:\n\n```Ada\nwith HAT;\n\nprocedure Hello is\nbegin\n  HAT.Put (\"Hello world!\");\nend Hello;\n```\n\nAnother classic example (file `fibo.adb`):\n\n```Ada\nwith HAT;\n\nprocedure Fibo is\n\n  function Fibonacci (P : Natural) return Positive is\n  begin\n    if P <= 2 then\n      return 1;\n    else\n      return Fibonacci (P - 1) + Fibonacci (P - 2);\n    end if;\n  end Fibonacci;\n\n  use HAT;\n\nbegin\n  for i in 1 .. 22 loop\n    Put_Line (Fibonacci (i));\n  end loop;\nend Fibo;\n```\n\nEnjoy!\n\n### License\n\nHAC is free, open-source and released under the MIT license.\n"
  },
  {
    "path": "save.hac",
    "content": "--#!/usr/bin/env hac\n\n--  Local backup Ada shell script for the HAC project.\n--\n--  This script works both with HAC (command: hac save.adb)\n--  and a full Ada compiler like GNAT, and that on different\n--  Operating Systems: Linux and Windows at least.\n--\n--  A \"shebang\" for Unix/Linux, such as \"#!/usr/bin/env hac\" can be\n--  added on the top line of this file.\n--  HAC will ignore it, but GNAT won't like it (that's normal).\n--\n--  The extension for the main procedure is a free choice.\n--  We choose \".hac\" so we can associate the \".hac\" files by\n--  default with hac.exe on Windows, for Explorer *and* command-line!\n--    Explorer: double-click / hit Return on \"save.hac\".\n--    Cmd / PowerShell: type \"save.hac\" and hit Return.\n\nwith HAT;\n\nprocedure Save is\n\n  use HAT;\n\n  function Nice_Date (with_intraday : Boolean) return VString is\n    t1 : constant Time := Clock;\n    day_secs, day_mins : Integer;\n    just_day : VString;\n    --\n    function Two_Digits (x : Integer) return VString is\n    begin\n      if x < 10 then\n        return \"0\" & Image (x);\n      else\n        return Image (x);\n      end if;\n    end Two_Digits;\n    --\n  begin\n    day_secs := Integer (Seconds (t1));\n    day_mins := day_secs / 60;\n    just_day := +\"\" &  --  VString concatenation\n      Year (t1)  & '-' &\n      Two_Digits (Month (t1)) & '-' &\n      Two_Digits (Day (t1));\n    if with_intraday then\n      return just_day & \"--\" &\n      Two_Digits (day_mins / 60) & '-' &\n      Two_Digits (day_mins mod 60) & '-' &\n      Two_Digits (day_secs mod 60);\n    else\n      return just_day;\n    end if;\n  end Nice_Date;\n\n  root, demos, examples, files, tests : VString;\n  zip_res : Integer;\n  sep : constant Character := Directory_Separator;\n\nbegin\n  Put_Line (\"Save date: \" & Nice_Date (True));\n  Put_Line (\"Current directory: \" & Current_Directory);\n  Put_Line (\"-----\");\n  root := Tail_After_Match (Current_Directory, sep);\n\n  Set_Directory (\"..\");\n\n  demos := root & \"/demo/data_exchange/*.ad* \" &\n           root & \"/demo/data_exchange_simple/*.ad* \" &\n           root & \"/demo/*.gpr \" &\n           root & \"/demo/*.prj \";\n\n  examples := root & \"/exm/*.ad* \"  &\n              root & \"/exm/*.gpr  \" & root & \"/exm/*.prj  \" &\n              root & \"/exm/e.cmd \"  &\n              root & \"/exm/not_working/*.ad* \" &\n              root & \"/exm/pdf/*.ad* \" &\n              root & \"/exm/tasking/*.ad* \" &\n              --\n              root & \"/exm/aoc/2020/aoc*.ad* \" &\n              root & \"/exm/aoc/2020/aoc*.txt \" &\n              root & \"/exm/aoc/2020/aoc*.gpr \" &\n              root & \"/exm/aoc/2020/aoc*.prj \" &\n              --\n              root & \"/exm/aoc/2021/aoc*.ad* \" &\n              root & \"/exm/aoc/2021/aoc*.txt \" &\n              root & \"/exm/aoc/2021/aoc*.gpr \" &\n              --\n              root & \"/exm/aoc/2022/aoc*.ad* \" &\n              root & \"/exm/aoc/2022/aoc*.txt \" &\n              root & \"/exm/aoc/2022/aoc*.gpr \" &\n              --\n              root & \"/exm/aoc/2023/aoc*.ad* \" &\n              root & \"/exm/aoc/2023/aoc*.txt \" &\n              root & \"/exm/aoc/2023/aoc*.gpr \" &\n\n              root & \"/exm/mathe_kal/2022/m*.ad* \" &\n              root & \"/exm/mathe_kal/2022/m*.gpr \";\n\n  tests    := root & \"/test/*.ad* \" &\n              root & \"/test/*.gpr \" & root & \"/test/*.prj \" &\n              root & \"/test/t.cmd \" &\n              root & \"/test/tf.cmd \" &\n              root & \"/test/*.aru \" &\n              root & \"/test/future/*.ad* \";\n\n  files := root & \"/src/*.ad* \" &\n           root & \"/src/apps/*.ad* \" &\n           root & \"/src/compile/*.ad* \" &\n           root & \"/src/compile/emit/*.ad* \" &\n           root & \"/src/execute/*.ad* \" &\n           root & \"/src/manage/*.ad* \" &\n           root & \"/*.gpr \" &\n           root & \"/*.prj \" &\n           root & \"/*.hac \" &\n           root & \"/build.cmd \" &\n           root & \"/fast.cmd \" &\n           root & \"/small.cmd \" &\n           root & \"/*.txt \" &\n           root & \"/doc/hac*.txt \" &\n           root & \"/doc/hac*.xls \" &\n           root & \"/doc/hac*.pdf \" &\n           root & \"/debug.pra \" &\n           root & \"/obj/hac_icon* \" &\n           root & \"/obj/debug/create_dir.txt \" &\n           root & \"/obj/fast/create_dir.txt \";\n\n  files := files & ' ' & demos & ' ' & examples & ' ' & tests;\n\n  --  The ZipAda command-line tool can be built or downloaded\n  --  from the project Zip-Ada @\n  --    https://unzip-ada.sourceforge.io/ ,\n  --    https://github.com/zertovitch/zip-ada\n  --  or from ALIRE (Ada LIbrary REpository) @ https://alire.ada.dev/\n  --\n  Shell_Execute (\"zipada -ep2 \" & root & sep & root & '-' & Nice_Date (True) & \"- \" & files, zip_res);\n  if zip_res = 0 then\n    Put_Line (\"Zip archive creation successful\");\n  else\n    Put_Line (\"Zip archive creation failed\");\n  end if;\n\n  Set_Directory (root);\n\n  Put (\"Press Return \");\n  Skip_Line;\n\nend Save;\n"
  },
  {
    "path": "save_modif.hac",
    "content": "--  #!/usr/bin/env hac\n--\n--  Local backup Ada shell script for a version-controlled repository.\n--\n--  This HAC script detects changes between two commits and\n--  saves the repository's modified files into a Zip-ball.\n--\n--  Version Control Systems supported:\n--  git, hg (mercurial), svn (subversion)\n--\n--  This is a HAC script *and* an Ada program.\n--  How to run it is your choice.\n--\n--  Usage with the HAC command-line tool :\n--\n--    hac save_modif.hac\n--\n--  The HAC (HAC Ada Compiler) command-line tool can be found @\n--    https://hacadacompiler.sourceforge.io/ ,\n--    https://github.com/zertovitch/hac\n--\n--  This program works both with HAC (command: hac save.hac)\n--  and a full Ada compiler like GNAT, and that on different\n--  Operating Systems: Linux and Windows at least.\n--\n--  The extension for the main procedure is a free choice.\n--  We choose \".hac\" so we can associate the \".hac\" files by\n--  default with hac.exe on Windows, for Explorer *and* command-line!\n--    Explorer: double-click / hit Return on \"save_modif.hac\".\n--    Cmd / PowerShell: type \"save_modif.hac\" and hit Return.\n\nwith HAT;\n\nprocedure Save_Modif is\n\n  use HAT;\n\n  function Nice_Date (with_intraday : Boolean) return VString is\n    t1 : constant Time := Clock;\n    day_secs, day_mins : Integer;\n    just_day : VString;\n    --\n    function Two_Digits (x : Integer) return VString is\n    begin\n      if x < 10 then\n        return \"0\" & Image (x);\n      else\n        return Image (x);\n      end if;\n    end Two_Digits;\n    --\n  begin\n    day_secs := Integer (Seconds (t1));\n    day_mins := day_secs / 60;\n    just_day := +\"\" &  --  VString concatenation\n      Year (t1)  & '-' &\n      Two_Digits (Month (t1)) & '-' &\n      Two_Digits (Day (t1));\n    if with_intraday then\n      return just_day & \"--\" &\n      Two_Digits (day_mins / 60) & '-' &\n      Two_Digits (day_mins mod 60) & '-' &\n      Two_Digits (day_secs mod 60);\n    else\n      return just_day;\n    end if;\n  end Nice_Date;\n\n  line, nd, root, mod_zip, files : VString;\n  f : File_Type;\n\n  log_name : constant VString := +\"modif.log\";\n  sep : constant Character := Directory_Separator;\n\n  type VCS_Type is (None, Git, Mercurial, Subversion);\n\n  function Detect_VCS return VCS_Type is\n  begin\n    if Directory_Exists (\".git\") then\n      return Git;\n    elsif Directory_Exists (\".hg\") then\n      return Mercurial;\n    elsif Directory_Exists (\".svn\") then\n      return Subversion;\n    end if;\n    return None;\n  end Detect_VCS;\n\n  function Abbreviation (vcs : VCS_Type) return VString is\n  begin\n    case vcs is\n      when Git        => return +\"git\";\n      when Mercurial  => return +\"hg\";\n      when Subversion => return +\"svn\";\n      when None       => return +\"\";\n    end case;\n  end Abbreviation;\n\n  vcs : constant VCS_Type := Detect_VCS;\n  col_name : Integer;\n  add_line : Boolean;\n\nbegin\n  Put_Line (\"Save date: \" & Nice_Date (True));\n  Put_Line (\"Version Control System: \" & VCS_Type'Image (vcs));\n  Put_Line (\"-----\");\n  root := Tail_After_Match (Current_Directory, sep);\n  files := root & sep & log_name;\n\n  case vcs is\n    when Git        => Shell_Execute (+\"git status -s -uno >\" & log_name); col_name := 4;\n    when Mercurial  => Shell_Execute (+\"hg  status    -q   >\" & log_name); col_name := 3;\n    when Subversion => Shell_Execute (+\"svn status    -q   >\" & log_name); col_name := 9;\n    when None =>\n      Put (\"Nothing to do! Press Return\");\n      Skip_Line;\n      return;\n  end case;\n\n  Open (f, log_name);\n  while not End_Of_File (f) loop\n    Get_Line (f, line);\n    if Length (line) > 3 and then not Ends_With (line, \".out\") then\n      add_line := False;\n      for col_tag in 1 .. 2 loop  --  Git tags are on two columns\n        case Element (line, col_tag) is\n          when ' ' | 'D' | 'R' | '!' =>\n            --  Ignore extra lines, or missing items, or items to be Deleted / Removed\n            null;\n          when others =>\n            add_line := True;\n        end case;\n      end loop;\n      if add_line then\n        line := root & sep & Slice (line, col_name, Length (line));\n        Put_Line (line);\n        files := files & ' ' & line;\n      end if;\n    end if;\n  end loop;\n  Close (f);\n  Put_Line (\"-----\");\n  New_Line;\n\n  --  Shell_Execute (\"echo . >>\" & log_name);\n  --  Shell_Execute (\"echo --- SVN Info --- >>\" & log_name);\n  --  Shell_Execute (\"svn info >>\" & log_name);\n\n  nd := Nice_Date (True);\n\n  mod_zip := root & sep & root & \"-modif-\" & Abbreviation (vcs) & '-' & nd & \".zip\";\n\n  Set_Directory (\"..\");\n  Shell_Execute (\"zipada -ep2 \" & mod_zip & ' ' & files);\n  Set_Directory (root);\n  --  Delete_File (log_name);\n\n  Put (\"Press Return \");\n  Skip_Line;\nend Save_Modif;\n"
  },
  {
    "path": "save_modif_and_untracked.hac",
    "content": "--  #!/usr/bin/env hac\n\n--  This HAC script detects changes between two commits and\n--  saves the repository's modified and untracked files into a Zip-ball.\n--\n--  Version Control Systems supported:\n--  git, hg (mercurial), svn (subversion)\n\nwith HAT;\n\nprocedure Save_Modif_and_Untracked is\n\n  use HAT;\n\n  function Nice_Date (with_intraday : Boolean) return VString is\n    t1 : constant Time := Clock;\n    day_secs, day_mins : Integer;\n    just_day : VString;\n    --\n    function Two_Digits (x : Integer) return VString is\n    begin\n      if x < 10 then\n        return \"0\" & Image (x);\n      else\n        return Image (x);\n      end if;\n    end Two_Digits;\n    --\n  begin\n    day_secs := Integer (Seconds (t1));\n    day_mins := day_secs / 60;\n    just_day := +\"\" &  --  VString concatenation\n      Year (t1)  & '-' &\n      Two_Digits (Month (t1)) & '-' &\n      Two_Digits (Day (t1));\n    if with_intraday then\n      return just_day & \"--\" &\n      Two_Digits (day_mins / 60) & '-' &\n      Two_Digits (day_mins mod 60) & '-' &\n      Two_Digits (day_secs mod 60);\n    else\n      return just_day;\n    end if;\n  end Nice_Date;\n\n  line, nd, root, mod_zip, files : VString;\n  f : File_Type;\n\n  log_name : constant VString := +\"modif.log\";\n  sep : constant Character := Directory_Separator;\n\n  type VCS_Type is (None, Git, Mercurial, Subversion);\n\n  function Detect_VCS return VCS_Type is\n  begin\n    if Directory_Exists (\".git\") then\n      return Git;\n    elsif Directory_Exists (\".hg\") then\n      return Mercurial;\n    elsif Directory_Exists (\".svn\") then\n      return Subversion;\n    end if;\n    return None;\n  end Detect_VCS;\n\n  function Abbreviation (vcs : VCS_Type) return VString is\n  begin\n    case vcs is\n      when Git        => return +\"git\";\n      when Mercurial  => return +\"hg\";\n      when Subversion => return +\"svn\";\n      when None       => return +\"\";\n    end case;\n  end Abbreviation;\n\n  vcs : constant VCS_Type := Detect_VCS;\n  col_name : Integer;\n  add_line : Boolean;\n\nbegin\n  Put_Line (\"Save date: \" & Nice_Date (True));\n  Put_Line (\"Version Control System: \" & VCS_Type'Image (vcs));\n  Put_Line (\"-----\");\n  root := Tail_After_Match (Current_Directory, sep);\n  --  files := root & sep & log_name;\n\n  case vcs is\n    when Git        => Shell_Execute (+\"git status -s -uno >\" & log_name); col_name := 4;\n    when Mercurial  => Shell_Execute (+\"hg  status         >\" & log_name); col_name := 3;\n    when Subversion => Shell_Execute (+\"svn status         >\" & log_name); col_name := 9;\n    when None =>\n      Put (\"Nothing to do! Press Return\");\n      Skip_Line;\n      return;\n  end case;\n\n  Open (f, log_name);\n  while not End_Of_File (f) loop\n    Get_Line (f, line);\n    if Length (line) > 3 then\n      add_line := False;\n      for col_tag in 1 .. 2 loop  --  Git tags are on two columns\n        case Element (line, col_tag) is\n          when ' ' | 'D' | 'R' | '!' =>\n            --  Ignore extra lines, or missing items, or items to be Deleted / Removed\n            null;\n          when others =>\n            add_line := True;\n        end case;\n      end loop;\n      if add_line then\n        line := root & sep & Slice (line, col_name, Length (line));\n        Put_Line (line);\n        files := files & ' ' & line;\n      end if;\n    end if;\n  end loop;\n  Close (f);\n  Put_Line (\"-----\");\n  New_Line;\n\n  --  Shell_Execute (\"echo . >>\" & log_name);\n  --  Shell_Execute (\"echo --- SVN Info --- >>\" & log_name);\n  --  Shell_Execute (\"svn info >>\" & log_name);\n\n  nd := Nice_Date (True);\n\n  mod_zip := root & sep & root & \"-modif-untracked-\" & Abbreviation (vcs) & '-' & nd & \".zip\";\n\n  Set_Directory (\"..\");\n  Shell_Execute (\"zipada -ep2 \" & mod_zip & ' ' & files);\n  --  Shell_Execute (\"7z t \" & mod_zip);\n  Set_Directory (root);\n  Delete_File (log_name);\n\n  Put (\"Press Return \");\n  Skip_Line;\nend Save_Modif_and_Untracked;\n"
  },
  {
    "path": "small.cmd",
    "content": "@echo off\necho Build...\ndel hac*.exe\ngprbuild -P hac hac       -XHAC_Build_Mode=Small_Unchecked -XHAC_OS=Win64\ncopy /B hac.exe hac_unchecked.exe\ndel hac.exe\ngprbuild -P hac           -XHAC_Build_Mode=Small           -XHAC_OS=Win64\ndel demo\\*.exe\ngprbuild -P demo/hac_demo -XHAC_Build_Mode=Small           -XHAC_OS=Win64\n\necho.\nfor %%I in (hac*.exe) do echo %%~zI ... %%I\nfor %%I in (demo\\*.exe) do echo %%~zI ... %%I\n\necho.\necho Stripping...\nstrip -s hac*.exe\nstrip -s demo/*.exe\n\necho Done.\necho.\nfor %%I in (hac*.exe) do echo %%~zI ... %%I\nfor %%I in (demo\\*.exe) do echo %%~zI ... %%I\n"
  },
  {
    "path": "src/apps/hac.adb",
    "content": "--  HAC: command-line build and execution tool for HAC (HAC Ada Compiler)\n--  Usage, license etc. : see `Help` below and the HAC_Sys package (hac_sys.ads).\n--  For a small version, see HAC_Mini (hac_mini.adb).\n--\n\nwith HAC_Pkg;\n\nwith HAC_Sys.Builder,\n     HAC_Sys.Co_Defs,\n     HAC_Sys.Defs,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\nwith HAT;\n\nwith Ada.Calendar,\n     Ada.Command_Line,\n     Ada.Text_IO;\n\nprocedure HAC is\n\n  cmp_dump_file_name : HAT.VString;\n  asm_dump : Boolean := False;\n  remarks : HAC_Sys.Defs.Remark_Set := HAC_Sys.Defs.default_remarks;\n\n  use HAC_Pkg;\n\n  procedure Compile_and_interpret_file (Ada_file_name : String; arg_pos : Positive) is\n    use Ada.Calendar, Ada.Text_IO;\n\n    source_stream   : HAC_Sys.Co_Defs.Source_Stream_Access;\n    t1, t2          : Ada.Calendar.Time;\n    BD              : HAC_Sys.Builder.Build_Data;\n    shebang_offset  : Natural := 0;\n\n    trace : constant HAC_Sys.Co_Defs.Compilation_Trace_Parameters :=\n      (pipe         => null,\n       progress     => Compilation_Feedback'Access,\n       detail_level => verbosity);\n\n    cat : aliased Path_Management.File_Catalogue;\n\n  begin\n    main_Ada_file_name := HAT.To_VString (Ada_file_name);\n    if verbosity > 1 then\n      New_Line;\n      Put_Line (HAC_margin_1 & \"HAC is free and open-source. Type \"\"hac\"\" for license.\");\n    end if;\n    cat.Source_Open (Ada_file_name, source_stream);\n    cat.Skip_Shebang (Ada_file_name, shebang_offset);\n    BD.Set_Diagnostic_Parameters (asm_dump, HAT.To_String (cmp_dump_file_name));\n    BD.Set_Remark_Set (remarks);\n    BD.Set_Main_Source_Stream (source_stream, Ada_file_name, shebang_offset);\n    BD.Set_Message_Feedbacks (trace);\n    BD.Set_Target (target);\n    BD.Set_File_Catalogue (cat'Unchecked_Access);\n    t1 := Clock;\n    BD.Build_Main;\n    t2 := Clock;\n    cat.Close (Ada_file_name);\n    if verbosity >= 2 then\n      Put_Line (\n        HAC_margin_2 & \"Build finished in\" &\n        Duration'Image (t2 - t1) &\n        \" seconds.\" &\n        Integer'Image (BD.Total_Compiled_Lines) & \" lines compiled in total.\"\n      );\n    end if;\n    --\n    if not BD.Build_Successful then\n      PLCE (\"Errors found, build failed.\");\n      HAC_Pkg.Failure;\n      return;\n    end if;\n    if verbosity >= 2 then\n      Put_Line (HAC_margin_2 & \"Target . : \" & BD.CD.target.Name);\n      Put_Line (HAC_margin_2 & \"CPU  . . : \" & BD.CD.target.CPU);\n      Put_Line (HAC_margin_2 & \"OS . . . : \" & BD.CD.target.OS);\n      --\n      if BD.CD.Is_HAC_VM then\n        Put_Line\n          (HAC_margin_2 & \"Object code size:\" &\n             Natural'Image (BD.Object_Code_Size) &\n             \" of\" &\n             Natural'Image (HAC_Sys.Builder.Maximum_Object_Code_Size) &\n             \" Virtual Machine instructions.\");\n        if BD.Folded_Instructions + BD.Specialized_Instructions > 0 then\n          Put_Line (HAC_margin_2 & \"Code optimization:\");\n          Put_Line\n            (HAC_margin_2 & \"  \" & Natural'Image (BD.Folded_Instructions) &\n               \" instructions folded\");\n          Put_Line\n            (HAC_margin_2 & \"  \" & Natural'Image (BD.Specialized_Instructions) &\n               \" instructions specialized\");\n        end if;\n      end if;\n    end if;\n    Post_Build (BD);\n    if compile_only then\n      null;\n    elsif BD.CD.Is_Executable then\n      Run (BD, arg_pos);\n    else\n      PLCE (\"Can only execute a parameterless procedure\");\n    end if;\n  exception\n    when Name_Error =>\n      PLCE\n        (HAC_margin_3 &\n         \"Error: file \"\"\" & Ada_file_name &\n         \"\"\" not found (perhaps in exm or test subdirectory ?)\");\n      HAC_Pkg.Failure;\n  end Compile_and_interpret_file;\n\n  hac_ing    : Boolean  := False;\n  quit       : Boolean  := False;\n  help_level : Positive := 1;\n\n  procedure Argument_Error (msg : String) is\n  begin\n    PLCE (msg);\n    NLCE;\n    quit := True;\n    delay 1.0;\n  end Argument_Error;\n\n  procedure Process_Argument (arg : String; arg_pos : Positive) is\n    opt : constant String := arg (arg'First + 1 .. arg'Last);\n    unknown_remark : Boolean;\n    use HAC_Sys.Defs, HAT;\n  begin\n    if arg (arg'First) = '-' then\n      if opt'Length = 0 then\n        Argument_Error (\"Missing option code after '-'\");\n        return;\n      end if;\n      case opt (opt'First) is\n        when 'a' =>\n          asm_dump := True;\n        when 'c' =>\n          compile_only := True;\n        when 'd' =>\n          cmp_dump_file_name := To_VString (compiler_dump_name);\n        when 'h' =>\n          if opt'Length > 1 and then opt (opt'First + 1) = '2' then\n            help_level := 2;\n          end if;\n          quit := True;\n        when 't' =>\n          if opt'Length = 1 then\n            Argument_Error (\"Missing target\");\n          else\n            declare\n              new_target_name : constant String := opt (opt'First + 1 .. opt'Last);\n            begin\n              Set_Target (new_target_name);\n            exception\n              when Constraint_Error =>\n                Argument_Error (\"Unknown target \" & new_target_name);\n            end;\n          end if;\n        when 'r' =>\n          if opt'Length = 1 then\n            Argument_Error (\"Missing remark switch\");\n          else\n            for letter in opt'First + 1 .. opt'Last loop\n              if opt (letter) in '0' .. '3' then\n                remarks := preset_remarks (Remark_Level'Value (opt (letter .. letter)));\n              else\n                unknown_remark := True;\n                for r in HAC_Sys.Defs.Compile_Remark loop\n                  if HAC_Sys.Defs.remark_letter (r) = opt (letter) then\n                    remarks (r) := True;\n                    unknown_remark := False;\n                  elsif To_Upper (HAC_Sys.Defs.remark_letter (r)) = opt (letter) then\n                    remarks (r) := False;\n                    unknown_remark := False;\n                  end if;\n                end loop;\n                if unknown_remark then\n                  Argument_Error (\"Unknown remark switch '\" & opt (letter) & ''');\n                  exit;\n                end if;\n              end if;\n            end loop;\n          end if;\n        when 'I' =>\n          if command_line_source_path /= \"\" then\n            command_line_source_path := command_line_source_path & ';';\n          end if;\n          command_line_source_path :=\n            command_line_source_path & To_VString (opt (opt'First + 1 .. opt'Last));\n        when 'v' =>\n          verbosity := 1;\n          if opt'Length > 1 and then opt (opt'First + 1) in '0' .. '9' then\n            verbosity := Character'Pos (opt (opt'First + 1)) - Character'Pos ('0');\n          end if;\n        when others =>\n          Argument_Error (\"Unknown option: \"\"\" & arg & '\"');\n      end case;\n    else\n      Compile_and_interpret_file (arg, arg_pos);\n      hac_ing := True;\n      quit := True;  --  The other arguments are for the HAC program.\n    end if;\n  end Process_Argument;\n\n  use Ada.Command_Line;\n\nbegin\n  for i in 1 .. Argument_Count loop\n    Process_Argument (Argument (i), i);\n    exit when quit;\n  end loop;\n  if not hac_ing then\n    Help (help_level);\n    if verbosity > 1 then\n      Ada.Text_IO.Put_Line (\"Size of a HAC VM memory unit:\" &\n        Integer'Image (HAC_Sys.PCode.Interpreter.In_Defs.Data_Type'Size / 8) &\n        \" bytes\"\n      );\n    end if;\n  end if;\nend HAC;\n"
  },
  {
    "path": "src/apps/hac_mini.adb",
    "content": "--  This is a minimalistic version of HAC, for showing the minimum code required\n--  to run HAC on a given Ada source file and display outputs on Standard_Output.\n--\n--  See HAC (hac.adb) for the full version of the command-line tool.\n\nwith Ada.Command_Line, Ada.Text_IO;\nwith HAC_Sys.Builder, HAC_Sys.PCode.Interpreter;\n\nprocedure HAC_Mini is\n  use Ada.Command_Line, Ada.Text_IO;\n  use HAC_Sys.PCode.Interpreter;\n  --\n  BD : HAC_Sys.Builder.Build_Data;\n  post_mortem : Post_Mortem_Data;\nbegin\n  if Argument_Count = 0 then\n    Put_Line (Current_Error, \"Usage: hac_mini main.adb\");\n  else\n\n    BD.Build_Main_from_File (Argument (1));\n\n    if BD.Build_Successful then\n\n      Interpret_on_Current_IO (BD, 1, \"\", post_mortem);\n\n      if Is_Exception_Raised (post_mortem.Unhandled) then\n        Put_Line (Current_Error, \"HAC VM: raised \" & Image (post_mortem.Unhandled));\n        Put_Line (Current_Error, Message (post_mortem.Unhandled));\n      end if;\n    end if;\n  end if;\nend HAC_Mini;\n"
  },
  {
    "path": "src/apps/hac_multi.adb",
    "content": "--  This is a demo of multiple instances of HAC running in parallel.\n--  Run as:   hac_multi >res_multi.csv\n--  and open the CSV file in your preferred spreadsheet software.\n--\n--  See HAC for the full version of the command-line tool.\n\nwith HAC_Sys.Builder,\n     HAC_Sys.Defs,\n     HAC_Sys.PCode.Interpreter;\n\nwith HAT;\n\nwith Ada.Calendar,\n     Ada.Command_Line,\n     Ada.Numerics.Float_Random,\n     Ada.Streams.Stream_IO,\n     Ada.Text_IO;\n\nprocedure HAC_Multi is\n\n  procedure Launch_Tasks is\n\n    use Ada.Text_IO;\n    sep : constant Character := ';';\n\n    task type HAC_Instance is\n      entry Start (id : Positive);\n    end HAC_Instance;\n\n    task body HAC_Instance is\n      use HAC_Sys.Builder, HAC_Sys.PCode.Interpreter;\n\n      procedure No_Put (Item : Character) is null;\n      procedure No_New_Line (Spacing : Positive_Count := 1) is null;\n\n      package Current_IO_Console is new\n        Console_Traits\n           (Ada.Text_IO.End_Of_File,\n            Ada.Text_IO.End_Of_Line,\n            Current_IO_Get_Needs_Skip_Line,\n            HAC_Sys.Defs.IIO.Get,\n            HAC_Sys.Defs.RIO.Get,\n            Ada.Text_IO.Get,\n            Ada.Text_IO.Get_Immediate,\n            Ada.Text_IO.Get_Line,\n            Ada.Text_IO.Skip_Line,\n            HAC_Sys.Defs.IIO.Put,\n            HAC_Sys.Defs.RIO.Put,\n            HAC_Sys.Defs.BIO.Put,\n            No_Put,  --  Ada.Text_IO.Put\n            Ada.Text_IO.Put,\n            No_New_Line  --  Ada.Text_IO.New_Line\n           );\n\n      package Custom_System_Calls is new\n        System_Calls_Traits\n           (Ada.Command_Line.Argument_Count,\n            Ada.Command_Line.Argument,\n            Ada.Command_Line.Command_Name,    --  Wrong but not used anyway in this demo.\n            HAT.Shell_Execute,\n            HAT.Shell_Execute,                --  This profile has an Output parameter.\n            HAT.Directory_Separator\n           );\n\n      use Ada.Calendar, Ada.Numerics.Float_Random, Ada.Streams.Stream_IO;\n\n      task_id : Positive;\n      tick : Time;\n      gen : Generator;\n\n      procedure Multi_Feedback (\n        Stack_Current, Stack_Total : in     Natural;\n        Wall_Clock                 : in     Ada.Calendar.Time;\n        User_Abort                 :    out Boolean\n      )\n      is\n      pragma Unreferenced (Stack_Current, Stack_Total);\n      begin\n        User_Abort := False;\n        if Wall_Clock - tick >= 0.005 then\n          if Random (gen) > 0.999 then\n            User_Abort := True;\n            Put_Line\n              (\"A1\" & sep & \" Task\" & sep &\n               Integer'Image (task_id) & sep\n               & \" wants to abort the HAC VM.\");\n          end if;\n          tick := Wall_Clock;\n        end if;\n      end Multi_Feedback;\n\n      procedure Interpret_for_Multi is new\n        Interpret\n           (Multi_Feedback,\n            Current_IO_Console,\n            Custom_System_Calls\n          );\n\n      Ada_file_name : constant String := \"exm/mandelbrot.adb\";\n      --\n      f : Ada.Streams.Stream_IO.File_Type;\n      BD : Build_Data;\n      post_mortem : Post_Mortem_Data;\n    begin\n      accept Start (id : Positive) do\n        task_id := id;\n      end Start;\n      tick := Clock;\n      Reset (gen);\n      --\n      Open (f, In_File, Ada_file_name);\n      Set_Main_Source_Stream (BD, Stream (f), Ada_file_name);\n      Build_Main (BD);\n      Close (f);\n      --\n      if Build_Successful (BD) then\n        Put_Line\n          (\"S\" & sep & \" Task\" & sep &\n           Integer'Image (task_id) & sep &\n           \" successful compilation. Running the VM.\");\n        Interpret_for_Multi (BD, post_mortem);\n        if Image (post_mortem.Unhandled) = \"User_Abort\" then\n          Put_Line\n            (\"A2\" & sep & \" Task\" & sep &\n             Integer'Image (task_id) & sep &\n             \" got \"\"User_Abort\"\" exception from HAC VM.\");\n        else\n          Put_Line\n            (\"D\" & sep & \" Task\" & sep &\n             Integer'Image (task_id) & sep & \" is done.\");\n        end if;\n      end if;\n    end HAC_Instance;\n\n    hacs : array (1 .. 20) of HAC_Instance;\n\n  begin\n    Put_Line (\"Event\" & sep & \"  Task #\" & sep & \"  Message\");\n    for T in hacs'Range loop\n      hacs (T).Start (T);\n      delay 0.01;\n    end loop;\n  end Launch_Tasks;\n\nbegin\n  Launch_Tasks;\nend HAC_Multi;\n"
  },
  {
    "path": "src/apps/hac_pkg.adb",
    "content": "with HAC_Sys.Defs,\n     HAC_Sys.PCode.Interpreter,\n     HAC_Sys.Targets.AMD64_Windows_Console_FASM;\n\nwith Show_MIT_License;\n\nwith Ada.Command_Line,\n     Ada.Containers,\n     Ada.Directories,\n     Ada.Exceptions,\n     Ada.Text_IO;\n\npackage body HAC_Pkg is\n\n  procedure Compilation_Feedback (message : String) is\n  begin\n    case verbosity is\n      when 0      => null;\n      when 1      => HAT.Put_Line (message);\n      when others => HAT.Put_Line (HAC_margin_2 & message);\n    end case;\n  end Compilation_Feedback;\n\n  package body Path_Management is\n\n    overriding function Exists (cat : File_Catalogue; name : String) return Boolean is\n    begin\n      return cat.Full_Source_Name (name) /= \"\";\n    end Exists;\n\n    overriding function Full_Source_Name (cat : File_Catalogue; name : String) return String is\n      --  Search order: same as GNAT's,\n      --  cf. 4.2.2 Search Paths and the Run-Time Library (RTL).\n      use Ada.Directories;\n    begin\n      --  0) The file name as such exists.\n      if HAC_Sys.Files.Default.File_Catalogue (cat).Exists (name) then\n        return name;\n      end if;\n      --  1) The directory containing the source file of the main unit\n      --     being compiled (the file name on the command line).\n      declare\n        fn : constant String :=\n          Ada.Directories.Containing_Directory (HAT.To_String (main_Ada_file_name)) &\n          HAT.Directory_Separator &\n          name;\n      begin\n        if Exists (fn) and then Kind (fn) = Ordinary_File then\n          return fn;\n        end if;\n      exception\n        when others => null;  --  Continue searching elsewhere.\n      end;\n      --  2) Each directory named by an -I switch given on the\n      --     hac command line, in the order given.\n      declare\n        fn : constant String :=\n          HAT.Search_File (name, HAT.To_String (command_line_source_path));\n      begin\n        if fn /= \"\" then\n          return fn;\n        end if;\n      end;\n      --  3) Omitted (directories listed in the text file whose name is given by ADA_PRJ_INCLUDE_FILE).\n      --  4) Each of the directories listed in the value of the ADA_INCLUDE_PATH environment variable.\n      declare\n        fn : constant String :=\n          HAT.Search_File (name, HAT.To_String (HAT.Get_Env (\"ADA_INCLUDE_PATH\")));\n      begin\n        if fn /= \"\" then\n          return fn;\n        end if;\n      end;\n      --  5) Omitted (content of the ada_source_path file).\n\n      --  Now, extra search capabilities specific to HAC:\n      declare\n        fn : constant String :=\n          HAT.Search_File (name, HAT.To_String (cat.extra_path));\n      begin\n        if fn /= \"\" then\n          return fn;\n        end if;\n      end;\n\n      return \"\";\n    end Full_Source_Name;\n\n    overriding function Is_Open (cat : File_Catalogue; name : String) return Boolean is\n    begin\n      return HAC_Sys.Files.Default.File_Catalogue (cat).Is_Open (cat.Full_Source_Name (name));\n    end Is_Open;\n\n    overriding procedure Source_Open\n      (cat         : in out File_Catalogue;\n       name        : in     String;\n       stream      :    out HAC_Sys.Files.Root_Stream_Class_Access)\n    is\n      ffn : constant String := cat.Full_Source_Name (name);\n    begin\n      if ffn = \"\" then\n        raise Ada.Directories.Name_Error;\n      else\n        HAC_Sys.Files.Default.File_Catalogue (cat).Source_Open (ffn, stream);\n      end if;\n    end Source_Open;\n\n    overriding procedure Skip_Shebang\n      (cat            : in out File_Catalogue;\n       name           : in     String;\n       shebang_offset :    out Natural) is\n    begin\n      HAC_Sys.Files.Default.File_Catalogue (cat).Skip_Shebang\n        (cat.Full_Source_Name (name),\n         shebang_offset);\n    end Skip_Shebang;\n\n    overriding procedure Close (cat : in out File_Catalogue; name : String) is\n    begin\n      HAC_Sys.Files.Default.File_Catalogue (cat).Close (cat.Full_Source_Name (name));\n    end Close;\n\n    overriding procedure Add_to_Source_Path (cat : in out File_Catalogue; new_dir : String) is\n      use HAT;\n    begin\n      cat.extra_path := cat.extra_path & ';' & new_dir;\n    end Add_to_Source_Path;\n\n  end Path_Management;\n\n  procedure PLCE (s : String) is\n    use Ada.Text_IO;\n  begin\n    Put_Line (Current_Error, s);\n  end PLCE;\n\n  procedure Option_Head (s : String) is\n  begin\n    NLCE;\n    PLCE (\"______\");\n    PLCE (\"Option \" & s);\n  end Option_Head;\n\n  procedure NLCE is\n    use Ada.Text_IO;\n  begin\n    New_Line (Current_Error);\n  end NLCE;\n\n  procedure Help (level : Positive) is\n    use HAC_Sys.Defs, Ada.Text_IO;\n    function Show_Level (r : Compile_Remark) return String is\n      (\" (from level\" & Minimum_Level (r)'Image & ')');\n  begin\n    PLCE (\"HAC: command-line build and execution tool for HAC (HAC Ada Compiler)\");\n    PLCE (version_info);\n    PLCE (\"Main URL: \"           & HAC_Sys.web);\n    PLCE (\"  Sources, site #1: \" & HAC_Sys.web2);\n    PLCE (\"  Sources, site #2: \" & HAC_Sys.web3);\n    PLCE (\"  Alire Crate: \"      & HAC_Sys.web4);\n    NLCE;\n    PLCE (\"Usage: hac [options] main.adb [command-line parameters for main]\");\n    NLCE;\n    PLCE (\"Options: -h, h1 : this help\");\n    PLCE (\"         -h2    : show more help & details about options\");\n    NLCE;\n    PLCE (\"         -a     : assembler output\");\n    PLCE (\"         -c     : compile only\");\n    PLCE (\"         -d     : dump compiler information in \" & compiler_dump_name);\n    PLCE (\"         -I     : specify source files search path\");\n    PLCE (\"         -rx    : enable / disable remarks\");\n    PLCE (\"         -tx    : target machine (default: HAC VM)\");\n    PLCE (\"         -v, v1 : verbose\");\n    PLCE (\"         -v2    : very verbose\");\n    NLCE;\n    PLCE (\"Note: HAC (this command-line tool) accepts source files with shebang's,\");\n    PLCE (\"      for instance:   #!/usr/bin/env hac     or     #!/usr/bin/hac\");\n    Show_MIT_License (Current_Error, \"hac_sys.ads\");\n    if level > 1 then\n      NLCE;\n      PLCE (\"/------------------------------------------\\\");\n      PLCE (\"| Extended help for HAC (command: hac -h2) |\");\n      PLCE (\"\\------------------------------------------/\");\n      Option_Head (\"-I : specify source files search path\");\n      NLCE;\n      PLCE (\"  The search path is a list of directories separated by commas (,) or semicolons (;).\");\n      PLCE (\"  HAC searches Ada source files in the following order:\");\n      PLCE (\"    1) The directory containing the source file of the main unit\");\n      PLCE (\"         being compiled (the file name on the command line).\");\n      PLCE (\"    2) Each directory named by an -I switch given on the\");\n      PLCE (\"         hac command line, in the order given.\");\n      PLCE (\"    3) Each of the directories listed in the value of the ADA_INCLUDE_PATH\");\n      PLCE (\"         environment variable.\");\n      Option_Head (\"-rx : enable remarks (warnings or notes) of kind x\");\n      PLCE (\"       -rX : disable remarks for letter x\");\n      PLCE (\"             x =\");\n      PLCE\n        (\"                 0 .. 3 : enable remarks of level x; default is\" &\n         default_remark_level'Image);\n      PLCE\n        (\"                 k :  notes for constant variables\" &\n         Show_Level (note_constant_variable));\n      PLCE\n        (\"                 r :  notes for redundant constructs\" &\n         Show_Level (note_redundant_construct));\n      PLCE\n        (\"                 u :  notes for unused items\" &\n         Show_Level (note_unused_item));\n      PLCE\n        (\"                 v :  warnings for uninitialized variables or parameters\" &\n         Show_Level (warn_read_but_not_written));\n      Option_Head (\"-tx : set target machine to x\");\n      PLCE (\"             x =\");\n      PLCE (\"                 amd64_windows_console_fasm\");\n      NLCE;\n    end if;\n    Ada.Text_IO.Put (\"Press Return\");\n    Ada.Text_IO.Skip_Line;\n  end Help;\n\n  type Target_List is\n    (hac_vm, amd64_windows_console_fasm);\n\n  target_choice : Target_List := hac_vm;\n\n  procedure Set_Target (name : String) is\n  begin\n    target_choice := Target_List'Value (name);\n    case target_choice is\n      when hac_vm =>\n        null;  --  Actual target in BD.CD is already initialized.\n      when amd64_windows_console_fasm =>\n        target := new HAC_Sys.Targets.AMD64_Windows_Console_FASM.Machine;\n    end case;\n  end Set_Target;\n\n  procedure Failure is\n    use HAT;\n  begin\n    if Ends_With (main_Ada_file_name, \".hac\") then\n      --  Main has the \"HAC script extension\", possibly run\n      --  from Explorer, Nautilus, etc.\n      Put (\"Failure in \" & main_Ada_file_name & \", press Return\");\n      Skip_Line;\n    end if;\n    Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);\n  end Failure;\n\n  procedure Run_HAC_VM (BD : in out HAC_Sys.Builder.Build_Data; arg_pos : Positive) is\n    use HAC_Sys.PCode.Interpreter, HAT;\n    use Ada.Containers;\n    --\n    procedure Show_Line_Information (\n      File_Name   : String;   --  Example: hac-pcode-interpreter.adb\n      Block_Name  : String;   --  Example: HAC.PCode.Interpreter.Do_Write_Formatted\n      Line_Number : Positive\n    )\n    is\n    begin\n      PLCE\n        (File_Name & \": \" &\n         Block_Name & \" at line\" &\n         Integer'Image (Line_Number));\n    end Show_Line_Information;\n    --\n    procedure CIO_Trace_Back is new Show_Trace_Back (Show_Line_Information);\n    --\n    post_mortem     : Post_Mortem_Data;\n    unhandled_found : Boolean;\n    t1, t2          : Time;\n  begin\n    if verbosity >= 1 then\n      New_Line;\n    end if;\n    t1 := Clock;\n    Interpret_on_Current_IO\n      (BD,\n       arg_pos,\n       Ada.Directories.Full_Name (To_String (main_Ada_file_name)),\n       post_mortem);\n    t2 := Clock;\n    unhandled_found := Is_Exception_Raised (post_mortem.Unhandled);\n    if verbosity >= 2 then\n      --  The \"if expression\" commented out here confuses ObjectAda 10.4.\n      --\n      --  Put_Line\n      --    (HAC_margin_3 &\n      --       (if unhandled_found then\n      --          \"VM interpreter stopped execution of \" &\n      --          Ada_file_name & \" due to an unhandled exception.\"\n      --        else\n      --          \"VM interpreter done after\" & Duration'Image (t2 - t1) & \" seconds.\"));\n      --\n      if unhandled_found then\n        Put_Line (\n          HAC_margin_3 & \"VM interpreter stopped execution of \" &\n            main_Ada_file_name & \" due to an unhandled exception.\");\n      else\n        Put_Line (\n          HAC_margin_3 & \"VM interpreter done after\" &\n          Duration'Image (t2 - t1) & \" seconds.\"\n        );\n      end if;\n    end if;\n    if unhandled_found then\n      PLCE (\"HAC VM: raised \" & Image (post_mortem.Unhandled));\n      PLCE (Message (post_mortem.Unhandled));\n      PLCE (\"Trace-back: approximate location\");\n      CIO_Trace_Back (post_mortem.Unhandled);\n      Failure;\n    elsif verbosity >= 1 then\n      Put_Line (\"Execution of \" & main_Ada_file_name & \" completed.\");\n    end if;\n    if verbosity >= 2 then\n      Put_Line (\n        \"Maximum stack usage:\" &\n        Integer'Image (post_mortem.Max_Stack_Usage) & \" of\" &\n        Integer'Image (post_mortem.Stack_Size) & \" memory units, around\" &\n        Integer'Image (100 * post_mortem.Max_Stack_Usage / post_mortem.Stack_Size) & \"%.\"\n      );\n    end if;\n    if verbosity >= 1 then\n      if post_mortem.Open_Files.Length > 0 then\n        Put_Line (\"List of files that were left open during execution:\");\n        for ofd of post_mortem.Open_Files loop\n          Put_Line\n           (\"  Name: \" & HAT.To_String (ofd.Name) &\n            \", mode: \" & Ada.Text_IO.File_Mode'Image (ofd.Mode));\n        end loop;\n      end if;\n    end if;\n  exception\n    when E : Abnormal_Termination =>\n      PLCE (\"Abnormal Termination (VM): \" & Ada.Exceptions.Exception_Message (E));\n      Failure;\n    when Ada.Text_IO.Name_Error =>\n      PLCE\n        (HAC_margin_3 &\n         \"Error: file \"\"\" & To_String (main_Ada_file_name) &\n         \"\"\" not found (perhaps in exm or test subdirectory ?)\");\n      Failure;\n  end Run_HAC_VM;\n\n  function Remaining_Arguments (arg_pos : Positive) return String is\n  (if arg_pos <= Ada.Command_Line.Argument_Count then\n     Ada.Command_Line.Argument (arg_pos) & Remaining_Arguments (arg_pos + 1)\n   else\n     \"\");\n\n  procedure Post_Build_amd64_windows_console_fasm\n    (BD : HAC_Sys.Builder.Build_Data)\n  is\n    use HAT;\n    use Ada.Directories;\n    main_base_name : constant String := Base_Name (To_String (main_Ada_file_name));\n  begin\n    Shell_Execute\n      (\"fasm \" &\n       BD.target.Assembler_File_Name &\n       ' ' &\n       main_base_name &\n       \".exe\");\n  end Post_Build_amd64_windows_console_fasm;\n\n  procedure Run_amd64_windows_console_fasm (arg_pos : Positive)\n  is\n    use HAT;\n    use Ada.Directories;\n    main_base_name : constant String := Base_Name (To_String (main_Ada_file_name));\n  begin\n    if Get_Env (\"OS\") = \"Windows_NT\" then\n      Shell_Execute (main_base_name & ' ' & Remaining_Arguments (arg_pos));\n    else\n      Put_Line (\"No run: build target (AMD64/Windows) is different than this system\");\n    end if;\n  end Run_amd64_windows_console_fasm;\n\n  procedure Post_Build (BD : in out HAC_Sys.Builder.Build_Data) is\n  begin\n    case target_choice is\n      when hac_vm                     => null;\n      when amd64_windows_console_fasm => Post_Build_amd64_windows_console_fasm (BD);\n    end case;\n  end Post_Build;\n\n  procedure Run (BD : in out HAC_Sys.Builder.Build_Data; arg_pos : Positive) is\n    use HAT;\n  begin\n    if verbosity >= 2 then\n      if BD.CD.Is_HAC_VM then\n        Put_Line (HAC_margin_2 & \"Starting p-code VM interpreter...\");\n      else\n        Put_Line (HAC_margin_2 & \"Running native (if target = native)\");\n      end if;\n    end if;\n    if target_choice /= hac_vm then\n      Put_Line (\"*** Caution *** Native code generation is experimental and incomplete !\");\n    end if;\n    case target_choice is\n      when hac_vm                     => Run_HAC_VM (BD, arg_pos);\n      when amd64_windows_console_fasm => Run_amd64_windows_console_fasm (arg_pos);\n    end case;\n  end Run;\n\nend HAC_Pkg;\n"
  },
  {
    "path": "src/apps/hac_pkg.ads",
    "content": "--  This package contains call-backs for the\n--  HAC command-line application, as well as various helpers.\n\nwith HAC_Sys.Builder,\n     HAC_Sys.Files.Default,\n     HAC_Sys.Targets;\n\nwith HAT;\n\npackage HAC_Pkg is\n\n  verbosity : Natural := 0;\n\n  version_info : constant String :=\n    \"Compiler version: \" & HAC_Sys.version & \" dated \" & HAC_Sys.reference & '.';\n\n  HAC_margin_1 : constant String := \"*******[ HAC ]*******   \";\n  HAC_margin_2 : constant String := \"       [ HAC ]          \";\n  HAC_margin_3 : constant String := \"-------[ HAC ]-------   \";\n\n  command_line_source_path, main_Ada_file_name : HAT.VString;\n\n  target : HAC_Sys.Targets.Abstract_Machine_Reference := null;\n\n  procedure Compilation_Feedback (message : String);\n\n  package Path_Management is  --  Specific search path management\n\n    type File_Catalogue is\n      limited new HAC_Sys.Files.Default.File_Catalogue with\n    record\n      extra_path : HAT.VString;\n    end record;\n\n    --  We enrich the default file system with searching of\n    --  files through pathes.\n\n    overriding function Exists (cat : File_Catalogue; name : String) return Boolean;\n\n    overriding function Full_Source_Name (cat : File_Catalogue; name : String) return String;\n\n    overriding function Is_Open (cat : File_Catalogue; name : String) return Boolean;\n\n    overriding procedure Source_Open\n      (cat    : in out File_Catalogue;\n       name   : in     String;\n       stream :    out HAC_Sys.Files.Root_Stream_Class_Access);\n\n    overriding procedure Skip_Shebang\n      (cat            : in out File_Catalogue;\n       name           : in     String;\n       shebang_offset :    out Natural);\n\n    overriding procedure Close (cat : in out File_Catalogue; name : String);\n\n    overriding procedure Add_to_Source_Path (cat : in out File_Catalogue; new_dir : String);\n\n  end Path_Management;\n\n  compiler_dump_name : constant String := \"compiler_dump.lst\";\n\n  compile_only : Boolean := False;\n\n  procedure PLCE (s : String);  --  Put_Line on Current Error\n  procedure NLCE;               --  New_Line on Current Error\n\n  procedure Help (level : Positive);\n\n  procedure Set_Target (name : String);\n\n  procedure Failure;\n\n  procedure Post_Build (BD : in out HAC_Sys.Builder.Build_Data);\n\n  procedure Run (BD : in out HAC_Sys.Builder.Build_Data; arg_pos : Positive);\n\nend HAC_Pkg;\n"
  },
  {
    "path": "src/apps/show_mit_license.adb",
    "content": "with Ada.Text_IO;\n\nprocedure Show_MIT_License\n  (file : Ada.Text_IO.File_Type; source_with_license : String)\nis\n  use Ada.Text_IO;\nbegin\n  New_Line (file);\n  Put_Line (file, \"| This software is free and open-source.\");\n  Put_Line (file, \"| It is provided \"\"as is\"\", WITHOUT WARRANTY OF ANY KIND.\");\n  Put_Line (file, \"| For the full license wording, see the header\" &\n                  \" (copyright & MIT license)\");\n  Put_Line (file, \"| appearing on top of this software's source files.\");\n  Put_Line (file, \"| In doubt, check the file: \" & source_with_license);\n  New_Line (file);\nend Show_MIT_License;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets-amd64_windows_console_fasm.adb",
    "content": "package body HAC_Sys.Targets.AMD64_Windows_Console_FASM is\n\n  --  Technical quotations are from:\n  --  AMD64 Architecture Programmer's Manual\n  --  24594 - Rev. 3.35 - June 2023\n\n  use Defs, HAT;\n\n  asm_name : constant String := \"hac_generated.asm\";\n\n  overriding procedure Initialize_Code_Emission (m : in out Machine) is\n  begin\n    Create (m.asm_file, asm_name);\n    Put_Line (m.asm_file, \";  Assembler file for the Flat Assembler - https://flatassembler.net/\");\n    New_Line (m.asm_file);\n    Put_Line (m.asm_file, \"format PE64 console\");\n    Put_Line (m.asm_file, \"entry _start\");\n    Put_Line (m.asm_file, \"include 'include\\win64a.inc'\");\n    New_Line (m.asm_file);\n    Put_Line (m.asm_file, \"section '.code' code readable executable\");\n    New_Line (m.asm_file);\n    Put_Line (m.asm_file, \"_start:\");\n  end Initialize_Code_Emission;\n\n  overriding procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings :        String)\n  is\n    procedure Dump_Strings is\n      printable : Boolean := True;\n      col : Integer;\n      function Needs_New_Line return Boolean is (col mod 60 = 10);\n      procedure Separate_with_Comma is\n      begin\n        if col > strings'First then\n          Put (m.asm_file, \", \");\n        end if;\n        if Needs_New_Line then\n          Put_Line (m.asm_file, \"\\ \");\n          Put (m.asm_file, \"    \");\n        end if;\n      end Separate_with_Comma;\n    begin\n      Put_Line (m.asm_file, \"_hac_end_of_line  db 10, 0\");\n      Put_Line (m.asm_file, \"_hac_decimal_format  db \"\"%d\"\", 0\");\n      Put (m.asm_file, \"_hac_strings_pool db \"\"X\");\n      for i in strings'Range loop\n        col := i;\n        if Character'Pos (strings (i)) in 32 .. 127 then\n          if printable then\n            if Needs_New_Line then\n              Put_Line (m.asm_file, \"\"\", \\\");\n              Put (m.asm_file, \"    \"\"\");\n            end if;\n          else\n            Separate_with_Comma;\n            Put (m.asm_file, '\"');\n            printable := True;\n          end if;\n          Put (m.asm_file, strings (i));\n        else\n          if printable then\n            Put (m.asm_file, '\"');\n            printable := False;\n          end if;\n          Separate_with_Comma;\n          Put (m.asm_file, Character'Pos (strings (i)), 0);\n        end if;\n      end loop;\n      if printable then\n        Put (m.asm_file, '\"');\n      end if;\n      New_Line (m.asm_file);\n    end Dump_Strings;\n  begin\n    if strings'Length > 0 then\n      Put_Line (m.asm_file, \"section '.data' data readable writeable\");\n      Dump_Strings;\n      New_Line (m.asm_file);\n    end if;\n    Put_Line (m.asm_file, \"section '.idata' import data readable\");\n    Put_Line (m.asm_file, \"library kernel,'kernel32.dll',\\\");\n    Put_Line (m.asm_file, \"        msvcrt,'msvcrt.dll'\");\n    Put_Line (m.asm_file, \"import  kernel,\\\");\n    Put_Line (m.asm_file, \"        ExitProcess,'ExitProcess'\");\n    Put_Line (m.asm_file, \"import  msvcrt,\\\");\n    Put_Line (m.asm_file, \"        printf,'printf'\");\n    Close (m.asm_file);\n  end Finalize_Code_Emission;\n\n  procedure Output (m : Machine; asm : Assembler_Line) is\n    instr_img : constant String :=\n      (case asm.instr is\n       when push_immediate => \"push\",\n       when xor_i          => \"xor\",\n       when others         => asm.instr'Image);\n  begin\n    Put_Line\n      (m.asm_file,\n       asm.label & Integer'Max (0, 9 - Length (asm.label)) * ' ' &\n       To_Lower (+instr_img) & (20 - instr_img'Length) * ' ' &\n       asm.operand_1 &\n       (if asm.operand_2 = \"\" then +\"\" else \", \" & asm.operand_2));\n  end Output;\n\n  procedure Peephole_Optimization (m : in out Machine) is\n    aux_line : Assembler_Line;\n    --\n    procedure Pass is\n      lines : Natural := Integer (m.asm_buf.Length);\n      current : Positive := 1;\n      cur_instr : Instruction;\n      --\n      procedure Replace_Pair is\n      begin\n        m.asm_buf.Delete (current);\n        m.asm_buf (current) := aux_line;\n        lines := lines - 1;\n      end Replace_Pair;\n      --\n      procedure Swap_Pair is\n      begin\n        aux_line := m.asm_buf (current);\n        m.asm_buf (current) := m.asm_buf (current + 1);\n        m.asm_buf (current + 1) := aux_line;\n      end Swap_Pair;\n      --\n    begin\n      while current <= lines loop\n        cur_instr := m.asm_buf (current).instr;\n        if current < lines\n          and then  m.asm_buf (current + 1).label = \"\"\n        then\n          --  Optimization involving this line and the next one.\n          case cur_instr is\n            when push | push_immediate =>\n              --  Displace or simplify PUSH instruction.\n              if cur_instr = push_immediate\n                or else m.asm_buf (current).operand_1 = \"rax\"\n              then\n                case m.asm_buf (current + 1).instr is\n                  when pop =>\n                    --  Fold \"push x; pop y;\" into \"mov y, x\"\n                    aux_line :=\n                      (label     => m.asm_buf (current).label,\n                       instr     => mov,\n                       operand_1 => m.asm_buf (current + 1).operand_1,\n                       operand_2 => m.asm_buf (current).operand_1);\n                    Replace_Pair;\n                  when mov | add | sub | imul | idiv | xor_i =>\n                    --  !!  check it is not an operation involving the stack pointer !!\n                    --  Move the \"push\" one line further. Perhaps it meets a \"pop\"...\n                    if m.asm_buf (current).operand_1 = \"rax\"\n                      and then\n                        (m.asm_buf (current + 1).operand_1 = \"rax\"\n                         or else m.asm_buf (current + 1).instr = idiv)\n                    then\n                      --  The pushed register *** is modified on next instruction,\n                      --  so we can't displace the current \"push *** \" instrction after it.\n                      null;\n                    else\n                      Swap_Pair;\n                    end if;\n                  when others =>\n                    null;\n                end case;\n              end if;\n            when others =>\n              null;\n          end case;\n        end if;\n        current := current + 1;\n      end loop;\n    end Pass;\n  begin\n    for pass_count in 1 .. 10 loop\n      Pass;\n    end loop;\n  end Peephole_Optimization;\n\n  procedure Flush_Assembler (m : in out Machine) is\n  begin\n    Peephole_Optimization (m);\n    for l of m.asm_buf loop\n      Output (m, l);\n    end loop;\n    m.asm_buf.Clear;\n  end Flush_Assembler;\n\n  procedure Emit\n    (m         : in out Machine;\n     instr     :        Instruction;\n     operand_1 :        String := \"\";\n     operand_2 :        String := \"\";\n     label     :        String := \"\")\n  is\n  begin\n    m.asm_buf.Append\n      ((label     => +label,\n        instr     => instr,\n        operand_1 => +operand_1,\n        operand_2 => +operand_2));\n  end Emit;\n\n  overriding procedure Emit_Arithmetic_Binary_Instruction\n    (m         : in out Machine;\n     operator  :        Defs.Arithmetic_Binary_Operator;\n     base_typ  :        Defs.Numeric_Typ)\n  is\n  begin\n    case base_typ is\n      when Floats =>\n        --  case operator is\n        --    when Plus    => raise combination_not_supported;\n        --    when Minus   => raise combination_not_supported;\n        --    when Times   => raise combination_not_supported;\n        --    when Divide  => raise combination_not_supported;\n        --    when Power   => raise combination_not_supported;\n        --  end case;\n        raise\n          combination_not_supported\n            with base_typ'Image & ' ' & operator'Image;\n      when Ints   =>\n        Emit (m, pop, \"r11\");  --  Right\n        Emit (m, pop, \"rax\");  --  Left\n        case operator is\n          when Plus    => Emit (m, add,  \"rax\", \"r11\");\n          when Minus   => Emit (m, sub,  \"rax\", \"r11\");\n          when Times   => Emit (m, imul, \"rax\", \"r11\");\n          when Divide  =>\n            Emit (m, xor_i, \"rdx, rdx\");\n            Emit (m, idiv, \"r11\");\n          when Power   =>\n            raise\n              combination_not_supported\n                with base_typ'Image & ' ' & operator'Image;\n        end case;\n        Emit (m, push, \"rax\");\n    end case;\n  end Emit_Arithmetic_Binary_Instruction;\n\n  overriding procedure Emit_Halt (m : in out Machine) is\n  begin\n    Emit (m, stdcall, \"[ExitProcess], 0\");\n    Flush_Assembler (m);\n    New_Line (m.asm_file);\n  end Emit_Halt;\n\n  overriding procedure Emit_Push_Discrete_Literal\n    (m : in out Machine; x : Defs.HAC_Integer) is\n  begin\n    --  P.327: \"In 64-bit mode, the operand size of all\n    --          PUSH instructions defaults to 64 bits\"\n    Emit (m, push_immediate, HAC_Image (x));\n  end Emit_Push_Discrete_Literal;\n\n  overriding procedure Emit_Push_Discrete_Literals\n    (m : in out Machine; x, y : Defs.HAC_Integer) is\n  begin\n    Emit (m, push_immediate, HAC_Image (x));\n    Emit (m, push_immediate, HAC_Image (y));\n  end Emit_Push_Discrete_Literals;\n\n  overriding procedure Emit_HAT_Builtin_Procedure\n    (m            : in out Machine;\n     builtin_proc :        Defs.SP_Code;\n     parameter    :        Defs.HAC_Integer)\n  is\n  begin\n    case builtin_proc is\n      when SP_Put .. SP_Put_Line =>\n        case Defs.Typen'Val (parameter) is\n          --  Register numbering is parameter position, plus 10.\n          when String_Literals =>\n            Emit (m, pop, \"r12\");  --  String Position in the strings pool\n            Emit (m, add, \"r12, _hac_strings_pool\");\n            Emit (m, pop, \"r11\");  --  String Length, discarded\n            Emit (m, ccall, \"[printf], r12\");\n          when Ints =>\n            Emit (m, pop, \"r13\");  --  Base  - support it !!\n            Emit (m, pop, \"r12\");  --  Width - support it !!\n            Emit (m, pop, \"r11\");  --  Integer value\n            Emit (m, ccall, \"[printf], _hac_decimal_format, r11\");\n          when others =>\n            raise combination_not_supported;\n        end case;\n        if builtin_proc = SP_Put_Line then\n          m.Emit_HAT_Builtin_Procedure (SP_New_Line, 0);\n        end if;\n      when SP_New_Line =>\n        Emit (m, ccall, \"[printf], _hac_end_of_line\");\n      when others =>\n        raise combination_not_supported with builtin_proc'Image;\n    end case;\n  end Emit_HAT_Builtin_Procedure;\n\n  overriding function Assembler_File_Name (m : Machine) return String is (asm_name);\n\nend HAC_Sys.Targets.AMD64_Windows_Console_FASM;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets-amd64_windows_console_fasm.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  This target is AMD64, Windows, using the Flat Assembler (FASM).\n--  https://flatassembler.net/\n\nwith Ada.Containers.Vectors;\nwith HAT;\n\npackage HAC_Sys.Targets.AMD64_Windows_Console_FASM is\n\n  type Machine is limited new Targets.Machine with private;\n\n  --------------------\n  --  Informations  --\n  --------------------\n\n  overriding function Name (m : Machine) return String is (\"Windows 64 Console via FASM\");\n  overriding function CPU (m : Machine) return String is (\"AMD64\");\n  overriding function OS (m : Machine) return String is (\"Windows\");\n  overriding function Null_Terminated_String_Literals (m : Machine) return Boolean is (True);\n\n  -------------------------------------------\n  --  Initialize & Finalize Code Emission  --\n  -------------------------------------------\n\n  overriding procedure Initialize_Code_Emission (m : in out Machine);\n  overriding procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings :        String);\n\n  ----------------------------\n  --  Machine Instructions  --\n  ----------------------------\n\n  overriding procedure Emit_Arithmetic_Binary_Instruction\n    (m         : in out Machine;\n     operator  :        Defs.Arithmetic_Binary_Operator;\n     base_typ  :        Defs.Numeric_Typ);\n\n  overriding procedure Emit_Halt (m : in out Machine);\n\n  overriding procedure Emit_Push_Discrete_Literal\n    (m : in out Machine; x : Defs.HAC_Integer);\n\n  overriding procedure Emit_Push_Discrete_Literals\n    (m : in out Machine; x, y : Defs.HAC_Integer);\n\n  ----------------------------\n  --  Built-In Subprograms  --\n  ----------------------------\n\n  overriding procedure Emit_HAT_Builtin_Procedure\n    (m            : in out Machine;\n     builtin_proc :        Defs.SP_Code;\n     parameter    :        Defs.HAC_Integer);\n\n  -------------\n  --  Misc.  --\n  -------------\n\n  overriding function Assembler_File_Name (m : Machine) return String;\n\nprivate\n\n  type Instruction is\n    (add,\n     ccall,\n     idiv,\n     imul,\n     mov,\n     pop,\n     push,\n     push_immediate,\n     stdcall,\n     sub,\n     xor_i);\n\n  type Assembler_Line is record\n    label     : HAT.VString := HAT.Null_VString;\n    instr     : Instruction;\n    operand_1 : HAT.VString := HAT.Null_VString;\n    operand_2 : HAT.VString := HAT.Null_VString;\n  end record;\n\n  package Assembler_Buffers is new Ada.Containers.Vectors (Positive, Assembler_Line);\n\n  type Machine is limited new Targets.Machine with record\n    asm_file : HAT.File_Type;\n    asm_buf  : Assembler_Buffers.Vector;\n  end record;\n\nend HAC_Sys.Targets.AMD64_Windows_Console_FASM;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets-hac_virtual_machine.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Defs,\n     HAC_Sys.Errors,\n     HAC_Sys.PCode;\n\npackage body HAC_Sys.Targets.HAC_Virtual_Machine is\n\n  overriding procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings :        String)\n  is\n    use Defs;\n  begin\n    if m.CD.Blocks_Table (1).VSize > StMax - (STKINCR * m.CD.Tasks_Definitions_Count) then\n      Errors.Error (m.CD.all, err_stack_size);\n    end if;\n  end Finalize_Code_Emission;\n\n  use Compiler.PCode_Emit, PCode;\n\n  overriding procedure Emit_Arithmetic_Binary_Instruction\n    (m         : in out Machine;\n     operator  :        Defs.Arithmetic_Binary_Operator;\n     base_typ  :        Defs.Numeric_Typ)\n  is\n    use Defs;\n  begin\n    case base_typ is\n      when Floats =>\n        case operator is\n          when Plus    => Emit (m.CD.all, k_ADD_Float);\n          when Minus   => Emit (m.CD.all, k_SUBTRACT_Float);\n          when Times   => Emit (m.CD.all, k_MULT_Float);\n          when Divide  => Emit (m.CD.all, k_DIV_Float);\n          when Power   => Emit (m.CD.all, k_Power_Float);\n        end case;\n      when Ints   =>\n        case operator is\n          when Plus    => Emit (m.CD.all, k_ADD_Integer);\n          when Minus   => Emit (m.CD.all, k_SUBTRACT_Integer);\n          when Times   => Emit (m.CD.all, k_MULT_Integer);\n          when Divide  => Emit (m.CD.all, k_DIV_Integer);\n          when Power   => Emit (m.CD.all, k_Power_Integer);\n        end case;\n    end case;\n  end Emit_Arithmetic_Binary_Instruction;\n\n  overriding procedure Emit_Halt (m : in out Machine) is\n  begin\n    Emit (m.CD.all, k_Halt_Interpreter);\n  end Emit_Halt;\n\n  overriding procedure Emit_Push_Discrete_Literal\n    (m : in out Machine; x : Defs.HAC_Integer)\n  is\n  begin\n    Emit_1 (m.CD.all, k_Push_Discrete_Literal, x);\n  end Emit_Push_Discrete_Literal;\n\n  overriding procedure Emit_Push_Discrete_Literals\n    (m : in out Machine; x, y : Defs.HAC_Integer)\n  is\n  begin\n    Emit_2 (m.CD.all, k_Push_Two_Discrete_Literals, x, y);\n  end Emit_Push_Discrete_Literals;\n\n  overriding procedure Emit_HAT_Builtin_Procedure\n    (m            : in out Machine;\n     builtin_proc :        Defs.SP_Code;\n     parameter    :        Defs.HAC_Integer)\n  is\n   begin\n     Emit_2 (m.CD.all, k_HAT_Procedure, Defs.SP_Code'Pos (builtin_proc), parameter);\n   end Emit_HAT_Builtin_Procedure;\n\nend HAC_Sys.Targets.HAC_Virtual_Machine;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets-hac_virtual_machine.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n\n--  Here is the code emission for the original HAC target, the\n--  HAC Virtual Machine (\"p-code\").\n\nwith HAC_Sys.Co_Defs;\n\npackage HAC_Sys.Targets.HAC_Virtual_Machine is\n\n  type Machine is limited new Targets.Machine with record\n    CD : Co_Defs.Compiler_Data_Access;\n    --  ^ In the future, the instruction table and other items\n    --    will be stored here and we can remove CD.\n    --    As long as this field exists, we keep it public for\n    --    convenience (it is needed in method Set_Target in Co_Defs).\n  end record;\n\n  --------------------\n  --  Informations  --\n  --------------------\n\n  overriding function Name (m : Machine) return String is (\"HAC Virtual Machine\");\n  overriding function CPU (m : Machine) return String is (\"HAC VM\");\n  overriding function OS (m : Machine) return String is (\"Any\");\n  overriding function Null_Terminated_String_Literals (m : Machine) return Boolean is (False);\n\n  -------------------------------------------\n  --  Initialize & Finalize Code Emission  --\n  -------------------------------------------\n\n  overriding procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings :        String);\n\n  ----------------------------\n  --  Machine Instructions  --\n  ----------------------------\n\n  overriding procedure Emit_Arithmetic_Binary_Instruction\n    (m         : in out Machine;\n     operator  :        Defs.Arithmetic_Binary_Operator;\n     base_typ  :        Defs.Numeric_Typ);\n\n  overriding procedure Emit_Halt (m : in out Machine);\n\n  overriding procedure Emit_Push_Discrete_Literal\n    (m : in out Machine; x : Defs.HAC_Integer);\n\n  overriding procedure Emit_Push_Discrete_Literals\n    (m : in out Machine; x, y : Defs.HAC_Integer);\n\n  ----------------------------\n  --  Built-In Subprograms  --\n  ----------------------------\n\n  overriding procedure Emit_HAT_Builtin_Procedure\n    (m            : in out Machine;\n     builtin_proc :        Defs.SP_Code;\n     parameter    :        Defs.HAC_Integer);\n\n  -------------\n  --  Misc.  --\n  -------------\n\n  overriding function Assembler_File_Name (m : Machine) return String is (\"asm_dump.pca\");\n  --  PCA = PCode Assembler\n\nend HAC_Sys.Targets.HAC_Virtual_Machine;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets-semantics.adb",
    "content": "with HAC_Sys.Defs;\n\nwith Ada.Unchecked_Deallocation;\n\npackage body HAC_Sys.Targets.Semantics is\n\n  overriding procedure Finalize (m : in out Machine) is\n    procedure Unchecked_Free is\n      new Ada.Unchecked_Deallocation\n        (Declaration_Line_Maps.Map, Declaration_Line_Map_Access);\n  begin\n    for line_map_a of m.loc_map loop\n      Unchecked_Free (line_map_a);\n    end loop;\n  end Finalize;\n\n  overriding procedure Initialize_Code_Emission (m : in out Machine) is\n    use HAT;\n  begin\n    m.busy := True;\n    m.started := Clock;\n    m.ref_map.Clear;\n  end Initialize_Code_Emission;\n\n  overriding procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings :        String)\n  is\n    use HAT;\n  begin\n    m.finished := Clock;\n    m.total_time := m.finished - m.started;\n    m.busy := False;\n  end Finalize_Code_Emission;\n\n  trace : constant Boolean := False;\n\n  overriding procedure Mark_Declaration\n    (m : in out Machine; is_built_in : Boolean := False)\n  is\n    use File_Names_to_Line_Maps_Maps;\n    curs : Cursor;\n    line_map_a : Declaration_Line_Map_Access;\n  begin\n    --  Feed the declaration array used for getting a declaration's coordinates\n    --  from an index in the identifier table, possibly obtained\n    --  via Find_Referenced_Declaration.\n    --\n    m.decl_array (m.CD.Id_Count) :=\n      (file_name   => (if is_built_in then HAT.Null_VString else m.CD.CUD.source_file_name),\n       line        => (if is_built_in then -1               else m.CD.CUD.location.line),\n       column      => (if is_built_in then -1               else m.CD.CUD.location.column_start),\n       is_built_in => is_built_in,\n       id_index    => m.CD.Id_Count,\n       others      => <>);\n\n    --  Feed the structures for searching possible declarations\n    --  at any given point of any source file.\n    --\n    if not is_built_in then\n      --  1) Find or create the line map associated to the file name.\n      curs := m.loc_map.Find (m.CD.CUD.source_file_name);\n      if curs = No_Element then\n        line_map_a := new Declaration_Line_Maps.Map;\n        m.loc_map.Insert (m.CD.CUD.source_file_name, line_map_a);\n      else\n        line_map_a := Element (curs);\n      end if;\n      --  2) Insert the infos for the declaration into the line map,\n      --     possibly replacing a value for the same line number.\n      line_map_a.Include (m.CD.CUD.location.line, m.CD.Id_Count);\n    end if;\n  end Mark_Declaration;\n\n  procedure Add_Reference\n    (m          : in out Machine;\n     ref        : in     Reference_Point'Class;\n     located_id : in     Natural)\n  is\n    use HAT;\n    admit_duplicates : constant Boolean := True;\n    key : constant VString :=\n      ref.file_name & ref.line'Image & ref.column'Image;\n      --  ^ Example: \"c:\\files\\source.adb 130 12\"\n  begin\n    if trace then\n      HAT.Put_Line\n        (\"Mark_Reference, key = [\" & key &\n         \"] for Id\" & located_id'Image & \", \" &\n         Defs.A2S (m.CD.id_table (located_id).name_with_case));\n    end if;\n    if admit_duplicates then\n      m.ref_map.Include (key, located_id);\n    else\n      m.ref_map.Insert (key, located_id);\n    end if;\n  exception\n    when Constraint_Error =>\n      raise Constraint_Error\n        with \"Duplicate reference key: \" & To_String (key);\n  end Add_Reference;\n\n  overriding procedure Mark_Spec_Body_Cross_References\n    (m                : in out Machine;\n     spec_id, body_id : in     Positive)\n  is\n  begin\n    m.decl_array (spec_id).body_id := body_id;\n    m.decl_array (body_id).spec_id := spec_id;\n    --\n    --  Add references to own declarations so a user can go from\n    --  spec to body, and vice-versa, directly from the declarations.\n    Add_Reference (m, m.decl_array (spec_id), spec_id);\n    Add_Reference (m, m.decl_array (body_id), body_id);\n  end Mark_Spec_Body_Cross_References;\n\n  overriding procedure Mark_Reference\n    (m : in out Machine; located_id : Natural) is\n  begin\n    Add_Reference\n      (m,\n       Reference_Point'\n         (m.CD.CUD.source_file_name,\n          m.CD.CUD.location.line,\n          m.CD.CUD.location.column_start),\n       located_id);\n  end Mark_Reference;\n\n  procedure Find_Referenced_Declarations\n    (m              : in     Machine;\n     ref            : in     Reference_Point'Class;\n     decl_1, decl_2 :    out Declaration_Point'Class;\n     found          :    out Natural)\n  is\n    use Co_Defs, HAT, Reference_Mapping;\n    key  : constant VString :=\n      ref.file_name & ref.line'Image & ref.column'Image;\n    curs : constant Reference_Mapping.Cursor := m.ref_map.Find (key);\n    index_1, index_2 : Positive;\n  begin\n    if curs = No_Element then\n      decl_1.id_index := -1;\n      decl_2.id_index := -1;\n      found := 0;\n    else\n      index_1 := Element (curs);\n      decl_1 := Declaration_Point'Class (m.decl_array (index_1));\n      if decl_1.spec_id = No_Id and then decl_1.body_id = No_Id then\n        found := 1;\n      else\n        found := 2;\n        --  There is a cross-reference.\n        --  In any case, decl_1 will be the spec and decl_2 will be the body.\n        if decl_1.spec_id /= No_Id then\n          --  We have a body referencing a spec.\n          index_2 := index_1;\n          index_1 := decl_1.spec_id;\n          decl_1 := Declaration_Point'Class (m.decl_array (index_1));\n        else\n          --  We have a spec referencing a body.\n          index_2 := decl_1.body_id;\n        end if;\n        decl_2 := Declaration_Point'Class (m.decl_array (index_2));\n        if Reference_Point (decl_2) = Reference_Point (ref) then\n          --  Mark cases where ref point = decl. point\n          decl_2.self_reference := True;\n        end if;\n      end if;\n      if found >= 1\n        and then Reference_Point (decl_1) = Reference_Point (ref)\n      then\n        --  Mark cases where ref point = decl. point\n        decl_1.self_reference := True;\n      end if;\n    end if;\n  end Find_Referenced_Declarations;\n\n  function Find_Possible_Declarations\n    (m        : Machine;\n     point    : Reference_Point'Class;\n     prefix   : String;\n     max_list : Positive;\n     max_scan : Positive) return String\n  is\n    use Co_Defs, HAT;\n    line_map_a : Declaration_Line_Map_Access;\n    idx, l : Natural;\n    package Declaration_Lists is new Ada.Containers.Ordered_Maps (VString, VString);\n    list : Declaration_Lists.Map;\n    up_prefix : constant VString := To_Upper (+prefix);\n    result : VString;\n    --\n    procedure Include_Special (word : String) is\n      up_word : constant VString := To_Upper (+word);\n    begin\n      if Starts_With (up_word, up_prefix) then\n        list.Include (up_word, +word);\n      end if;\n    end Include_Special;\n    --\n  begin\n    --  1) Find the line map associated to the given file name.\n    declare\n      use File_Names_to_Line_Maps_Maps;\n      curs : constant Cursor := m.loc_map.Find (point.file_name);\n    begin\n      if curs = No_Element then\n        return \"\";\n      else\n        line_map_a := Element (curs);\n      end if;\n    end;\n    --  2) Find the last declaration before given line.\n    declare\n      use Declaration_Line_Maps;\n      curs : Cursor;\n    begin\n      curs := line_map_a.Floor (point.line - 1);\n      if curs = No_Element then\n        return \"\";\n      else\n        idx := Element (curs);\n      end if;\n    end;\n    --  3) Build an identifier list matching the prefix.\n    if trace then\n      Put_Line\n        (+\"Find_Possible_Declarations, identifiers matching \"\"\" &\n         prefix & \"\"\":\");\n    end if;\n    for scan in 1 .. max_scan loop\n      exit when idx = No_Id;\n      exit when Integer (list.Length) = max_list;\n      declare\n        item : Identifier_Table_Entry renames m.CD.id_table (idx);\n        use type Defs.Nesting_Level;\n      begin\n        if Starts_With (item.name, up_prefix) then\n          --  Enter the identifier in a case-insensitive way:\n          list.Include (item.name, item.name_with_case);\n          if trace then\n            Put_Line (+\"    \" & item.name_with_case);\n          end if;\n        end if;\n        if item.link = No_Id\n          and then idx - 1 > No_Id\n          and then m.CD.id_table (idx - 1).entity in prozedure | funktion\n          and then item.lev > 0\n          and then m.CD.id_table (idx - 1).lev = item.lev - 1\n        then\n          --  Jump to last declaration of level - 1, that\n          --  is the subprogram declaration (if any) preceding\n          --  the exhausted local identifier list.\n          idx := idx - 1;\n        else\n          --  Jump to previous identifier index, or to No_Id.\n          idx := item.link;\n        end if;\n      end;\n    end loop;\n    --  4) Add some keywords\n    Include_Special (\"record\");\n    Include_Special (\"begin\");\n    Include_Special (\"end\");\n    Include_Special (\"case\");\n    Include_Special (\"when\");\n    Include_Special (\"others\");\n    Include_Special (\"loop\");\n    Include_Special (\"while\");\n    Include_Special (\"exit\");\n    Include_Special (\"return\");\n    Include_Special (\"procedure\");\n    Include_Special (\"function\");\n    Include_Special (\"package\");\n    Include_Special (\"body\");\n    --  5) Output the list as a single string seperated by spaces:\n    for s of list loop\n      --  Like `result := result & s & ' ';`, possibly more efficient:\n      VStr_Pkg.Append (result, s);\n      VStr_Pkg.Append (result, ' ');\n    end loop;\n    l := Length (result);\n    if l > 0 then\n      Delete (result, l, l);  --  Remove trailing ' '\n    end if;\n    if trace then\n      Put_Line (+\"    [\" & result & \"]\");\n    end if;\n    return To_String (result);\n  end Find_Possible_Declarations;\n\nend HAC_Sys.Targets.Semantics;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets-semantics.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n\n--  The target Semantics produces no machine code but\n--  serves semantics analysis purposes, like cross-references\n--  for an editor with auto-complete, contextual menus and tool tips.\n\nwith Ada.Containers.Hashed_Maps,\n     Ada.Containers.Ordered_Maps,\n     Ada.Strings.Unbounded.Hash;\n\nwith HAC_Sys.Co_Defs;\n\nwith HAT;\n\npackage HAC_Sys.Targets.Semantics is\n\n  type Reference_Point is tagged record\n    file_name    : HAT.VString;\n    line, column : Integer;\n  end record;\n\n  type Declaration_Point is new Reference_Point with record\n    is_built_in    : Boolean;\n    id_index       : Integer;\n    spec_id        : Natural := Co_Defs.No_Id;  --  For a body item: link to its spec.\n    body_id        : Natural := Co_Defs.No_Id;  --  For a spec item: link to its body.\n    self_reference : Boolean := False;\n  end record;\n\n  --  Reference map\n  --  =============\n  --\n  --  This container holds all references to variables, functions,\n  --  types, etc. The search key is the exact position of the first\n  --  letter of the identifier.\n\n  --\n  --  Key                  Value\n  --  ===                  =====\n  --  [file_name i j]      index in the Id Table\n\n  package Reference_Mapping is new Ada.Containers.Hashed_Maps\n    (Key_Type        => HAT.VString,                --  [file_name i j]\n     Element_Type    => Positive,                   --  Index in the Id Table\n     Hash            => Ada.Strings.Unbounded.Hash,\n     Equivalent_Keys => Ada.Strings.Unbounded.\"=\");\n\n  --  Declaration array\n  --  =================\n  --\n  --  This container holds the exact position of the declarations.\n  --  It is a simple array; the element #i corresponds to\n  --  the identifer #i in the compiler's identifier table.\n  --\n  --  Key                  Value\n  --  ===                  =====\n  --  index in Id Table    file_name, i, j of declaration\n\n  type Declaration_Point_Array is\n    array (Co_Defs.Identifier_Table_Type'Range) of Declaration_Point;\n\n  --  Possible sanity checks for an usage within an editor:\n  --    - compare identifiers between the one at [file_name i j] and\n  --      the one in the identifier table (weak check)\n  --    - ensure the analysis was completed after the latest\n  --      modification in the editor (keystroke, cut, paste, ...)\n  --\n\n  --  Declaration localization\n  --  ========================\n  --\n  --  This container provides the reverse operation of a\n  --  Declaration_Point_Array. It enables the localization of the index\n  --  of the last identifier on any given line in a source code file.\n  --  From the index, it is then possible to gather all the identifiers\n  --  visible at the next line (we don't go down to a column-wise\n  --  localization for simplicity purposes).\n  --  Due to nesting, that overall identifier list is not simply growing\n  --  along the text, so the list of visible identifiers it is a part of\n  --  a declaration tree. You build it by going from a leaf (index of\n  --  the last identifier) to the root.\n\n  package Declaration_Line_Maps is new Ada.Containers.Ordered_Maps\n    (Key_Type        => Integer,     --  Line number\n     Element_Type    => Natural);    --  Index in the Id Table\n\n  type Declaration_Line_Map_Access is access Declaration_Line_Maps.Map;\n\n  package File_Names_to_Line_Maps_Maps is new Ada.Containers.Hashed_Maps\n    (Key_Type        => HAT.VString,                  --  File_name\n     Element_Type    => Declaration_Line_Map_Access,\n     Hash            => Ada.Strings.Unbounded.Hash,\n     Equivalent_Keys => Ada.Strings.Unbounded.\"=\");\n\n  type Machine is limited new Targets.Machine with record\n    CD         : Co_Defs.Compiler_Data_Access;\n    ref_map    : Reference_Mapping.Map;\n    decl_array : Declaration_Point_Array;\n    loc_map    : File_Names_to_Line_Maps_Maps.Map;\n    started    : HAT.Time;\n    finished   : HAT.Time;\n    total_time : Duration := 0.0;\n    busy       : Boolean  := False with Volatile;\n  end record;\n\n  type Semantics_Machine_Reference is access all Machine'Class;\n\n  overriding procedure Finalize (m : in out Machine);\n\n  --------------------\n  --  Informations  --\n  --------------------\n\n  overriding function Name (m : Machine) return String is (\"HAC Semantics\");\n  overriding function CPU (m : Machine) return String is (\"No CPU\");\n  overriding function OS (m : Machine) return String is (\"Any\");\n  overriding function Null_Terminated_String_Literals (m : Machine) return Boolean is (False);\n\n  ---------------------------------------\n  --  Initialize & Finalize Semantics  --\n  ---------------------------------------\n\n  overriding procedure Initialize_Code_Emission (m : in out Machine);\n  overriding procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings :        String);\n\n  ----------------------------\n  --  Machine Instructions  --\n  ----------------------------\n\n  overriding procedure Emit_Arithmetic_Binary_Instruction\n    (m         : in out Machine;\n     operator  :        Defs.Arithmetic_Binary_Operator;\n     base_typ  :        Defs.Numeric_Typ) is null;\n\n  overriding procedure Emit_Halt (m : in out Machine) is null;\n\n  overriding procedure Emit_Push_Discrete_Literal\n    (m : in out Machine; x : Defs.HAC_Integer) is null;\n\n  overriding procedure Emit_Push_Discrete_Literals\n    (m : in out Machine; x, y : Defs.HAC_Integer) is null;\n\n  ----------------------------\n  --  Built-In Subprograms  --\n  ----------------------------\n\n  overriding procedure Emit_HAT_Builtin_Procedure\n    (m            : in out Machine;\n     builtin_proc :        Defs.SP_Code;\n     parameter    :        Defs.HAC_Integer) is null;\n\n  -------------\n  --  Misc.  --\n  -------------\n\n  overriding function Assembler_File_Name (m : Machine) return String is (\"\");\n\n  overriding procedure Mark_Reference\n    (m : in out Machine; located_id : Natural);\n\n  overriding procedure Mark_Declaration\n    (m : in out Machine; is_built_in : Boolean := False);\n\n  overriding procedure Mark_Spec_Body_Cross_References\n    (m                : in out Machine;\n     spec_id, body_id : in     Positive);\n\n  --  From given valid reference point, get the corresponding declaration.\n  procedure Find_Referenced_Declarations\n    (m              : in     Machine;\n     ref            : in     Reference_Point'Class;\n     decl_1, decl_2 :    out Declaration_Point'Class;\n     found          :    out Natural);\n\n  --  This is for \"auto-complete\" purposes.\n  --  The list of identifiers is sorted, separated by spaces.\n  function Find_Possible_Declarations\n    (m        : Machine;\n     point    : Reference_Point'Class;\n     prefix   : String;\n     max_list : Positive;\n     max_scan : Positive) return String;\n\nend HAC_Sys.Targets.Semantics;\n"
  },
  {
    "path": "src/compile/emit/hac_sys-targets.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n\n--  This package defines an interface for emitting machine\n--  code in an abstract way. This allows to emit code for\n--  various targets:\n--\n--    -  the HAC virtual machine (\"p-code\")\n--    -  <CPU>_<OS>_<Assembler>\n--\n--  ! Goal: replace all \"Emit\" in the compiler with\n--  ! method calls from this interface.\n--  ! There will be likely hundreds of such methods in the end.\n--  ! This will be done progressively. Be patient (or contribute)!\n\nwith HAC_Sys.Defs;\n\nwith Ada.Finalization;\n\npackage HAC_Sys.Targets is\n\n  type Machine is\n    abstract new Ada.Finalization.Limited_Controlled with null record;\n\n  type Abstract_Machine_Reference is access all Machine'Class;\n\n  --------------------\n  --  Informations  --\n  --------------------\n\n  function Name (m : Machine) return String is abstract;\n  function CPU (m : Machine) return String is abstract;\n  function OS (m : Machine) return String is abstract;\n  function Null_Terminated_String_Literals (m : Machine) return Boolean is abstract;\n\n  -------------------------------------------\n  --  Initialize & Finalize Code Emission  --\n  -------------------------------------------\n\n  procedure Initialize_Code_Emission (m : in out Machine) is null;\n\n  procedure Finalize_Code_Emission\n    (m       : in out Machine;\n     strings : in     String) is null;\n\n  ----------------------------\n  --  Machine Instructions  --\n  ----------------------------\n\n  procedure Emit_Arithmetic_Binary_Instruction\n    (m         : in out Machine;\n     operator  : in     Defs.Arithmetic_Binary_Operator;\n     base_typ  : in     Defs.Numeric_Typ) is abstract;\n\n  procedure Emit_Halt (m : in out Machine) is abstract;\n\n  procedure Emit_Push_Discrete_Literal\n    (m : in out Machine; x : Defs.HAC_Integer) is abstract;\n\n  procedure Emit_Push_Discrete_Literals\n    (m : in out Machine; x, y : Defs.HAC_Integer) is abstract;\n\n  ----------------------------\n  --  Built-In Subprograms  --\n  ----------------------------\n\n  procedure Emit_HAT_Builtin_Procedure\n    (m            : in out Machine;\n     builtin_proc : in     Defs.SP_Code;\n     parameter    : in     Defs.HAC_Integer) is abstract;\n\n  -------------\n  --  Misc.  --\n  -------------\n\n  function Assembler_File_Name (m : Machine) return String is abstract;\n\n  procedure Mark_Reference\n    (m : in out Machine; located_id : Natural) is null;\n\n  procedure Mark_Declaration\n    (m : in out Machine; is_built_in : Boolean := False) is null;\n\n  procedure Mark_Spec_Body_Cross_References\n    (m                : in out Machine;\n     spec_id, body_id : in     Positive) is null;\n\n  combination_not_supported : exception;\n\nend HAC_Sys.Targets;\n"
  },
  {
    "path": "src/compile/hac_sys-builder.adb",
    "content": "with HAC_Sys.Compiler,\n     HAC_Sys.Errors,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Targets.HAC_Virtual_Machine;\n\nwith Ada.Characters.Handling,\n     Ada.Exceptions,\n     Ada.Integer_Text_IO,\n     Ada.Text_IO,\n     Ada.Unchecked_Deallocation;\n\npackage body HAC_Sys.Builder is\n\n  overriding procedure Finalize (BD : in out Build_Data) is\n\n    procedure Unchecked_Free is\n      new Ada.Unchecked_Deallocation\n        (Co_Defs.Compiler_Data, Co_Defs.Compiler_Data_Access);\n\n  begin\n    Unchecked_Free (BD.CD);\n  end Finalize;\n\n  procedure Compile_Pending_Bodies_Single_Round\n    (BD : in out Build_Data; num_pending : out Natural)\n  is\n    use HAT, Librarian, Targets;\n    pending : Library_Unit_Vectors.Vector;\n    previous_context : Co_Defs.Id_Maps.Map;\n    needs_body_dummy : Boolean;\n  begin\n    for lu of BD.LD.library loop\n      if lu.status in Spec_Done then\n        pending.Append (lu);\n      end if;\n    end loop;\n    --\n    --  Here: the list of pending bodies is now established\n    --  for this round. Of course the library may expand\n    --  further due to dependencies, via Register_Unit,\n    --  adding pending bodies for the next round.\n    --\n    num_pending := 0;\n    if BD.CD.error_count > 0 then\n      return;\n    end if;\n    for lu of pending loop\n      declare\n        upper_vname : constant VString := To_Upper (lu.full_name);\n        upper_name : constant String := To_String (upper_vname);\n        fn_spec : constant String := Find_Unit_File_Name (BD.LD, upper_name);\n        fn_body : constant String := BD.LD.cat.Full_Body_Source_Name (fn_spec);\n      begin\n        case Spec_Done (lu.status) is\n          when Body_Postponed =>\n\n            previous_context :=\n              BD.LD.library.Element (BD.LD.map.Element (upper_vname)).spec_context;\n            BD.CD.remarks := BD.global_remarks;\n            if BD.target /= null then\n              BD.CD.target  := BD.target;\n            end if;\n\n            Compiler.Compile_Unit\n              (CD                     => BD.CD.all,\n               LD                     => BD.LD,\n               upper_name             => upper_name,\n               file_name              => fn_body,\n               as_specification       => False,\n               as_main_unit           => upper_name = Defs.A2S (BD.CD.Id),\n               needs_opening_a_stream => True,\n               first_compilation      => False,\n               specification_id_index => lu.id_index,\n               new_id_index           => lu.id_body_index,\n               unit_context           => previous_context,\n               kind                   => lu.kind,\n               needs_body             => needs_body_dummy);\n\n            exit when BD.CD.error_count > 0;\n\n            num_pending := num_pending + 1;\n\n          when Spec_Only =>\n\n            if BD.LD.cat.Exists (fn_body) then\n              Errors.Error\n                (BD.CD.all,\n                 Defs.err_library_error,\n                 \"library package declaration shall not have a body unless it \" &\n                   \"requires a body (Ada RM 7.2 (4)); found the file: \" & fn_body);\n            end if;\n\n        end case;\n\n        lu.status := Done;\n        Change_Unit_Details (BD.LD, lu);\n      end;\n    end loop;\n  end Compile_Pending_Bodies_Single_Round;\n\n  procedure Build_Main\n    (BD                            : in out Build_Data;\n     body_compilation_rounds_limit :        Rounds_Range := full_build)\n  is\n    use Co_Defs, Defs, HAT.VStr_Pkg, Librarian, Targets;\n    use Ada.Exceptions, Ada.Text_IO;\n\n    main_unit : Library_Unit :=\n      (full_name     => BD.main_name_hint,\n       kind          => Procedure_Unit,\n       status        => In_Progress,  --  Temporary value.\n       id_index      => No_Id,        --  Temporary value.\n       id_body_index => No_Id,        --  Temporary value.\n       spec_context  => Id_Maps.Empty_Map);\n\n    procedure Finalize_Target is\n    begin\n      BD.CD.target.Finalize_Code_Emission\n        (BD.CD.Strings_Constants_Table (1 .. BD.CD.Strings_Table_Top));\n    end Finalize_Target;\n\n    procedure Progress (s : String; min_level : Positive) is\n    begin\n      if BD.CD.trace.detail_level >= min_level then\n        Compiler.Progress_Message (BD.CD.all, s);\n      end if;\n    end Progress;\n\n    procedure Complete_Graph_Build is\n      num_pending : Natural;\n    begin\n      if body_compilation_rounds_limit > 0 then\n        Progress\n          (\"------  Compilation of possibly uncompiled unit bodies  ------\", 2);\n      end if;\n      for round in 1 .. body_compilation_rounds_limit loop\n        Compile_Pending_Bodies_Single_Round (BD, num_pending);\n        --  Now, other bodies may have appeared that have\n        --  not been yet compiled.\n        if num_pending > 0 then\n          Progress\n            (\"------  End of Round\" & round'Image &\n             \", compiled bodies:\" & num_pending'Image & \"  ------\", 2);\n        end if;\n        exit when num_pending = 0;\n      end loop;\n    end Complete_Graph_Build;\n\n    procedure Dump_Object_Map (var_map_file_name : String) is\n      map_file : File_Type;\n      use type HAC_Integer;\n    begin\n      Create (map_file, Out_File, var_map_file_name);\n      Put_Line (map_file, \"  -* Object Table *-\");\n      New_Line (map_file);\n      Put_Line (map_file, \"  LOC  Name       scope\");\n      Put_Line (map_file, \"------------------------\");\n      New_Line (map_file);\n      for Blk of BD.CD.id_table (BD.CD.Blocks_Table (0).Last_Id_Idx + 1 .. BD.CD.Id_Count) loop\n        if Blk.entity in Object_Kind then\n          if Blk.xtyp.TYP /= NOTYP then\n            Ada.Integer_Text_IO.Put (map_file, Integer (Blk.adr_or_sz), 4);\n            Put (map_file, A2S (Blk.name) & \"   \");\n          end if;\n          Put_Line\n            (map_file,\n             (if Blk.lev = 1 then  --  TBD: check this, should be 0.\n                \" Global (\"\n              else\n                \" Local  (\") &\n             Blk.lev'Image & ')');\n        end if;\n      end loop;\n      New_Line (map_file);\n      Close (map_file);\n    end Dump_Object_Map;\n\n    procedure Restart_with_Spec is\n      fn_body : constant String := HAT.To_String (BD.CD.CUD.source_file_name);\n    begin\n      if BD.LD.cat.Is_Open (fn_body) then\n        BD.LD.cat.Close (fn_body);\n      end if;\n      Progress (\"\\---> Cannot start build with a package's body.\", 1);\n      Progress (\"      We restart from a possible spec.\", 1);\n\n      BD.Build_Main_from_File\n        (file_name =>\n           (if fn_body'Length = 0 then\n              --  The body hasn't a file name (like just typed in an editor bound to HAC).\n              --  Let's try to invent a name for the spec.\n              Librarian.GNAT_File_Naming (A2S (BD.CD.main_unit_ident_with_case)) & \".ads\"\n            else\n              BD.LD.cat.Full_Spec_Source_Name (fn_body)),\n            --\n         body_compilation_rounds_limit =>\n           (if body_compilation_rounds_limit = Rounds_Range'Last then\n              Rounds_Range'Last\n            else\n              body_compilation_rounds_limit + 1));\n    end Restart_with_Spec;\n\n    procedure Build_Main_Inner is\n      main_file_name : constant String := To_String (BD.CD.CUD.source_file_name);\n\n      new_id_index : Natural;\n      needs_body : Boolean;\n      as_specification : Boolean;\n\n    begin\n      BD.LD.library.Clear;\n      BD.LD.map.Clear;\n\n      --  The main unit is from the beginning registered with the In_Progress\n      --  status, so we can catch a possible circular dependency of the main\n      --  unit on itself - directly or indirectly.\n      --\n      --     Examples:\n      --                   with A; procedure A is begin null; end;\n      --\n      --                   with Y; procedure X is begin null; end;\n      --                   with X; procedure Y is begin null; end;\n      --\n      Librarian.Register_Unit (BD.LD, main_unit);\n\n      BD.CD.remarks := BD.global_remarks;\n      if BD.target /= null then\n        BD.CD.target := BD.target;\n      end if;\n\n      BD.CD.listing_requested := BD.listing_file_name /= \"\";\n      if BD.CD.listing_requested then\n        Create (BD.CD.listing, Name => To_String (BD.listing_file_name));\n        Put_Line (BD.CD.listing, Defs.Header);\n      end if;\n\n      BD.CD.comp_dump_requested := BD.cmp_dump_file_name /= \"\";\n      if BD.CD.comp_dump_requested then\n        Create (BD.CD.comp_dump, Name => To_String (BD.cmp_dump_file_name));\n        Put_Line (BD.CD.comp_dump,\n          \"Compiler: main unit file name is \" & main_file_name);\n      end if;\n\n      Progress (\"HAC Ada Compiler version \" & version & \", \" & reference, 1);\n      Progress (\"Compiling main: \" & main_file_name, 1);\n\n      begin\n        Compiler.Init_for_new_Build (BD.CD.all);\n      exception\n        when End_Error =>\n          --  Happens if the text stream is empty.\n          Errors.Error (BD.CD.all, err_unexpected_end_of_text, severity => Errors.major);\n      end;\n\n      as_specification := main_file_name (main_file_name'Last) = 's';\n\n      Compiler.Compile_Unit\n        (CD                     => BD.CD.all,\n         LD                     => BD.LD,\n         upper_name             => To_String (BD.main_name_hint),\n         file_name              => main_file_name,\n         as_specification       => as_specification,\n         as_main_unit           => True,\n         needs_opening_a_stream => False,\n         first_compilation      => True,\n         specification_id_index => No_Id,\n         new_id_index           => new_id_index,\n         unit_context           => main_unit.spec_context,\n         kind                   => main_unit.kind,\n         needs_body             => needs_body);\n\n      if as_specification then\n        case main_unit.kind is\n          when Subprogram_Unit =>\n            main_unit.status := Body_Postponed;\n          when Package_Declaration =>\n            main_unit.status := (if needs_body then Body_Postponed else Spec_Only);\n          when Package_Body =>\n            null;  --  Not relevant (spec.)\n        end case;\n      else\n        case main_unit.kind is\n          when Procedure_Unit =>\n            --  !!  The following should be performed by Statements_Part_Closing\n            --      in Parser... But it doesn't happen for the main block.\n            BD.CD.Blocks_Table (1).SrcTo := BD.CD.CUD.location.line;\n          when Function_Unit =>\n            null;\n          when Package_Body =>\n            null;\n          when Package_Declaration =>\n            null;  --  not relevant\n        end case;\n        main_unit.status := Done;\n      end if;\n\n      Progress (\"Compilation of \" & main_file_name & \" (main) completed\", 2);\n\n      main_unit.id_index := new_id_index;\n      Librarian.Change_Unit_Details (BD.LD, main_unit);\n      --\n      --  Here: compilation of Main unit is finished (with or without\n      --  minor or medium errors).\n      --\n      Complete_Graph_Build;\n      --\n      --  Here: build of the whole unit graph is finished (with or without\n      --  minor or medium errors).\n      --\n      Finalize_Target;\n      --\n      if BD.CD.LC > BD.CD.ObjCode'First\n        and then BD.CD.target.all not in Targets.HAC_Virtual_Machine.Machine'Class\n      then\n        --  Some machine code was emitted for the HAC VM instead of the alternative target.\n        Errors.Error\n          (BD.CD.all,\n           err_general_error,\n           \"Code generation for alternative target (non-HAC-VM) is incomplete\");\n      end if;\n      --\n      if BD.CD.error_count = 0 then\n        Parser.Helpers.Check_Incomplete_Definitions (BD.CD.all, 0);\n      end if;\n\n      if BD.CD.diags /= no_diagnostic then\n        Errors.Compilation_Diagnostics_Summary (BD.CD.all);\n      end if;\n\n      if BD.CD.comp_dump_requested then\n        Compiler.Print_Tables (BD.CD.all);\n        Close (BD.CD.comp_dump);\n      end if;\n      if BD.asm_dump then\n        Compiler.Dump_HAC_VM_Asm (BD.CD.all, BD.CD.target.Assembler_File_Name);\n      end if;\n      if BD.CD.listing_requested then\n        Close (BD.CD.listing);\n      end if;\n      if Length (BD.obj_map_file_name) > 0 then\n        Dump_Object_Map (To_String (BD.obj_map_file_name));\n      end if;\n    exception\n      when Errors.Compilation_of_package_body_before_spec =>\n        Restart_with_Spec;\n      when E : HAC_Sys.Librarian.Circular_Unit_Dependency =>\n        Finalize_Target;  --  Needed even on incomplete compilation.\n        Errors.Error\n          (BD.CD.all,\n           Defs.err_library_error,\n           \"circular unit dependency (\"\"->\"\" means \"\"depends on\"\"): \" &\n           To_String (BD.main_name_hint) & \" -> \" &\n           Exception_Message (E));\n    end Build_Main_Inner;\n\n  begin\n    Build_Main_Inner;\n  exception\n    when Errors.Compilation_abandoned =>\n      --  Hit a severe error...\n      Finalize_Target;  --  Needed even on incomplete compilation.\n      Errors.Compilation_Diagnostics_Summary (BD.CD.all);\n      if BD.CD.comp_dump_requested then\n        Compiler.Print_Tables (BD.CD.all);\n        Close (BD.CD.comp_dump);\n      end if;\n      if BD.asm_dump then\n        Compiler.Dump_HAC_VM_Asm (BD.CD.all, BD.CD.target.Assembler_File_Name);\n      end if;\n  end Build_Main;\n\n  procedure Build_Main_from_File\n    (BD                            : in out Build_Data;\n     file_name                     :        String;\n     body_compilation_rounds_limit :        Rounds_Range := full_build)\n  is\n    source_stream : Co_Defs.Source_Stream_Access;\n  begin\n    BD.CD.error_count := 0;\n    if BD.LD.cat.Exists (file_name) then\n      BD.LD.cat.Source_Open (file_name, source_stream);\n    else\n      BD.CD.CUD.location := (0, 1, 1);\n      Errors.Error\n        (BD.CD.all, Defs.err_library_error,\n         \"file \" & file_name & \" not found\", severity => Errors.medium);\n    end if;\n    if BD.CD.error_count = 0 then\n      BD.Set_Main_Source_Stream (source_stream, file_name);\n      BD.Build_Main (body_compilation_rounds_limit);\n      BD.LD.cat.Close (file_name);\n    end if;\n  end Build_Main_from_File;\n\n  procedure Set_Diagnostic_Parameters\n    (BD                 : in out Build_Data;\n     asm_dump           :        Boolean := False;  --  Assembler output of compiled object code\n     cmp_dump_file_name :        String  := \"\";     --  Compiler dump\n     listing_file_name  :        String  := \"\";     --  Listing of source code with details\n     obj_map_file_name  :        String  := \"\")     --  Output of objects (map)\n  is\n    use HAT;\n  begin\n    BD.asm_dump           := asm_dump;\n    BD.cmp_dump_file_name := To_VString (cmp_dump_file_name);\n    BD.listing_file_name  := To_VString (listing_file_name);\n    BD.obj_map_file_name  := To_VString (obj_map_file_name);\n  end Set_Diagnostic_Parameters;\n\n  procedure Set_Remark_Set\n    (BD  : in out Build_Data;\n     set : in     Defs.Remark_Set) is\n  begin\n    BD.global_remarks := set;\n  end Set_Remark_Set;\n\n  --  Set current main source stream (file, editor data, zipped file,...)\n  procedure Set_Main_Source_Stream\n    (BD         : in out Build_Data;\n     s          : in     Co_Defs.Source_Stream_Access;\n     file_name  : in     String;         --  Can be a virtual name (editor title, zip entry)\n     start_line : in     Natural := 0)   --  We could have a shebang or other Ada sources before\n  is\n    main_name_guess : String := Ada.Characters.Handling.To_Upper (file_name);\n    last_slash, last_dot : Natural := 0;\n  begin\n    Co_Defs.Set_Source_Stream (BD.CD.CUD, s, file_name, start_line);\n    --  Guess unit name from file name (operation is the reverse of GNAT_Naming in Librarian).\n    for i in main_name_guess'Range loop\n      case main_name_guess (i) is\n        when '.'       => last_dot := i;\n        when '/' | '\\' => last_slash := i;\n        when '-'       => main_name_guess (i) := '.';  --  Child unit (GNAT naming convention)\n        when others    => null;\n      end case;\n    end loop;\n    if last_dot = 0  --  no dot at all\n      or else last_dot < last_slash  --  dot only in a path\n    then\n      last_dot := main_name_guess'Last + 1;\n    end if;\n    BD.main_name_hint := HAT.To_VString (main_name_guess (last_slash + 1 .. last_dot - 1));\n  end Set_Main_Source_Stream;\n\n  procedure Set_File_Catalogue\n    (BD  : in out Build_Data;\n     cat : in     Files.Abstract_File_Catalogue_Reference)\n  is\n  begin\n    BD.CD.Set_File_Catalogue (cat);\n    BD.LD.Set_File_Catalogue (cat);\n  end Set_File_Catalogue;\n\n  procedure Set_Message_Feedbacks\n    (BD           : in out Build_Data;\n     trace_params : in     Co_Defs.Compilation_Trace_Parameters)\n  is\n  begin\n    Compiler.Set_Message_Feedbacks (BD.CD.all, trace_params);\n  end Set_Message_Feedbacks;\n\n  procedure Set_Target\n    (BD         : in out Build_Data;\n     new_target :        Targets.Abstract_Machine_Reference)\n  is\n    use Targets;\n  begin\n    if new_target /= null then\n      BD.target := new_target;\n    end if;\n  end Set_Target;\n\n  function Build_Successful (BD : Build_Data) return Boolean is\n  begin\n    return Compiler.Unit_Compilation_Successful (BD.CD.all);\n    --  NB: currently, only full builds are supported.\n  end Build_Successful;\n\n  function Total_Compiled_Lines (BD : Build_Data) return Natural is\n  begin\n    return BD.CD.total_lines;\n  end Total_Compiled_Lines;\n\n  function Object_Code_Size (BD : Build_Data) return Natural is\n  begin\n    return Compiler.Unit_Object_Code_Size (BD.CD.all);\n    --  Whatever the build mode, the entire object code lands into BD.CD's object code.\n  end Object_Code_Size;\n\n  function Folded_Instructions (BD : Build_Data) return Natural is\n  begin\n    return BD.CD.folded_instructions;\n  end Folded_Instructions;\n\n  function Specialized_Instructions (BD : Build_Data) return Natural is\n  begin\n    return BD.CD.specialized_instructions;\n  end Specialized_Instructions;\n\n  function Maximum_Object_Code_Size return Natural is\n  begin\n    return Defs.CDMax;\n  end Maximum_Object_Code_Size;\n\nend HAC_Sys.Builder;\n"
  },
  {
    "path": "src/compile/hac_sys-builder.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  Builder: *the* entry point for building an executable (possibly for the p-code\n--  virtual machine) from Ada sources (a main procedure and possible depending units).\n\nwith HAC_Sys.Co_Defs,\n     HAC_Sys.Defs,\n     HAC_Sys.Files,\n     HAC_Sys.Librarian,\n     HAC_Sys.Targets;\n\nwith HAT;\n\nwith Ada.Containers.Hashed_Maps,\n     Ada.Finalization,\n     Ada.Strings.Unbounded.Hash;\n\npackage HAC_Sys.Builder is\n\n  package String_Maps is new Ada.Containers.Hashed_Maps\n    (Key_Type        => HAT.VString,\n     Element_Type    => HAT.VString,\n     Hash            => Ada.Strings.Unbounded.Hash,\n     Equivalent_Keys => HAT.\"=\",\n     \"=\"             => HAT.\"=\");\n\n  type Build_Data is new Ada.Finalization.Limited_Controlled with record\n    CD                  : Co_Defs.Compiler_Data_Access := new Co_Defs.Compiler_Data;\n    LD                  : Librarian.Library_Data;\n    global_VM_variables : String_Maps.Map;\n    global_remarks      : Defs.Remark_Set := Defs.default_remarks;\n    --  Main name hint is the upper-case Ada name of the main unit\n    --  as guessed from a file name.\n    --  This is used for circular unit dependency detection.\n    --  The name has to be known before the parsing of main unit's\n    --  context clause, and so, before the parsing of the name itself.\n    main_name_hint      : HAT.VString;\n    asm_dump            : Boolean := False;  --  Assembler output of compiled object code\n    cmp_dump_file_name  : HAT.VString;       --  Compiler dump\n    listing_file_name   : HAT.VString;       --  Listing of source code with details\n    obj_map_file_name   : HAT.VString;       --  Output of variables (map)\n    target              : Targets.Abstract_Machine_Reference := null;  --  Always heap-allocated!\n  end record;\n\n  overriding procedure Finalize (BD : in out Build_Data);\n\n  type Rounds_Range is range 0 .. 1e9;\n  compile_only : constant Rounds_Range := Rounds_Range'First;\n  full_build   : constant Rounds_Range := Rounds_Range'Last;\n\n  --  Build a main unit (possibly, the main procedure).\n  --  The main unit's source code stream is already\n  --  available via Set_Main_Source_Stream.\n  --  If the stream stems from a file, the file must be already open and won't be closed.\n  --\n  --  Build_Main takes care of all other needed compilations around main as well,\n  --  depending on the value of body_compilation_rounds_limit.\n  --    body_compilation_rounds_limit = 0 -> compile the given unit only, plus the WITH-ed specs.\n  --    body_compilation_rounds_limit = full_build (default) -> main procedure will be executable.\n  --\n  procedure Build_Main\n    (BD                            : in out Build_Data;\n     body_compilation_rounds_limit :        Rounds_Range := full_build);\n\n  procedure Build_Main_from_File\n    (BD                            : in out Build_Data;\n     file_name                     :        String;\n     body_compilation_rounds_limit :        Rounds_Range := full_build);\n\n  procedure Set_Diagnostic_Parameters\n    (BD                 : in out Build_Data;\n     asm_dump           :        Boolean := False;  --  Assembler output of compiled object code\n     cmp_dump_file_name :        String  := \"\";     --  Compiler dump\n     listing_file_name  :        String  := \"\";     --  Listing of source code with details\n     obj_map_file_name  :        String  := \"\");    --  Output of objects (map)\n\n  procedure Set_Remark_Set\n    (BD  : in out Build_Data;\n     set : in     Defs.Remark_Set);\n\n  --  Set current main source stream (file, editor data, zipped file,...)\n  procedure Set_Main_Source_Stream\n    (BD         : in out Build_Data;\n     s          : in     Co_Defs.Source_Stream_Access;\n     file_name  : in     String;         --  Can be a virtual name (editor title, zip entry)\n     start_line : in     Natural := 0);  --  We could have a shebang or other Ada sources before\n\n  procedure Set_File_Catalogue\n    (BD  : in out Build_Data;\n     cat : in     Files.Abstract_File_Catalogue_Reference);\n\n  procedure Set_Message_Feedbacks (\n    BD           : in out Build_Data;\n    trace_params : in     Co_Defs.Compilation_Trace_Parameters\n  );\n\n  procedure Set_Target\n    (BD         : in out Build_Data;\n     new_target :        Targets.Abstract_Machine_Reference);\n\n  function Build_Successful (BD : Build_Data) return Boolean;\n  function Total_Compiled_Lines (BD : Build_Data) return Natural;\n  function Object_Code_Size (BD : Build_Data) return Natural;\n  function Folded_Instructions (BD : Build_Data) return Natural;\n  function Specialized_Instructions (BD : Build_Data) return Natural;\n  function Maximum_Object_Code_Size return Natural;\n\nend HAC_Sys.Builder;\n"
  },
  {
    "path": "src/compile/hac_sys-co_defs.adb",
    "content": "with HAC_Sys.Targets.HAC_Virtual_Machine;\n\nwith Ada.Unchecked_Deallocation;\n\npackage body HAC_Sys.Co_Defs is\n\n  procedure Construct_Root (Root : out Exact_Typ; Typ : Typen) is\n  begin\n    Root.TYP      := Typ;\n    Root.Ref      := 0;\n    Root.Is_Range := False;\n  end Construct_Root;\n\n  overriding procedure Construct_Root (Root : out Exact_Subtyp; Typ : Typen) is\n  begin\n    Construct_Root (Exact_Typ (Root), Typ);  --  Call parent method.\n    Root.Discrete_First := HAC_Integer'First;\n    Root.Discrete_Last  := HAC_Integer'Last;\n  end Construct_Root;\n\n  function Construct_Root (Typ : Typen) return Exact_Subtyp is\n    result : Exact_Subtyp;\n  begin\n    Construct_Root (result, Typ);\n    return result;\n  end Construct_Root;\n\n  procedure Elevate_to_Maybe (item : in out No_Maybe_Yes) is\n  begin\n    --  no    -> maybe\n    --  maybe -> maybe\n    --  yes   -> yes\n    item := No_Maybe_Yes'Max (item, maybe);\n  end Elevate_to_Maybe;\n\n  procedure Elevate_to_Maybe_or_Yes (item : in out No_Maybe_Yes; context : Flow_Context) is\n  begin\n    if context.is_within_condition or context.is_within_loop then\n      --  The condition might not be fullfilled, the loop might be skipped.\n      Elevate_to_Maybe (item);\n    else\n      item := yes;\n    end if;\n  end Elevate_to_Maybe_or_Yes;\n\n  procedure Set_Source_Stream\n    (CUD        : in out Current_Unit_Data;\n     s          : in     Source_Stream_Access;\n     file_name  : in     String;         --  Can be a virtual name (editor title, zip entry)\n     start_line : in     Natural := 0)\n  is\n  begin\n    CUD.compiler_stream  := s;\n    CUD.source_file_name := HAT.To_VString (file_name);\n    CUD.location.line    := start_line;\n  end Set_Source_Stream;\n\n  function Get_Source_Name (CUD : Current_Unit_Data) return String is\n  begin\n    return HAT.VStr_Pkg.To_String (CUD.source_file_name);\n  end Get_Source_Name;\n\n  function Source_Buffer_has_Data (CUD : Current_Unit_Data) return Boolean is\n  (CUD.buffer_length > 0);\n\n  procedure Unchecked_Free is\n    new Ada.Unchecked_Deallocation\n      (Targets.Machine'Class, Targets.Abstract_Machine_Reference);\n\n  function Is_Executable (CD : Compiler_Data) return Boolean is\n  begin\n    return CD.main_proc_id_index /= HAC_Sys.Co_Defs.No_Id;\n  end Is_Executable;\n\n  function Is_HAC_VM (CD : Compiler_Data) return Boolean\n  is\n    use Targets;\n  begin\n    return CD.target /= null\n      and then CD.target.all in HAC_Virtual_Machine.Machine'Class;\n  end Is_HAC_VM;\n\n  procedure Set_Target\n    (CD : in out Compiler_Data; new_target : Targets.Abstract_Machine_Reference)\n  is\n    use Targets;\n  begin\n    if new_target /= null then\n      if CD.target /= null then\n        Unchecked_Free (CD.target);\n      end if;\n      CD.target := new_target;\n      --  Special case for a special target: the HAC VM.\n      if new_target.all in HAC_Virtual_Machine.Machine'Class then\n        HAC_Virtual_Machine.Machine (new_target.all).CD := CD'Unchecked_Access;\n      end if;\n    end if;\n  end Set_Target;\n\n  procedure Set_File_Catalogue\n    (CD  : in out Compiler_Data;\n     cat : in     Files.Abstract_File_Catalogue_Reference)\n  is\n  begin\n    CD.cat := cat;\n  end Set_File_Catalogue;\n\n  overriding procedure Initialize (CD : in out Compiler_Data) is\n  begin\n    --  Ensure the CD has a valid target from the beginning:\n    CD.Set_Target (new Targets.HAC_Virtual_Machine.Machine);\n  end Initialize;\n\n  overriding procedure Finalize (CD : in out Compiler_Data) is\n  begin\n    Unchecked_Free (CD.target);\n  end Finalize;\n\n  function Discrete_Image\n    (CD : Compiler_Data; value : HAC_Integer; Typ : Typen; Ref : Index) return String is\n  begin\n    case Typ is\n      when Ints  => return HAC_Image (value);\n      when Bools => return Boolean'Image (Boolean'Val (value));\n      when Chars => return Character'Image (Character'Val (value));\n      when Enums =>\n        if value in 0 .. CD.id_table (Ref).xtyp.Discrete_Last then\n          return A2S (CD.id_table (Ref + 1 + Integer (value)).name_with_case);\n        else\n          return \"[invalid position: \" &  HAC_Image (value) & ']';\n        end if;\n      when others => raise Program_Error with \"Non-discrete type\";\n    end case;\n  exception\n    when Constraint_Error =>\n      return \"[invalid position: \" &  HAC_Image (value) & ']';\n  end Discrete_Image;\n\n  function Discrete_Range_Image\n    (CD : Compiler_Data; value_1, value_2 : HAC_Integer; Typ : Typen; Ref : Index) return String is\n  begin\n    return\n      Discrete_Image (CD, value_1, Typ, Ref) &\n      \" .. \" &\n      Discrete_Image (CD, value_2, Typ, Ref);\n  end Discrete_Range_Image;\n\n  function Size_of (CD : Compiler_Data; Id_Index : Natural) return Positive is\n    X : constant Exact_Subtyp := CD.id_table (Id_Index).xtyp;\n  begin\n    case X.TYP is\n      when Arrays =>\n        return CD.Arrays_Table (X.Ref).Array_Size;\n      when Records =>\n        return CD.Blocks_Table (X.Ref).VSize;\n      when others =>\n        return 1;\n    end case;\n  end Size_of;\n\n  procedure Increment_Nesting_or_Descending_Level (CD : in out Compiler_Data) is\n  begin\n    CD.CUD.use_hat_stack_top := CD.CUD.use_hat_stack_top + 1;\n    if CD.CUD.use_hat_stack_top > 0 then\n      --  \"Inherit\" the possible presence of a USE clause for HAT.\n      CD.CUD.Use_HAT_Stack (CD.CUD.use_hat_stack_top) :=\n        CD.CUD.Use_HAT_Stack (CD.CUD.use_hat_stack_top - 1);\n    end if;\n  end Increment_Nesting_or_Descending_Level;\n\n  procedure Decrement_Nesting_or_Descending_Level (CD : in out Compiler_Data) is\n  begin\n    CD.CUD.use_hat_stack_top := CD.CUD.use_hat_stack_top - 1;\n  end Decrement_Nesting_or_Descending_Level;\n\nbegin\n  undefined_subtyp.Construct_Root (NOTYP);\nend HAC_Sys.Co_Defs;\n"
  },
  {
    "path": "src/compile/hac_sys-co_defs.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  Co_Defs: Compiler Definitions\n\nwith HAC_Sys.Defs,\n     HAC_Sys.Files.Default,\n     HAC_Sys.PCode,\n     HAC_Sys.Targets;\n\nwith HAT;\n\nwith Ada.Containers.Hashed_Maps,\n     Ada.Containers.Indefinite_Hashed_Maps,\n     Ada.Finalization,\n     Ada.Strings.Hash,\n     Ada.Strings.Unbounded.Hash,\n     Ada.Text_IO;\n\npackage HAC_Sys.Co_Defs is\n  --  NB: cannot be a child package of Compiler because of Parser, Scanner, ...\n\n  use Defs;\n\n  ------------------\n  --  Exact type  --\n  ------------------\n\n  type Exact_Typ is tagged record  --  NB: was called \"Item\" in SmallAda.\n    TYP  : Typen;\n    Ref  : Index;\n    --  If TYP is not a standard type, then (TYP, Ref) does identify the base type.\n    --  E.g. it can be (Enums, [index of the enumerated type definition]).\n    --\n    --  Ref is an index into different tables, depending on TYP:\n    --    If TYP = Records,      Block_Table;\n    --    if TYP = Arrays,       Arrays_Table;\n    --    if TYP = Enums,        Idtab (the enumeration type's declaration).\n    --\n    Is_Range : Boolean;\n    --  ^ For X'Range expressions, indicates a pair of values waiting on the stack.\n  end record;\n\n  procedure Construct_Root (Root : out Exact_Typ; Typ : Typen)\n  with Inline;\n\n  ---------------------\n  --  Exact subtype  --\n  ---------------------\n\n  type Exact_Subtyp is new Exact_Typ with record\n    Discrete_First : HAC_Integer;   --  If subtype S is discrete, S'First\n    Discrete_Last  : HAC_Integer;   --  If subtype S is discrete, S'Last\n  end record;\n\n  overriding procedure Construct_Root (Root : out Exact_Subtyp; Typ : Typen)\n  with Inline;\n\n  function Construct_Root (Typ : Typen) return Exact_Subtyp\n  with Inline;\n\n  undefined_subtyp : Exact_Subtyp;  --  This global variable is initialized.\n\n  -------------------------------------------------------------------------\n  ------------------------------------------------------------ATabEntry----\n  -------------------------------------------------------------------------\n  --  An Array Table Entry represents an array.  Each entry contains\n  --  the following fields (fields marked with a C are used only by\n  --  the compiler and ignored by the interpreter):\n  --\n  type Array_Table_Entry is record\n    Index_xTyp   : Exact_Subtyp;  --  C  Subtype of the index (with bounds).\n    Element_Size : Index;         --     Size of an element.\n    Element_xTyp : Exact_Subtyp;  --  C  Subtype of the elements of the array.\n                                  --     If the elements of the array are themselves\n                                  --     arrays, Element_xTYP.Ref is an index to an\n                                  --     entry in Arrays_Table (it's not a special case).\n    Array_Size   : Index;         --  C  Total size of the array.\n    dimensions   : Positive;      --  C  Total dimensions of the array.\n  end record;\n\n  -------------------------------------------------------------------------\n  ------------------------------------------------------------BTabEntry----\n  -------------------------------------------------------------------------\n  --  Block Table Entry : Each entry represents a subprogram or a record type.\n  --\n  --  A subprogram activation record consists of:\n  --\n  --         (1) the five word fixed area; (see definition of S in Interpreter)\n  --         (2) an area for the actual parameters (whether values or\n  --             addresses), and\n  --         (3) an area for the local variables of the subprogram\n  --\n  --  Once again, fields marked with C are used only by the compiler\n  --\n  type Block_Table_Entry is record\n    Id                 : Alfa;         --   Name of the block\n    Last_Id_Idx        : Index;        -- C index of the last identifier in this block\n    First_Param_Id_Idx : Index;        -- C index of the first parameter in this block\n    Last_Param_Id_Idx  : Index;        -- C index of the last parameter in this block\n                                       --     (if first > last, it's parameterless)\n    PSize              : Index;        --   sum of the lengths of areas (1) & (2) above\n    VSize              : Index := 0;   --   sum of PSize and length of area (3)\n                                       --   (i.e. size of the activation record for\n                                       --    this block if it is a subprogram)\n    SrcFrom            : Positive;     --   Source code line count.  Source starts here\n    SrcTo              : Positive;     --   and goes until here    (* Manuel *)\n  end record;\n\n  fixed_area_size : constant := 5;  --  Size of area (1) described above.\n\n  type Package_Table_Entry is record\n    first_public_declaration  : Positive;\n    last_public_declaration   : Natural;   -- = 0 if none.\n    last_private_declaration  : Natural;   -- = 0 if none.\n  end record;\n\n  type Entity_Kind is  --  RM 3.1\n    (declared_number_or_enum_item,  --  Declared number: untyped constant, like\n                                    --  \"pi : constant := 3.1415927\" (RM 3.3.2)\n     --\n     variable_object,  --  RM 3.3.1(5)\n     constant_object,  --  RM 3.3.1(6)\n     --\n     type_mark,\n     --\n     paquetage,\n     paquetage_body,\n     --\n     prozedure,\n     prozedure_intrinsic,\n     funktion,\n     funktion_intrinsic,\n     --\n     tache,\n     entree,\n     --\n     loop_identifier,\n     alias);   --  Short name of another entity (\"use\" clause).\n\n  subtype Object_Kind is Entity_Kind range variable_object .. constant_object;  --  RM 3.3\n\n  type Declaration_Kind is\n    (spec_unresolved, spec_resolved, complete,\n     param_in, param_in_out, param_out);\n\n  subtype Split_Declaration_Kind is Declaration_Kind range spec_unresolved .. complete;\n\n  subtype Parameter_Kind is Declaration_Kind range param_in .. param_out;\n\n  type Initialized_Kind is (none, explicit, implicit);\n\n  type No_Maybe_Yes is (no, maybe, yes);\n\n  --  Unless we are in the main execution path (not within \"if\", \"loop\", etc.)\n  --  we can only note that a variable or field is *maybe* read or written.\n  --\n  procedure Elevate_to_Maybe (item : in out No_Maybe_Yes)\n  with Inline;\n\n  --  Elevate certainty level to \"maybe\" or \"yes\", depending on the context.\n  --\n  procedure Elevate_to_Maybe_or_Yes (item : in out No_Maybe_Yes; context : Flow_Context)\n  with Inline;\n\n  ------------------------------\n  --  Identifier Table Entry  --\n  ------------------------------\n  type Identifier_Table_Entry is record\n    name             : Alfa;                   --  Identifier name in ALL CAPS\n    name_with_case   : Alfa;                   --  Identifier name with original casing\n    link             : Index;                  --  Previous declaration on same nesting level, or No_Id\n    entity           : Entity_Kind;\n    decl_kind        : Declaration_Kind;       --  Declaration kind: forward or complete.\n    --                                             Matters for a type, a constant, a subprogram;\n    --                                             Values param_in .. param_out are\n    --                                             for subprogram parameters.\n    xtyp                  : Exact_Subtyp;      --  Subtype identification\n    block_or_pkg_ref      : Index;             --  Reference in the block or package tables.\n    normal                : Boolean;           --  value param?\n    lev                   : Nesting_Level;\n    adr_or_sz             : HAC_Integer;       --  Address, Size; index of aliased entity (USE) !! rather use block_or_pkg_ref ?!\n    is_referenced         : Boolean;           --  For any item: is it referenced at all?\n    is_read               : No_Maybe_Yes;      --  For variable or constant: is it read?\n    is_written_after_init : No_Maybe_Yes;      --  Is variable written via \":=\" or \"out\" mode?\n    is_initialized        : Initialized_Kind;  --  For variable or constant: is it initialized?\n    location              : Symbol_Location;\n  end record;\n\n  --  Entity                        Meaning of Adr_or_Sz\n  --  -------------------------------------------------------------------------------\n  --  declared_number_or_enum_item  Value (number), position (enumerated type)\n  --  variable_object               Relative position in the stack.\n  --  constant_object               Relative position in the stack.\n  --  type_mark                     Size (in PCode stack items) of an object\n  --                                    of the declared type.\n  --  prozedure                     Index into the Object Code table.\n  --  prozedure_intrinsic           Standard Procedure code (SP_Code).\n  --  funktion                      Index into the Object Code table.\n  --  funktion_intrinsic            Standard Function code (SF_Code).\n  --  tache                         ?\n  --  entree                        ?\n  --  loop_identifier               ?\n  --  alias                         Index into the Identifier table of the aliased entity.\n\n  type Loop_Info is record\n    loop_Id     : Natural;  --  No_Id : no identifier\n    is_FOR_loop : Boolean;  --  Emit k_FOR_Release_Stack for each exited FOR loop\n    start_line  : Natural;\n  end record;\n\n  subtype Source_Buffer_String is String (1 .. 65_536);\n\n  subtype Source_Line_String is String (1 .. 1000);  --  Must be at least 200 (RM 2.2 (15))\n\n  -----------------------\n  --  Compiler tables  --\n  -----------------------\n\n  type    Arrays_Table_Type            is array (1 .. AMax)             of Array_Table_Entry;\n  type    Blocks_Table_Type            is array (0 .. BMax)             of Block_Table_Entry;\n  type    Display_Type                 is array (Nesting_Level)         of Integer;\n  type    Entries_Table_Type           is array (0 .. entry_table_max)  of Index;\n  type    Identifier_Table_Type        is array (0 .. Id_Table_Max)     of Identifier_Table_Entry;\n  type    Nested_Loop_Table_Type       is array (1 .. loop_nesting_max) of Loop_Info;\n  type    Packages_Table_Type          is array (0 .. package_table_max)             of Package_Table_Entry;\n  type    Tasks_Definitions_Table_Type is array (0 .. TaskMax)          of Index;\n  --      ^ Task #0 is main task.\n\n  type    Use_HAT_Stack_Type           is array (0 .. nesting_and_descending_max) of Boolean;\n\n  --  Display: keeps track of addressing by nesting level. See Ben-Ari Appendix A.\n\n  No_Id       : constant :=  0;\n  No_Id_Cache : constant := -1;\n\n  subtype Source_Stream_Access is Files.Root_Stream_Class_Access;\n\n  package Id_Maps is new Ada.Containers.Hashed_Maps\n    (Key_Type        => Alfa,\n     Element_Type    => Positive,\n     Hash            => Ada.Strings.Unbounded.Hash,\n     Equivalent_Keys => HAT.\"=\");\n\n  type Current_Unit_Data is record\n    --  Current source code information and scanner data\n    compiler_stream   : Source_Stream_Access;\n    source_file_name  : HAT.VString;           --  Indicative, for error messages\n    buffer            : Source_Buffer_String;\n    buffer_length     : Natural;               --  = 0 only on init or when exhausted.\n    buffer_position   : Positive;              --  Points to the next character to be read.\n    --  Parsing\n    location          : Symbol_Location;\n    input_line        : Source_Line_String;\n    c, prev_c         : Character;           --  Character read from source program\n    CC                : Integer;             --  Character counter (=column in current line)\n    LL                : Natural;             --  Length of current line\n    --  Level 0 definitions visible to currently compiled unit:\n    level_0_def       : Id_Maps.Map;\n    Use_HAT_Stack     : Use_HAT_Stack_Type;\n    use_hat_stack_top : Natural;\n  end record;\n\n  --  Set current source stream (file, editor data, zipped file,...)\n  procedure Set_Source_Stream\n    (CUD        : in out Current_Unit_Data;\n     s          : in     Source_Stream_Access;\n     file_name  : in     String;         --  Can be a virtual name (editor title, zip entry)\n     start_line : in     Natural := 0);  --  We could have a shebang or other Ada sources before\n\n  function Get_Source_Name (CUD : Current_Unit_Data) return String;\n\n  function Source_Buffer_has_Data (CUD : Current_Unit_Data) return Boolean;\n\n  type Compilation_Feedback is access procedure (message : String);\n\n  type Compilation_Trace_Parameters is record\n    pipe         : Defs.Smart_Error_Pipe := null;  --  Default: messages to Current_Error.\n    progress     : Compilation_Feedback  := null;  --  Default: messages to Current_Output.\n    detail_level : Natural               := 0;\n  end record;\n\n  default_trace : constant Compilation_Trace_Parameters := (others => <>);\n\n  procedure Silent_Diagnostics (kit : Diagnostic_Kit) is null;\n  procedure Silent_Feedback (message : String) is null;\n\n  silent_trace : constant Compilation_Trace_Parameters :=\n    (Silent_Diagnostics'Access, Silent_Feedback'Access, 0);\n\n  type Dummy_Procedure_Access is access procedure;\n\n  package Exported_Procedure_Mapping is new Ada.Containers.Indefinite_Hashed_Maps\n    (Key_Type        => String,\n     Element_Type    => Dummy_Procedure_Access,\n                        --  Actually: HAC_Sys.Interfacing.Exported_Procedure, but we\n                        --  end up in a circular unit dependency mess.\n     Hash            => Ada.Strings.Hash,\n     Equivalent_Keys => \"=\");\n\n  --  Global object used as a default for library file management:\n  default_file_catalogue : aliased Files.Default.File_Catalogue;\n\n  ---------------------\n  --  Compiler_Data  --\n  ---------------------\n\n  type Compiler_Data is new Ada.Finalization.Limited_Controlled with record\n    CUD : Current_Unit_Data;\n    --  Scanning & Parsing\n    Sy, prev_sy      : Symbol;         --  sy: last Symbol read by In_Symbol\n    prev_sy_loc      : Symbol_Location;\n    Id               : Alfa;               --  Identifier from In_Symbol\n    Id_with_case     : Alfa;               --  Same as Id, but with casing.\n    Id_location      : Integer;            --  Cache for Locate_CD_Id\n    INum             : HAC_Integer;        --  Integer from In_Symbol\n    RNum             : HAC_Float;          --  Float number from In_Symbol\n    SLeng            : Integer;            --  String Length\n    pkg_prefix       : HAT.VString;        --  Prefix of package being currently parsed.\n    --  Compiler tables. Floats and Strings are used by interpreter at run-time.\n    Arrays_Table            : Arrays_Table_Type;  --  NB: only static-sized arrays so far.\n    Blocks_Table            : Blocks_Table_Type;\n    Display                 : Display_Type;\n    Entries_Table           : Entries_Table_Type;\n    Float_Constants_Table   : Float_Constants_Table_Type;\n    id_table                : Identifier_Table_Type;\n    Nested_Loop_Table       : Nested_Loop_Table_Type;\n    Packages_Table          : Packages_Table_Type;\n    Strings_Constants_Table : Strings_Constants_Table_Type;\n    Tasks_Definitions_Table : Tasks_Definitions_Table_Type;\n    --  Indices to compiler tables\n    Arrays_Count            : Natural;\n    Blocks_Count            : Natural;\n    Entries_Count           : Natural;\n    Float_Constants_Count   : Natural;\n    Id_Count                : Natural;\n    loop_nesting_level      : Natural;\n    main_proc_id_index      : Natural := No_Id;  --  No_Id <=> the main unit is not executable.\n    Packages_Count          : Natural;\n    String_Id_Index         : Natural;\n    Strings_Table_Top       : Natural;\n    Tasks_Definitions_Count : Natural;\n    --  Object code\n    --  Mostly for HAC VM / p-code -> will be moved to HAC_Sys.Targets.HAC_Virtual_Machine)\n    target                  : Targets.Abstract_Machine_Reference := null;\n    ObjCode                 : PCode.Object_Code_Table (0 .. CDMax);\n    LC                      : Integer;  --  Location counter in the Object_Code_Table\n    CMax                    : Integer;  --  Top of available ObjCode table;\n                                        --  CMax + 1 .. CDMax: variable initialization code\n    folded_instructions      : Natural;\n    specialized_instructions : Natural;\n    --  Information about source code\n    Full_Block_Id             : HAT.VString;         --  Full block's Id (P1.P2.F3.P4)\n    main_unit_ident           : Alfa := Empty_Alfa;\n    main_unit_ident_with_case : Alfa := Empty_Alfa;\n    Exported_Procedures       : Exported_Procedure_Mapping.Map;\n    --\n    listing_requested   : Boolean := False;\n    comp_dump_requested : Boolean := False;\n    listing   : Ada.Text_IO.File_Type;\n    comp_dump : Ada.Text_IO.File_Type;\n    --\n    error_count, minor_error_count : Natural;\n    remarks      : Remark_Set := default_remarks;\n    diags        : Diagnostic_Set;\n    total_lines  : Natural;\n    cat          : Files.Abstract_File_Catalogue_Reference :=\n                     default_file_catalogue'Access;\n    trace        : Compilation_Trace_Parameters;\n    --  On `WITH X`, we start the recursive compilation of X,\n    --  if X is not yet compiled or built-in. We monitor the\n    --  recursion level for the fun of it.\n    recursion    : Natural := 0;\n  end record;\n\n  overriding procedure Initialize (CD : in out Compiler_Data);\n  overriding procedure Finalize (CD : in out Compiler_Data);\n\n  function Is_Executable (CD : Compiler_Data) return Boolean;\n  function Is_HAC_VM (CD : Compiler_Data) return Boolean;\n\n  procedure Set_Target\n    (CD : in out Compiler_Data; new_target : Targets.Abstract_Machine_Reference);\n\n  --  Method used internally by HAC.\n  --  Prefer using Build_Data's Set_File_Catalogue method.\n  --\n  procedure Set_File_Catalogue\n    (CD  : in out Compiler_Data;\n     cat : in     Files.Abstract_File_Catalogue_Reference);\n\n  type Compiler_Data_Access is access all Co_Defs.Compiler_Data;\n\n  --  Image function for compilation errors or out-of-range exception messages.\n  --\n  function Discrete_Image\n    (CD : Compiler_Data; value : HAC_Integer; Typ : Typen; Ref : Index) return String;\n\n  function Discrete_Range_Image\n    (CD : Compiler_Data; value_1, value_2 : HAC_Integer; Typ : Typen; Ref : Index) return String;\n\n  --  Size of a variable or subprogram parameter\n  --\n  function Size_of (CD : Compiler_Data; Id_Index : Natural) return Positive;\n\n  procedure Increment_Nesting_or_Descending_Level (CD : in out Compiler_Data);\n  procedure Decrement_Nesting_or_Descending_Level (CD : in out Compiler_Data);\n\n  Universe : constant HAT.VString := HAT.To_VString (\"[-- The Universe --]\");\n\n  type Constant_Rec is record\n    TP : Exact_Subtyp;\n    I  : HAC_Integer;  --  Includes Character and enumeration types (including Boolean)\n    R  : HAC_Float;\n  end record;\n\nend HAC_Sys.Co_Defs;\n"
  },
  {
    "path": "src/compile/hac_sys-compiler-pcode_emit.adb",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Errors;\n\npackage body HAC_Sys.Compiler.PCode_Emit is\n\n  function Compiler_Data_to_Debug_Info (CD : Compiler_Data) return Debug_Info is\n  begin\n    return (Line_Number   => CD.CUD.location.line,\n            Full_Block_Id => CD.Full_Block_Id,\n            File_Name     => CD.CUD.source_file_name);\n  end Compiler_Data_to_Debug_Info;\n\n  procedure Emit (\n    CD   : in out Compiler_Data;\n    FCT  :        Opcode\n  )\n  is\n  begin\n    Emit_3 (CD, FCT, 0, 0, 0);\n  end Emit;\n\n  procedure Emit_1 (\n    CD   : in out Compiler_Data;\n    FCT  :        Opcode;\n    B    :        Operand_2_Type\n  )\n  is\n  begin\n    Emit_3 (CD, FCT, 0, B, 0);\n  end Emit_1;\n\n  procedure Emit_2 (\n    CD   : in out Compiler_Data;\n    FCT  :        Opcode;\n    a    :        Operand_1_Type;\n    B    :        Operand_2_Type\n  )\n  is\n  begin\n    Emit_3 (CD, FCT, a, B, 0);\n  end Emit_2;\n\n  procedure Emit_3 (\n    CD   : in out Compiler_Data;\n    FCT  :        Opcode;\n    a    :        Operand_1_Type;\n    B    :        Operand_2_Type;\n    c    :        Operand_3_Type\n  )\n  is\n    folded, specialized : Boolean;\n  begin\n    PCode.Emit_Instruction (\n      CD.ObjCode (CD.ObjCode'First .. CD.CMax),\n      --  ^ We don't pass the full object code table (CD.ObjCode)\n      --    but the part before variable initialization code,\n      --    for preventing overwriting existing initialization code.\n      CD.LC, Compiler_Data_to_Debug_Info (CD), FCT, a, B, c,\n      folded,\n      specialized\n    );\n    if folded then\n      CD.folded_instructions := CD.folded_instructions + 1;\n    end if;\n    if specialized then\n      CD.specialized_instructions := CD.specialized_instructions + 1;\n    end if;\n  end Emit_3;\n\n  procedure Emit_Std_Funct (\n    CD    : in out Compiler_Data;\n    Code  :        SF_Code;\n    Extra :        Operand_1_Type := 0\n  )\n  is\n  begin\n    Emit_2 (CD, k_HAT_Function, Extra, SF_Code'Pos (Code));\n  end Emit_Std_Funct;\n\n  procedure Emit_Comparison_Instruction (\n    CD        : in out Compiler_Data;\n    Operator  :        Comparison_Operator;\n    Base_Typ  :        Typen\n  )\n  is\n  begin\n    if Base_Typ = Floats then\n      case Operator is\n        when EQL => Emit (CD, k_EQL_Float);\n        when NEQ => Emit (CD, k_NEQ_Float);\n        when LSS => Emit (CD, k_LSS_Float);\n        when LEQ => Emit (CD, k_LEQ_Float);\n        when GTR => Emit (CD, k_GTR_Float);\n        when GEQ => Emit (CD, k_GEQ_Float);\n      end case;\n    elsif Discrete_Typ (Base_Typ) then\n      case Operator is\n        when EQL => Emit (CD, k_EQL_Integer);\n        when NEQ => Emit (CD, k_NEQ_Integer);\n        when LSS => Emit (CD, k_LSS_Integer);\n        when LEQ => Emit (CD, k_LEQ_Integer);\n        when GTR => Emit (CD, k_GTR_Integer);\n        when GEQ => Emit (CD, k_GEQ_Integer);\n      end case;\n    elsif Base_Typ = VStrings then\n      case Operator is\n        when EQL => Emit (CD, k_EQL_VString);\n        when NEQ => Emit (CD, k_NEQ_VString);\n        when LSS => Emit (CD, k_LSS_VString);\n        when LEQ => Emit (CD, k_LEQ_VString);\n        when GTR => Emit (CD, k_GTR_VString);\n        when GEQ => Emit (CD, k_GEQ_VString);\n      end case;\n    else\n      raise Errors.Internal_error with\n        \"Emit_Comparison_Instruction: comparison instruction for not supported type\";\n    end if;\n  end Emit_Comparison_Instruction;\n\n  procedure Emit_Unary_Minus (\n    CD        : in out Compiler_Data;\n    Base_Typ  :        Numeric_Typ\n  )\n  is\n  begin\n    case Base_Typ is\n      when Floats => Emit (CD, k_Unary_MINUS_Float);\n      when Ints   => Emit (CD, k_Unary_MINUS_Integer);\n    end case;\n  end Emit_Unary_Minus;\n\n  procedure Emit_Push_Float_Literal (\n    CD : in out Compiler_Data;\n    X  :        HAC_Float\n  )\n  is\n    RNum_Index : Natural;\n  begin\n    Enter_or_find_Float (CD, X, RNum_Index);\n    Emit_1 (CD, k_Push_Float_Literal, Operand_2_Type (RNum_Index));\n  end Emit_Push_Float_Literal;\n\n  procedure Enter_or_find_Float (\n    CD         : in out Compiler_Data;\n    X          :        HAC_Float;\n    RNum_Index :    out Natural\n  )\n  is\n    use Errors;\n    use type HAC_Float;\n  begin\n    if CD.Float_Constants_Count = float_const_table_max - 1 then\n      Fatal (FLOAT_CONSTANTS);  --  Exception is raised there.\n    end if;\n    --  We add X's value as an extra item: potential new item *and* sentinel value.\n    CD.Float_Constants_Table (CD.Float_Constants_Count + 1) := X;\n    RNum_Index := 1;\n    while CD.Float_Constants_Table (RNum_Index) /= X loop  --  Binary equality.\n      RNum_Index := RNum_Index + 1;\n    end loop;\n    if RNum_Index > CD.Float_Constants_Count then  --  X's value was not previously in the table.\n      CD.Float_Constants_Count := RNum_Index;\n    end if;\n  end Enter_or_find_Float;\n\n  procedure Emit_Lower_Bound_Check (CD : in out Compiler_Data; S : Exact_Subtyp) is\n    use type HAC_Integer;\n  begin\n    if S.Discrete_First > HAC_Integer'First then\n      Emit_3\n        (CD, k_Check_Lower_Bound,\n         S.Discrete_First, Typen'Pos (S.TYP), Operand_3_Type (S.Ref));\n    end if;\n  end Emit_Lower_Bound_Check;\n\n  procedure Emit_Upper_Bound_Check (CD : in out Compiler_Data; S : Exact_Subtyp) is\n    use type HAC_Integer;\n  begin\n    if S.Discrete_Last < HAC_Integer'Last then\n      Emit_3\n        (CD, k_Check_Upper_Bound,\n         S.Discrete_Last, Typen'Pos (S.TYP), Operand_3_Type (S.Ref));\n    end if;\n  end Emit_Upper_Bound_Check;\n\nend HAC_Sys.Compiler.PCode_Emit;\n"
  },
  {
    "path": "src/compile/hac_sys-compiler-pcode_emit.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  This package facilitates the code emission for the HAC VM, but will\n--  shrink in the future in favour of HAC_Sys.Targets.HAC_Virtual_Machine.\n\nwith HAC_Sys.Defs,\n     HAC_Sys.PCode;\n\npackage HAC_Sys.Compiler.PCode_Emit is\n\n  --  This layer could be developed to abstract the virtual machine\n  --  code emission, for instance for producing real machine code.\n\n  use Defs, PCode;\n\n  procedure Emit\n    (CD   : in out Compiler_Data;\n     FCT  :        Opcode);\n\n  procedure Emit_1\n    (CD   : in out Compiler_Data;\n     FCT  :        Opcode;\n     B    :        Operand_2_Type);\n\n  procedure Emit_2\n    (CD   : in out Compiler_Data;\n     FCT  :        Opcode;\n     a    :        Operand_1_Type;\n     B    :        Operand_2_Type);\n\n  procedure Emit_3\n    (CD   : in out Compiler_Data;\n     FCT  :        Opcode;\n     a    :        Operand_1_Type;\n     B    :        Operand_2_Type;\n     c    :        Operand_3_Type);\n\n  procedure Emit_Std_Funct\n    (CD    : in out Compiler_Data;\n     Code  :        SF_Code;\n     Extra :        Operand_1_Type := 0);\n\n  procedure Emit_Comparison_Instruction\n    (CD        : in out Compiler_Data;\n     Operator  :        Comparison_Operator;\n     Base_Typ  :        Typen);\n\n  procedure Emit_Unary_Minus\n    (CD        : in out Compiler_Data;\n     Base_Typ  :        Numeric_Typ);\n\n  procedure Emit_Push_Float_Literal\n    (CD : in out Compiler_Data;\n     X  :        HAC_Float);\n\n  procedure Enter_or_find_Float\n    (CD         : in out Compiler_Data;\n     X          :        HAC_Float;\n     RNum_Index :    out Natural);\n\n  procedure Emit_Lower_Bound_Check\n    (CD : in out Compiler_Data; S : Exact_Subtyp);\n\n  procedure Emit_Upper_Bound_Check\n    (CD : in out Compiler_Data; S : Exact_Subtyp);\n\nend HAC_Sys.Compiler.PCode_Emit;\n"
  },
  {
    "path": "src/compile/hac_sys-compiler.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Defs,\n     HAC_Sys.Errors,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Modularity,\n     HAC_Sys.Parser.Packages,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner;\n\nwith HAT;\n\nwith Ada.Integer_Text_IO,\n     Ada.Strings.Fixed,\n     Ada.Text_IO;\n\npackage body HAC_Sys.Compiler is\n\n  use Defs;\n\n  procedure Set_Message_Feedbacks\n    (CD           : in out Compiler_Data;\n     trace_params : in     Compilation_Trace_Parameters)\n  is\n  begin\n    CD.trace := trace_params;\n  end Set_Message_Feedbacks;\n\n  --  Initialize the compiler for a new unit.\n  procedure Init (CUD : in out Current_Unit_Data) is\n  begin\n    CUD.buffer_length   := 0;\n    CUD.buffer_position := 1;\n    CUD.c := ' ';\n    CUD.CC       := 0;\n    CUD.LL       := 0;\n    CUD.location := (0, 1, 1);\n    CUD.level_0_def.Clear;\n    CUD.use_hat_stack_top := 0;\n    CUD.Use_HAT_Stack (CUD.use_hat_stack_top) := False;\n  end Init;\n\n  --  Initialize the compiler for an entire build.\n  procedure Init_for_new_Build (CD : out Compiler_Data) is\n  begin\n    CD.Arrays_Count          := 0;\n    CD.Blocks_Count          := 0;\n    CD.Float_Constants_Count := 0;\n    CD.loop_nesting_level    := 0;\n    CD.Packages_Count        := 0;\n    --  Identifiers\n    CD.Id_Count := 0;\n    CD.id_table (CD.Id_Count).name := Empty_Alfa;\n    --  Strings literals\n    CD.Strings_Table_Top := Strings_Constants_Table_Type'First - 1;\n    --  Tasks, Entries\n    CD.Tasks_Definitions_Count := 0;\n    CD.Entries_Count := 0;\n    --  Location Counter (in output code)\n    CD.LC   := 0;\n    CD.CMax := CDMax;\n    --  Code optimization:\n    CD.folded_instructions      := 0;\n    CD.specialized_instructions := 0;\n    --  Current block name for debugging of HAC programs.\n    CD.Full_Block_Id := Universe;\n    --\n    CD.main_unit_ident           := Empty_Alfa;\n    CD.main_unit_ident_with_case := Empty_Alfa;\n    CD.main_proc_id_index        := No_Id;\n    --\n    --  Current unit data\n    --\n    Init (CD.CUD);\n    --  Scanner data\n    CD.Sy                := Dummy_Symbol;\n    CD.prev_sy_loc       := (0, 1, 1);\n    CD.error_count       := 0;\n    CD.minor_error_count := 0;\n    CD.diags             := no_diagnostic;\n    CD.total_lines       := 0;\n    Scanner.In_Symbol (CD);\n    --\n    CD.Display (0) := 0;  --  Added 7-Dec-2009\n    CD.pkg_prefix := HAT.Null_VString;\n    --\n    CD.target.Initialize_Code_Emission;\n    --\n    --  Block Table Entry 0 is not a real block but serves only for\n    --  its index in the identifier table, which lists global,\n    --  level 0 stuff, outside any subprogram including Main.\n    --  This entry is accessed by Locate_Identifier_Internal (implicitly),\n    --  Dump_Object_Map, Enter_Library_Level_Def (explicitly).\n    CD.Blocks_Table (0) :=\n     (Id                 => S2A (\"--  Definitions at level 0\"),\n      Last_Id_Idx        => 0,  --  Updated by Enter_Library_Level_Def.\n      First_Param_Id_Idx => 1,\n      Last_Param_Id_Idx  => 0,\n      PSize              => 0,\n      VSize              => 0,\n      SrcFrom            => 1,\n      SrcTo              => 1);\n  end Init_for_new_Build;\n\n  --  Print_Tables is for debugging purposes.\n  --\n  procedure Print_Tables (CD : in Compiler_Data) is\n    use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Strings.Fixed;\n    package HIIO is new Integer_IO (HAC_Integer);\n    use HIIO;\n    --\n    function Cut_name (n : String; l : Natural) return String is\n      dots : constant String := \"...\";\n    begin\n      if n'Length > l then\n        return dots & n (n'Last - (l - 1) + dots'Length .. n'Last);\n      else\n        return n;\n      end if;\n    end Cut_name;\n    --\n    procedure Show_Padded (n : String; t : Positive) is\n      trunc : constant String := Cut_name (n, t);\n    begin\n      Put (CD.comp_dump, \"  \" & trunc & Integer'Max (0, t - trunc'Length) * ' ');\n    end Show_Padded;\n    use type Alfa;\n    Alng : constant := 50;  --  Max characters displayed on this dump.\n  begin\n    New_Line (CD.comp_dump);\n    Put_Line (CD.comp_dump,\n       \" Identifiers\" & (Alng - 6) * ' ' &\n       \"Link  Object                        \" &\n       \"TYP                    Ref  Norm Lvl  Adr Blck\"\n    );\n    Put_Line (CD.comp_dump,\n       (Alng + Entity_Kind'Width + Typen'Width + Boolean'Width + 34) * '-'\n    );\n    --  We list all definitions, starting\n    --  from Main (last Id of the \"zero block\" / standard).\n    --\n    for I in 1 .. CD.Id_Count loop\n      declare\n        r : Identifier_Table_Entry renames CD.id_table (I);\n      begin\n        Put (CD.comp_dump, I, 4);\n        Show_Padded (A2S (r.name_with_case), Alng);\n        Put (CD.comp_dump, r.link, 4);\n        Show_Padded (Entity_Kind'Image (r.entity), Entity_Kind'Width);\n        Show_Padded (Typen'Image (r.xtyp.TYP), Typen'Width);\n        Put (CD.comp_dump, r.xtyp.Ref, 5);\n        Show_Padded (Boolean'Image (r.normal), Boolean'Width);\n        Put (CD.comp_dump, Integer (r.lev), 3);\n        Put (CD.comp_dump, r.adr_or_sz, 5);\n        if r.block_or_pkg_ref > 0 then\n          Put (CD.comp_dump, r.block_or_pkg_ref, 5);\n        else\n          Put (CD.comp_dump, \"     \");\n        end if;\n        Put (CD.comp_dump, \"  \" & Declaration_Kind'Image (r.decl_kind));\n        New_Line (CD.comp_dump);\n      end;\n    end loop;\n\n    New_Line (CD.comp_dump);\n    Put_Line (CD.comp_dump, \" Tasks       Block#\");\n    for I in 1 .. CD.Tasks_Definitions_Count loop\n      Put (CD.comp_dump, I, 4);\n      Put (CD.comp_dump, ' ');\n      Put (CD.comp_dump, A2S (CD.id_table (CD.Tasks_Definitions_Table (I)).name) & \"  \");\n      Put (CD.comp_dump, CD.id_table (CD.Tasks_Definitions_Table (I)).block_or_pkg_ref);\n      New_Line (CD.comp_dump);\n    end loop;\n\n    New_Line (CD.comp_dump);\n\n    if CD.Entries_Count > 0 then\n      Put (CD.comp_dump, \" Entries \");\n      New_Line (CD.comp_dump);\n      for I in 1 .. CD.Entries_Count loop\n        Put (CD.comp_dump, I, 4);\n        Put (CD.comp_dump,\n             ' ' & A2S (CD.id_table (CD.Entries_Table (I)).name) & \" in Task \" &\n             A2S (CD.id_table (\n               CD.Tasks_Definitions_Table (Integer (CD.id_table (CD.Entries_Table (I)).adr_or_sz))\n             ).name)\n        );\n        New_Line (CD.comp_dump);\n      end loop;\n      New_Line (CD.comp_dump);\n    end if;\n\n    Put_Line (CD.comp_dump, \" Blocks\" & Alng * ' ' & \"  Last_ID FPar LPar PSze Vsze\");\n    for I in 1 .. CD.Blocks_Count loop\n      declare\n        r : Block_Table_Entry renames CD.Blocks_Table (I);\n      begin\n        Put (CD.comp_dump, I, 4);\n        Show_Padded (A2S (r.Id), Alng);\n        Put (CD.comp_dump, r.Last_Id_Idx, 10);\n        Put (CD.comp_dump, r.First_Param_Id_Idx, 5);\n        Put (CD.comp_dump, r.Last_Param_Id_Idx, 5);\n        Put (CD.comp_dump, r.PSize, 5);\n        Put (CD.comp_dump, r.VSize, 5);\n        New_Line (CD.comp_dump);\n      end;\n    end loop;\n    New_Line (CD.comp_dump);\n\n    if CD.Arrays_Count = 0 then\n      Put_Line (CD.comp_dump, \" Arrays: none\");\n    else\n      Put_Line\n        (CD.comp_dump,\n         \" Array   | Index: typ_________ \" &\n         \" Element: typ_______ref   \" &\n         \" Low___High   El. Size Ar. Size Dims\");\n      --\n      for i in 1 .. CD.Arrays_Count loop\n        declare\n          r : Array_Table_Entry renames CD.Arrays_Table (i);\n          package TIO is new Enumeration_IO (Typen);\n          use TIO;\n          typ_img : String (1 .. Typen'Width);\n        begin\n          Put (CD.comp_dump, i, 7);\n          Put (typ_img, r.Index_xTyp.TYP);    --  Padded\n          Put (CD.comp_dump, \"  | \" & typ_img);\n          Put (typ_img, r.Element_xTyp.TYP);  --  Padded\n          Put (CD.comp_dump, \"  \" & typ_img);\n          Put (CD.comp_dump, r.Element_xTyp.Ref, 3);\n          Put (CD.comp_dump, r.Index_xTyp.Discrete_First, 7);\n          Put (CD.comp_dump, r.Index_xTyp.Discrete_Last,  7);\n          Put (CD.comp_dump, r.Element_Size, 11);\n          Put (CD.comp_dump, r.Array_Size,    9);\n          Put (CD.comp_dump, r.dimensions,    5);\n        end;\n        New_Line (CD.comp_dump);\n      end loop;\n    end if;\n    New_Line (CD.comp_dump);\n\n    if CD.Packages_Count = 0 then\n      Put_Line (CD.comp_dump, \" Packages: none\");\n    else\n      Put_Line\n        (CD.comp_dump, \" Package  | First decl. | Last public | Last private\");\n      for i in 1 .. CD.Packages_Count loop\n        declare\n          p : Package_Table_Entry renames CD.Packages_Table (i);\n        begin\n          Put (CD.comp_dump, i, 8);\n          Put (CD.comp_dump, p.first_public_declaration, 15);\n          Put (CD.comp_dump, p.last_public_declaration,  14);\n          Put (CD.comp_dump, p.last_private_declaration, 15);\n        end;\n        New_Line (CD.comp_dump);\n      end loop;\n    end if;\n    New_Line (CD.comp_dump);\n    Put_Line (CD.comp_dump, \" Library Level visible identifiers (unordered list):\");\n    for l0 of CD.CUD.level_0_def loop\n      Put_Line (CD.comp_dump, \"    \" & A2S (CD.id_table (l0).name));\n    end loop;\n    New_Line (CD.comp_dump);\n\n    if CD.main_unit_ident /= Empty_Alfa then\n      Put_Line (CD.comp_dump, \" Information about Main procedure:\");\n      Put_Line (CD.comp_dump, \"   Name    : \" & A2S (CD.main_unit_ident_with_case));\n      Put_Line (CD.comp_dump, \"   Block # : \" &\n        Defs.Index'Image (CD.id_table (CD.main_proc_id_index).block_or_pkg_ref));\n    end if;\n\n    New_Line (CD.comp_dump);\n    Put_Line (CD.comp_dump, \"String table. Length:\" & CD.Strings_Table_Top'Image);\n    Put_Line (CD.comp_dump, \"----\");\n    for i in Strings_Constants_Table_Type'First .. CD.Strings_Table_Top loop\n      Put (CD.comp_dump, CD.Strings_Constants_Table (i));\n      if i mod 70 = 0 or else i = CD.Strings_Table_Top then\n        New_Line (CD.comp_dump);\n      end if;\n    end loop;\n    Put_Line (CD.comp_dump, \"----\");\n  end Print_Tables;\n\n  ---------------------------------------------------------------------------\n\n  procedure Progress_Message (CD : Co_Defs.Compiler_Data; msg : String) is\n  begin\n    if CD.trace.progress = null then\n      Ada.Text_IO.Put_Line (msg);\n    else\n      CD.trace.progress (msg);\n    end if;\n  end Progress_Message;\n\n  procedure Dump_HAC_VM_Asm (CD : Co_Defs.Compiler_Data; file_name : String) is\n    use Ada.Text_IO;\n    asm_dump : File_Type;\n  begin\n    if CD.Is_HAC_VM then\n      Create (asm_dump, Out_File, file_name);\n      PCode.Dump\n        (CD.ObjCode (CD.ObjCode'First .. CD.LC - 1),  --  Dump only compiled part.\n         CD.Strings_Constants_Table,\n         CD.Float_Constants_Table,\n         asm_dump);\n      Close (asm_dump);\n    end if;\n  end Dump_HAC_VM_Asm;\n\n  procedure Compile_Unit\n    (CD                     : in out Co_Defs.Compiler_Data;\n     LD                     : in out Librarian.Library_Data;\n     upper_name             :        String;\n     file_name              :        String;\n     as_specification       :        Boolean;\n     as_main_unit           :        Boolean;\n     needs_opening_a_stream :        Boolean;\n     first_compilation      :        Boolean;  --  First compilation of whole build\n     specification_id_index :        Natural;\n     new_id_index           :    out Natural;\n     unit_context           : in out Co_Defs.Id_Maps.Map;  --  in : empty for spec, spec's context for body\n                                                           --  out: spec's context or body's full context.\n     kind                   :    out Librarian.Unit_Kind;  --  The unit kind is discovered during parsing.\n     needs_body             :    out Boolean)\n  is\n    use Ada.Strings.Fixed, Ada.Text_IO, Errors, Librarian, Parser.Helpers, PCode;\n    --\n    --  Save state of unit currently being parsed (within a WITH clause).\n    --  That compilation is frozen until the point where `mem` is copied\n    --  back to CD.CUD.\n    mem : constant Current_Unit_Data := CD.CUD;\n    --\n    Unit_Id_with_case : Alfa;\n    unit_block : Parser.Block_Data_Type;\n    indent : Natural := 0;\n    src_stream : Co_Defs.Source_Stream_Access;\n\n    function Spec_or_Body return String is\n      (\" (\" & (if as_specification then \"specification)\" else \"body)\"));\n\n    procedure Reactivate_USE_HAT is\n      --  Detect a directly visible item of the HAT package.\n      --  It that case, it proves that a \"USE HAT\" was in the context\n      --  clause of the specification.\n      some_stuff_in_HAT_str : constant String := \"VSTRING\";\n      some_stuff_in_HAT     : constant Alfa := S2A (some_stuff_in_HAT_str);\n      stuff_index : Integer;\n    begin\n      if unit_context.Contains (some_stuff_in_HAT) then\n        stuff_index := unit_context (some_stuff_in_HAT);\n        if CD.id_table (stuff_index).entity = alias then\n          --  Item named VSTRING from a USE clause was detected.\n          --  Get the real item behind the alias (VSTRING -> ?.VSTRING):\n          stuff_index := Integer (CD.id_table (stuff_index).adr_or_sz);\n          if A2S (CD.id_table (stuff_index).name) = HAT_Name & '.' & some_stuff_in_HAT_str then\n            --  Now we are sure the item stems from the HAT package.\n            --  Normally, the full name is \"HAT.VSTRING\", unless HAT_Name has been customized.\n            CD.CUD.Use_HAT_Stack (CD.CUD.use_hat_stack_top) := True;\n          end if;\n        end if;\n      end if;\n    end Reactivate_USE_HAT;\n\n    function Indent_String (starting : Boolean) return String is\n      (case indent is\n         when 0 => \"\",\n         when 1 => \"| \",\n         when others =>\n           (indent - 1) * ' ' &\n           (if starting then '\\' else '/') & ' ');\n\n    full_file_name : constant String := LD.cat.Full_Source_Name (file_name);\n\n    procedure Check_No_Extra_Symbol is\n    begin\n      Scanner.In_Symbol (CD);\n      Error (CD, err_general_error, \"end of file is expected here, found extra symbol\");\n    exception\n      --  Compiler bug: when compiled with -Os -ffunction-sections -fdata-sections,\n      --  GNAT 21 and 23 (possibly more versions) ignore this handler!\n      when End_Error =>\n        null;  --  It's the expected case.\n    end Check_No_Extra_Symbol;\n\n  begin\n    CD.recursion := CD.recursion + 1;\n    if CD.trace.detail_level >= 1 then\n      if CD.trace.detail_level >= 2 then\n        indent := CD.recursion;\n      end if;\n      Progress_Message\n        (CD,\n         Indent_String (True) & \"Compiling \" &\n         file_name & Spec_or_Body);\n    end if;\n    if needs_opening_a_stream then\n      begin\n        LD.cat.Source_Open (full_file_name, src_stream);\n        Set_Source_Stream (CD.CUD, src_stream, full_file_name, 0);\n      exception\n        when Name_Error =>\n          Error\n            (CD, err_library_error,\n             \"file \" & file_name & Spec_or_Body & \" not found\", severity => major);\n      end;\n    end if;\n    if not first_compilation then\n      --  Reset scanner data (line counter etc.) and\n      --  library-level visible declarations (processed WITH of caller's compilation)\n      Init (CD.CUD);\n      --  If we are compiling the body of a unit, unit_context already contains, automatically:\n      --    - the WITH and USE context clauses of the spec,\n      --    - the package's declarations, incuding the private part.\n      --  Basically the body is a continuation of the spec, possibly in another file.\n      CD.CUD.level_0_def := unit_context;\n      Reactivate_USE_HAT;\n      Scanner.In_Symbol (CD);\n    end if;\n    --\n    --  We define Standard, or activate if this is not the first unit compiled.\n    --\n    Librarian.Apply_WITH_USE_Standard (CD, LD);  --  The invisible \"with Standard; use Standard;\"\n    --  HAT.PUT_LINE(\"Unit \" & upper_name & \" sees and uses Standard\");\n\n    Parser.Modularity.Context_Clause (CD, LD);  --  Parse the \"with\"'s and \"use\"'s, compile units.\n    case CD.Sy is\n      when PACKAGE_Symbol =>\n        Scanner.In_Symbol (CD);\n        if CD.Sy = BODY_Symbol then\n          Scanner.In_Symbol (CD);  --  Absorb the BODY symbol.\n          kind := Package_Body;\n          if as_specification then\n            Error\n              (CD, err_library_error,\n               \"specification expected in this file; found body\", severity => major);\n          end if;\n        else\n          kind := Package_Declaration;\n          if not as_specification then\n            Error\n              (CD, err_library_error,\n               \"body expected in this file; found specification\", severity => major);\n          end if;\n        end if;\n      when FUNCTION_Symbol =>\n        kind := Function_Unit;\n        Scanner.In_Symbol (CD);\n      when PROCEDURE_Symbol =>\n        kind := Procedure_Unit;\n        Scanner.In_Symbol (CD);\n      when others =>\n        kind := Package_Declaration;  --  Useless, but this removes an ObjectAda warning.\n        Error\n          (CD,\n           err_general_error,\n           \"`package`, `procedure` or `function` expected here\", severity => major);\n    end case;\n    if CD.Sy /= IDent then\n      Error (CD, err_identifier_missing, severity => major);\n    end if;\n    if as_main_unit then\n      CD.main_unit_ident           := CD.Id;\n      CD.main_unit_ident_with_case := CD.Id_with_case;\n    end if;\n    if A2S (CD.Id) /= upper_name then\n      Error (CD, err_wrong_unit_name, upper_name, A2S (CD.Id), major);\n    end if;\n    if first_compilation and then kind = Package_Body then\n      raise Compilation_of_package_body_before_spec;\n    end if;\n    --\n    --  Enter the identifier:\n    --\n    Unit_Id_with_case := CD.Id_with_case;\n    case kind is\n      when Procedure_Unit =>\n        Librarian.Enter_Library_Level_Def (CD, A2S (Unit_Id_with_case), prozedure, NOTYP, 0);\n      when Function_Unit =>\n        Librarian.Enter_Library_Level_Def (CD, A2S (Unit_Id_with_case), funktion, NOTYP, 0);\n        --  ^ The type of the return value is adjusted by Block.Function_Result_Profile.\n      when Package_Declaration =>\n        Librarian.Enter_Library_Level_Def (CD, A2S (Unit_Id_with_case), paquetage, NOTYP, 0);\n      when Package_Body =>\n        Librarian.Enter_Library_Level_Def (CD, A2S (Unit_Id_with_case), paquetage_body, NOTYP, 0);\n        --  ^ The identifier is used only by the Semantics target.\n    end case;\n    new_id_index := CD.Id_Count;\n    if specification_id_index /= No_Id then\n      CD.target.Mark_Spec_Body_Cross_References\n        (spec_id => specification_id_index,\n         body_id => new_id_index);\n    end if;\n\n    case kind is\n      when Subprogram_Unit =>\n        --  Absorb the identifier symbol:\n        Scanner.In_Symbol (CD);\n        --\n        --  At this point, the current symbol should be: \";\", \"IS\", \"(\",\n        --  or, for a parameterless function, \"RETURN\".\n        --\n        unit_block.context.level                 := 1;\n        unit_block.block_id_index                := new_id_index;\n        unit_block.entity                        := (if kind = Function_Unit then funktion else prozedure);\n        unit_block.is_main                       := as_main_unit;\n        unit_block.previous_declaration_id_index := specification_id_index;\n\n        Parser.Block\n          (CD, Block_Begin_Symbol + Statement_Begin_Symbol,\n           False,\n           unit_block,\n           CD.id_table (CD.Id_Count).name,\n           Unit_Id_with_case);\n\n        if as_main_unit then\n\n          if kind = Procedure_Unit\n            and then Number_of_Parameters (CD, unit_block.block_id_index) = 0\n          then\n            --  This main unit can be executed.\n            CD.main_proc_id_index          := unit_block.block_id_index;\n            CD.Tasks_Definitions_Table (0) := unit_block.block_id_index;  --  Task Table Entry for main task.\n          else\n            CD.main_proc_id_index := No_Id;\n          end if;\n\n          Check_No_Extra_Symbol;\n\n        end if;\n\n        case Split_Declaration_Kind (CD.id_table (unit_block.block_id_index).decl_kind) is\n          when complete =>\n            if as_specification then\n              Error\n                (CD, err_library_error,\n                 \"specification expected in this file; found body\", severity => major);\n            end if;\n            if kind = Function_Unit then\n              --  When this part of the machine code is reached, it means\n              --  that the end of a function was reached without\n              --  a \"RETURN\" statement. This will raise Program_Error.\n              PCode_Emit.Emit_1 (CD, k_Return_Function, End_Function_without_Return);\n            elsif as_main_unit then\n              CD.target.Emit_Halt;\n            else\n              PCode_Emit.Emit_1 (CD, k_Return_Call, Normal_Procedure_Call);\n            end if;\n          when spec_unresolved =>\n            if not as_specification then\n              Error\n                (CD, err_library_error,\n                 \"body expected in this file; found specification\", severity => major);\n            end if;\n          when spec_resolved =>\n            raise Program_Error with \"Unexpected case: spec_resolved\";\n        end case;\n        needs_body := as_specification;\n\n      when Package_Declaration =>\n        unit_block.context.level := 0;  --  Actually, not a block.\n        CD.id_table (new_id_index).decl_kind := spec_resolved;\n        --  Why spec_resolved ? missing bodies for possible suprograms\n        --  in that package are checked anyway.\n        Parser.Packages.Package_Declaration (CD, empty_symset, unit_block, needs_body);\n\n      when Package_Body =>\n        unit_block.context.level := 0;  --  Actually, not a block.\n        Parser.Packages.Package_Body (CD, empty_symset, unit_block);\n        needs_body := False;\n    end case;\n\n    if needs_opening_a_stream then\n      LD.cat.Close (full_file_name);\n    end if;\n\n    if CD.trace.detail_level >= 2 then\n      Progress_Message\n        (CD,\n         Indent_String (False) &\n         \"          \" & file_name & \": done.\");\n    end if;\n    --  Export library-level context, possibly needed later by a body:\n    unit_context := CD.CUD.level_0_def;\n    CD.total_lines := CD.total_lines + CD.CUD.location.line;\n    --  Forget about the compilation just completed, and go back to the\n    --  ongoing compilation that triggered a call to Compile_Unit via a WITH:\n    CD.CUD := mem;\n    CD.recursion := CD.recursion - 1;\n  exception\n    when End_Error =>\n      kind := Function_Unit;  --  Fake but valid value.\n      Error (CD, err_unexpected_end_of_text);\n    when others =>\n      if needs_opening_a_stream then\n        LD.cat.Close (full_file_name);\n      end if;\n      raise;\n  end Compile_Unit;\n\n  function Unit_Compilation_Successful (CD : Compiler_Data) return Boolean is\n  begin\n    return CD.error_count = 0;\n  end Unit_Compilation_Successful;\n\n  function Unit_Object_Code_Size (CD : Compiler_Data) return Natural is\n  begin\n    return CD.LC;\n  end Unit_Object_Code_Size;\n\nend HAC_Sys.Compiler;\n"
  },
  {
    "path": "src/compile/hac_sys-compiler.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Co_Defs, HAC_Sys.Librarian;\n\npackage HAC_Sys.Compiler is\n\n  --  Compile unit not yet in the library.\n  --  Registration into the library is done elsewhere, by the Librarian.\n  --\n  procedure Compile_Unit\n    (CD                     : in out Co_Defs.Compiler_Data;\n     LD                     : in out Librarian.Library_Data;\n     upper_name             :        String;\n     file_name              :        String;\n     as_specification       :        Boolean;\n     as_main_unit           :        Boolean;\n     needs_opening_a_stream :        Boolean;\n     first_compilation      :        Boolean;  --  First compilation of whole build\n     specification_id_index :        Natural;\n     new_id_index           :    out Natural;\n     unit_context           : in out Co_Defs.Id_Maps.Map;  --  in : empty for spec, spec's context for body\n                                                           --  out: spec's context or body's full context.\n     kind                   :    out Librarian.Unit_Kind;  --  The unit kind is discovered during parsing.\n     needs_body             :    out Boolean);\n\n  use Co_Defs;\n\n  --  Initialize the compiler for an entire build.\n  procedure Init_for_new_Build (CD : out Compiler_Data);\n\n  procedure Set_Message_Feedbacks\n    (CD           : in out Compiler_Data;\n     trace_params : in     Compilation_Trace_Parameters);\n\n  procedure Print_Tables (CD : in Compiler_Data);\n  procedure Progress_Message (CD : Co_Defs.Compiler_Data; msg : String);\n  procedure Dump_HAC_VM_Asm (CD : Co_Defs.Compiler_Data; file_name : String);\n\n  function Unit_Compilation_Successful (CD : Compiler_Data) return Boolean;\n  function Unit_Object_Code_Size (CD : Compiler_Data) return Natural;\n\nend HAC_Sys.Compiler;\n"
  },
  {
    "path": "src/compile/hac_sys-defs.adb",
    "content": "package body HAC_Sys.Defs is\n\n  function \"+\" (a, b : Symset) return Symset is\n  begin\n    return a or b;\n  end \"+\";\n\n  function \"+\" (a : Symset; b : Symbol) return Symset is\n    c : Symset := a;\n  begin\n    c (b) := True;\n    return c;\n  end \"+\";\n\n  function \"-\" (a, b : Symset) return Symset is\n  begin\n    return a and not b;\n  end \"-\";\n\n  function \"-\" (a : Symset; b : Symbol) return Symset is\n    c : Symset := a;\n  begin\n    c (b) := False;\n    return c;\n  end \"-\";\n\n  function Minimum_Level (r : Compile_Remark) return Remark_Level is\n  begin\n    for lev in Remark_Level loop\n      if preset_remarks (lev)(r) then return lev; end if;\n    end loop;\n    return Remark_Level'Last;\n  end Minimum_Level;\n\nend HAC_Sys.Defs;\n"
  },
  {
    "path": "src/compile/hac_sys-defs.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n\n--  This package contains constants and types for the\n--  compiler and the p-code interpreter.\n\nwith HAT;\n\nwith Ada.Characters.Handling,\n     Ada.Text_IO;\n\nwith Interfaces;\n\npackage HAC_Sys.Defs is\n\n  HAT_Name : constant String := \"HAT\";  --  Stands for:  HAC Ada Toolbox (was: Library).\n\n  subtype HAC_Integer is Interfaces.Integer_64;\n  HAC_Integer_Name       : constant String := \"Integer\";\n  HAC_Integer_Name_Upper : constant String := Ada.Characters.Handling.To_Upper (HAC_Integer_Name);\n  function HAC_Image is new HAT.HAC_Generic_Image (Abstract_Integer => HAC_Integer);\n\n  --  HAC's default floating-point type is double-precision\n  --  and is called \"Real\" in HAC's HAT package.\n  --  There is *no* Float in HAC's Standard package.\n  --  Float is commonly assumed to be single-precision -> no practical use and would\n  --  complicate the parsing in HAC by having multiple possible\n  --  floating-point type expressions.\n  --  On top of that a universal float would be probably needed.\n  --\n  subtype HAC_Float is HAT.Real;\n  HAC_Float_Name       : constant String := \"Real\";\n  HAC_Float_Name_Upper : constant String := Ada.Characters.Handling.To_Upper (HAC_Float_Name);\n\n  --  Max & Min Exponents. IEEE Double Precision.\n  --  TBD: !! find the attribute, applied on HAC_Float, that matches this value.\n  EMax : constant :=  308;\n  EMin : constant := -308;\n\n  ------------------------\n  --  Global constants  --\n  ------------------------\n\n  StMax   : constant := 5_000_000;    --  Maximum Stack Size\n  STKINCR : constant :=     2_000;    --  Stack Increment allocated per Task\n\n  Header : constant String := \"HAC - HAC Ada Compiler\";\n  --  Alternative name: Hackers' Ada Compiler\n  --  Was: \"Small-Ada  Macintosh Ver 1.1  Nov 1989  George Washington University\"\n\n  MaxINT     : constant Integer := Integer'Last - 1;\n\n  AMax               : constant := 1_000;    --  Size OF ARRAY-TABLE\n  BMax               : constant := 10_000;   --  Size OF Block-TABLE\n  float_const_table_max\n                     : constant := 200;\n  Cases_Max          : constant := 2000;     --  Max number of cases in a CASE statement\n  CDMax              : constant := 100_000;  --  Size OF ObjCode\n  entry_table_max    : constant := 30;       --  Maximum Number of Entries\n  integer_digits_max : constant := 18;       --  Maximum digits for an integer literal, was KMAX:\n                                             --  decimal representation of 2**63, minus 1 digit.\n  package_table_max  : constant := 10_000;   --  Size of Package table\n  loop_nesting_max   : constant := 100;\n  nesting_level_max  : constant := 20;       --  Maximum subprogram nesting level, was LMAX.\n\n  nesting_and_descending_max : constant := 40;  --  subprograms, subpackages and child packages\n\n  End_Function_without_Return : constant := -1;\n\n  Normal_Procedure_Call  : constant := 0;\n  Normal_Entry_Call      : constant := 1;\n  Timed_Entry_Call       : constant := 2;\n  Conditional_Entry_Call : constant := 3;\n\n  OrdMinChar : constant := 0;             --  Ord of First Char\n  OrdMaxChar : constant := 255;           --  Ord of last Char\n\n  PriMax     : constant := 100;           --  Maximum Task priority\n  SMax       : constant := 100_000;       --  Size of String table\n  TaskMax    : constant := 12;            --  Max # of concurrent tasks\n\n  string_folding_scan_limit : constant := 1000;\n\n  Wind_Size    : constant := TaskMax + 2;    --  SnapShot window size\n  Id_Table_Max : constant := 10_000;         --  Size of identifier table\n  XMax         : constant Integer := MaxINT;\n\n  Patch_Max : constant := 100;\n\n  identifier_length_max : constant := 200;\n\n  --------------------\n  --  Global types  --\n  --------------------\n\n  -----------------------------------------------------------------------\n  ------------------------ Symbol - All symbols used by the compiler ----\n  -----------------------------------------------------------------------\n\n  type Symbol is\n    (integer_literal,\n     real_literal,\n     character_literal,\n     string_literal,\n     --\n     Plus,     --  +\n     Minus,    --  -\n     Times,    --  *\n     Divide,   --  /\n     Power,    --  **\n     --\n     EQL,      --  =\n     NEQ,      --  /=\n     GTR,      --  >\n     GEQ,      --  >=\n     LSS,      --  <\n     LEQ,      --  <=\n     --\n     LParent,\n     RParent,\n     LBrack,\n     RBrack,\n     Apostrophe,\n     Comma,\n     Semicolon,\n     Period,\n     Range_Double_Dot_Symbol,  --  \"..\" compound delimiter (RM 2.2)\n     Colon,\n     Alt,\n     Finger,\n     Becomes,\n     IDent,\n     Dummy_Symbol,       --  Symbol that is never scanned.\n     Ampersand_Symbol,\n     --------------------\n     --                --\n     --  Ada keywords  --\n     --                --\n     --------------------\n     ABORT_Symbol,\n     ABS_Symbol,\n     ABSTRACT_Symbol,\n     ACCEPT_Symbol,\n     ACCESS_Symbol,\n     ALIASED_Symbol,\n     ALL_Symbol,\n     AND_Symbol,\n     AND_THEN_Symbol,  --  This symbol is never scanned as such.\n     ARRAY_Symbol,\n     AT_Symbol,\n     BEGIN_Symbol,\n     BODY_Symbol,\n     CASE_Symbol,\n     CONSTANT_Symbol,\n     DECLARE_Symbol,\n     DELAY_Symbol,\n     DELTA_Symbol,\n     DIGITS_Symbol,\n     DO_Symbol,\n     ELSE_Symbol,\n     ELSIF_Symbol,\n     END_Symbol,\n     ENTRY_Symbol,\n     EXCEPTION_Symbol,\n     EXIT_Symbol,\n     FOR_Symbol,\n     FUNCTION_Symbol,\n     GENERIC_Symbol,\n     GOTO_Symbol,\n     IF_Symbol,\n     IN_Symbol,\n     INTERFACE_Symbol,\n     IS_Symbol,\n     LIMITED_Symbol,\n     LOOP_Symbol,\n     MOD_Symbol,\n     NEW_Symbol,\n     NOT_Symbol,\n     NULL_Symbol,\n     OF_Symbol,\n     OR_Symbol,\n     OR_ELSE_Symbol,  --  This symbol is never scanned as such.\n     OTHERS_Symbol,\n     OUT_Symbol,\n     OVERRIDING_Symbol,\n     PACKAGE_Symbol,\n     PARALLEL_Symbol,\n     PRAGMA_Symbol,\n     PRIVATE_Symbol,\n     PROCEDURE_Symbol,\n     PROTECTED_Symbol,\n     RAISE_Symbol,\n     RANGE_Keyword_Symbol,  --  \"range\" reserved word (RM 2.9)\n     RECORD_Symbol,\n     REM_Symbol,\n     RENAMES_Symbol,\n     REQUEUE_Symbol,\n     RETURN_Symbol,\n     REVERSE_Symbol,\n     SELECT_Symbol,\n     SEPARATE_Symbol,\n     SOME_Symbol,\n     SUBTYPE_Symbol,\n     SYNCHRONIZED_Symbol,\n     TAGGED_Symbol,\n     TASK_Symbol,\n     TERMINATE_Symbol,\n     THEN_Symbol,\n     TYPE_Symbol,\n     UNTIL_Symbol,\n     USE_Symbol,\n     WHEN_Symbol,\n     WHILE_Symbol,\n     WITH_Symbol,\n     XOR_Symbol);\n\n  subtype Plus_Minus is Symbol range Plus .. Minus;\n  subtype Comparison_Operator is Symbol range EQL .. LEQ;\n  subtype Arithmetic_Binary_Operator is Symbol range Plus .. Power;\n\n  ---------------------\n  -- Sets of symbols --\n  ---------------------\n\n  type Symset is array (Symbol) of Boolean;\n  --  The \"+\" and \"-\" reproduce the Pascal set operators.\n  function \"+\" (a, b : Symset) return Symset;\n  function \"+\" (a : Symset; b : Symbol) return Symset;\n  function \"-\" (a, b : Symset) return Symset;\n  function \"-\" (a : Symset; b : Symbol) return Symset;\n  empty_symset : constant Symset := (others => False);\n\n  -----------------\n  -- Identifiers --\n  -----------------\n\n  subtype Alfa is HAT.VString;  --  Originally, Alfa was a space-padded fixed string.\n  Empty_Alfa : Alfa renames HAT.Null_VString;\n  function A2S (a : Alfa) return String renames HAT.To_String;\n  function S2A (s : String) return Alfa renames HAT.To_VString;\n\n  --  Data types in HAC. We call them \"Typ\" (with an Akzent ;-) ) to avoid\n  --  confusion with the types of the HAC code itself.\n  --\n  --  The order of these is significant.\n  --\n  type Typen is (\n    ----------------------\n    --  Built-in types  --\n    ----------------------\n    NOTYP,  --  Appears when the parsing of an expression fails at some point.\n    Ints,\n    Floats,\n    Bools,\n    Chars,\n    VStrings,\n    Times,\n    Durations,\n    --\n    Text_Files,  --  This one is limited (like Ada's File_Type).\n    ------------------------------------\n    --  Types defined by programmers  --\n    ------------------------------------\n    Arrays,\n    Records,\n    Enums,\n    -------------------------------------------------------\n    --  Special types appearing only during the parsing  --\n    --  and unavailable to the programmer.               --\n    -------------------------------------------------------\n    String_Literals,     --  Strings in the \"abcd\" form. Takes 2 items on the stack.\n    Strings_as_VStrings  --  VString value, but semantically a String. E.g. returned by S'Image\n  );\n  for Typen'Size use 8;\n\n  type Typ_Set is array (Typen) of Boolean;\n\n  empty_typ_set : constant Typ_Set := (others => False);\n\n  subtype Standard_Typ is Typen range NOTYP .. Text_Files;\n\n  subtype Special_Strings is Typen range String_Literals .. Strings_as_VStrings;\n\n  subtype Composite_Typ is Typen range Arrays .. Records;\n\n  Standard_or_Enum_Typ : constant Typ_Set :=\n    (Standard_Typ | Enums => True, others => False);\n\n  Discrete_Typ : constant Typ_Set :=  --  RM 3.2 (12)\n    (Ints | Bools | Chars | Enums => True, others  => False);\n\n  subtype Numeric_Typ is Typen range Ints .. Floats;  --  RM 3.2 (1)\n\n  Auto_Init_Typ : constant Typ_Set :=\n    (VStrings | Text_Files => True, others => False);\n\n  Typ_with_Variant_Part : constant Typ_Set :=\n    (Floats | VStrings | Times | Durations | Text_Files => True, others => False);\n\n  subtype Index is Integer range -XMax .. +XMax;\n\n  type Float_Constants_Table_Type is array (1 .. float_const_table_max) of HAC_Float;\n\n  subtype Nesting_Level is HAC_Integer range 0 .. nesting_level_max;\n\n  type Flow_Context is record\n    level                  : Nesting_Level;\n    --  This is for rudimentary flow analysis\n    --  and the issuance of clever warnings and notes.\n    is_within_loop         : Boolean := False;  --  Reversed on leaving top loop\n    is_within_condition    : Boolean := False;  --  Reversed on leaving top condition\n    is_in_cond_within_loop : Boolean := False;  --  Reversed on leaving this case\n  end record;\n\n  ------------------------------\n  --  Compilation error type  --\n  ------------------------------\n\n  type Compile_Diagnostic is\n     --  Errors that may occur during the scanning of symbols (tokens):\n    (err_scanner_character_zero_chars,\n     err_scanner_control_character,\n     err_scanner_digit_expected,\n     err_scanner_double_underline_not_permitted,\n     err_scanner_identifier_cannot_end_with_underline,\n     err_scanner_identifier_too_long,\n     err_scanner_illegal_character,\n     err_scanner_illegal_character_in_number,\n     err_scanner_negative_exponent_for_integer_literal,\n     err_scanner_exponent_too_large,\n     err_scanner_integer_literal_too_large,\n     err_scanner_space_missing_after_number,\n     --  Errors that may occur during parsing:\n     err_undefined_identifier,\n     err_duplicate_identifier,\n     err_identifier_missing,\n     err_missing_a_procedure_declaration,\n     err_closing_parenthesis_missing,\n     err_colon_missing,\n     err_colon_missing_for_named_statement,\n     err_incorrectly_used_symbol,\n     err_missing_OF,\n     err_missing_an_opening_parenthesis,\n     err_left_bracket_instead_of_parenthesis,\n     err_right_bracket_instead_of_parenthesis,\n     err_missing_type_begin_symbol,\n     err_expecting_double_dot,\n     err_semicolon_missing,\n     err_duplicate_semicolon,\n     err_extra_right_parenthesis,                 --  2021-12-29\n     err_bad_result_type_for_a_function,\n     err_type_of_return_statement_doesnt_match,\n     err_illegal_statement_start_symbol,\n     err_expecting_a_boolean_expression,\n     err_control_variable_of_the_wrong_type,\n     err_bounds_type_mismatch,\n     err_IS_missing,\n     err_incorrect_name_after_END,\n     err_bad_type_for_a_case_statement,\n     err_illegal_constant_or_constant_identifier,\n     err_wrong_type_for_array_index,\n     err_too_few_array_indices,\n     err_too_many_array_indices,\n     err_illegal_array_bounds,\n     err_indexed_variable_must_be_an_array,\n     err_missing_a_type_identifier,\n     err_undefined_type,\n     err_var_with_field_selector_must_be_record,\n     err_resulting_type_should_be_Boolean,\n     err_illegal_type_for_arithmetic_expression,\n     err_mod_requires_integer_arguments,\n     err_incompatible_types_for_comparison,\n     err_parameter_types_do_not_match,\n     err_variable_missing,\n     err_number_of_parameters_do_not_match,\n     err_illegal_parameters_to_Get,\n     err_illegal_parameters_to_Put,\n     err_parameter_must_be_of_type_Float,\n     err_parameter_must_be_Integer,\n     err_expected_constant_function_variable_or_subtype,\n     err_types_of_assignment_must_match,\n     err_case_label_not_same_type_as_case_clause,\n     err_duplicate_case_choice_value,\n     err_argument_to_std_function_of_wrong_type,\n     err_stack_size,\n     err_illegal_symbol_for_a_number_declaration,\n     err_BECOMES_missing,\n     err_THEN_missing,\n     err_IN_missing,\n     err_missing_closing_LOOP,\n     err_missing_closing_LOOP_2,\n     err_BEGIN_missing,\n     err_END_missing,\n     err_primary_unexpected_symbol,\n     err_RETURN_missing,\n     err_RECORD_missing,\n     err_missing_closing_IF,\n     err_missing_closing_IF_2,\n     err_WHEN_missing,\n     err_FINGER_missing,\n     err_missing_closing_CASE,\n     err_missing_closing_CASE_2,\n     err_functions_must_return_a_value,\n     err_procedures_cannot_return_a_value,\n     err_missing_an_entry,\n     err_missing_expression_for_delay,\n     err_wrong_type_in_DELAY,\n     err_COMMA_missing,\n     err_expecting_accept_when_or_entry_id,\n     err_expecting_task_entry,\n     err_expecting_OR_or_ELSE_in_SELECT,\n     err_expecting_DELAY,\n     err_SELECT_missing,\n     err_program_incomplete,\n     --  These errors messages are new in HAC and weren't in SmallAda\n     err_OF_instead_of_IS,\n     err_THEN_instead_of_Arrow,\n     err_EQUALS_instead_of_BECOMES,\n     err_numeric_constant_expected,\n     err_statement_expected,\n     err_duplicate_loop_identifier,\n     err_unexpected_end_of_text,                  --  2018-04-01\n     err_not_yet_implemented,                     --  2019-03-24\n     err_type_conversion_not_supported,           --  2020-03-31\n     err_numeric_type_coercion,                   --  2020-04-06\n     err_numeric_type_coercion_operator,\n     err_operator_not_defined_for_types,          --  2020-04-06\n     err_no_null_functions,                       --  2020-04-10\n     err_cannot_modify_constant_or_in_parameter,\n     err_case_others_alone_last,\n     err_no_X_for_END_X,\n     err_END_LOOP_ident_missing,\n     err_END_LOOP_ident_wrong,\n     err_general_error,                           --  Default (without hint): the classic \"syntax error\"\n     err_string_to_vstring_assignment,\n     err_range_constraint_error,\n     err_discrete_type_expected,\n     err_membership_test_type_mismatch,\n     err_string_not_supported_as_parameter,\n     err_string_lengths_do_not_match,\n     err_object_used_before_end_own_declaration,  --  2021-12-11\n     err_attribute_prefix_invalid,                --  2021-12-26\n     err_attribute_prefix_must_be_discrete_type,  --  2021-12-26\n     err_invalid_dimension_number,                --  2022-01-09\n     err_spec_body_mismatch,                      --  2022-01-22\n     err_incomplete_declaration,                  --  2022-01-22\n     err_non_public_entity,                       --  2022-04-02\n     err_choices_not_covered,\n     err_choice_out_of_range,\n     err_mixed_logical_operators,\n     err_library_error,\n     err_wrong_unit_name,\n     err_obsolete_hat_name,\n     err_assignment_not_allowed_declarative,\n     --\n     note_redundant_construct,\n     note_unused_item,\n     note_constant_variable,\n     --\n     warn_read_but_not_written);\n\n  subtype Compile_Note is Compile_Diagnostic\n    range note_redundant_construct .. note_constant_variable;\n\n  subtype Compile_Warning is Compile_Diagnostic\n    range warn_read_but_not_written .. warn_read_but_not_written;\n\n  --  A Remark is either a Warning (about something potentially dangerous)\n  --  or a Note (about something harmless but typically superfluous).\n  subtype Compile_Remark is Compile_Diagnostic\n    range Compile_Note'First .. Compile_Warning'Last;\n\n  --  Summary of Compile_Diagnostic:\n  --\n  --          +------------------------+\n  --          |      Diagnostic        |\n  --          +---v-----------v--------+\n  --          |       |     Remark     |\n  --          | Error |--v--------v----+\n  --          |       | Note | Warning |\n  --          +-------+------+---------+\n\n  type Remark_Set is array (Compile_Remark) of Boolean;\n\n  type Remark_Level is range 0 .. 3;\n  default_remark_level : constant Remark_Level := 1;\n\n  --  Level 0 means: no remarks are issued.\n  --  Level 1 corresponds roughly to the GNAT defaults (when you type \"gnatmake\"\n  --            on a command-line interpreter, it's the warnings marked\n  --            with a '*', plus others that are always enabled.\n  --  Level 2 corresponds roughly to the GNAT's \"-gnatwa\" option, that is,\n  --            warnings marked with a '+' in the help.\n  --  Level 3 means: all remarkes are enabled. This level corresponds roughly to\n  --            the \"-gnatw.e\" switch.\n\n  preset_remarks : constant array (Remark_Level) of Remark_Set :=\n    (0 => (others => False),\n     1 => (warn_read_but_not_written => True, others => False),\n     2 => (note_redundant_construct |\n           note_unused_item |\n           note_constant_variable |\n           warn_read_but_not_written => True),\n     3 => (others => True));\n\n  function Minimum_Level (r : Compile_Remark) return Remark_Level;\n\n  default_remarks : constant Remark_Set :=\n    preset_remarks (default_remark_level);\n\n  remark_letter : constant array (Compile_Remark) of Character :=\n    (note_redundant_construct => 'r',\n     note_unused_item         => 'u',\n     note_constant_variable   => 'k',\n     --\n     warn_read_but_not_written => 'v');\n\n  subtype Compile_Error is Compile_Diagnostic\n    range Compile_Diagnostic'First ..\n          Compile_Diagnostic'Pred (Compile_Remark'First);\n\n  type Diagnostic_Set is array (Compile_Diagnostic) of Boolean;\n  no_diagnostic : constant Diagnostic_Set := (others => False);\n\n  type Repair_Kind_Type is (none, insert, replace_token);\n\n  type Repair_Kit is tagged record\n    repair_kind : Repair_Kind_Type := none;\n    alternative : HAT.VString      := HAT.Null_VString;\n  end record;\n\n  --  The Symbol_Location record unifies the location of symbols\n  --  within a source stream, basically for errors & warnings.\n\n  type Symbol_Location is record\n    line         : Integer;\n    column_start : Integer;\n    column_stop  : Integer;\n  end record;\n\n  type Diagnostic_Kind_Type is (error, warning, note, style);\n\n  subtype Remark_Type is Diagnostic_Kind_Type range warning .. note;\n\n  type Diagnostic_Kit is new Repair_Kit with record\n    diagnostic_kind : Diagnostic_Kind_Type := error;\n    message         : HAT.VString          := HAT.Null_VString;\n    file_name       : HAT.VString          := HAT.Null_VString;\n    location        : Symbol_Location      := (0, 0, 0);\n  end record;\n\n  type Smart_Error_Pipe is access procedure (kit : Diagnostic_Kit);\n\n  package IIO is new Ada.Text_IO.Integer_IO (HAC_Integer);\n  package RIO is new Ada.Text_IO.Float_IO (HAC_Float);\n  package BIO is new Ada.Text_IO.Enumeration_IO (Boolean);\n\n  --  package REF is new Ada.Numerics.Generic_Elementary_Functions (HAC_Float);\n\n  subtype Strings_Constants_Table_Type is String (1 .. SMax);\n\n  ------------------------------------\n  --  Standard function operations  --\n  ------------------------------------\n\n  type SF_Code is (\n    SF_Abs_Int,\n    SF_Abs_Float,\n    SF_T_Val,                   --  S'Val  : RM 3.5.5 (5)\n    SF_T_Pos,                   --  S'Pos  : RM 3.5.5 (2)\n    SF_T_Succ,                  --  S'Succ : RM 3.5 (22)\n    SF_T_Pred,                  --  S'Pred : RM 3.5 (25)\n    SF_in_discrete_Interval,\n    SF_not_in_discrete_Interval,\n    --  Numerical functions\n    SF_Round_Float_to_Int,\n    SF_Trunc_Float_to_Int,\n    SF_Float_to_Duration,\n    SF_Duration_to_Float,\n    SF_Int_to_Duration,\n    SF_Duration_to_Int,\n    SF_Sin,\n    SF_Cos,\n    SF_Exp,\n    SF_Log,\n    SF_Sqrt,\n    SF_Arctan,\n    SF_Sgn_Int,\n    SF_Sgn_Float,\n    SF_EOF,\n    SF_EOLN,\n    SF_Is_Open,\n    SF_Random_Int,\n    SF_Min_Int,\n    SF_Max_Int,\n    SF_Min_Float,\n    SF_Max_Float,\n    --\n    --  VString functions (Ada.Strings.Unbounded-like)\n    --\n    SF_String_to_VString,          --  +s        (s is a fixed-size string)\n    SF_String_Literal_to_VString,  --  +\"Hello\"\n    SF_VString_to_String,          --  -v\n    SF_Char_to_VString,            --  +'x'\n    SF_Two_VStrings_Concat,        --  v1 & v2\n    SF_VString_Char_Concat,        --  v & 'x'\n    SF_Char_VString_Concat,        --  'x' & v\n    SF_LStr_VString_Concat,        --  \"Hello \" & v\n    --\n    SF_VString_Int_Concat,       --  v & 123\n    SF_Int_VString_Concat,       --  123 & v\n    SF_VString_Float_Concat,     --  v & 3.14159\n    SF_Float_VString_Concat,     --  3.14159 & v\n    SF_VString_Duration_Concat,  --  v & (Time_1 - Time_0)\n    SF_Duration_VString_Concat,  --  (Time_1 - Time_0) & v\n    SF_VString_Boolean_Concat,   --  v & is_found\n    SF_Boolean_VString_Concat,   --  is_found & v\n    --\n    SF_Element,\n    SF_Length,\n    SF_Slice,\n    --\n    SF_To_Lower_Char,\n    SF_To_Upper_Char,\n    SF_To_Lower_VStr,\n    SF_To_Upper_VStr,\n    SF_Index,\n    SF_Index_Backward,\n    SF_Int_Times_Char,\n    SF_Int_Times_VStr,\n    --\n    SF_Trim_Left,\n    SF_Trim_Right,\n    SF_Trim_Both,\n    --\n    SF_Head,\n    SF_Head_Before_Match,\n    SF_Tail,\n    SF_Tail_After_Match,\n    SF_Starts_With,\n    SF_Ends_With,\n    --\n    --  Ada.Calendar-like functions\n    --\n    SF_Time_Subtract,    --  T2 - T1 -> Duration\n    SF_Duration_Add,\n    SF_Duration_Subtract,\n    SF_Year,\n    SF_Month,\n    SF_Day,\n    SF_Seconds,\n    --\n    SF_Image_Ints,              --  HAT.Image without the nasty ' ' before non-negative values\n    SF_Image_Floats,            --  HAT.Image with a human-readable formatting whenever possible\n    SF_Image_Times,             --  HAT.Image\n    SF_Image_Durations,         --  HAT.Image\n    --\n    SF_Integer_Value,\n    SF_Float_Value,\n    --  'Image attribute \"as is\" from Ada:\n    SF_Image_Attribute_Ints,\n    SF_Image_Attribute_Floats,\n    SF_Image_Attribute_Bools,\n    SF_Image_Attribute_Chars,\n    SF_Image_Attribute_Durs,\n    SF_Image_Attribute_Enums,\n    --  'Value attribute \"as is\" from Ada:\n    SF_Value_Attribute_Ints,\n    SF_Value_Attribute_Floats,\n    SF_Value_Attribute_Bools,\n    SF_Value_Attribute_Chars,\n    SF_Value_Attribute_Durs,\n    SF_Value_Attribute_Enums,\n    --\n    SF_Argument,\n    --  Ada.Directories-like\n    SF_Directory_Exists,\n    SF_Exists,\n    SF_File_Exists,\n    --  Ada.Environment_Variables-like\n    SF_Get_Env,\n    SF_Get_VM_Variable,\n    --\n    --  Niladic functions (they have no arguments).\n    --\n    SF_Clock,\n    SF_Random_Float,\n    SF_Null_VString,\n    SF_Argument_Count,\n    SF_Command_Name,\n    SF_Directory_Separator,\n    SF_Current_Directory,  --  Ada.Directories-like\n    --\n    SF_Get_Needs_Skip_Line  --  Informs whether Get from console needs Skip_Line\n  );\n\n  subtype SF_Niladic is SF_Code range SF_Clock .. SF_Get_Needs_Skip_Line;\n\n  subtype SF_Min_Max_Int is SF_Code range SF_Min_Int .. SF_Max_Int;\n\n  subtype SF_File_or_Console_Information is SF_Code range SF_EOF .. SF_EOLN;\n\n  subtype SF_Index_Any_Direction is SF_Code range SF_Index .. SF_Index_Backward;\n\n  -------------------------------------\n  --  Standard procedure operations  --\n  -------------------------------------\n\n  type SP_Code is (\n    SP_Create,\n    SP_Open,\n    SP_Append,\n    SP_Close,\n    --\n    SP_Push_Abstract_Console,\n    --\n    SP_Get,\n    SP_Get_Immediate,\n    SP_Get_Line,\n    SP_Get_File,\n    SP_Get_Line_File,\n    SP_Skip_Line,\n    --\n    SP_Put,\n    SP_Put_Line,\n    SP_Put_File,\n    SP_Put_Line_File,\n    SP_New_Line,\n    --\n    SP_Randomize,\n    SP_Random_Seed,\n    --\n    SP_Wait,\n    SP_Signal,\n    --\n    SP_Quantum,\n    SP_Priority,\n    SP_InheritP,\n    --\n    --  Ada.Environment_Variables-like procedures\n    --\n    SP_Set_Env,\n    SP_Set_VM_Variable,\n    --\n    --  Ada.Directories-like procedures\n    --\n    SP_Copy_File,\n    SP_Create_Directory,\n    SP_Create_Path,\n    SP_Delete_Directory,\n    SP_Delete_File,\n    SP_Rename,\n    SP_Set_Directory,\n    SP_Set_Exit_Status,\n    --\n    --  VString procedures (Ada.Strings.Unbounded-like)\n    --\n    SP_Delete,\n    --\n    --  Other system procedures\n    --\n    SP_Shell_Execute_without_Result,  --  Result: no,  Output no\n    SP_Shell_Execute_with_Result,     --  Result: yes, Output no\n    SP_Shell_Execute_Output,          --  Result: no,  Output yes\n    SP_Shell_Execute_Result_Output    --  Result: yes, Output yes\n  );\n\n  subtype SP_Shell_Execute is SP_Code\n    range SP_Shell_Execute_without_Result .. SP_Shell_Execute_Result_Output;\n\nend HAC_Sys.Defs;\n"
  },
  {
    "path": "src/compile/hac_sys-errors.adb",
    "content": "with HAC_Sys.Librarian;\n\nwith Ada.Strings.Fixed,\n     Ada.Text_IO;\n\npackage body HAC_Sys.Errors is\n\n  use Defs;\n\n  function Diagnostic_String\n    (code   : Defs.Compile_Diagnostic;\n     hint_1 : String := \"\";\n     hint_2 : String := \"\") return String\n  is\n  begin\n    case code is\n      when err_undefined_identifier =>\n        return \"undefined identifier\" & (if hint_1 = \"\" then \"\" else \": \" & hint_1);\n      when err_duplicate_identifier =>\n        return \"duplicate identifier: \" & hint_1;\n      when err_identifier_missing =>\n        return \"missing an identifier\";\n      when err_missing_a_procedure_declaration =>\n        return \"missing a procedure declaration\" & hint_1;\n      when err_closing_parenthesis_missing =>\n        return \"missing closing parenthesis \"\")\"\"\";\n      when err_colon_missing =>\n        return \"missing a colon \"\":\"\"\";\n      when err_colon_missing_for_named_statement =>\n        return\n          \"undefined identifier (\" & hint_1 & \");\" &\n          \" if a named statement is meant, a colon \"\":\"\" would be expected here\";\n      when err_incorrectly_used_symbol =>\n        return \"incorrectly used symbol [\" & hint_1 & ']';\n      when err_missing_OF =>\n        return \"missing \"\"of\"\"\";\n      when err_missing_an_opening_parenthesis =>\n        return \"missing an opening parenthesis \"\"(\"\"\";\n      when err_left_bracket_instead_of_parenthesis =>\n        return \"found '[' instead of '('\";\n      when err_right_bracket_instead_of_parenthesis =>\n        return \"found ']' instead of ')'\";\n      when err_missing_type_begin_symbol =>\n        --  We only show the supported symbols for starting a type definition.\n        return \"missing \"\"(\"\", \"\"array\"\" or \"\"record\"\"\";\n      when err_expecting_double_dot =>\n        return \"expecting double dot symbol: \"\"..\"\"\";\n      when err_semicolon_missing =>\n        return \"missing a semicolon: \"\";\"\"\";\n      when err_duplicate_semicolon =>\n        return \"duplicate semicolon: \"\";\"\"\";\n      when err_extra_right_parenthesis =>\n        return \"extra ')' ignored\";\n      when err_bad_result_type_for_a_function =>\n        return \"this type is not supported for a function's result; \" &\n               \"try a procedure with an \"\"out\"\" parameter\";\n      when err_type_of_return_statement_doesnt_match =>\n        return \"type of expression in return statement doesn't match: \" & hint_1;\n      when err_illegal_statement_start_symbol =>\n        return \"statement cannot start with a \" & hint_1;\n      when err_expecting_a_boolean_expression =>\n        return \"expecting a Boolean expression\";\n      when err_control_variable_of_the_wrong_type =>\n        return \"control variable must be discrete; found: \" & hint_1;\n      when err_bounds_type_mismatch =>\n        return \"bounds in range must be of the same type\";\n      when err_IS_missing =>\n        return \"missing \"\"is\"\"\";\n      when err_scanner_exponent_too_large =>\n        return \"total actual exponent is too large:\" & hint_1;\n      when err_scanner_integer_literal_too_large =>\n        return \"integer part of number literal is too large; max =\" & integer_digits_max'Image & \" digits\";\n      when err_scanner_illegal_character_in_number =>\n        return \"illegal character in number\" & hint_1;\n      when err_scanner_negative_exponent_for_integer_literal =>\n        return \"integer literal with negative exponent; possible: a float with \"\".0\"\" such as\" & hint_1;\n      when err_incorrect_name_after_END =>\n        return \"\"\"end \" & hint_1 & \";\"\" expected here\";\n      when err_bad_type_for_a_case_statement =>\n        return \"bad type for a case statement\";\n      when err_scanner_illegal_character =>\n        return \"illegal character\";\n      when err_illegal_constant_or_constant_identifier =>\n        return \"illegal constant or constant identifier\";\n      when err_wrong_type_for_array_index =>\n        return \"type mismatch in array index: \" & hint_1;\n      when err_too_few_array_indices =>\n        return \"too few indices in array reference: found\" & hint_1 & \", needed\" & hint_2;\n      when err_too_many_array_indices =>\n        return \"too many indices in array reference: found\" & hint_1 & \", needed\" & hint_2;\n      when err_illegal_array_bounds =>\n        return \"illegal bounds for an array index: \" & hint_1;\n      when err_indexed_variable_must_be_an_array =>\n        return \"indexed variable must be an array\";\n      when err_missing_a_type_identifier =>\n        return \"identifier is not a type\";\n      when err_undefined_type =>\n        return \"undefined type\";\n      when err_var_with_field_selector_must_be_record =>\n        return \"var with field selector must be record\";\n      when err_resulting_type_should_be_Boolean =>\n        return \"resulting type should be Boolean\";\n      when err_illegal_type_for_arithmetic_expression =>\n        return \"illegal type for arithmetic expression\";\n      when err_mod_requires_integer_arguments =>\n        return \"\"\"mod\"\" requires integer arguments\";\n      when err_incompatible_types_for_comparison =>\n        return \"incompatible types for comparison: \" & hint_1;\n      when err_parameter_types_do_not_match =>\n        return \"parameter types do not match: \" & hint_1;\n      when err_variable_missing =>\n        if hint_1 = \"\" then\n          return \"variable expected here\";\n        else\n          return \"variable expected as actual for \"\"\" & hint_1 & '\"';\n        end if;\n      when err_scanner_character_zero_chars =>\n        return \"a character literal is of the form 'x'; \" &\n               \"strings are delimited by double quote character\";\n      when err_number_of_parameters_do_not_match =>\n        return \"number of parameters do not match\" & hint_1;\n      when err_illegal_parameters_to_Get =>\n        return \"illegal parameters to \"\"Get\"\"\";\n      when err_illegal_parameters_to_Put =>\n        return \"illegal parameters to \"\"Put\"\"\";\n      when err_parameter_must_be_of_type_Float =>\n        return \"parameter must be of type Float\";\n      when err_parameter_must_be_Integer =>\n        return \"parameter must be of type Integer\";\n      when err_expected_constant_function_variable_or_subtype =>\n        return \"expected a constant, function, variable or subtype name\";\n      when err_types_of_assignment_must_match =>\n        return \"types must match in an assignment: \" & hint_1;\n      when err_case_label_not_same_type_as_case_clause =>\n        return \"case label not of same type as case clause: \" & hint_1;\n      when err_duplicate_case_choice_value =>\n        return \"duplicate choice value in \"\"case\"\" statement\";\n      when err_argument_to_std_function_of_wrong_type =>\n        return \"wrong type of argument to operator or standard function: \" & hint_1;\n      when err_stack_size =>\n        return \"the program requires too much storage\";\n      when err_illegal_symbol_for_a_number_declaration =>\n        return \"illegal symbol for a number declaration or a literal\";\n      when err_BECOMES_missing =>\n        return \"missing \"\":=\"\"\";\n      when err_THEN_missing =>\n        return \"missing \"\"then\"\"\";\n      when err_IN_missing  =>\n        return \"missing \"\"in\"\"\";\n      when err_missing_closing_LOOP | err_missing_closing_LOOP_2 =>\n        return \"missing closing \"\"loop\"\"\";\n      when err_BEGIN_missing =>\n        return \"missing \"\"begin\"\"\";\n      when err_END_missing =>\n        return \"missing \"\"end\"\"\";\n      when err_primary_unexpected_symbol =>\n        return \"expected \"\"(\"\", or: name, number, string, ... (RM 4.4 (7), 4.5(8))\";\n      when err_RETURN_missing =>\n        return \"missing \"\"return\"\"\";\n      when err_scanner_control_character =>\n        return \"control character present in source \";\n      when err_RECORD_missing =>\n        return \"missing \"\"record\"\"\";\n      when err_missing_closing_IF | err_missing_closing_IF_2 =>\n        return \"missing closing \"\"if\"\"\";\n      when err_WHEN_missing =>\n        return \"missing \"\"when\"\" (must have at least one alternative)\";\n      when err_FINGER_missing =>\n        return \"missing the finger \"\"=>\"\"\";\n      when err_missing_closing_CASE | err_missing_closing_CASE_2 =>\n        return \"missing closing \"\"case\"\"\";\n      when err_functions_must_return_a_value =>\n        return \"functions must return a value\";\n      when err_procedures_cannot_return_a_value =>\n        return \"procedures cannot return a value (use functions instead)\";\n      when err_missing_an_entry =>\n        return \"expecting an entry\";\n      when err_missing_expression_for_delay =>\n        return \"missing expression for \"\"delay\"\"\";\n      when err_wrong_type_in_DELAY =>\n        return \"delay time must be type Float\";\n      when err_COMMA_missing =>\n        return \"comma expected\";\n      when err_expecting_accept_when_or_entry_id =>\n        return \"expecting \"\"accept\"\", \"\"when\"\", or entry id\";\n      when err_expecting_task_entry =>\n        return \"expecting Task.Entry\";\n      when err_expecting_OR_or_ELSE_in_SELECT =>\n        return \"expecting \"\"or\"\" or \"\"else\"\" in select\";\n      when err_expecting_DELAY =>\n        return \"expecting \"\"delay\"\"\";\n      when err_SELECT_missing =>\n        return \"missing \"\"select\"\"\";\n      when err_program_incomplete =>\n        return \"program incomplete\";\n      when err_OF_instead_of_IS =>\n        return \"found \"\"of\"\", should be \"\"is\"\"\";\n      when err_THEN_instead_of_Arrow =>\n        return \"found \"\"then\"\", should be \"\"=>\"\"\";\n      when err_EQUALS_instead_of_BECOMES =>\n        return \"found \"\"=\"\", should be \"\":=\"\"\";\n      when err_numeric_constant_expected =>\n        return \"numeric constant expected\";\n      when err_scanner_identifier_too_long =>\n        return\n          \"identifier is too long; max =\" &\n          Integer'Image (identifier_length_max) & \" characters\";\n      when err_scanner_identifier_cannot_end_with_underline =>\n        return \"identifier cannot end with underline\";\n      when err_scanner_double_underline_not_permitted =>\n        return \"double underline not permitted\";\n      when err_statement_expected =>\n        return \"statement expected, can be \"\"null\"\"\";\n      when err_duplicate_loop_identifier =>\n        return \"loop identifier already defined above: \" & hint_1;\n      when err_unexpected_end_of_text =>\n        return \"unexpected end of text\";\n      when err_not_yet_implemented =>\n        return \"construct not yet implemented or supported by HAC: \" & hint_1;\n      when err_type_conversion_not_supported =>\n        return \"this type conversion is not supported: \" & hint_1;\n      when err_numeric_type_coercion =>\n        return \"numeric types don't match: \" & hint_1 & \" - please use explicit conversion\";\n      when err_numeric_type_coercion_operator =>\n        return \"numeric types don't match (\" & hint_1 & \"): \" &\n               hint_2 & \" - please use explicit conversion\";\n      when err_operator_not_defined_for_types =>\n        return \"operator (\" & hint_1 & \") is not defined for that type(s) of operand(s): \" & hint_2;\n      when err_no_null_functions =>\n        return \"a function cannot be null; only a procedure can\";\n      when err_scanner_digit_expected =>\n        return \"digit expected\";\n      when err_cannot_modify_constant_or_in_parameter =>\n        return \"cannot modify a constant or a \"\"in\"\" parameter\" & hint_1;\n      when err_case_others_alone_last =>\n        return \"the \"\"others\"\" choice must appear alone and in the last choice list (RM 5.4 (5))\";\n      when err_no_X_for_END_X =>\n        return \"no \"\"\" & hint_1 & \"\"\" for this \"\"end \" & hint_1 & \"\"\"\";\n      when err_END_LOOP_ident_missing =>\n        return \"\"\"end loop \" & hint_1 & \";\"\" expected (RM 5.5 (5))\";\n      when err_END_LOOP_ident_wrong =>\n        return \"wrong loop identifier: \"\"end loop \" & hint_1 & \";\"\" expected\";\n      when err_general_error =>\n        if hint_1 = \"\" then\n          return \"syntax error\";\n        else\n          return hint_1;  --  The message is the hint.\n        end if;\n      when err_string_to_vstring_assignment =>\n        return \"fixed string assigned to a variable string;\" &\n               \" put a \"\"+\"\" in front of the fixed string\";\n      when err_range_constraint_error =>\n        return \"error in range constraint: \" & hint_1;\n      when err_discrete_type_expected =>\n        return \"discrete type expected\";\n      when err_membership_test_type_mismatch =>\n        return \"incompatible types in membership test: \" & hint_1;\n      when err_string_not_supported_as_parameter =>\n        return \"string not supported as parameter\" &\n          \" - define a constrained \"\"subtype S2 is String (1..2)\"\" or use a VString\";\n      when err_string_lengths_do_not_match =>\n        return \"fixed-size string lengths do not match: \" & hint_1;\n      when err_library_error =>\n        return \"library error: \" & hint_1;\n      when err_wrong_unit_name =>\n        return \"unit name \"\"\" & hint_1 & \"\"\" expected in this file, found: \"\"\" & hint_2 & '\"';\n      when err_obsolete_hat_name =>\n        return \"the new name of \"\"\" & hint_2 & \"\"\" is \"\"\" & hint_1 & '\"';\n      when err_object_used_before_end_own_declaration =>\n        return \"attempt to use object \" & hint_1 & \"before end of its own declaration\";\n      when err_attribute_prefix_invalid =>\n        return \"invalid prefix for \"\"\" & hint_1 & \"\"\" attribute\";\n      when err_attribute_prefix_must_be_discrete_type =>\n        return \"prefix of \"\"\" & hint_1 & \"\"\" attribute must be discrete type\";\n      when err_invalid_dimension_number =>\n        return \"invalid dimension number for array type, \" & hint_1;\n      when err_spec_body_mismatch =>\n        return \"specification vs. body mismatch: \" & hint_1;\n      when err_incomplete_declaration =>\n        return \"missing body or full declaration for \" & hint_1;\n      when err_non_public_entity =>\n        return '\"' & hint_1 & \"\"\" is not a public entity of the package in prefix\";\n      when err_choices_not_covered =>\n        return \"all case values shall be covered, either explicitly \" &\n               \"or by \"\"others\"\" (RM 5.4 (6))\" & hint_1;\n      when err_choice_out_of_range =>\n        return \"choice(s) out of range of case expression\";\n      when err_mixed_logical_operators =>\n        return \"mixed logical operators in expression (RM 4.4 (2)) - \" &\n               \"clarify by using parentheses\";\n      when err_scanner_space_missing_after_number =>\n        return\n          \"space missing here; \" &\n          \"if an identifier was meant, it cannot start with a number\";\n      when err_assignment_not_allowed_declarative =>\n        return\n          \"assignment (variable := ...) not allowed in declarative part\";\n      when others =>\n        return hint_1;\n    end case;\n  end Diagnostic_String;\n\n  ----------------------------------------------------------------------------\n\n  function \"+\" (S : String) return HAT.VString renames HAT.\"+\";\n\n  --  The \"[...]\" are replaced by the correct identifier.\n\n  repair_table : constant array (Compile_Diagnostic) of Repair_Kit :=\n    (\n      err_missing_a_procedure_declaration\n                                             => (insert,        +\"procedure \"),\n      err_colon_missing                      => (insert,        +\": \"),\n      err_semicolon_missing                  => (insert,        +\"; \"),\n      err_RETURN_missing                     => (insert,        +\"return \"),\n      err_statement_expected                 => (insert,        +\"null;\"),\n      err_IN_missing                         => (insert,        +\"in \"),\n      err_IS_missing                         => (insert,        +\"is \"),\n      err_OF_instead_of_IS                   => (replace_token, +\"is\"),\n      err_THEN_instead_of_Arrow              => (replace_token, +\"=>\"),\n      err_FINGER_missing                     => (insert,        +\" => \"),\n      err_missing_closing_LOOP               => (insert,        +\" loop\"),\n      err_missing_closing_LOOP_2             => (replace_token, +\"loop\"),\n      err_missing_closing_CASE               => (insert,        +\" case\"),\n      err_missing_closing_CASE_2             => (replace_token, +\"case\"),\n      err_missing_closing_IF                 => (insert,        +\" if\"),\n      err_missing_closing_IF_2               => (replace_token, +\"if\"),\n      err_RECORD_missing                     => (insert,        +\" record\"),\n      err_closing_parenthesis_missing        => (insert,        +\")\"),\n      err_END_LOOP_ident_missing             => (insert,        +\"[ something... ]\"),\n      err_scanner_space_missing_after_number => (insert,        +\" \"),\n      err_choices_not_covered =>\n        (insert,        +\"\\twhen others => null;  --  Use with caution...\\n\"),\n      err_incorrect_name_after_END |\n      err_END_LOOP_ident_wrong     |\n      err_wrong_unit_name          |\n      err_obsolete_hat_name         => (replace_token, +\"[ something... ]\"),\n      err_EQUALS_instead_of_BECOMES => (replace_token, +\":=\"),\n      err_duplicate_semicolon       => (replace_token, +\"\"),\n      err_extra_right_parenthesis   => (replace_token, +\"\"),\n      others                        => nothing_to_repair\n    );\n\n  procedure Diagnostic\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Diagnostic;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     severity            :        Error_Severity         := medium;\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0))\n  is\n    use Ada.Strings, Ada.Strings.Fixed, Ada.Text_IO;\n    to_be_marked : Symbol_Location;\n    --\n    procedure Show_to_comp_dump (objNumber : Integer) is\n    begin\n      if CD.comp_dump_requested then\n        Put_Line\n         (CD.comp_dump,\n          \" Error code = \" &\n          Defs.Compile_Diagnostic'Image (code) &\n          \" (\" &\n          Diagnostic_String (code, hint_1, hint_2) &\n          \") \" &\n          \" srcNumber=\" & to_be_marked.line'Image &\n          \" charStart=\" & to_be_marked.column_start'Image &\n          \" charEnd=\"   & to_be_marked.column_stop'Image &\n          \" objNumber=\" & objNumber'Image);\n      end if;\n    end Show_to_comp_dump;\n    --\n    updated_repair_kit : Repair_Kit := repair_table (code);\n    ub_hint : constant HAT.VString := HAT.To_VString (hint_1);\n    use HAT.VStr_Pkg;\n    kit : Diagnostic_Kit;\n    --\n    function Diagnostic_Suffix return String is\n      (case kit.diagnostic_kind is\n         when warning | note => \" [-r\" & remark_letter (code) & ']',\n         when others         => \"\");\n  begin\n\n    kit.diagnostic_kind :=\n      (case code is\n         when Compile_Error   => error,\n         when Compile_Warning => warning,\n         when Compile_Note    => note);\n\n    to_be_marked :=\n      (case location_method is\n         when current_symbol  => CD.CUD.location,\n         when previous_symbol => CD.prev_sy_loc,\n         when explicit        => explicit_location);\n\n    Show_to_comp_dump (-1);\n    CD.diags (code) := True;\n\n    if code in Compile_Error then\n      if severity = minor then\n        CD.minor_error_count := CD.minor_error_count + 1;\n      else\n        CD.error_count := CD.error_count + 1;\n      end if;\n    end if;\n\n    if CD.trace.pipe = null then\n      Put_Line\n        (Current_Error,\n         (if CD.CUD.source_file_name = \"\" then\n            \"\"\n          else\n            To_String (CD.CUD.source_file_name) & \": \" &\n            Trim (to_be_marked.line'Image,         Left) & ':' &\n            Trim (to_be_marked.column_start'Image, Left) & '-' &\n            Trim (to_be_marked.column_stop'Image,  Left) & \": \")\n         &\n         Diagnostic_Prefix (kit.diagnostic_kind) &\n         Diagnostic_String (code, hint_1, hint_2) &\n         Diagnostic_Suffix);\n    else\n\n      case code is\n        when err_incorrect_name_after_END =>\n          if hint_1 = \"\" then\n            updated_repair_kit.repair_kind := none;\n          else\n            updated_repair_kit.alternative := ub_hint;\n          end if;\n        when err_END_LOOP_ident_missing =>\n          updated_repair_kit.alternative := ' ' & ub_hint;\n        when err_END_LOOP_ident_wrong |\n             err_obsolete_hat_name\n          =>\n          updated_repair_kit.alternative := ub_hint;\n        when err_wrong_unit_name =>\n          updated_repair_kit.alternative :=\n            HAT.To_VString (Librarian.Ada_RM_Casing (HAT.To_String (ub_hint)));\n        when others =>\n          null;\n      end case;\n\n      Repair_Kit (kit) := updated_repair_kit;\n      kit.message   := To_Unbounded_String (Diagnostic_String (code, hint_1, hint_2));\n      kit.file_name := To_Unbounded_String (Co_Defs.Get_Source_Name (CD.CUD));\n      kit.location  := to_be_marked;\n\n      CD.trace.pipe (kit);\n    end if;\n    --  Uncomment the next line for getting a nice trace-back of 1st error.\n    --  raise Constraint_Error;\n    --\n    if code in Compile_Error and then severity = major then\n      --  Useless to continue compiling, the source is FUBAR\n      --  and the compiler close to total confusion!\n      raise Compilation_abandoned;\n    end if;\n  end Diagnostic;\n\n  procedure Error\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Error;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     severity            :        Error_Severity         := medium;\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0))\n  is\n  begin\n    Diagnostic (CD, code, hint_1, hint_2, severity, location_method, explicit_location);\n  end Error;\n\n  procedure Remark\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Remark;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0);\n     remark_made         :    out Boolean)\n  is\n  begin\n    remark_made := False;\n    if CD.remarks (code) then\n      --  Remark (Note or Warning) is optional.\n      --  Severity (minor passed here) does nothing for remarks.\n      Diagnostic (CD, code, hint_1, hint_2, minor, location_method, explicit_location);\n      remark_made := True;\n    end if;\n  end Remark;\n\n  procedure Remark\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Remark;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0))\n  is\n    dummy : Boolean;\n  begin\n    Remark (CD, code, hint_1, hint_2, location_method, explicit_location, dummy);\n  end Remark;\n\n  ----------------------------------------------------------------------------\n\n  procedure Fatal (N : Table_OverFlow_Error; Current_Error_Output : Boolean := False) is\n    use Ada.Text_IO;\n  begin\n    if Current_Error_Output then\n      Put (Current_Error, \"The Compiler TABLE for: *\");\n      case N is\n        when FLOAT_CONSTANTS  => Put (Current_Error, \"Float Constants\");\n        when STRING_CONSTANTS => Put (Current_Error, \"Strings Constants\");\n        when Object_Code      => Put (Current_Error, \"Object Code\");\n        when PATCHING         => Put (Current_Error, \"ObjCode PATCHING\");\n        when others           => Put (Current_Error, Table_OverFlow_Error'Image (N));\n      end case;\n      Put_Line (Current_Error, \"* is too SMALL\");\n      New_Line (Current_Error);\n      Put_Line (Current_Error, \" Please take this output to the maintainers of \");\n      Put_Line (Current_Error, \" HAC for your installation \");\n      New_Line (Current_Error);\n      Put_Line (Current_Error, \" Fatal termination of HAC\");\n    end if;\n    --\n    raise Failure_1_0 with\n      \"HAC.UErrors.Fatal:\" &\n      \" internal HAC compiler error.\" &\n      \" The table for \" &\n      Table_OverFlow_Error'Image (N) &\n      \" is too small. More details with qDebug=True\";\n  end Fatal;\n\n  ----------------------------------------------------------------------------\n\n  procedure Compilation_Diagnostics_Summary (CD : Co_Defs.Compiler_Data) is\n    use Ada.Text_IO;\n    procedure Summary_Line (s : String) is\n    begin\n      if CD.comp_dump_requested then\n        Put_Line (CD.comp_dump, s);\n      end if;\n      if CD.listing_requested then\n        Put_Line (CD.listing, s);\n      end if;\n    end Summary_Line;\n  begin\n    Summary_Line (\"\");\n    for K in CD.diags'Range loop\n      if K = Compile_Error'First then\n        Summary_Line (\"==== Error Message(s) ====\");\n      elsif K = Compile_Warning'First then\n        Summary_Line (\"==== Warning(s) ==========\");\n      end if;\n      if CD.diags (K) then\n        Summary_Line (K'Image & \":  \" & Diagnostic_String (K));\n      end if;\n    end loop;\n  end Compilation_Diagnostics_Summary;\n\nend HAC_Sys.Errors;\n"
  },
  {
    "path": "src/compile/hac_sys-errors.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n\nwith HAC_Sys.Co_Defs,\n     HAC_Sys.Defs;\n\nwith HAT;\n\npackage HAC_Sys.Errors is\n\n  nothing_to_repair : constant Defs.Repair_Kit := (Defs.none, HAT.Null_VString);\n\n  type Error_Severity is\n    (minor,   --  Extra ';', ')', value out of range, etc.: we can continue the\n              --     compilation normally for catching other possible errors.\n     medium,  --  Compilation is shortened at some points in order to avoid\n              --     infinite loops in the parser. Tricky!\n     major);  --  In this case, the best choice is to STOP the compilation immediately.\n\n  type Symbol_Location_Method is\n    (current_symbol, previous_symbol, explicit);\n\n  procedure Error\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Error;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     severity            :        Error_Severity         := medium;\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0));\n\n  procedure Remark\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Remark;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0);\n     remark_made         :    out Boolean);\n\n  procedure Remark\n    (CD                  : in out Co_Defs.Compiler_Data;\n     code                :        Defs.Compile_Remark;\n     hint_1              :        String                 := \"\";\n     hint_2              :        String                 := \"\";\n     location_method     :        Symbol_Location_Method := current_symbol;\n     explicit_location   :        Defs.Symbol_Location   := (0, 0, 0));\n\n  function Diagnostic_Prefix (kind : Defs.Diagnostic_Kind_Type) return String is\n    (case kind is\n       when Defs.error   => \"\",\n       when Defs.warning => \"warning: \",\n       when Defs.note    => \"note: \",\n       when Defs.style   => \"style: \");\n\n  procedure Compilation_Diagnostics_Summary (CD : Co_Defs.Compiler_Data);\n\n  type Table_OverFlow_Error is\n    (IDENTIFIERS,\n     PROCEDURES,\n     FLOAT_CONSTANTS,\n     ARRAYS,\n     LEVELS,\n     Loop_Nesting_Levels,\n     Object_Code,\n     Case_Labels,\n     STRING_CONSTANTS,\n     TASKS,\n     ENTRIES,\n     PATCHING);\n\n  procedure Fatal (N : Table_OverFlow_Error; Current_Error_Output : Boolean := False);\n\n  Internal_error : exception;\n  Failure_1_0 : exception;\n  Compilation_abandoned : exception;\n  Compilation_of_package_body_before_spec : exception;\n\nend HAC_Sys.Errors;\n"
  },
  {
    "path": "src/compile/hac_sys-multi_precision_integers.adb",
    "content": "-----------------------------------------------------------------------------\r\n--  File: hac_sys-multi_precision_integers.ads\r\n-----------------------------------------------------------------------------\r\n--    Aug-2007: - No more generics (Long_Block_type,\r\n--                Block_type,... always the largest possible idea: J.C.)\r\n--              - Fixed Basic(...) (based on J.C.'s remarks)\r\n--    Nov-2006: - Multiply_internal with/without copy of result (automatic\r\n--                detection of when it is needed)\r\n--              - Explicit Multiply_internal for Multi_int * Basic_int\r\n--              - Multiply(multi,basic,multi) available as procedure\r\n--              - useless zeroing of quotient removed\r\n--              - useless zeroing of blocks removed for indices\r\n--                above last possible used in *\r\n--  24-Feb-2002: Div_Rem(u, v, v, r) also possible\r\n--  23-Feb-2002: DEBUG: +: multiplications are verified by dividing the result\r\n--                     +: divisions are verified by comparing i2*q+r and i1\r\n--  15-Feb-2002: \"zero\" and 1st index in Divide_absolute_normalized\r\n--                 bugs fixed by Duncan Sands (D.S.)\r\n\r\npragma Warnings (\".P\");\r\npragma Warnings (\".I\");\r\npragma Warnings (\"C\");\r\n\r\nwith Ada.Unchecked_Deallocation;\r\n\r\npackage body HAC_Sys.Multi_Precision_Integers is\r\n  use type Basic_Int;\r\n\r\n  function Shift_Left\r\n    (Value  : Block_type;\r\n     Amount : Natural) return Block_type is\r\n  begin\r\n    return Value * (2 ** Amount);\r\n  end Shift_Left;\r\n\r\n  function Shift_Right\r\n    (Value  : Block_type;\r\n     Amount : Natural) return Block_type is\r\n  begin\r\n    return Value / (2 ** Amount);\r\n  end Shift_Right;\r\n\r\n  function Shift_Left\r\n    (Value  : Long_Block_type;\r\n     Amount : Natural) return Long_Block_type is\r\n  begin\r\n    return Value * (2 ** Amount);\r\n  end Shift_Left;\r\n\r\n  function Shift_Right\r\n    (Value  : Long_Block_type;\r\n     Amount : Natural) return Long_Block_type is\r\n  begin\r\n    return Value / (2 ** Amount);\r\n  end Shift_Right;\r\n\r\n  --  Internal_error: exception;\r\n  --  Not_done: exception;\r\n\r\n  type compar is (smaller, equal, greater);\r\n\r\n  function Min (a, b : Index_Int) return Index_Int is\r\n  begin\r\n    return (if a < b then a else b);\r\n  end Min;\r\n\r\n  function Max (a, b : Index_Int) return Index_Int is\r\n  begin\r\n    return (if a > b then a else b);\r\n  end Max;\r\n\r\n  procedure Reduce_last_nonzero (n : in out Multi_int) is\r\n    old_last : constant Index_Int := n.last_used;\r\n  begin\r\n    if n.zero then -- We avoid de-zeroing accidentally\r\n      return;      -- and returning a false non-zero with rubbish :-)\r\n    end if;\r\n\r\n    n.zero := True;\r\n    for i in 0 .. old_last loop -- after old_last it *is* rubbish anyway.\r\n      if n.blk (i) /= 0 then\r\n        n.zero := False;\r\n        n.last_used := i;\r\n      end if;\r\n    end loop;\r\n  end Reduce_last_nonzero;\r\n\r\n  function Compare_absolute (i1, i2 : Multi_int) return compar is\r\n    l1, l2 : Index_Int;\r\n  begin\r\n    --  On ne compare que ABS(i1) et ABS(i2)\r\n    l1 := i1.last_used;\r\n    l2 := i2.last_used;\r\n    if l1 > l2 then         -- i1 a plus de blocs non nuls\r\n      return greater;\r\n    elsif l1 < l2 then      -- i1 a moins de blocs non nuls\r\n      return smaller;\r\n    else                       -- i1 et i2 ont le meme nb de blocs\r\n      for i in reverse 0 .. l1 loop -- on parcourt du + signifiant au -\r\n        if    i1.blk (i) > i2.blk (i) then -- <<chiffre>> de i1 plus grand\r\n          return greater;\r\n        elsif i1.blk (i) < i2.blk (i) then -- <<chiffre>> de i1 plus petit\r\n          return smaller;\r\n        end if;\r\n        --  M\\^emes chiffres -> au suivant!\r\n      end loop;\r\n      --  Bon, les 2 nombres sont egaux!\r\n      return equal;\r\n    end if;\r\n  end Compare_absolute;\r\n\r\n  ----- Informations, conversions\r\n\r\n  function Multi (small : Basic_Int) return Multi_int is\r\n    long                           : Long_Block_type_signed;\r\n    abs_long, heading              : Long_Block_type;\r\n    small_enough, case_first_value : Boolean;\r\n    negs                           : constant Boolean := small < 0;\r\n    Conversion_overflow : exception;\r\n  begin\r\n    abs_long := 0;\r\n    long := Long_Block_type_signed (small);\r\n    case_first_value := long = Long_Block_type_signed'First;\r\n    if case_first_value then\r\n      --  `long` is equal to the lowest value for Long_Block_type_signed.\r\n      --  Then, (abs long) will automatically overflow.\r\n      --  For example, for a 64-bit integer, -2**63 is ok, but 2**63 is\r\n      --  larger than the maximum 64-bit integer, 2**63 - 1.\r\n      --  So we have to have a special case for that value.\r\n      small_enough := False;\r\n    else\r\n      abs_long := Long_Block_type (abs long);\r\n      small_enough := abs_long <= Long_Block_type (maxblock);\r\n    end if;\r\n    --\r\n    if small_enough then\r\n      return Multi_int'\r\n             (n =>         0,                            --  One block is enough.\r\n              blk =>      (0 => Block_type (abs_long)),  --  The block contains the number.\r\n              neg =>       negs,\r\n              zero =>      small = 0,\r\n              last_used => 0\r\n             );\r\n    elsif case_first_value then\r\n      heading := Shift_Right\r\n        (Long_Block_type (-(Long_Block_type_signed'First / 2)),  --  E.g. for 64-bit: 2**62.\r\n         Block_type_bits - 1);                                   --  First shift is done by the / 2.\r\n      return Multi_int'\r\n             (n =>         1,                                   --  Two blocks are needed.\r\n              blk =>      (0 => 0,                              --  Block #0\r\n                           1 => Block_type (heading)),          --  Block #1\r\n              neg =>       True,\r\n              zero =>      False,\r\n              last_used => 1\r\n             );\r\n    else\r\n      heading := Shift_Right (abs_long, Block_type_bits);\r\n      if heading <= Long_Block_type (maxblock) then\r\n        return (n =>         1,                                    --  Two blocks are needed.\r\n                blk =>      (0 => Block_type (abs_long and maxblock),  --  Block #0\r\n                             1 => Block_type (heading)),           --  Block #1\r\n                neg =>       negs,\r\n                zero =>      False,\r\n                last_used => 1\r\n               );\r\n      else\r\n        if Shift_Right (heading, Block_type_bits) > Long_Block_type (maxblock) then\r\n           raise Conversion_overflow;\r\n        end if;\r\n\r\n        return (n =>     2,   --  Three blocks are needed. (e.g. 31 bits: 15+15+1)\r\n                blk =>  (0 => Block_type (abs_long and maxblock),                      --  Block #0\r\n                         1 => Block_type (heading and maxblock),                   --  Block #1\r\n                         2 => Block_type (Shift_Right (heading, Block_type_bits))  --  Block #2\r\n                         ),\r\n                 neg =>   negs,\r\n                 zero =>  False,\r\n                 last_used => 2\r\n               );\r\n      end if;\r\n    end if;\r\n  end Multi;\r\n\r\n  zero : constant Multi_int := Multi (0);\r\n  one : constant Multi_int := Multi (1);\r\n\r\n  Blocks_Per_Basic : constant Positive :=\r\n     (Basic_Int'Size + Block_type'Size - 1) / Block_type'Size;\r\n\r\n  --  Convert Multi_int to Basic_int (when possible, else: Cannot_fit raised)\r\n  --  2007:\r\n  --  - correct code for block sizes smaller than Basic_int\r\n  --  - fixed usage of negative flag\r\n  function Basic (large : Multi_int) return Basic_Int is\r\n    type Same_as_Basic_natural is mod 2 ** Basic_Int'Size;\r\n    function Shift_Left\r\n      (Value  : Same_as_Basic_natural;\r\n       Amount : Natural) return Same_as_Basic_natural is\r\n    begin\r\n      return Value * (2 ** Amount);\r\n    end Shift_Left;\r\n    result : Same_as_Basic_natural;\r\n    block_value : Block_type;\r\n    type Huge_int is mod System.Max_Binary_Modulus;\r\n    last_bit : Natural;\r\n  begin\r\n    if large.zero then -- <- 17-Feb-2002\r\n      return 0;\r\n    end if;\r\n    --  Case: too many blocks (whatever sizes)\r\n    if 1 + large.last_used > Blocks_Per_Basic then\r\n      raise Cannot_fit;\r\n    end if;\r\n    --  Case: block size and contents larger than basic\r\n    block_value := large.blk (large.last_used);\r\n    if Huge_int (block_value) > Huge_int (Basic_Int'Last) then\r\n      raise Cannot_fit;\r\n    end if;\r\n    declare\r\n      tmp : Block_type := block_value;\r\n    begin\r\n      last_bit := 0;\r\n      while tmp /= 0 loop\r\n        tmp := tmp / 2;\r\n        last_bit := last_bit + 1;\r\n      end loop;\r\n    end;\r\n    result := Same_as_Basic_natural (block_value);\r\n    --  If the following loop was on all blocks,\r\n    --  the shift by Block_type_bits in the loop could do meaningless\r\n    --  things the case Basic_int'Size <= Block_Type'Size\r\n    for b in reverse 0 .. large.last_used - 1 loop\r\n      result := Shift_Left (result, Block_type_bits);\r\n      --  An overflow is not detected by shifting (it's the way we want it!)\r\n      --  so we need to detect the overall overflow by locating the\r\n      --  last bit.\r\n      last_bit := last_bit + Block_type_bits;\r\n      if last_bit > Basic_Int'Size - 1 then\r\n        --  ^ \"- 1\" because of sign bit in Basic_int\r\n        raise Cannot_fit;\r\n      end if;\r\n      result := result + Same_as_Basic_natural (large.blk (b));\r\n    end loop;\r\n    if large.neg then\r\n      return -Basic_Int (result);\r\n    else\r\n      return Basic_Int (result);\r\n    end if;\r\n  end Basic;\r\n\r\n  --  14-Feb-2002: \"zero\" bug fixed by Duncan Sands\r\n  procedure Fill (what : out Multi_int; with_smaller : Multi_int) is\r\n    l : constant Index_Int := with_smaller.last_used;\r\n  begin\r\n    what.zero := with_smaller.zero;\r\n\r\n    if with_smaller.zero then\r\n      return;\r\n    end if;\r\n\r\n    if what.n < l then\r\n      raise Array_too_small;   -- contenant trop petit\r\n    end if;\r\n\r\n    what.blk (0 .. l) := with_smaller.blk (0 .. l); -- copy contents\r\n    what.neg := with_smaller.neg;\r\n    what.last_used := l;\r\n  end Fill;\r\n\r\n  procedure Fill (what : out Multi_int; with_basic : Basic_Int) is\r\n  begin\r\n    Fill (what, Multi (with_basic));\r\n  end Fill;\r\n\r\n  function Bits_per_block return Positive is\r\n  begin\r\n    return Block_type_bits;\r\n  end Bits_per_block;\r\n\r\n  ---------------------------\r\n  ----- Unary operators -----\r\n  ---------------------------\r\n\r\n  function \"+\" (i : Multi_int) return Multi_int is begin return i; end \"+\";\r\n\r\n  procedure Opp (i : in out Multi_int) is\r\n  begin\r\n    i.neg := not i.neg; -- -0 possible, anyway i.zero = True in such a case\r\n  end Opp;\r\n\r\n  function \"-\" (i : Multi_int) return Multi_int is\r\n    res : Multi_int (i.n) := i; -- copy + stack :-(\r\n  begin\r\n    Opp (res);\r\n    return res;\r\n  end \"-\";\r\n\r\n  procedure Abso (i : in out Multi_int) is\r\n  begin\r\n    i.neg := False;\r\n  end Abso;\r\n\r\n  function \"Abs\" (i : Multi_int) return Multi_int is\r\n    abs_i : Multi_int (i.n) := i; -- copy + stack :-(\r\n  begin\r\n    abs_i.neg := False;\r\n    return abs_i;\r\n  end \"Abs\";\r\n\r\n  function Sign (i : Multi_int) return Basic_Int is\r\n  begin\r\n    if    i.zero then return  0;\r\n    elsif i.neg  then return -1;\r\n    else              return +1;\r\n    end if;\r\n  end Sign;\r\n\r\n  function Even (i : Multi_int) return Boolean is\r\n  begin\r\n    return i.zero or else i.blk (0) mod 2 = 0;\r\n  end Even;\r\n\r\n  function Odd (i : Multi_int) return Boolean is\r\n  begin\r\n    return (not i.zero) and then i.blk (0) mod 2 = 1;\r\n  end Odd;\r\n\r\n  ----------------------------\r\n  ----- Binary operators -----\r\n  ----------------------------\r\n\r\n  --  Internal algorithm to add two numbers AS POSITIVE ( > 0 ) !\r\n\r\n  procedure Add_absolute (i1, i2 : in Multi_int; i3 : out Multi_int) is\r\n    l1 : constant Index_Int := i1.last_used;\r\n    l2 : constant Index_Int := i2.last_used;\r\n    min_ind : constant Index_Int := Min (l1, l2);\r\n    max_ind : constant Index_Int := Max (l1, l2);\r\n    s : Long_Block_type := 0;\r\n    retenue_finale : Block_type;\r\n  begin\r\n\r\n    if max_ind > i3.n then\r\n      raise Result_undersized;\r\n    end if; -- 17-Feb-2002\r\n\r\n    --  (1) On additionne sur le <<support commun>>\r\n    for ind in 0 .. min_ind loop\r\n      s := Long_Block_type (i1.blk (ind)) + Long_Block_type (i2.blk (ind)) +\r\n              Shift_Right (s, Block_type_bits); --  (retenue)\r\n      i3.blk (ind) := Block_type (s and maxblock);\r\n      --  NB: dans un cas de Add(a,b,a) ou Add(a,b,b),\r\n      --  i1.blk(ind) ou i2.blk(ind) est modifie en meme temps!\r\n    end loop;\r\n\r\n    --  (2) On poursuit au besoin si i1 a plus de blocs...\r\n    if l1 > min_ind then\r\n      for ind in min_ind + 1 .. max_ind loop\r\n        s := Long_Block_type (i1.blk (ind)) +\r\n              Shift_Right (s, Block_type_bits); --  (retenue)\r\n        i3.blk (ind) := Block_type (s and maxblock);\r\n      end loop;\r\n    --  ... ou bien si i2 en a plus.\r\n    elsif l2 > min_ind then\r\n      for ind in min_ind + 1 .. max_ind loop\r\n        s := Long_Block_type (i2.blk (ind)) +\r\n              Shift_Right (s, Block_type_bits); --  (retenue)\r\n        i3.blk (ind) := Block_type (s and maxblock);\r\n      end loop;\r\n    end if;\r\n\r\n    --  (3) Il peut rester une retenue\r\n    retenue_finale := Block_type (Shift_Right (s, Block_type_bits));\r\n    if retenue_finale /= 0 then\r\n      if max_ind + 1 > i3.n then\r\n        raise Result_undersized;\r\n      end if; -- 17-Feb-2002\r\n      i3.blk (max_ind + 1) := retenue_finale;\r\n      i3.last_used := max_ind + 1;\r\n    else\r\n      i3.last_used := max_ind;\r\n    end if;\r\n\r\n    --  (4) i3 = i1+i2 > 0\r\n    i3.neg := False;\r\n    i3.zero := False;\r\n\r\n  end Add_absolute;\r\n\r\n  --  Internal algorithm to subtract two numbers AS POSITIVE ( > 0 ) !\r\n\r\n  procedure Sub_absolute (i1, i2 : in Multi_int; i3 : in out Multi_int;\r\n                         sgn : out Boolean) is\r\n    l1 : constant Index_Int := i1.last_used;\r\n    l2 : constant Index_Int := i2.last_used;\r\n    max_ind : constant Index_Int := Max (l1, l2);\r\n    ai, bi : Long_Block_type;\r\n    s : Block_type;\r\n    retenue_finale : Long_Block_type;\r\n  begin\r\n\r\n    if max_ind > i3.n then raise Result_undersized; end if; -- 17-Feb-2002\r\n\r\n    i3.last_used := 0;\r\n    i3.zero := True;\r\n    s := 0;\r\n\r\n    --  (1) Soustraction avec retenue\r\n    for ind in 0 .. max_ind loop\r\n      if ind <= l1 then\r\n        ai := Long_Block_type (i1.blk (ind));\r\n      else\r\n        ai := 0;\r\n      end if;\r\n      if ind <= l2 then\r\n        bi := Long_Block_type (i2.blk (ind)) + Long_Block_type (s);\r\n      else\r\n        bi := Long_Block_type (s);\r\n      end if;\r\n\r\n      if ai < bi then\r\n        ai := ai + cardblock;\r\n        s := 1;\r\n      else\r\n        s := 0;\r\n      end if;\r\n\r\n      i3.blk (ind) := Block_type (ai - bi);\r\n      --  NB: dans un cas de Sub(a,b,a) ou Sub(a,b,b),\r\n      --  i1.blk(ind) ou i2.blk(ind) est modifie en meme temps!\r\n\r\n      if i3.blk (ind) /= 0 then -- au passage, on corrige .last_used et .zero\r\n        i3.last_used := ind;\r\n        i3.zero := False;\r\n      end if;\r\n    end loop;\r\n\r\n    --  (2) Traitement de la derni\\`ere retenue\r\n    if s = 0 then\r\n      i3.neg := False;\r\n      sgn    := False;\r\n    else\r\n      i3.neg := True;\r\n      sgn    := True;\r\n      i3.last_used := 0;\r\n      retenue_finale := 1; -- on fait \"9-chaque chiffre\" et on ajoute 1 au tout\r\n      for i in 0 .. max_ind loop\r\n        retenue_finale :=\r\n          Long_Block_type (maxblock) -\r\n          Long_Block_type (i3.blk (i)) + retenue_finale;\r\n        i3.blk (i) := Block_type (retenue_finale and maxblock);\r\n        if i3.blk (i) /= 0 then\r\n          i3.last_used := i;\r\n        end if;\r\n        retenue_finale := Shift_Right (retenue_finale, Block_type_bits);\r\n      end loop;\r\n    end if;\r\n\r\n  end Sub_absolute;\r\n\r\n  procedure Add (i1, i2 : in Multi_int; i3 : in out Multi_int) is\r\n    sgn : Boolean;\r\n  begin\r\n    --  (1) Les cas o\\`u i1 ou i2 = 0\r\n    if i1.zero and i2.zero then\r\n      i3.zero := True;\r\n    elsif i1.zero then\r\n      Fill (i3, i2);\r\n    elsif i2.zero then\r\n      Fill (i3, i1);\r\n    --  (2) Maintenant: i1 /= 0 et i2 /= 0; on regarde les signes\r\n    --  (2.1) Facile: i1 et i2 de m\\^eme signe\r\n    elsif i1.neg = i2.neg then\r\n      Add_absolute (i1, i2, i3); -- On fait comme si i1>0 et i2>0\r\n      i3.neg := i1.neg;           -- et on met le bon signe\r\n    --  (2.2) i1 < 0, i2 > 0, donc i3 = i2 - abs(i1)\r\n    elsif i1.neg and not i2.neg then\r\n      Sub_absolute (i2, i1, i3, sgn);\r\n    --  (2.3) i1 > 0, i2 < 0, donc i3 = i1 - abs(i2)\r\n    elsif i2.neg and not i1.neg then\r\n      Sub_absolute (i1, i2, i3, sgn);\r\n    end if;\r\n  end Add;\r\n\r\n  function \"+\" (i1, i2 : Multi_int) return Multi_int is\r\n    somme : Multi_int (Max (i1.n, i2.n) + 1);\r\n  begin\r\n    Add (i1, i2, somme);\r\n    return somme;\r\n  end \"+\";\r\n\r\n  procedure Sub (i1, i2 : in Multi_int; i3 : in out Multi_int) is\r\n    sgn : Boolean;\r\n  begin\r\n    --  (1) Les cas o\\`u i1 ou i2 = 0\r\n    if    i1.zero and i2.zero then i3.zero := True;\r\n    elsif i1.zero then Fill (i3, i2); i3.neg := not i2.neg;\r\n    elsif i2.zero then Fill (i3, i1);\r\n\r\n    --  (2) Maintenant: i1 /= 0 et i2 /= 0; on regarde les signes\r\n\r\n    --  (2.1) Facile: i1 et i2 de m\\^eme signe\r\n    elsif i1.neg = i2.neg then\r\n      Sub_absolute (i1, i2, i3, sgn); -- On fait comme si i1>0 et i2>0\r\n                                      --  et on met le bon signe\r\n    i3.neg := i1.neg xor sgn;\r\n    --  26-Mar-2002: equivalent a:\r\n    --      if i1.neg then\r\n    --        i3.neg:= NOT sgn;\r\n    --      else\r\n    --        i3.neg:= sgn;\r\n    --      end if;\r\n\r\n    --  (2.2) i1 < 0, i2 > 0, donc i3 = i1-i2 = - (abs(i1) + abs(i2))\r\n    elsif i1.neg and not i2.neg then\r\n      Add_absolute (i1, i2, i3);\r\n      i3.neg := True;\r\n\r\n    --  (2.3) i1 > 0, i2 < 0, donc i3 = i1-i2 = i1 + (-i2) = i1 + abs(i2)\r\n    elsif i2.neg and not i1.neg then\r\n      Add_absolute (i1, i2, i3);\r\n    end if;\r\n\r\n  end Sub;\r\n\r\n  function \"-\" (i1, i2 : Multi_int) return Multi_int is\r\n    diff : Multi_int (Max (i1.n, i2.n) + 1); -- +1: retenue possible (add_abs.)\r\n  begin\r\n    Sub (i1, i2, diff);\r\n    return diff;\r\n  end \"-\";\r\n\r\n  function \"+\" (i1 : Multi_int; i2 : Basic_Int) return Multi_int is\r\n  begin return i1 + Multi (i2); end \"+\";\r\n\r\n  function \"+\" (i1 : Basic_Int; i2 : Multi_int) return Multi_int is\r\n  begin return Multi (i1) + i2; end \"+\";\r\n\r\n  function \"-\" (i1 : Multi_int; i2 : Basic_Int) return Multi_int is\r\n  begin return i1 - Multi (i2); end \"-\";\r\n\r\n  function \"-\" (i1 : Basic_Int; i2 : Multi_int) return Multi_int is\r\n  begin return Multi (i1) - i2; end \"-\";\r\n\r\n  ----- Begin of MULTIPLICATION part -----\r\n\r\n  --  Added 2006: choice to copy result into i3 or write directly into i3\r\n  generic\r\n    copy : Boolean;\r\n  procedure Multiply_internal_m_m (i1, i2 : in Multi_int; i3 : in out Multi_int);\r\n\r\n  type p_Block_array is access Block_array;\r\n  procedure Dispose is new Ada.Unchecked_Deallocation (Block_array, p_Block_array);\r\n\r\n  -------------------\r\n  -- Multi * Multi --\r\n  -------------------\r\n\r\n  --  To do: implement a faster algorithm.\r\n  --  1) Karatsuba's algorithm\r\n  --     Ada code for string arithm exists\r\n  --     http://www.csc.liv.ac.uk/~ped/teachadmin/algor/karatsuba.ada\r\n  --  2) Better: Schnhage-Strassen algorithm (no Ada code)\r\n\r\n  procedure Multiply_internal_m_m (i1, i2 : in Multi_int; i3 : in out Multi_int) is\r\n    l1 : constant Index_Int := i1.last_used;\r\n    l2 : constant Index_Int := i2.last_used;\r\n    last_max : constant Index_Int := l1 + l2 + 2;\r\n    prod, sum_carry, rk, i1j : Long_Block_type;\r\n    i, k : Index_Int;\r\n    res : p_Block_array;\r\n    --  res: buffer used in the \"copy\" variant to avoid\r\n    --  problems with Multiply(i,j,i) or Multiply(j,i,i)\r\n  begin\r\n    if i1.zero or i2.zero then\r\n      i3.zero := True;\r\n      return;\r\n    end if;\r\n\r\n    if last_max > i3.n then\r\n      raise Result_undersized;\r\n    end if;\r\n\r\n    if copy then\r\n      res := new Block_array (0 .. last_max);\r\n      for k in res'Range loop res (k) := 0; end loop;\r\n      --  Seems slower :-( :  res:= new Block_array'( 0..last_max => 0);\r\n    else\r\n      for k in 0 .. last_max loop i3.blk (k) := 0; end loop;\r\n      --  Slower :-( :  i3.blk(0..last_max):= (others => 0);\r\n    end if;\r\n\r\n    i3.zero := False;\r\n    i3.last_used := last_max;\r\n    --  NB: va changer i1.last_used ou i2.last_used si\r\n    --  i1 ou i2 et i3 sont les memes\r\n\r\n    for j in 0 .. l1 loop\r\n      i1j := Long_Block_type (i1.blk (j));\r\n      sum_carry := 0;\r\n      i := 0;\r\n      k := j;\r\n      loop\r\n        if i <= l2 then\r\n          prod := i1j * Long_Block_type (i2.blk (i));\r\n        else\r\n          exit when sum_carry = 0; -- nothing more to add\r\n          prod := 0;\r\n        end if;\r\n        if copy then\r\n          rk := Long_Block_type (res (k));\r\n        else\r\n          rk := Long_Block_type (i3.blk (k));\r\n        end if;\r\n        sum_carry := rk + prod + sum_carry;\r\n        if copy then\r\n          res (k) := Block_type (sum_carry and maxblock); -- somme\r\n        else\r\n          i3.blk (k) := Block_type (sum_carry and maxblock); -- somme\r\n        end if;\r\n        sum_carry := Shift_Right (sum_carry, Block_type_bits); -- retenue\r\n        i := i + 1;\r\n        k := k + 1;\r\n      end loop;\r\n    end loop;\r\n\r\n    if copy then\r\n      i3.blk (res'Range) := res.all;\r\n      Dispose (res);\r\n    end if;\r\n\r\n    Reduce_last_nonzero (i3);\r\n\r\n    i3.neg := i1.neg /= i2.neg;\r\n\r\n  end Multiply_internal_m_m;\r\n\r\n  procedure Multiply_internal_copy is\r\n    new Multiply_internal_m_m (copy => True);\r\n  procedure Multiply_internal_copy_export (i1, i2 : in Multi_int; i3 : in out Multi_int)\r\n    renames Multiply_internal_copy;\r\n  --  ^ At least GNAT <= GPL 2006 requires the trick with renames...\r\n  --   ObjectAda 7.2.2 too -> there must be a good reason...\r\n\r\n  procedure Multiply_internal_no_copy is\r\n    new Multiply_internal_m_m (copy => False);\r\n\r\n  -------------------\r\n  -- Multi * Basic --\r\n  -- added 2006    --\r\n  -------------------\r\n\r\n  generic\r\n    copy : Boolean;\r\n  procedure Multiply_internal_m_b (i1 : in Multi_int; i2 : Basic_Int; i3 : in out Multi_int);\r\n\r\n  procedure Multiply_internal_m_b (i1 : in Multi_int; i2 : Basic_Int; i3 : in out Multi_int) is\r\n    l1 : constant Index_Int := i1.last_used;\r\n    last_max : constant Index_Int := l1 + 2;\r\n    prod, sum_carry, rk, i2a : Long_Block_type;\r\n    k : Index_Int;\r\n    res : p_Block_array;\r\n    --  res: buffer used in the \"copy\" variant to avoid\r\n    --  problems with Multiply(i,j,i) or Multiply(j,i,i)\r\n  begin\r\n    if i1.zero or i2 = 0 then\r\n      i3.zero := True;\r\n      return;\r\n    end if;\r\n\r\n    if last_max > i3.n then\r\n      raise Result_undersized;\r\n    end if;\r\n\r\n    if copy then\r\n      res := new Block_array (0 .. last_max);\r\n      for k in res'Range loop res (k) := 0; end loop;\r\n      --  Seems slower :-( :  res:= new Block_array'( 0..last_max => 0);\r\n    else\r\n      for k in 0 .. last_max loop i3.blk (k) := 0; end loop;\r\n      --  Slower :-( :  i3.blk(0..last_max):= (others => 0);\r\n    end if;\r\n\r\n    i3.zero := False;\r\n    i3.last_used := last_max;\r\n    --  NB: va changer i1.last_used ou i2.last_used si i1 ou i2 et i3 sont les memes\r\n    i2a := Long_Block_type (abs i2);\r\n\r\n    for j in 0 .. l1 loop\r\n      k := j;\r\n      sum_carry := 0;\r\n      prod := Long_Block_type (i1.blk (j)) * i2a;\r\n      loop\r\n        if copy then\r\n          rk := Long_Block_type (res (k));\r\n        else\r\n          rk := Long_Block_type (i3.blk (k));\r\n        end if;\r\n        sum_carry := rk + prod + sum_carry;\r\n        if copy then\r\n          res (k) := Block_type (sum_carry and maxblock); -- somme\r\n        else\r\n          i3.blk (k) := Block_type (sum_carry and maxblock); -- somme\r\n        end if;\r\n        sum_carry := Shift_Right (sum_carry, Block_type_bits); -- retenue\r\n        exit when sum_carry = 0; -- nothing more to add\r\n        prod := 0;\r\n        k := k + 1;\r\n      end loop;\r\n    end loop;\r\n\r\n    if copy then\r\n      i3.blk (res'Range) := res.all;\r\n      Dispose (res);\r\n    end if;\r\n\r\n    Reduce_last_nonzero (i3);\r\n\r\n    i3.neg := i1.neg /= (i2 < 0);\r\n\r\n  end Multiply_internal_m_b;\r\n\r\n  procedure Multiply_internal_copy is\r\n    new Multiply_internal_m_b (copy => True);\r\n\r\n  procedure Multiply_internal_no_copy is\r\n    new Multiply_internal_m_b (copy => False);\r\n\r\n  procedure Multiply (i1, i2 : in Multi_int; i3 : in out Multi_int) is\r\n    use System;\r\n  begin\r\n    if Debug then\r\n      declare\r\n        m1 : constant Multi_int := i1;\r\n        m2 : constant Multi_int := i2;\r\n      begin\r\n        Multiply_internal_no_copy (m1, m2, i3);\r\n      end;\r\n    else\r\n      if i1'Address = i3'Address or i2'Address = i3'Address then\r\n        --  Ada.Text_IO.Put_Line(\"* with copy\");\r\n        Multiply_internal_copy (i1, i2, i3);\r\n      else\r\n        --  Ada.Text_IO.Put_Line(\"* without copy\");\r\n        Multiply_internal_no_copy (i1, i2, i3);\r\n      end if;\r\n    end if;\r\n  end Multiply;\r\n\r\n  procedure Multiply (i1 : in Multi_int; i2 : Basic_Int; i3 : in out Multi_int) is\r\n    use System;\r\n  begin\r\n    if Debug then\r\n      declare\r\n        m1 : constant Multi_int := i1;\r\n        m2 : constant Basic_Int := i2;\r\n      begin\r\n        Multiply_internal_no_copy (m1, m2, i3);\r\n      end;\r\n    else\r\n      if i1'Address = i3'Address or i2'Address = i3'Address then\r\n        --  Ada.Text_IO.Put_Line(\"* with copy\");\r\n        Multiply_internal_copy (i1, i2, i3);\r\n      else\r\n        --  Ada.Text_IO.Put_Line(\"* without copy\");\r\n        Multiply_internal_no_copy (i1, i2, i3);\r\n      end if;\r\n    end if;\r\n  end Multiply;\r\n\r\n  function \"*\" (i1, i2 : Multi_int) return Multi_int is\r\n  begin\r\n    if i1.zero or i2.zero then\r\n      return zero;\r\n    else\r\n      declare\r\n        prod : Multi_int (i1.last_used + i2.last_used + 2);\r\n      begin\r\n        Multiply (i1, i2, prod);\r\n        return prod;\r\n      end;\r\n    end if;\r\n  end \"*\";\r\n\r\n  function \"*\" (i1 : Multi_int; i2 : Basic_Int) return Multi_int is\r\n  begin\r\n    if i1.zero or i2 = 0 then\r\n      return zero;\r\n    else\r\n      declare\r\n        prod : Multi_int (i1.last_used + 4);\r\n      begin\r\n        Multiply (i1, i2, prod);\r\n        return prod;\r\n      end;\r\n    end if;\r\n  end \"*\";\r\n\r\n  function \"*\" (i1 : Basic_Int; i2 : Multi_int) return Multi_int is\r\n  begin\r\n    if i2.zero or i1 = 0 then\r\n      return zero;\r\n    else\r\n      declare\r\n        prod : Multi_int (i2.last_used + 4);\r\n      begin\r\n        Multiply (i2, i1, prod);\r\n        return prod;\r\n      end;\r\n    end if;\r\n  end \"*\";\r\n\r\n  ----- Begin of DIVISION part -----\r\n\r\n  --  Interne: Division et reste en 1 coup\r\n\r\n  procedure Div_Rem (a, b : Long_Block_type; q, r : out Long_Block_type) is\r\n    Conflict_with_REM : exception;\r\n  begin\r\n    q := a / b;\r\n    r := a - b * q;\r\n    if Debug and then r /= (a rem b) then\r\n      raise Conflict_with_REM;\r\n    end if;\r\n  end Div_Rem;\r\n\r\n  procedure Divide_absolute_normalized (u : in out Multi_int; -- output: u = r\r\n                                         v : in     Multi_int;\r\n                                         q : in out Multi_int) is\r\n    qi : Index_Int := u.last_used - v.last_used - 1; -- was: q.n; D.S. Feb-2002\r\n    v1 : constant Long_Block_type := Long_Block_type (v.blk (v.last_used));\r\n    v2 : constant Long_Block_type := Long_Block_type (v.blk (v.last_used - 1));\r\n\r\n    vlast     : constant Index_Int := v.last_used;\r\n    v1L       : constant Long_Block_type := v1;\r\n    guess,\r\n    comparand : Long_Block_type;\r\n\r\n    function Divide_subtract (ustart : Index_Int) return Block_type is\r\n      ui    : Index_Int;\r\n      carry : Long_Block_type;\r\n    begin\r\n      if guess = 0 then\r\n        return 0;\r\n      end if;\r\n      ui := ustart;\r\n      carry := 0;\r\n\r\n      --  On soustrait (le chiffre du quotient) * diviseur au dividende\r\n\r\n      for vi in 0 .. vlast loop\r\n        declare\r\n          prod : constant Long_Block_type   := Long_Block_type (v.blk (vi)) * guess + carry;\r\n          bpro : constant Block_type := Block_type (prod and maxblock);\r\n          diff : constant Long_Block_type_signed   := Long_Block_type_signed (u.blk (ui)) - Long_Block_type_signed (bpro);\r\n        begin\r\n          if diff < 0 then\r\n            u.blk (ui) := Block_type (diff + cardblock);\r\n            carry := Shift_Right (prod, Block_type_bits) + 1;\r\n          else\r\n            u.blk (ui) := Block_type (diff);\r\n            carry := Shift_Right (prod, Block_type_bits);\r\n          end if;\r\n          ui := ui + 1;\r\n        end;\r\n      end loop;\r\n\r\n      if carry = 0 then\r\n        return Block_type (guess and maxblock);\r\n      end if;\r\n\r\n      declare\r\n        diff : constant Long_Block_type_signed :=\r\n          Long_Block_type_signed (u.blk (ui)) - Long_Block_type_signed (carry and maxblock);\r\n      begin\r\n          if diff < 0 then\r\n            u.blk (ui) := Block_type (diff + cardblock); -- carry generated\r\n          else\r\n            u.blk (ui) := Block_type (diff);\r\n            return Block_type (guess and maxblock);\r\n          end if;\r\n      end;\r\n\r\n      --  Carry was generated\r\n      declare\r\n        icarry : Block_type := 0;\r\n      begin\r\n        ui := ustart;\r\n        for vi in 0 .. vlast loop\r\n          declare\r\n            sum : constant Long_Block_type :=\r\n              Long_Block_type (v.blk (vi)) +\r\n              Long_Block_type (u.blk (ui)) +\r\n              Long_Block_type (icarry);\r\n          begin\r\n            u.blk (ui) := Block_type (sum and maxblock);\r\n            ui := ui + 1;\r\n            icarry := Block_type (Shift_Right (sum, Block_type_bits));\r\n          end;\r\n        end loop;\r\n\r\n        if icarry = 1 then\r\n          u.blk (ui) := Block_type ((Long_Block_type (u.blk (ui)) + 1) and maxblock);\r\n        end if;\r\n      end;\r\n\r\n      return Block_type ((guess - 1) and maxblock);\r\n\r\n    end Divide_subtract;\r\n\r\n    is_q_zero : Boolean := True;\r\n\r\n  begin -- Divide_absolute_normalized\r\n    --  for i in q.blk'Range loop q.blk(i):= 0; end loop;\r\n    --\r\n    --  ^ zeroing useless: q.last_used = u.last_used-v.last_used-1\r\n    --   and q.blk(0..q.last_used) is written below q.blk(qi) := ...\r\n    --   GM 4-nov-2006\r\n\r\n    q.last_used := qi; -- was: q.n; D.S. Feb-2002\r\n\r\n    for j in reverse vlast + 1 .. u.last_used loop\r\n      declare\r\n        uj       : constant Long_Block_type := Long_Block_type (u.blk (j));\r\n        uj1      : constant Long_Block_type := Long_Block_type (u.blk (j - 1));\r\n        uj2      : constant Long_Block_type := Long_Block_type (u.blk (j - 2));\r\n        ujL, rmL : Long_Block_type;\r\n      begin\r\n        ujL := Shift_Left (uj, Block_type_bits) + uj1;\r\n        Div_Rem (ujL, v1L, guess, rmL);\r\n        comparand := Shift_Left (rmL, Block_type_bits) + uj2;\r\n\r\n        while comparand < v2 * guess loop\r\n          guess := guess - 1;\r\n          comparand := comparand + Shift_Left (v1L, Block_type_bits);\r\n          exit when comparand > cardblock * cardblock;\r\n        end loop;\r\n\r\n        q.blk (qi) := Divide_subtract (j - vlast - 1);\r\n\r\n        if q.blk (qi) /= 0 and then is_q_zero then -- n'arrive que 0 ou 1 fois\r\n          is_q_zero := False;\r\n          q.last_used := qi;\r\n        end if;\r\n\r\n        qi := qi - 1;\r\n      end;\r\n\r\n    end loop; -- j\r\n\r\n    q.zero := is_q_zero;\r\n\r\n  end Divide_absolute_normalized;\r\n\r\n  procedure Divide_absolute_big_small (u :   in     Multi_int;\r\n                                        v :   in     Long_Block_type;\r\n                                        q :      out Multi_int;\r\n                                        r :      out Long_Block_type) is\r\n    n : Long_Block_type;\r\n    Quotient_constraint_error : exception;\r\n    last_u_nz :  constant Index_Int := u.last_used;\r\n    u_zero : constant Boolean := u.zero;\r\n    --  in case u and q are the same variables\r\n    is_q_zero : Boolean := True;\r\n  begin\r\n    if q.n < last_u_nz then raise Quotient_constraint_error; end if;\r\n    q.last_used := 0;\r\n    q.neg := False;\r\n    r := 0;\r\n    if not u_zero then\r\n      for i in reverse 0 .. last_u_nz loop\r\n        n := Long_Block_type (u.blk (i)) + Shift_Left (r, Block_type_bits);\r\n        r := n mod v;\r\n        q.blk (i) := Block_type (n  /  v);\r\n        if q.blk (i) /= 0 and then is_q_zero then\r\n          is_q_zero := False;\r\n          q.last_used := i;\r\n        end if;\r\n      end loop;\r\n      q.zero := is_q_zero;\r\n    end if;\r\n  end Divide_absolute_big_small;\r\n\r\n  procedure Solve_signs_for_Div_Rem (i1n, i2n : in Boolean; qn, rn : out Boolean) is\r\n  begin\r\n    --  Invariant: i1= i2*q+r   on cherche (pos) = (pos)*(pos)+(pos)\r\n\r\n    if i1n and i2n then        -- i1<0;  i2<0  (-i1) = (-i2) *  q  + (-r)\r\n      qn := False; -- Quotient > 0\r\n    --      rn:= True;  -- Reste    < 0\r\n    elsif i1n then             -- i1<0;  i2>0  (-i1) =   i2  *(-q) + (-r)\r\n      qn := True;  -- Quotient < 0\r\n    --      rn:= True;  -- Reste    < 0\r\n    elsif i2n then             -- i1>0;  i2<0    i1  = (-i2) *(-q) +   r\r\n      qn := True;  -- Quotient < 0\r\n    --      rn:= False; -- Reste    > 0\r\n    else                       -- i1>0;  i2>0    i1  =   i2  *  q  +   r\r\n      qn := False; -- Quotient > 0\r\n    --      rn:= False; -- Reste    > 0\r\n    end if;\r\n    --  on observe que... \"(A rem B) has the sign of A \" ARM 4.5.5\r\n    --  en effet on peut mettre:\r\n    rn := i1n;\r\n  end Solve_signs_for_Div_Rem;\r\n\r\n  procedure Div_Rem (i1 : in     Multi_int; i2 : in     Basic_Int;\r\n                     q :    out Multi_int;  r :    out Basic_Int) is\r\n    i1_neg : constant Boolean := i1.neg;\r\n    --  in case i1 and q are the same variables\r\n    rneg : Boolean;\r\n    lai2, lr : Long_Block_type;\r\n  begin\r\n    if i2 = 0 then raise Division_by_zero; end if;\r\n\r\n    if i1.zero then -- 15-Feb-2002: 0/i2\r\n      q.zero := True;\r\n      r := 0;\r\n      return;\r\n    end if;\r\n\r\n    lai2 := Long_Block_type (abs i2);\r\n    Divide_absolute_big_small (i1, lai2, q, lr);\r\n    r := Basic_Int (lr);\r\n\r\n    Solve_signs_for_Div_Rem (i1_neg, i2 < 0, q.neg, rneg);\r\n    if rneg then r := -r; end if;\r\n\r\n  end Div_Rem;\r\n\r\n  type Div_Rem_mode is (div_only, both);\r\n\r\n  generic\r\n    div_rem_output : Div_Rem_mode;\r\n  procedure Div_Rem_internal (i1, i2 : in Multi_int; q, r : in out Multi_int);\r\n\r\n  procedure Div_Rem_internal (i1, i2 : in Multi_int; q, r : in out Multi_int) is\r\n\r\n    --  Calculate u/v\r\n\r\n    procedure Divide_absolute (u, v : in     Multi_int;\r\n                                q, r : in out Multi_int) is\r\n      shift : Integer := 0;\r\n      v1 : Block_type := v.blk (v.last_used);\r\n      v_zero, v1_zero : exception;\r\n      u_work : Multi_int (u.last_used + 2);\r\n      use System;\r\n\r\n      procedure Normalization (source : in     Multi_int;\r\n                                target : in out Multi_int) is\r\n        carry : Block_type := 0;\r\n        tl : constant Index_Int := target.last_used;\r\n        blk :  Block_type;\r\n      begin\r\n        for i in 0 .. source.last_used loop\r\n          blk := source.blk (i);\r\n          target.blk (i) := Shift_Left (blk, shift) + carry;\r\n          carry         := Shift_Right (blk, Block_type_bits - shift);\r\n        end loop;\r\n        if source.last_used < tl then\r\n          target.blk (source.last_used + 1) := carry;\r\n        end if;\r\n        for i in source.last_used + 2 .. tl  loop\r\n          target.blk (i) := 0;\r\n        end loop;\r\n      end Normalization;\r\n\r\n      procedure Unnormalization (m : in out Multi_int) is\r\n        carry : Block_type := 0;\r\n        blk :  Block_type;\r\n      begin\r\n        for i in reverse 0 .. m.last_used loop\r\n          blk := m.blk (i);\r\n          m.blk (i) := Shift_Right (blk, shift) + carry;\r\n          carry    := Shift_Left (blk, Block_type_bits - shift);\r\n        end loop;\r\n      end Unnormalization;\r\n\r\n    begin -- Divide_absolute (multi u / multi v)\r\n\r\n      if Debug then\r\n        if v.zero then raise v_zero; end if;\r\n        if v1 = 0 then raise v1_zero; end if;\r\n      end if;\r\n\r\n      --  Calculate shift needed to normalize\r\n      u_work.last_used := u_work.n;\r\n      u_work.zero := False;\r\n      while v1 < 2**(Block_type_bits - 1) loop\r\n        shift := shift + 1;\r\n        v1 := v1 * 2;\r\n      end loop;\r\n      if shift = 0 then                  -- no shift needed\r\n        u_work.blk (0 .. u.last_used) := u.blk (0 .. u.last_used);\r\n        u_work.blk (u.last_used + 1 .. u_work.last_used) := (0, 0);\r\n        --  Now, u is copied, so a Div_Rem(u, v, u, r) won't crash\r\n\r\n        if v'Address = q'Address then\r\n          declare\r\n            v_work : Multi_int (v.last_used);\r\n          begin\r\n            --  23-Feb-2002: also copy v, in case of a Div_Rem(u, v, v, r)\r\n            v_work.blk (0 .. v.last_used) := v.blk (0 .. v.last_used);\r\n            v_work.neg      := v.neg;\r\n            v_work.zero     := v.zero;\r\n            v_work.last_used := v.last_used;\r\n            --  Now, u is copied, so a Div_Rem(u, v, v, r) won't crash\r\n            --  Ada.Text_IO.Put_Line(\"* divisor with copy\");\r\n            Divide_absolute_normalized (u_work, v_work, q);\r\n          end;\r\n        else\r\n          --  Ada.Text_IO.Put_Line(\"* divisor without copy\");\r\n          Divide_absolute_normalized (u_work, v, q);\r\n        end if;\r\n\r\n      else  -- shift needed\r\n        declare\r\n          v_work : Multi_int (v.last_used);\r\n        begin\r\n          v_work.last_used := v_work.n;\r\n          Normalization (u, u_work);\r\n          Normalization (v, v_work);\r\n          Reduce_last_nonzero (v_work);\r\n\r\n          Divide_absolute_normalized (u_work, v_work, q);\r\n        end;\r\n\r\n        if div_rem_output /= div_only then\r\n          Unnormalization (u_work);\r\n        end if;\r\n      end if;\r\n      q.neg := False; -- check friendly\r\n      if div_rem_output /= div_only then\r\n        u_work.neg := False; -- check friendly\r\n        Reduce_last_nonzero (u_work);\r\n        Fill (r, u_work);\r\n      end if;\r\n\r\n    end Divide_absolute;\r\n\r\n    l1 : constant Index_Int := i1.last_used;\r\n    l2 : constant Index_Int := i2.last_used;\r\n    rl : Long_Block_type;\r\n  begin -- Div_Rem_internal\r\n    if i2.zero then raise Division_by_zero; end if;\r\n\r\n    if i1.zero then -- 15-Feb-2002: 0/i2\r\n      q.zero := True;\r\n      r.zero := True;\r\n      return;\r\n    end if;\r\n\r\n    if q.n < l1 - l2 then\r\n      --  17-Feb-2002\r\n      raise Quotient_undersized;\r\n    end if;\r\n\r\n    if div_rem_output /= div_only and then r.n < Max (l1, l2) then\r\n      --  17-Feb-2002\r\n      raise Remainder_undersized;\r\n    end if;\r\n\r\n    if l2 = 0 then\r\n      if l1 = 0 then      -- On a affaire a une ridicule division d'entiers\r\n        q.blk (0) := i1.blk (0) / i2.blk (0);\r\n        if div_rem_output /= div_only then\r\n          r.blk (0) := Block_type (\r\n            abs (\r\n                 Long_Block_type_signed (i1.blk (0))\r\n               - Long_Block_type_signed (i2.blk (0))\r\n               * Long_Block_type_signed (q.blk (0))\r\n            )\r\n          );\r\n        end if;\r\n        q.zero := q.blk (0) = 0;\r\n        q.last_used := 0;\r\n      else                -- multi / entier\r\n        Divide_absolute_big_small (i1, Long_Block_type (i2.blk (0)), q, rl);\r\n        if div_rem_output /= div_only then\r\n          r.blk (0) := Block_type (rl);\r\n        end if;\r\n      end if;\r\n      if div_rem_output /= div_only then\r\n        r.zero := r.blk (0) = 0;\r\n        r.last_used := 0;\r\n      end if;\r\n\r\n    else  -- multi / multi\r\n\r\n      case Compare_absolute (i2, i1) is\r\n\r\n        when greater =>\r\n          q.zero := True;    -- q:=  0;\r\n          q.last_used := 0;\r\n          q.neg := False;\r\n\r\n          if div_rem_output /= div_only then\r\n            Fill (r, i1);  -- r:= i1, q:=0 car i1 = 0 * i2 (>i1 en v.abs) + r\r\n          end if;\r\n          return;\r\n\r\n        when equal =>\r\n          Fill (q, one); -- Fill( q, Multi(1) );\r\n          r.zero := True;  -- Fill( r, Multi(0) );\r\n\r\n        when smaller => -- cas <<normal>>: diviseur < dividende\r\n\r\n          Divide_absolute (i1, i2, q, r);\r\n\r\n      end case;\r\n    end if;\r\n\r\n    Solve_signs_for_Div_Rem (i1.neg, i2.neg, q.neg, r.neg);\r\n  end Div_Rem_internal;\r\n\r\n  procedure Div_Rem_internal_div_only is\r\n    new Div_Rem_internal (div_rem_output => div_only);\r\n\r\n  procedure Div_Rem_internal_both is\r\n    new Div_Rem_internal (div_rem_output => both);\r\n\r\n  procedure Div_Rem_internal_both_export (i1, i2 : in Multi_int; q, r : in out Multi_int)\r\n    renames Div_Rem_internal_both;\r\n\r\n  procedure Div_Rem (i1, i2 : in Multi_int; q, r : out Multi_int) is\r\n  begin\r\n    if Debug then\r\n      declare\r\n        m1 : constant Multi_int := i1;\r\n        m2 : constant Multi_int := i2;\r\n      begin\r\n        Div_Rem_internal_both (m1, m2, q, r);\r\n      end;\r\n    else\r\n      Div_Rem_internal_both (i1, i2, q, r);\r\n    end if;\r\n  end Div_Rem;\r\n\r\n  procedure Divide (i1, i2 : in Multi_int; q : out Multi_int) is\r\n  begin\r\n    if Debug then\r\n      declare\r\n        m1 : constant Multi_int := i1;\r\n        m2 : constant Multi_int := i2;\r\n        r : Multi_int (Max (i1.last_used, i2.last_used) + 2);\r\n      begin\r\n        Div_Rem_internal_both (m1, m2, q, r);\r\n      end;\r\n    else\r\n      declare\r\n        r : Multi_int (0); -- Fake\r\n      begin\r\n        Div_Rem_internal_div_only (i1, i2, q, r);\r\n      end;\r\n    end if;\r\n  end Divide;\r\n\r\n  function \"/\" (i1, i2 : Multi_int) return Multi_int is\r\n    q : Multi_int (Max (0, i1.last_used - i2.last_used + 1));\r\n    r : Multi_int (Max (i1.last_used, i2.last_used) + 2);\r\n  begin\r\n    Div_Rem (i1, i2, q, r);\r\n    return q;\r\n  end \"/\";\r\n\r\n  function \"/\" (i1 : Multi_int; i2 : Basic_Int) return Multi_int is\r\n    q : Multi_int (i1.last_used + 1);\r\n    r : Basic_Int;\r\n  begin\r\n    Div_Rem (i1, i2, q, r);\r\n    return q;\r\n  end \"/\";\r\n\r\n  function \"rem\" (i1, i2 : Multi_int) return Multi_int is\r\n    q : Multi_int (Max (0, i1.last_used - i2.last_used + 1));\r\n    r : Multi_int (Max (i1.last_used, i2.last_used) + 2);\r\n  begin\r\n    Div_Rem (i1, i2, q, r);\r\n    return r;\r\n  end \"rem\";\r\n\r\n  function \"rem\" (i1 : Multi_int; i2 : Basic_Int) return Multi_int is\r\n  begin return i1 rem Multi (i2); end \"rem\";\r\n\r\n  function \"rem\" (i1 : Multi_int; i2 : Basic_Int) return Basic_Int is\r\n    q : Multi_int (i1.last_used + 1);\r\n    r : Basic_Int;\r\n  begin\r\n    Div_Rem (i1, i2, q, r);\r\n    return r;\r\n  end \"rem\";\r\n\r\n  function \"mod\" (i1, i2 : Multi_int) return Multi_int is\r\n    q : Multi_int (Max (0, i1.last_used - i2.last_used + 1));\r\n    r : Multi_int (Max (i1.last_used, i2.last_used) + 2);\r\n  begin\r\n    --  Ada RM, 4.5.5 Multiplying Operators\r\n    --  (8)\r\n    --  The signed integer modulus operator is defined such that\r\n    --  the result of A mod B has the sign of B and an absolute value\r\n    --  less than the absolute value of B; in addition, for some signed\r\n    --  integer value N, this result satisfies the relation:\r\n    --  (9) A = B*N + (A mod B)\r\n\r\n    Div_Rem (i1, i2, q, r);\r\n    if r.zero or else i2.neg = r.neg then  --  (A rem B) est nul ou\r\n      return r;     -- a le meme signe que B, donc (A mod B) = (A rem B)\r\n    else  -- signe opposes\r\n      return i2 + r;  -- alors (B + (A rem B)) est le bon candidat\r\n    end if;\r\n  end \"mod\";\r\n\r\n  function \"mod\" (i1 : Multi_int; i2 : Basic_Int) return Multi_int is\r\n  begin return i1 mod Multi (i2); end \"mod\";\r\n\r\n  function \"mod\" (i1 : Multi_int; i2 : Basic_Int) return Basic_Int is\r\n    r : constant Basic_Int := i1 rem i2;\r\n  begin\r\n    if r = 0 or else (i2 < 0) = (r < 0) then  --  (A rem B) est nul ou\r\n      return r;     -- a le meme signe que B, donc (A mod B) = (A rem B)\r\n    else  -- signe opposes\r\n      return i2 + r;  -- alors (B + (A rem B)) est le bon candidat\r\n    end if;\r\n  end \"mod\";\r\n\r\n----- End of DIVISION part ------\r\n\r\n----- Begin of POWER part -------\r\n\r\n  procedure Power (i : Multi_int; n : Natural; ipn : out Multi_int) is\r\n    max_ipn_last : Index_Int; -- 17-Feb-2002\r\n  begin\r\n    if i.zero then\r\n      if n = 0 then\r\n        raise Zero_power_zero;\r\n      else\r\n        --  The 0**n = 0 case (17-Feb-2002).\r\n        ipn.zero := True; -- 4-Nov-2006, was: Fill( ipn, Multi(0) );\r\n        return;\r\n      end if;\r\n    end if;\r\n\r\n    max_ipn_last := ((1 + i.last_used) * Index_Int (n) - 1) + 2;\r\n    if ipn.n < max_ipn_last then\r\n      raise Result_undersized;\r\n    end if;\r\n\r\n    case n is\r\n      when 0 => Fill (ipn, one); -- the i**0 = 1 case\r\n      when 1 => Fill (ipn, i);    -- the i**1 = i case\r\n      when others =>\r\n        declare\r\n          nn : Natural := n - 1;\r\n          i0, ii : Multi_int (max_ipn_last);\r\n        begin\r\n          Fill (i0, i);\r\n          Fill (ii, i0);\r\n\r\n          while nn > 0 loop\r\n            if nn mod 2 = 0 then -- x^(2 c) = (x^2) ^c\r\n              Mult (i0, i0, i0);\r\n              nn := nn / 2;\r\n            else\r\n              Mult (i0, ii, ii);\r\n              nn := nn - 1;\r\n            end if;\r\n          end loop;\r\n          Fill (ipn, ii);\r\n        end;\r\n    end case;\r\n  end Power;\r\n\r\n  function \"**\" (i : Multi_int; n : Natural) return Multi_int is\r\n    ipn : Multi_int ((1 + i.last_used) * Index_Int (n) + 2);\r\n  begin\r\n    Power (i, n, ipn);\r\n    return ipn;\r\n  end \"**\";\r\n\r\n  procedure Power (i : Multi_int; n : Multi_int; ipn : out Multi_int;\r\n                   modulo : Multi_int) is\r\n    max_ipn_last : Index_Int;\r\n  begin\r\n    if i.zero then\r\n      if n.zero then\r\n        raise Zero_power_zero;\r\n      else\r\n        --  The 0**n = 0 case (17-Feb-2002).\r\n        ipn.zero := True; -- 4-Nov-2006, was: Fill( ipn, Multi(0) );\r\n        return;\r\n      end if;\r\n    end if;\r\n\r\n    if n.neg then\r\n     raise Power_negative;\r\n    end if;\r\n\r\n    if modulo.zero or else (i.neg or modulo.neg) then\r\n      raise Power_modulo_non_positive;\r\n    end if;\r\n\r\n    max_ipn_last := 2 * modulo.last_used + 2;\r\n    if ipn.n < max_ipn_last then\r\n      raise Result_undersized;\r\n    end if;\r\n\r\n    if n.zero then\r\n      Fill (ipn, one); -- the i**0 = 1 case\r\n    elsif Equal (n, one) then\r\n      Fill (ipn, i);    -- the i**1 = i case\r\n    else\r\n      declare\r\n        nn : Multi_int (n.n) := n;\r\n        i0, ii, dummy : Multi_int (max_ipn_last);\r\n        dummy_b : Basic_Int;\r\n      begin\r\n        Subtract (nn, one, nn); -- nn:= nn - 1;\r\n        Fill (i0, i);\r\n        Fill (ii, i0);\r\n\r\n        while nn > 0 loop\r\n          if Even (nn) then                -- x^(2 c) = (x^2) ^c\r\n            Mult (i0, i0, i0);\r\n            Div_Rem (nn, 2, nn, dummy_b);  -- nn:= nn/2\r\n            Div_Rem (i0, modulo, dummy, i0);  -- i0:= i0 mod modulo\r\n          else\r\n            Mult (i0, ii, ii);\r\n            Subtract (nn, one, nn);      -- nn:= nn - 1;\r\n            Div_Rem (ii, modulo, dummy, ii);  -- ii:= ii mod modulo\r\n          end if;\r\n        end loop;\r\n        Fill (ipn, ii);\r\n      end;\r\n    end if;\r\n  end Power;\r\n\r\n----- End of POWER part ---------\r\n\r\n----- Comparisons\r\n\r\n  function Equal (i1, i2 : Multi_int) return Boolean is\r\n  begin\r\n    return\r\n      (i1.zero and then i2.zero)\r\n      or else\r\n        (i1.zero = i2.zero and then\r\n         i1.neg  = i2.neg  and then\r\n         i1.last_used = i2.last_used and then\r\n         i1.blk (0 .. i1.last_used) = i2.blk (0 .. i2.last_used));\r\n  end Equal;\r\n\r\n  function Equal (i1 : Multi_int; i2 : Basic_Int) return Boolean is\r\n  begin\r\n    return Equal (i1, Multi (i2));\r\n  end Equal;\r\n\r\n  function \">\" (i1, i2 : Multi_int) return Boolean is\r\n  begin\r\n    --  (1) Cas \\'evident o\\`u:         i1 <= i2\r\n    if (i1.zero or i1.neg) and then             -- i1 <= 0 et\r\n       (i2.zero or not i2.neg)                  -- i2 >= 0\r\n    then\r\n        return False;\r\n    end if;\r\n\r\n    --  (2.1) Cas \\'evident o\\`u:       i1 > i2\r\n    if ((not i1.zero) and not i1.neg) and then  -- i1 > 0 et\r\n       (i2.zero or i2.neg)                      -- i2 <= 0\r\n    then\r\n        return True;\r\n    end if;\r\n\r\n    --  (2.2) Cas \\'evident o\\`u:       i1 > i2\r\n    if (i1.zero or not i1.neg) and then         -- i1 >= 0 et\r\n       ((not i2.zero) and i2.neg)               -- i2 < 0\r\n    then\r\n        return True;\r\n    end if;\r\n\r\n    --  Cas faciles resolus:\r\n    --  i1 > i2  -  0  +\r\n    -------------------\r\n    --  -       #  F  F\r\n    --  0       T  F  F\r\n    --  +       T  T  #\r\n\r\n    --  On a les cas avec \"#\", o\\`u i1 et i2 ont le meme signe\r\n\r\n    if i1.neg then\r\n      return not (Compare_absolute (i1, i2) = greater);\r\n    else\r\n      return     (Compare_absolute (i1, i2) = greater);\r\n    end if;\r\n\r\n  end \">\";\r\n\r\n  function \">\" (i1 : Multi_int; i2 : Basic_Int) return Boolean is\r\n  begin\r\n    return i1 > Multi (i2);\r\n  end \">\";\r\n\r\n  function \"<\" (i1, i2 : Multi_int) return Boolean is\r\n  begin return i2 > i1; end \"<\";\r\n\r\n  function \"<\" (i1 : Multi_int; i2 : Basic_Int) return Boolean is\r\n  begin\r\n    return i1 < Multi (i2);\r\n  end \"<\";\r\n\r\n  function \">=\" (i1, i2 : Multi_int) return Boolean is\r\n  begin return not (i2 > i1); end \">=\";\r\n\r\n  function \">=\" (i1 : Multi_int; i2 : Basic_Int) return Boolean is\r\n  begin\r\n    return i1 >= Multi (i2);\r\n  end \">=\";\r\n\r\n  function \"<=\" (i1, i2 : Multi_int) return Boolean is\r\n  begin return not (i1 > i2); end \"<=\";\r\n\r\n  function \"<=\" (i1 : Multi_int; i2 : Basic_Int) return Boolean is\r\n  begin\r\n    return i1 <= Multi (i2);\r\n  end \"<=\";\r\n\r\nend HAC_Sys.Multi_Precision_Integers;\r\n"
  },
  {
    "path": "src/compile/hac_sys-multi_precision_integers.ads",
    "content": "------------------------------------------------------------------------------\r\n--  File:            hac_sys-multi_precision_integers.ads\r\n--\r\n--  Description:     Multiple precision integers package, copy\r\n--                     for HAC internals. Stems from Mathpaqs project:\r\n--                       http://mathpaqs.sf.net/\r\n--                       https://github.com/zertovitch/mathpaqs\r\n--                       Alire ( https://alire.ada.dev/ ): alr get mathpaqs\r\n--\r\n--  Date/version:       Aug-2007: - No more generics (Long_Block_type,\r\n--                                  Block_type,... always the largest possible\r\n--                                  idea: J.C.)\r\n--                                - Fixed Basic(...) (based on J.C.'s remarks)\r\n--                      Nov-2006: - unsigned types for blocks\r\n--                                - a block uses 2 bits more\r\n--                                - Ada95+ only\r\n--                      Mar-2002: Bugs fixed related to zero field, division\r\n--                      Nov-1999: - procedures (no stack, less copies !)\r\n--                                - new data structure\r\n--                      Dec-1996: First version (operators only)\r\n--\r\n--  Author:          G. de Montmollin, Univ. Neuchatel\r\n--\r\n--  Thanks to:       Duncan Sands, Univ. Paris-Sud, CNRS\r\n--                   Jeffrey R. Carter\r\n--\r\n--  Tested on:       Intel 586 (32 bit) - Windows 98, NT4+ - GNAT 3.13p+\r\n--                   Intel 586 (32 bit) - Windows 98, NT4+ - ObjectAda 7.2.1+\r\n--                   Alpha-AXP (64 bit) - OpenVMS 7.1      - Compaq Ada\r\n--\r\n--  Division algorithm adaptated from BigInt 1.0 library,\r\n--  by Stephen Adams, that refers to\r\n--  D. E. Knuth, the Art of computer programming\r\n--  volume 2, \"Seminumerical Algorithms\"\r\n--  section 4.3.1, \"Multiple-Precision Arithmetic\"\r\n--\r\n------------------------------------------------------------------------------\r\n\r\nwith HAC_Sys.Defs;\r\n\r\nwith System;\r\n\r\npackage HAC_Sys.Multi_Precision_Integers is\r\n\r\n  -- Integers for array indexing --\r\n\r\n  subtype Index_Int is Integer;\r\n\r\n  -- THE multi-precision integer type --\r\n\r\n  type Multi_Int (n : Index_Int) is private;\r\n\r\n  -- Integer type for small values --\r\n\r\n  subtype Basic_Int is Defs.HAC_Integer; -- the \"normal\" signed integer\r\n\r\n  ----------------------------------------------------------------\r\n  -- Debug mode: checks results of arithmetic operations and    --\r\n  -- Multi_int variables' integrity.                            --\r\n  -- CAUTION: Debug = True reduces monstruously the performance --\r\n  ----------------------------------------------------------------\r\n\r\n  Debug : constant Boolean := False;\r\n\r\n  ---------------------------------------------\r\n  ----- Informations, conversions, filling ----\r\n  ---------------------------------------------\r\n\r\n  --  Convert Basic_int to Multi_int\r\n  function Multi (small : Basic_Int) return Multi_Int;\r\n\r\n  --  Convert Multi_int to Basic_int (when possible, else: Cannot_fit raised)\r\n  function Basic (large : Multi_Int) return Basic_Int;\r\n\r\n  --  Fill an Multi_int of greater array dimension with a smaller one\r\n  procedure Fill (what : out Multi_Int; with_smaller : Multi_Int);\r\n  procedure Fill (what : out Multi_Int; with_basic : Basic_Int);\r\n\r\n  --  Comparisons\r\n  function Equal (i1, i2 : Multi_Int) return Boolean;\r\n  function Equal (i1 : Multi_Int; i2 : Basic_Int) return Boolean;\r\n  function \">\" (i1, i2 : Multi_Int) return Boolean;\r\n  function \">\" (i1 : Multi_Int; i2 : Basic_Int) return Boolean;\r\n  function \"<\" (i1, i2 : Multi_Int) return Boolean;\r\n  function \"<\" (i1 : Multi_Int; i2 : Basic_Int) return Boolean;\r\n  function \">=\" (i1, i2 : Multi_Int) return Boolean;\r\n  function \">=\" (i1 : Multi_Int; i2 : Basic_Int) return Boolean;\r\n  function \"<=\" (i1, i2 : Multi_Int) return Boolean;\r\n  function \"<=\" (i1 : Multi_Int; i2 : Basic_Int) return Boolean;\r\n\r\n  --  Other informations\r\n  function Bits_per_block return Positive;\r\n\r\n  ---------------------------------------------------------------------------\r\n  -------- Arithmetic operators.                                   ----------\r\n  -------- For speed, the \"procedure\" variants should be preferred ----------\r\n  ---------------------------------------------------------------------------\r\n\r\n  ---------------------------\r\n  ----- Unary operators -----\r\n  ---------------------------\r\n\r\n  procedure Opp (i : in out Multi_Int);\r\n  function \"+\" (i : Multi_Int) return Multi_Int;\r\n  function \"-\" (i : Multi_Int) return Multi_Int;\r\n\r\n  procedure Abso (i : in out Multi_Int);\r\n  function \"ABS\" (i : Multi_Int) return Multi_Int;\r\n\r\n  function Sign (i : Multi_Int) return Basic_Int;\r\n  function Even (i : Multi_Int) return Boolean;\r\n  function Odd (i : Multi_Int) return Boolean;\r\n\r\n  ----------------------------\r\n  ----- Binary operators -----\r\n  ----------------------------\r\n\r\n  ---------------------------\r\n  -- Addition, subtraction --\r\n  ---------------------------\r\n\r\n  procedure Add (i1, i2 : in Multi_Int; i3 : in out Multi_Int);\r\n\r\n  function \"+\" (i1, i2 : Multi_Int) return Multi_Int;\r\n  function \"+\" (i1 : Multi_Int; i2 : Basic_Int) return Multi_Int;\r\n  function \"+\" (i1 : Basic_Int; i2 : Multi_Int) return Multi_Int;\r\n\r\n  procedure Sub      (i1, i2 : in Multi_Int; i3 : in out Multi_Int);\r\n  procedure Subtract (i1, i2 : in Multi_Int; i3 : in out Multi_Int)\r\n    renames Sub;\r\n\r\n  function \"-\" (i1, i2 : Multi_Int) return Multi_Int;\r\n  function \"-\" (i1 : Multi_Int; i2 : Basic_Int) return Multi_Int;\r\n  function \"-\" (i1 : Basic_Int; i2 : Multi_Int) return Multi_Int;\r\n\r\n  --------------------\r\n  -- Multiplication --\r\n  --------------------\r\n\r\n  procedure Multiply (i1, i2 : in Multi_Int; i3 : in out Multi_Int);\r\n  procedure Mult     (i1, i2 : in Multi_Int; i3 : in out Multi_Int)\r\n    renames Multiply;\r\n\r\n  procedure Multiply (i1 : in Multi_Int; i2 : Basic_Int; i3 : in out Multi_Int);\r\n  procedure Mult     (i1 : in Multi_Int; i2 : Basic_Int; i3 : in out Multi_Int)\r\n    renames Multiply;\r\n\r\n  function \"*\" (i1, i2 : Multi_Int) return Multi_Int;\r\n  function \"*\" (i1 : Multi_Int; i2 : Basic_Int) return Multi_Int;\r\n  function \"*\" (i1 : Basic_Int; i2 : Multi_Int) return Multi_Int;\r\n\r\n  -------------------------\r\n  -- Division, Remainder --\r\n  -------------------------\r\n\r\n  procedure Div_Rem (i1 : in     Multi_Int; i2 : in     Basic_Int;\r\n                     q  :    out Multi_Int; r :    out Basic_Int);\r\n  procedure Div_Rem (i1, i2 : in Multi_Int;  q, r :   out Multi_Int);\r\n\r\n  procedure Divide (i1, i2 : in Multi_Int; q : out Multi_Int);\r\n\r\n  function \"/\" (i1, i2 : Multi_Int) return Multi_Int;\r\n  function \"/\" (i1 : Multi_Int; i2 : Basic_Int) return Multi_Int;\r\n  function \"Rem\" (i1, i2 : Multi_Int) return Multi_Int;\r\n  function \"Rem\" (i1 : Multi_Int; i2 : Basic_Int) return Multi_Int;\r\n  function \"Rem\" (i1 : Multi_Int; i2 : Basic_Int) return Basic_Int;\r\n  function \"Mod\" (i1, i2 : Multi_Int) return Multi_Int;\r\n  function \"Mod\" (i1 : Multi_Int; i2 : Basic_Int) return Multi_Int;\r\n  function \"Mod\" (i1 : Multi_Int; i2 : Basic_Int) return Basic_Int;\r\n\r\n  -----------\r\n  -- Power --\r\n  -----------\r\n\r\n  procedure Power (i : Multi_Int; n : Natural; ipn : out Multi_Int);\r\n  function \"**\" (i : Multi_Int; n : Natural) return Multi_Int;\r\n  --  + 26-Mar-2002 :\r\n  procedure Power (i : Multi_Int; n : Multi_Int; ipn : out Multi_Int;\r\n                   modulo : Multi_Int);\r\n\r\n  Cannot_fit, Empty_multi_int : exception;\r\n\r\n  Array_too_small : exception;\r\n\r\n  Result_undersized,\r\n  Quotient_undersized,\r\n  Remainder_undersized : exception;\r\n\r\n  Division_by_zero : exception;\r\n\r\n  Zero_power_zero, Power_negative : exception;\r\n  Power_modulo_non_positive : exception;\r\n\r\nprivate\r\n\r\n  --> Long_Block_type is used for + and * of blocks.\r\n  --  It is by design\r\n  --   a/ the largest possible modular integer, and\r\n  --   b/ twice the size of Block_type defined below.\r\n  --  With the double of bits (2n) one can store m**2 + 2m without overflow\r\n  --   where m = 2**n - 1 is the largest value possible on n bits.\r\n  type Long_Block_type is mod System.Max_Binary_Modulus;\r\n\r\n  --> Same size as Long_Block_type, but signed:\r\n  type Long_Block_type_signed is\r\n    range -2**(Long_Block_type'Size - 1) .. 2**(Long_Block_type'Size - 1) - 1;\r\n\r\n  --> Block_type: unsigned integer used to store a chunk of a Multi_int.\r\n  type Block_type is mod 2 ** (Long_Block_type'Size / 2);\r\n\r\n  Block_type_bits : constant := Block_type'Size;\r\n\r\n  cardblock : constant := 2 ** Block_type_bits;\r\n  --  Number of possible values\r\n  maxblock : constant := Block_type'Last;\r\n  --  NB: GNAT (2006) optimizes out correctly the Block_type(l and maxblock_long)\r\n  --     to Block_type(l), the latter form being caught when range checks are on.\r\n\r\n  type Block_array is array (Index_Int range <>) of Block_type;\r\n  --  2006: was \"of Basic_int\" for obscure reasons...\r\n\r\n  type Multi_int (n : Index_Int) is record\r\n    blk :       Block_array (0 .. n); --  the n blocks with ABSOLUTE value\r\n    neg :       Boolean := False;     --  negative flag\r\n    zero :      Boolean := True;      --  zero flag (supercedes the other fields)\r\n    last_used : Index_Int;            --  the others blocks are supposed 0\r\n  end record;\r\n\r\n  --  NB the `zero' field supercedes EVERY other information (last_used, neg)\r\n\r\n  ----------------------------------------------------------------------------\r\n  --   Format of type Multi_int.blk: ( i_0, i_1, ..., i_k, *, ..., * )      --\r\n  --   i_0..i_k are >=0 ; others (*) are treated as 0                       --\r\n  ----------------------------------------------------------------------------\r\n\r\n  --  Some internal procedures use by check:\r\n\r\n  procedure Multiply_internal_copy_export (i1, i2 : in Multi_int; i3 : in out Multi_int);\r\n\r\n  procedure Div_Rem_internal_both_export (i1, i2 : in Multi_int; q, r : in out Multi_int);\r\n\r\nend HAC_Sys.Multi_Precision_Integers;\r\n"
  },
  {
    "path": "src/compile/hac_sys-parser-attributes.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Ranges,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Attributes is\n\n  type Attribute is\n    (First,\n     Image,\n     Last,\n     Length,\n     Pos,\n     Pred,\n     Range_Attr,\n     Succ,\n     Val,\n     Value);\n\n  procedure Which_Attribute (CD : in out Co_Defs.Compiler_Data; attr : out Attribute) is\n    use Co_Defs, Defs, Errors;\n    attr_ID : constant String := A2S (CD.Id);\n  begin\n    attr := (if attr_ID = \"RANGE\" then Range_Attr else Attribute'Value (attr_ID));\n    Scanner.In_Symbol (CD);  --  Consume the attribute name (First, Last, ...)\n  exception\n    when Constraint_Error =>\n      Error (CD, err_general_error, \"unknown attribute: \" & attr_ID, severity => major);\n  end Which_Attribute;\n\n  procedure Array_Subtype_Attribute\n    (CD                : in out Co_Defs.Compiler_Data;\n     Level             : in     Defs.Nesting_Level;\n     FSys              : in     Defs.Symset;\n     Array_Index       : in     Natural;\n     attr              : in     Attribute;\n     xSubtyp_of_Result :    out Co_Defs.Exact_Subtyp)\n  is\n    use Co_Defs, Defs, Helpers, Errors;\n    A : Array_Table_Entry := CD.Arrays_Table (Array_Index);\n    Low, High : Index;\n    N : Constant_Rec;\n    use Compiler.PCode_Emit, Expressions, PCode, Scanner;\n    use type HAC_Integer;\n  begin\n    N.I := 1;\n    if CD.Sy = LParent then\n      In_Symbol (CD);\n      Static_Scalar_Expression (CD, Level, FSys + RParent, N);\n      if N.TP.TYP /= Ints then\n        Error (CD, err_parameter_must_be_Integer, severity => major);\n      end if;\n      Need (CD, RParent, err_closing_parenthesis_missing);\n    end if;\n    if N.I < 1 then\n      Error (CD, err_invalid_dimension_number, \"minimum is 1\", severity => major);\n    end if;\n    --\n    Jump_to_next_Dimension :\n    for Skip_Dim in 2 .. N.I loop\n      if A.Element_xTyp.TYP = Arrays then\n        A := CD.Arrays_Table (A.Element_xTyp.Ref);\n      else\n        Error (CD, err_invalid_dimension_number, \"maximum is\" &\n          HAC_Integer'Image (Skip_Dim - 1), severity => major);\n      end if;\n    end loop Jump_to_next_Dimension;\n    --\n    Low  := Index (A.Index_xTyp.Discrete_First);\n    High := Index (A.Index_xTyp.Discrete_Last);\n    case attr is\n      when First =>       --  RM 3.6.2 (3, 4)\n        Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (Low));\n        xSubtyp_of_Result := A.Index_xTyp;\n      when Last =>        --  RM 3.6.2 (5, 6)\n        Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (High));\n        xSubtyp_of_Result := A.Index_xTyp;\n      when Range_Attr =>  --  RM 3.6.2 (7, 8)\n        Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (Low));\n        Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (High));\n        xSubtyp_of_Result := A.Index_xTyp;\n        xSubtyp_of_Result.Is_Range := True;\n      when Length =>      --  RM 3.6.2 (9, 10)\n        Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (High - Low + 1));\n        Construct_Root (xSubtyp_of_Result, Ints);\n      when others =>\n        Error (CD, err_general_error, \"attribute not defined for this type\", severity => major);\n    end case;\n  end Array_Subtype_Attribute;\n\n  procedure Image_Attribute  --  S'Image (...) or X'Image\n    (CD                : in out Co_Defs.Compiler_Data;\n     S                 : in     Co_Defs.Exact_Subtyp;\n     xSubtyp_of_Result :    out Co_Defs.Exact_Subtyp)\n  is\n    use Co_Defs, Compiler.PCode_Emit, Defs, Errors, PCode;\n  begin\n    --  The value to get an image from is assumed to be on top\n    --  of the stack. The appropriate built-in function will replace\n    --  it by its image as a string (internal type: Strings_as_VStrings).\n    case S.TYP is\n      when NOTYP     => null;  --  Already in error\n      when Ints      => Emit_Std_Funct (CD, SF_Image_Attribute_Ints);\n      when Floats    => Emit_Std_Funct (CD, SF_Image_Attribute_Floats);\n      when Bools     => Emit_Std_Funct (CD, SF_Image_Attribute_Bools);\n      when Chars     => Emit_Std_Funct (CD, SF_Image_Attribute_Chars);\n      when Durations => Emit_Std_Funct (CD, SF_Image_Attribute_Durs);\n      when Enums     =>\n        --  The enumeration items' declarations follow the type name\n        --  For example: `type Enum is (a, b, c)`, we send the index\n        --  of the first item, `a`, in the identifier table.\n        Emit_Std_Funct (CD, SF_Image_Attribute_Enums, Operand_1_Type (S.Ref + 1));\n      when others =>\n        Error (CD, err_attribute_prefix_invalid, \"Image\", severity => major);\n    end case;\n    --  The result subtype is a VString disguised as a String.\n    Construct_Root (xSubtyp_of_Result, Strings_as_VStrings);\n  end Image_Attribute;\n\n  procedure Object_Attribute (\n    CD                : in out Co_Defs.Compiler_Data;\n    Level             : in     Defs.Nesting_Level;\n    FSys              : in     Defs.Symset;\n    Object_xSubtyp    : in     Co_Defs.Exact_Subtyp;\n    LC_before_Object  : in     Integer;\n    xSubtyp_of_Result :    out Co_Defs.Exact_Subtyp\n  )\n  is\n    use Defs, Helpers, Errors;\n    attr : Attribute;\n  begin\n    Which_Attribute (CD, attr);\n    case attr is\n      when Image =>  --  X'Image   (Ada 2022)\n        Image_Attribute (CD, Object_xSubtyp, xSubtyp_of_Result);\n      when others =>\n        if Arrays_Set (Object_xSubtyp.TYP) then\n          --  Forget all the code emitted for selecting the array variable.\n          --  It can be a complex thing like `a (i * 2).loc_x (3)` !\n          CD.LC := LC_before_Object;\n          Array_Subtype_Attribute (CD, Level, FSys + RParent, Object_xSubtyp.Ref, attr, xSubtyp_of_Result);\n        else\n          Error (CD, err_general_error, \"attribute not defined for this object\", severity => major);\n        end if;\n    end case;\n  end Object_Attribute;\n\n  procedure Subtype_Attribute\n    (CD                : in out Co_Defs.Compiler_Data;\n     context           : in     Defs.Flow_Context;\n     FSys              : in     Defs.Symset;\n     Typ_ID_Index      : in     Natural;\n     xSubtyp_of_Result :    out Co_Defs.Exact_Subtyp)\n  is\n    use Co_Defs, Defs, Helpers, Errors;\n    Typ_ID : Identifier_Table_Entry renames CD.id_table (Typ_ID_Index);\n    S : Exact_Subtyp renames Typ_ID.xtyp;\n    attr_ID : constant String := A2S (CD.Id);\n    attr : Attribute;\n    --\n    procedure Scalar_Subtype_Attribute is\n      use Compiler.PCode_Emit, PCode;\n      --\n      procedure First_Last is  --  S'First, S'Last: RM 3.5 (12, 13)\n      begin\n        case S.TYP is\n          when NOTYP =>\n            null;  --  Already in error\n          when Floats =>\n            --  !! To do: floating point strict subtypes\n            if attr = First then\n              Emit (CD, k_Push_Float_First);\n            else\n              Emit (CD, k_Push_Float_Last);\n            end if;\n          when others =>\n            if Discrete_Typ (S.TYP) then\n              Emit_1 (CD, k_Push_Discrete_Literal,\n                (if attr = First then S.Discrete_First else S.Discrete_Last)\n              );\n            else\n              Error (CD, err_attribute_prefix_invalid, attr_ID, severity => major);\n            end if;\n        end case;\n        xSubtyp_of_Result := S;\n        if Discrete_Typ (S.TYP) then\n          Ranges.Set_Singleton_Range\n            (xSubtyp_of_Result, (if attr = First then S.Discrete_First else S.Discrete_Last));\n        end if;\n      end First_Last;\n      --\n      procedure Range_Attribute is  --  S'Range: RM 3.5 (14)\n      begin\n        case S.TYP is\n          when NOTYP =>\n            null;  --  Already in error\n          when Floats =>\n            --  !! To do: floating point strict subtypes\n            Emit_Push_Float_Literal (CD, HAC_Float'First);\n            Emit_Push_Float_Literal (CD, HAC_Float'Last);\n          when others =>\n            if Discrete_Typ (S.TYP) then\n              Emit_1 (CD, k_Push_Discrete_Literal, S.Discrete_First);\n              Emit_1 (CD, k_Push_Discrete_Literal, S.Discrete_Last);\n            else\n              Error (CD, err_attribute_prefix_invalid, attr_ID, severity => major);\n            end if;\n        end case;\n        xSubtyp_of_Result          := S;\n        xSubtyp_of_Result.Is_Range := True;\n      end Range_Attribute;\n      --\n      procedure Pred_Succ_Discrete is\n        use type HAC_Integer;\n      begin\n        Emit_1 (CD, k_Push_Discrete_Literal, 1);\n        if attr = Pred then\n          --  !!  overflow check here if arg = hac_integer'first.\n          Emit (CD, k_SUBTRACT_Integer);\n          Emit_Lower_Bound_Check (CD, S);\n        else\n          --  !!  overflow check here if arg = hac_integer'first.\n          Emit (CD, k_ADD_Integer);\n          Emit_Upper_Bound_Check (CD, S);\n        end if;\n      end Pred_Succ_Discrete;\n      --\n      procedure Pred_Succ is  --  S'Pred (...), S'Succ (...): RM 3.5 (22, 25)\n        s_base : Exact_Typ;\n        type_of_argument : Exact_Subtyp;\n      begin\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Expressions.Expression (CD, context, FSys + RParent, type_of_argument);\n        --  Argument is of the base type (S'Base).\n        s_base := Exact_Typ (S);\n        if s_base = Exact_Typ (type_of_argument) then\n          case S.TYP is\n            when NOTYP =>\n              null;  --  Already in error\n            when Floats =>\n              --  !! To do\n              Error\n                (CD, err_not_yet_implemented, \"attribute \" & attr_ID & \" for this subtype\", severity => major);\n            when others =>\n              if Discrete_Typ (S.TYP) then\n                Pred_Succ_Discrete;\n              else\n                Error (CD, err_attribute_prefix_invalid, attr_ID, severity => major);\n              end if;\n          end case;\n        else\n          Type_Mismatch (CD, err_parameter_types_do_not_match, type_of_argument, s_base);\n        end if;\n        Need (CD, RParent, err_closing_parenthesis_missing);\n        xSubtyp_of_Result := S;\n      end Pred_Succ;\n      --\n      procedure Pos is  --  S'Pos (...): RM 3.5.5 (2)\n        s_base : Exact_Typ;\n        type_of_argument : Exact_Subtyp;\n      begin\n        if Discrete_Typ (S.TYP) then\n          Need (CD, LParent, err_missing_an_opening_parenthesis);\n          Expressions.Expression (CD, context, FSys + RParent, type_of_argument);\n          --  Argument is of the base type (S'Base).\n          s_base := Exact_Typ (S);\n          if s_base = Exact_Typ (type_of_argument) then\n            --  Just set the desired type, and that's it - no VM instruction!\n            xSubtyp_of_Result := Standard_Integer;\n          else\n            Type_Mismatch (CD, err_parameter_types_do_not_match, type_of_argument, s_base);\n          end if;\n          Need (CD, RParent, err_closing_parenthesis_missing);\n        else\n          Error (CD, err_attribute_prefix_must_be_discrete_type, attr_ID, severity => major);\n        end if;\n      end Pos;\n      --\n      procedure Val is  --  S'Val (...): RM 3.5.5 (5)\n        type_of_argument : Exact_Subtyp;\n      begin\n        if Discrete_Typ (S.TYP) then\n          Helpers.Need (CD, LParent, err_missing_an_opening_parenthesis);\n          Expressions.Expression (CD, context, FSys + RParent, type_of_argument);\n          if type_of_argument.TYP = Ints then\n            --  Just set the desired subtype, and that's it - no VM instruction for\n            --  the conversion itself!\n            xSubtyp_of_Result := S;\n            --  ...but we need to add a range check.\n            Emit_Lower_Bound_Check (CD, S);\n            Emit_Upper_Bound_Check (CD, S);\n          else\n            Helpers.Type_Mismatch\n              (CD, err_parameter_types_do_not_match, type_of_argument, Helpers.Standard_Integer);\n          end if;\n          Helpers.Need (CD, RParent, err_closing_parenthesis_missing);\n        else\n          Error (CD, err_attribute_prefix_must_be_discrete_type, attr_ID, severity => major);\n        end if;\n      end Val;\n      --\n      procedure Image is  --  S'Image (...)\n        type_of_argument : Exact_Subtyp;\n        --  Argument of the function is of the base type, that is: S'Base.\n        --  Translation: we forget the subtype constraints here.\n        s_base : constant Exact_Typ := Exact_Typ (S);\n      begin\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Expressions.Expression (CD, context, FSys + RParent, type_of_argument);\n        if s_base = Exact_Typ (type_of_argument) then\n          Image_Attribute (CD, S, xSubtyp_of_Result);\n        else\n          Type_Mismatch (CD, err_parameter_types_do_not_match, type_of_argument, s_base);\n        end if;\n        Need (CD, RParent, err_closing_parenthesis_missing);\n      end Image;\n      --\n      procedure Value is\n        type_of_argument : Exact_Subtyp;\n      begin\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Expressions.Expression (CD, context, FSys + RParent, type_of_argument);\n        --  Argument is of the base type (S'Base).\n        if type_of_argument.TYP = String_Literals then\n          Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n        elsif type_of_argument.TYP = Strings_as_VStrings then\n          null;\n        elsif Is_Char_Array (CD, type_of_argument) then\n          Emit_Std_Funct (CD,\n            SF_String_to_VString,\n            Operand_1_Type (CD.Arrays_Table (type_of_argument.Ref).Array_Size)\n          );\n        else\n        Type_Mismatch\n          (CD,\n           err_parameter_types_do_not_match,\n           Found    => type_of_argument,\n           Expected => Str_Lit_Set or Str_as_VStr_Set or Arrays_Set);\n        end if;\n        case S.TYP is\n          when NOTYP     => null;  --  Already in error\n          when Ints      =>\n            Emit_Std_Funct (CD, SF_Value_Attribute_Ints);\n            Construct_Root (xSubtyp_of_Result, Ints);\n          when Floats    =>\n            Emit_Std_Funct (CD, SF_Value_Attribute_Floats);\n            Construct_Root (xSubtyp_of_Result, Floats);\n          when Bools     =>\n            Emit_Std_Funct (CD, SF_Value_Attribute_Bools);\n            Construct_Root (xSubtyp_of_Result, Bools);\n          when Chars     =>\n            Emit_Std_Funct (CD, SF_Value_Attribute_Chars);\n            Construct_Root (xSubtyp_of_Result, Chars);\n          when Durations =>\n            Emit_Std_Funct (CD, SF_Value_Attribute_Durs);\n            Construct_Root (xSubtyp_of_Result, Durations);\n          when Enums     =>\n            Emit_Std_Funct (CD, SF_Value_Attribute_Enums, Operand_1_Type (S.Ref));\n            xSubtyp_of_Result := S;\n          when others =>\n            Error (CD, err_attribute_prefix_invalid, attr_ID, severity => major);\n        end case;\n        Need (CD, RParent, err_closing_parenthesis_missing);\n      end Value;\n      --\n    begin\n      case attr is\n        when First | Last => First_Last;       --  RM 3.5 (12, 13)\n        when Range_Attr   => Range_Attribute;  --  RM 3.5 (14)\n        when Pred  | Succ => Pred_Succ;\n        when Pos          => Pos;\n        when Val          => Val;\n        when Image        => Image;\n        when Value        => Value;\n        when others =>\n          Error\n            (CD,\n             err_general_error,\n             \"attribute not defined for this type\",\n             severity => major);\n      end case;\n    end Scalar_Subtype_Attribute;\n    --\n  begin\n    pragma Assert (Typ_ID.entity = type_mark);\n    --\n    Which_Attribute (CD, attr);\n    if Scalar_Set (S.TYP) then\n      Scalar_Subtype_Attribute;\n    elsif Arrays_Set (S.TYP) then\n      Array_Subtype_Attribute (CD, context.level, FSys + RParent, S.Ref, attr, xSubtyp_of_Result);\n    else\n      Error\n        (CD, err_general_error,\n         \"no attribute defined for this type: \" &\n         A2S (Typ_ID.name_with_case), severity => major);\n    end if;\n  end Subtype_Attribute;\n\nend HAC_Sys.Parser.Attributes;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-attributes.ads",
    "content": "private package HAC_Sys.Parser.Attributes is\n\n  procedure Object_Attribute (\n    CD                : in out Co_Defs.Compiler_Data;\n    Level             : in     Defs.Nesting_Level;\n    FSys              : in     Defs.Symset;\n    Object_xSubtyp    : in     Co_Defs.Exact_Subtyp;\n    LC_before_Object  : in     Integer;\n    xSubtyp_of_Result :    out Co_Defs.Exact_Subtyp\n  );\n\n  --  Subtype attributes. Ada RM ref: scalar 3.5 (10), arrays 3.6 (2)\n  --\n  --  The subtype name has just been parsed and determined to\n  --  be corresponding to subtype S. The symbol \"'\" has been parsed too.\n  --  In output, the type of the returned value is set in X.\n  --  Example:\n  --    S is Boolean, we have the expression ` Boolean'Image (Flag) `\n  --    From here we parse the attribute (` Image `), then, its\n  --    parameter ` (Flag) `, if any.\n  --    The return type is X = (Strings_as_VStrings, 0), an internal type in this case.\n\n  procedure Subtype_Attribute\n    (CD                : in out Co_Defs.Compiler_Data;\n     context           : in     Defs.Flow_Context;\n     FSys              : in     Defs.Symset;\n     Typ_ID_Index      : in     Natural;\n     xSubtyp_of_Result :    out Co_Defs.Exact_Subtyp);\n\nend HAC_Sys.Parser.Attributes;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-calls.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Calls is\n\n  use Compiler.PCode_Emit, Co_Defs, Defs, Expressions, Helpers, PCode, Scanner, Errors;\n  use type HAC_Integer;\n\n  procedure Push_Parameter_by_Value\n    (CD       : in out Co_Defs.Compiler_Data;\n     context  :        Defs.Flow_Context;\n     fsys     :        Defs.Symset;\n     expected :        Co_Defs.Exact_Subtyp)\n  is\n    X : Exact_Subtyp;\n    expected_array_len : Natural;\n  begin\n    --  Expression does all the job of parsing and, for\n    --  atomic types, emitting the correct \"push\" instructions.\n    Expression (CD, context, fsys + Colon_Comma_RParent, X);\n    --  What is remaining is:\n    --    - checking types\n    --    - for composite types, emit an instruction for pushing\n    --        the contents on the stack.\n    if X.TYP = expected.TYP then\n      if X.Ref /= expected.Ref then\n        Type_Mismatch (CD, err_parameter_types_do_not_match, X, expected);\n      elsif X.TYP = Arrays then\n        Emit_1 (CD, k_Load_Block, Operand_2_Type (CD.Arrays_Table (X.Ref).Array_Size));\n      elsif X.TYP = Records then\n        Emit_1 (CD, k_Load_Block, Operand_2_Type (CD.Blocks_Table (X.Ref).VSize));\n      end if;\n    elsif X.TYP = Ints and expected.TYP = Floats then\n      Forbid_Type_Coercion (CD, X, expected);\n      Emit_1 (CD, k_Integer_to_Float, 0);  --  Left as a \"souvenir\" of SmallAda...\n    elsif X.TYP = String_Literals and then Is_Char_Array (CD, expected) then\n      expected_array_len := CD.Arrays_Table (expected.Ref).Array_Size;\n      if expected_array_len = CD.SLeng then\n        Emit_1 (CD, k_Load_String_Literal, Operand_2_Type (expected_array_len));\n      else\n        Error\n          (CD, err_string_lengths_do_not_match,\n           \"subprogram parameter has length\" & expected_array_len'Image &\n           \", literal has length\" & CD.SLeng'Image,\n           severity => minor);\n      end if;\n    elsif X.TYP /= NOTYP then\n      Type_Mismatch (CD, err_parameter_types_do_not_match, X, expected);\n    end if;\n  end Push_Parameter_by_Value;\n\n  procedure Push_Parameter_by_Reference\n    (CD      : in out Co_Defs.Compiler_Data;\n     context :        Defs.Flow_Context;\n     fsys    :        Defs.Symset;\n     name    :        String;\n     mode    :        Co_Defs.Parameter_Kind;\n     found   :    out Co_Defs.Exact_Subtyp)\n  is\n    K : Integer;\n  begin\n    found := undefined_subtyp;\n    if CD.Sy = IDent then\n      K := Locate_CD_Id (CD, context.level);\n      In_Symbol (CD);\n      if K = No_Id then\n        null;  --  Error already issued due to undefined identifier\n      elsif CD.id_table (K).entity not in Object_Kind then\n        Error (CD, err_variable_missing, name, severity => major);\n      elsif CD.id_table (K).entity = constant_object then\n        Error\n          (CD, err_cannot_modify_constant_or_in_parameter,\n           \": passed to OUT or IN OUT parameter\");\n      else\n        found := CD.id_table (K).xtyp;\n\n        --  Update the reference analysis for the variable.\n        --  The concerned flags (.is_read, .is_written) are\n        --  raised from `no` to `maybe`.\n        --  The usage of the subprogram's parameters is\n        --  checked at the end of the subprogram's compilation\n        --  (see Formal_Parameter_List for startup values).\n        --\n        case mode is\n          when param_in =>\n            Elevate_to_Maybe (CD.id_table (K).is_read);\n          when param_in_out =>\n            Elevate_to_Maybe (CD.id_table (K).is_read);\n            Elevate_to_Maybe (CD.id_table (K).is_written_after_init);\n          when param_out =>\n            Elevate_to_Maybe (CD.id_table (K).is_written_after_init);\n        end case;\n\n        Emit_2\n          (CD,\n           (if CD.id_table (K).normal then\n              k_Push_Address           --  Push \"v'Access\".\n            else\n              k_Push_Discrete_Value),  --  Push \"(a.all)'Access\", that is, a (a is an access type).\n           Operand_1_Type (CD.id_table (K).lev),\n           Operand_2_Type (CD.id_table (K).adr_or_sz));\n\n        if Selector_Symbol_Loose (CD.Sy) then  --  '.' or '(' or (wrongly) '['\n          Selector (CD, context, fsys + Colon_Comma_RParent, found);\n        end if;\n      end if;\n    else\n      Error (CD, err_variable_missing, name, severity => major);\n    end if;\n  end Push_Parameter_by_Reference;\n\n  ------------------------------------------------------------------\n  -----------------------------------------Subprogram_or_Entry_Call-\n  procedure Subprogram_or_Entry_Call\n    (CD          : in out Co_Defs.Compiler_Data;\n     context     :        Defs.Flow_Context;\n     fsys        :        Defs.Symset;\n     ident_index :        Integer;\n     call_type   :        PCode.Operand_1_Type)\n  is\n    --****************************************************************\n    --  Generate ObjCode for subprogram or Task Entry Call\n    --  CallType specifies type of Call\n    --    = 0 then standard subprogram Call,       CallSTDP\n    --    = 1 then standard Task Entry Call,       CallSTDE\n    --    = 2 then timed Task Entry Call,          CallTMDE\n    --    = 3 then conditional Task Entry Call,    CallCNDE\n    --****************************************************************\n    last_param, current_param : Index;\n    found, expected : Exact_Subtyp;\n    block_idx : Index;\n  begin\n    Emit_1 (CD, k_Mark_Stack, Operand_2_Type (ident_index));\n    block_idx := CD.id_table (ident_index).block_or_pkg_ref;\n    current_param := CD.Blocks_Table (block_idx).First_Param_Id_Idx - 1;\n    last_param    := CD.Blocks_Table (block_idx).Last_Param_Id_Idx;\n    if CD.Sy = LParent then  --  Actual parameter list\n      loop\n        In_Symbol (CD);\n        if current_param >= last_param then\n          Error\n            (CD,\n             err_number_of_parameters_do_not_match,\n             \": too many actual parameters\",\n             severity => major);\n        else\n          current_param := current_param + 1;\n          expected := CD.id_table (current_param).xtyp;\n          if CD.id_table (current_param).normal then\n            ------------------------------------------------------\n            --  Value parameter                                 --\n            --  Only IN mode; value is passed by value (copy).  --\n            ------------------------------------------------------\n            Push_Parameter_by_Value (CD, context, fsys, expected);\n          else\n            ------------------------------------\n            --  Variable (Name) parameter     --\n            --  This is passed by reference.  --\n            ------------------------------------\n            Push_Parameter_by_Reference\n              (CD,\n               context,\n               fsys,\n               A2S (CD.id_table (current_param).name_with_case),\n               CD.id_table (current_param).decl_kind,\n               found);\n\n            if Exact_Typ (found) /= Exact_Typ (expected) then\n              Type_Mismatch (CD, err_parameter_types_do_not_match, found, expected);\n            end if;\n          end if;\n          if CD.Sy = Finger then\n            Error\n              (CD,\n               err_not_yet_implemented,\n               \"positional association\",\n               severity => major);\n          end if;\n        end if;\n        Test (CD, Comma_RParent, fsys, err_incorrectly_used_symbol);\n        exit when CD.Sy /= Comma;\n      end loop;\n      Need (CD, RParent, err_closing_parenthesis_missing);\n    end if;\n    if current_param < last_param then\n      Error\n        (CD,\n         err_number_of_parameters_do_not_match,\n         \": too few actual parameters\",\n         severity => major);\n    end if;\n    --\n    Emit_2 (CD, k_Call, call_type, Operand_2_Type (CD.Blocks_Table (CD.id_table (ident_index).block_or_pkg_ref).PSize - 1));\n    if call_type /= Normal_Procedure_Call then  --  Some for of entry call\n      Emit_1 (CD, k_Return_Call, Operand_2_Type (call_type));  --  Return from Entry Call\n    end if;\n    --\n    if CD.id_table (ident_index).lev < context.level then\n      Emit_2\n        (CD,\n         k_Update_Display_Vector,\n         Operand_1_Type (CD.id_table (ident_index).lev),\n         Operand_2_Type (context.level));\n    end if;\n  end Subprogram_or_Entry_Call;\n\n  ------------------------------------------------------------------\n  -------------------------------------------------------Entry_Call-\n  procedure Entry_Call\n    (CD        : in out Co_Defs.Compiler_Data;\n     context   :        Defs.Flow_Context;\n     fsys      :        Defs.Symset;\n     i         :        Integer;\n     call_type :        PCode.Operand_1_Type)\n  is\n    --  Hathorn\n    Addr, J : Integer;\n    use type Alfa;\n  begin\n    if CD.Sy = Period then\n      In_Symbol (CD);                  --  Task Entry Selector\n      if CD.Sy = IDent then\n        J := CD.Blocks_Table (CD.id_table (i).block_or_pkg_ref).Last_Id_Idx;\n        CD.id_table (0).name := CD.Id;\n        while CD.id_table (J).name /= CD.Id loop\n          J := CD.id_table (J).link;\n        end loop;\n        --\n        if J = 0 then\n          Error (CD, err_undefined_identifier, A2S (CD.Id_with_case));\n        end if;\n        --\n        Addr := J;\n        In_Symbol (CD);\n        Subprogram_or_Entry_Call (CD, context, fsys, Addr, call_type);\n      else\n        Error_then_Skip (CD, Semicolon, err_identifier_missing);\n      end if;\n    else\n      Error_then_Skip (CD, Semicolon, err_incorrectly_used_symbol);\n    end if;\n  end Entry_Call;\n\nend HAC_Sys.Parser.Calls;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-calls.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.PCode;\n\nprivate package HAC_Sys.Parser.Calls is\n\n  procedure Push_Parameter_by_Value\n    (CD       : in out Co_Defs.Compiler_Data;\n     context  :        Defs.Flow_Context;\n     fsys     :        Defs.Symset;\n     expected :        Co_Defs.Exact_Subtyp);\n\n  procedure Push_Parameter_by_Reference\n    (CD      : in out Co_Defs.Compiler_Data;\n     context :        Defs.Flow_Context;\n     fsys    :        Defs.Symset;\n     name    :        String;\n     mode    :        Co_Defs.Parameter_Kind;\n     found   :    out Co_Defs.Exact_Subtyp);\n\n  procedure Entry_Call\n    (CD        : in out Co_Defs.Compiler_Data;\n     context   :        Defs.Flow_Context;\n     fsys      :        Defs.Symset;\n     i         :        Integer;\n     call_type :        PCode.Operand_1_Type);\n\n  procedure Subprogram_or_Entry_Call\n    (CD          : in out Co_Defs.Compiler_Data;\n     context     :        Defs.Flow_Context;\n     fsys        :        Defs.Symset;\n     ident_index :        Integer;\n     call_type   :        PCode.Operand_1_Type);\n\nend HAC_Sys.Parser.Calls;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-const_var.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Co_Defs,\n     HAC_Sys.Defs,\n     HAC_Sys.Parser.Enter_Def,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Statements,\n     HAC_Sys.Parser.Type_Def,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Const_Var is\n\n  procedure Var_Declaration\n    (CD         : in out Co_Defs.Compiler_Data;\n     FSys       :        Defs.Symset;\n     Block_Data : in out Block_Data_Type)\n  is\n    use Compiler.PCode_Emit, Co_Defs, Defs, Enter_Def, Helpers, PCode, Errors;\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n\n    --  This procedure processes both Variable and Constant declarations.\n    procedure Possibly_Initialized_Constant_or_Variable\n      (explicity         : Boolean;\n       id_first, id_last : Integer;\n       var_typ           : Exact_Subtyp)\n    is\n      LC0 : Integer :=  CD.LC;\n      LC1 : Integer;\n    begin\n      --  Create constant or variable initialization ObjCode\n      --  The new variables Id's are in the range id_first .. id_last.\n      if explicity then\n        --  We do an assignment to the last one.\n        --  Example:\n        --     for:            \"a, b, c : Real := F (x);\"\n        --     we do first:    \"c := F (x)\".\n        Statements.Assignment (CD, FSys, Block_Data.context, id_last, check_is_variable => False);\n        CD.id_table (id_last).is_initialized := explicit;\n        --  Id_Last has been assigned.\n        --  Now, we emit the code for copying the value\n        --  of id_last to id_first .. id_last - 1.\n        --  In the above example:  \"a := c\"  and  \"b := c\".\n        for var of CD.id_table (id_first .. id_last - 1) loop\n          --  Push destination address:\n          Emit_2 (CD, k_Push_Address, var.lev, Operand_2_Type (var.adr_or_sz));\n          if var_typ.TYP in Composite_Typ then\n            --  Push source address:\n            Emit_2 (CD, k_Push_Address, CD.id_table (id_last).lev,\n              Operand_2_Type (CD.id_table (id_last).adr_or_sz)\n            );\n            case Composite_Typ (var_typ.TYP) is\n              when Arrays =>\n                Emit_1 (CD, k_Copy_Block,\n                  Operand_2_Type (CD.Arrays_Table (var_typ.Ref).Array_Size)\n                );\n              when Records =>\n                Emit_1 (CD, k_Copy_Block,\n                  Operand_2_Type (CD.Blocks_Table (var_typ.Ref).VSize)\n                );\n            end case;\n          else\n            --  Non-composite type. We copy the value.\n            Emit_2 (CD, k_Push_Value,\n              CD.id_table (id_last).lev,\n              Operand_2_Type (CD.id_table (id_last).adr_or_sz)\n            );\n            Emit_1 (CD, k_Store, Typen'Pos (var_typ.TYP));\n          end if;\n          var.is_initialized := explicit;\n        end loop;\n      else\n        --  Implicit initialization (for instance, VString's and File_Type's).\n        for var of CD.id_table (id_first .. id_last) loop\n          if Auto_Init_Typ (var.xtyp.TYP) then\n            Emit_2 (CD, k_Push_Address, var.lev, Operand_2_Type (var.adr_or_sz));\n            Emit_1 (CD, k_Variable_Initialization, Typen'Pos (var.xtyp.TYP));\n            var.is_initialized := implicit;\n          end if;\n          --  !!  TBD: Must handle composite types (arrays or records) containing\n          --           initialized types, too... Bug #2\n        end loop;\n      end if;\n      --\n      LC1 := CD.LC;\n      --  Reset ObjCode pointer as if ObjCode had not been generated\n      CD.LC := LC0;\n      --  Copy ObjCode to end of ObjCode table in reverse order.\n      --\n      --  This buffering is needed for having the initialization code placed\n      --  right after the \"BEGIN\" of current block (see Statements_Part_Setup).\n      --  Nested subprograms have their own code and their possible own\n      --  initialization code coming before in the object code table.\n      Block_Data.initialization_object_code_size := Block_Data.initialization_object_code_size + (LC1 - LC0);  --  Size of initialization ObjCode\n      if LC0 + Block_Data.initialization_object_code_size >= CD.CMax - Block_Data.initialization_object_code_size then\n        Fatal (Object_Code);  --  Collision during the copy (loop below). Garbage guaranteed.\n      end if;\n      while LC0 < LC1 loop\n        CD.ObjCode (CD.CMax) := CD.ObjCode (LC0);\n        CD.CMax              := CD.CMax - 1;\n        LC0                  := LC0 + 1;\n      end loop;\n    end Possibly_Initialized_Constant_or_Variable;\n    --\n    procedure Single_Var_Declaration is\n      T0, T1, Sz, T0i                            : Integer;\n      xTyp                                       : Exact_Subtyp;\n      is_constant, is_typed, is_untyped_constant : Boolean;\n      C                                          : Constant_Rec;\n      Dummy_First, Dummy_Last                    : HAC_Integer;\n    begin\n      C.TP.TYP := NOTYP;\n      T0 := CD.Id_Count;\n      Enter_Variables (CD, Block_Data.context.level, True);\n      if CD.Sy = Becomes then\n        Error (CD, err_assignment_not_allowed_declarative, severity => major);\n      else\n        Need (CD, Colon, err_colon_missing);  --  ':'   in   \"x, y : Integer;\"\n      end if;\n      T1 := CD.Id_Count;\n      --\n      Test\n        (CD,\n         Type_Begin_Symbol + Subtype_Begin_Symbol + CONSTANT_Symbol,\n         Semicolon_Set,\n         err_incorrectly_used_symbol);\n      --\n      is_constant := False;\n      if CD.Sy = CONSTANT_Symbol then  --  Consume \"constant\" in \"x : constant ...;\"\n        is_constant := True;\n        In_Symbol;\n      end if;\n      --\n      is_typed := False;\n      if Type_Begin_Symbol (CD.Sy) or CD.Sy = IDent then\n        --  Here, a type name or an anonymous type definition (array or access)\n        --  See Object Declaration.\n        is_typed := True;\n        case CD.Sy is\n          when IDent =>\n            Type_Def.Subtype_Indication\n              (CD, Block_Data.context.level, Becomes_Comma_IDent_Semicolon + FSys, xTyp, Sz);\n          when ARRAY_Symbol =>\n            --  Anonymous array type in \"v : array (1 .. 5) of Integer;\"\n            Type_Def.Type_Definition\n              (CD, Block_Data.context.level, Becomes_Comma_IDent_Semicolon + FSys, xTyp, Sz);\n          when ACCESS_Symbol =>\n            Error (CD, err_not_yet_implemented, \"access types\", severity => major);\n          when others =>\n            Error\n              (CD,\n               err_general_error,\n               \"this kind of anonymous type definition is not allowed here\");\n            --  Recovery:\n            Type_Def.Type_Definition\n              (CD, Block_Data.context.level, Becomes_Comma_IDent_Semicolon + FSys, xTyp, Sz);\n        end case;\n      end if;\n      Test (CD, Becomes_EQL_Semicolon, empty_symset, err_incorrectly_used_symbol);\n      --\n      if CD.Sy = EQL then\n        --  Common mistake by BASIC or C programmers.\n        Error (CD, err_EQUALS_instead_of_BECOMES);\n        CD.Sy := Becomes;\n      end if;\n      --\n      is_untyped_constant := is_constant and not is_typed;\n      --\n      if is_untyped_constant then\n        --  Numeric constant: we parse the number here (\"k : constant := 123.0\").\n        if CD.Sy = Becomes then\n          In_Symbol;\n          Expressions.Static_Scalar_Expression (CD, Block_Data.context.level, Comma_IDent_Semicolon + FSys, C);\n        else\n          Error (CD, err_BECOMES_missing);\n        end if;\n      end if;\n      --\n      T0i := T0;\n      if is_constant or is_typed then\n        --  This path covers all correct cases, since untyped\n        --  variable errors (\"a : := 5;\", \"a : ;\", \"a;\") were\n        --  caught earlier.\n        --\n        --  Update identifier table for all entered names:\n        while T0 < T1 loop\n          T0 := T0 + 1;\n          declare\n            r : Identifier_Table_Entry renames CD.id_table (T0);\n          begin\n            r.entity                := (if is_constant then constant_object else variable_object);\n            r.is_referenced         := False;\n            r.is_read               := no;\n            r.is_written_after_init := no;\n            r.is_initialized        := (if is_untyped_constant then explicit else none);\n                                       --  ^ This value may be changed below.\n            if is_untyped_constant then\n              r.entity := declared_number_or_enum_item;  --  r was initially a Variable.\n              r.xtyp := C.TP;\n              case C.TP.TYP is\n                when Floats =>\n                  Enter_or_find_Float (CD, C.R, Integer (r.adr_or_sz));\n                when Ints =>\n                  r.adr_or_sz := C.I;\n                when others =>\n                  Error (CD, err_numeric_constant_expected);\n                  --  \"boo : constant := True;\" or \"x: constant := 'a';\" are wrong in Ada.\n                  r.adr_or_sz := C.I;\n              end case;\n            else  --  A variable or a typed constant\n              r.xtyp      := xTyp;\n              r.adr_or_sz := HAC_Integer (Block_Data.data_allocation_index);\n              Block_Data.data_allocation_index := Block_Data.data_allocation_index + Sz;\n            end if;\n          end;\n        end loop;  --  While T0 < T1\n      end if;\n      --\n      if CD.Sy = EQL and not is_untyped_constant then\n        Error (CD, err_EQUALS_instead_of_BECOMES);\n        CD.Sy := Becomes;\n      end if;\n      if is_constant and is_typed then\n        --  For typed constants, the \":=\" is required and consumed with the Assignment below.\n        Test (CD, Becomes_Set, empty_symset, err_BECOMES_missing);\n      end if;\n      --\n      if not is_untyped_constant then\n        Possibly_Initialized_Constant_or_Variable\n          (explicity => CD.Sy = Becomes,\n           id_first  => T0i + 1,\n           id_last   => T1,\n           var_typ   => xTyp);\n      end if;\n      Need_Semicolon_after_Declaration (CD, FSys);\n    end Single_Var_Declaration;\n  begin\n    while CD.Sy = IDent loop\n      Single_Var_Declaration;\n    end loop;\n  end Var_Declaration;\n\nend HAC_Sys.Parser.Const_Var;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-const_var.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  Package around constants and variables declarations.\n\nprivate package HAC_Sys.Parser.Const_Var is\n\n  procedure Var_Declaration\n    (CD         : in out Co_Defs.Compiler_Data;\n     FSys       :        Defs.Symset;\n     Block_Data : in out Block_Data_Type);\n\nend HAC_Sys.Parser.Const_Var;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-enter_def.adb",
    "content": "with HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\nwith HAT;\n\npackage body HAC_Sys.Parser.Enter_Def is\n\n  use Co_Defs, Defs, Errors;\n  use type HAC_Integer;\n\n  ------------------------------------------------------------------\n  ------------------------------------------------------Enter_Block-\n  procedure Enter_Block\n    (CD    : in out Co_Defs.Compiler_Data;\n     Tptr  :        Integer)\n  is\n  begin\n    if CD.Blocks_Count = BMax then\n      Fatal (PROCEDURES);  --  Exception is raised there.\n    end if;\n    CD.Blocks_Count := CD.Blocks_Count + 1;\n    declare\n      New_B : Block_Table_Entry renames CD.Blocks_Table (CD.Blocks_Count);\n    begin\n      New_B.Id                 := CD.id_table (Tptr).name;\n      New_B.Last_Id_Idx        := 0;\n      New_B.First_Param_Id_Idx := 0;\n      New_B.Last_Param_Id_Idx  := 0;\n      New_B.SrcFrom            := CD.CUD.location.line;\n    end;\n  end Enter_Block;\n\n  ------------------------------------------------------------------\n  ------------------------------------------------------------Enter-\n  procedure Enter_Simple\n    (CD               : in out Co_Defs.Compiler_Data;\n     Level            :        Defs.Nesting_Level;\n     Id, Id_with_case :        Defs.Alfa;\n     K                :        Co_Defs.Entity_Kind;\n     Forward_Decl_Id  :    out Natural)\n  is\n    last_id : constant Index :=\n      CD.Blocks_Table (CD.Display (Level)).Last_Id_Idx;\n    J : Integer := last_id;\n    use HAT;\n  begin\n    Forward_Decl_Id := No_Id;\n    if CD.Id_Count = Id_Table_Max then\n      Fatal (IDENTIFIERS);  --  Exception is raised there.\n    end if;\n    CD.id_table (No_Id).name := Id;  --  Sentinel\n    --  Follow the chain of identifiers for current Level:\n    while CD.id_table (J).name /= Id loop\n      J := CD.id_table (J).link;\n    end loop;\n    if J = No_Id then\n      --  All good: the identifier is new at this nesting level,\n      --  and we don't care about lower levels: name hiding is allowed.\n      null;\n    elsif\n       ((K = prozedure or K = funktion)\n        and then K = CD.id_table (J).entity\n        and then CD.id_table (J).decl_kind = spec_unresolved)\n      or else\n       (K = paquetage_body and then CD.id_table (J).entity = paquetage)\n    then\n      --  No duplicate name in those cases: J is a specification,\n      --  new declaration is the corresponding body.\n      Forward_Decl_Id := J;\n    else\n      Error\n        (CD,\n         err_duplicate_identifier,\n         A2S (Id)\n         --  & \", previous is a \" & CD.IdTab (J).entity'Image\n         ,\n         severity => major);\n    end if;\n    --  Enter identifier in table IdTab\n    CD.Id_Count            := CD.Id_Count + 1;\n    CD.id_table (CD.Id_Count) :=\n      (name                  => Id,\n       name_with_case        => Id_with_case,\n       link                  => last_id,\n       entity                => K,\n       decl_kind             => complete,\n       xtyp                  => undefined_subtyp,\n       block_or_pkg_ref      => 0,\n       normal                => True,\n       lev                   => Level,\n       adr_or_sz             => 0,\n       is_referenced         => False,\n       is_read               => no,\n       is_written_after_init => no,\n       is_initialized        => none,\n       location              => CD.CUD.location);\n    --\n    CD.target.Mark_Declaration;\n    --  Update start of identifier chain:\n    CD.Blocks_Table (CD.Display (Level)).Last_Id_Idx := CD.Id_Count;\n    if Level = 0 then\n      CD.CUD.level_0_def.Include (Id, CD.Id_Count);\n    end if;\n  end Enter_Simple;\n\n  procedure Enter_Prefixed\n    (CD               : in out Co_Defs.Compiler_Data;\n     Level            :        Defs.Nesting_Level;\n     Id, Id_with_case :        Defs.Alfa;\n     K                :        Co_Defs.Entity_Kind;\n     Forward_Decl_Id  :    out Natural)\n  is\n    use HAT;\n    prefixed_Id           : constant Alfa := CD.pkg_prefix & Id;\n    prefixed_Id_with_case : constant Alfa := CD.pkg_prefix & Id_with_case;\n  begin\n    Enter_Simple (CD, Level, prefixed_Id, prefixed_Id_with_case, K, Forward_Decl_Id);\n  end Enter_Prefixed;\n\n  procedure Enter\n    (CD               : in out Co_Defs.Compiler_Data;\n     Level            :        Defs.Nesting_Level;\n     prefixed         :        Boolean;\n     Id, Id_with_case :        Defs.Alfa;\n     K                :        Co_Defs.Entity_Kind;\n     Forward_Decl_Id  :    out Natural)\n  is\n  begin\n    if prefixed then\n      Enter_Prefixed (CD, Level, Id, Id_with_case, K, Forward_Decl_Id);\n    else\n      Enter_Simple (CD, Level, Id, Id_with_case, K, Forward_Decl_Id);\n    end if;\n  end Enter;\n\n  ------------------------------------------------------------------\n  -------------------------------------------------------EnterArray-\n\n  procedure Enter_Array\n    (CD        : in out Co_Defs.Compiler_Data;\n     Index_STP :        Co_Defs.Exact_Subtyp)\n  is\n  begin\n    if Index_STP.Discrete_First > Index_STP.Discrete_Last then\n      Error\n        (CD,\n         err_illegal_array_bounds,\n         \"Low > High. NB: legal in Ada (empty array)\", -- !!\n         severity => major);\n    end if;\n    if Index_STP.Discrete_First < -HAC_Integer (XMax) or else\n       Index_STP.Discrete_Last  >  HAC_Integer (XMax)\n    then\n      Error\n        (CD,\n         err_illegal_array_bounds,\n         \"absolute value of a bound exceeds maximum possible value\",\n         severity => major);\n    end if;\n    if CD.Arrays_Count = AMax then\n      Fatal (ARRAYS);  --  Exception is raised there.\n    end if;\n    CD.Arrays_Count := CD.Arrays_Count + 1;\n    CD.Arrays_Table (CD.Arrays_Count).Index_xTyp := Index_STP;\n  end Enter_Array;\n\n  ------------------------------------------------------------------\n  --------------------------------------------------Enter_Variables-\n\n  procedure Enter_Variables\n    (CD       : in out Co_Defs.Compiler_Data;\n     Level    :        Defs.Nesting_Level;\n     prefixed :        Boolean)\n  is\n    procedure Enter_Variable is\n      dummy_id_idx : Natural;\n    begin\n      if CD.Sy = IDent then\n        Enter (CD, Level, prefixed, CD.Id, CD.Id_with_case, variable_object, dummy_id_idx);\n        Scanner.In_Symbol (CD);\n      else\n        Error (CD, err_identifier_missing);\n      end if;\n    end Enter_Variable;\n    --\n  begin\n    Enter_Variable;\n    while CD.Sy = Comma loop  --  ','  in  \"a, b, c : Integer;\"\n      Scanner.In_Symbol (CD);\n      Enter_Variable;\n    end loop;\n  end Enter_Variables;\n\nend HAC_Sys.Parser.Enter_Def;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-enter_def.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  Package around entering definitions, from the parser or \"by hand\",\n--  for built-in packages.\n\npackage HAC_Sys.Parser.Enter_Def is\n\n  procedure Enter_Block\n    (CD    : in out Co_Defs.Compiler_Data;\n     Tptr  :        Integer);\n\n  procedure Enter_Simple\n    (CD               : in out Co_Defs.Compiler_Data;\n     Level            :        Defs.Nesting_Level;\n     Id, Id_with_case :        Defs.Alfa;\n     K                :        Co_Defs.Entity_Kind;\n     Forward_Decl_Id  :    out Natural);\n\n  --  Enter a definition with package prefix.\n  procedure Enter_Prefixed\n    (CD               : in out Co_Defs.Compiler_Data;\n     Level            :        Defs.Nesting_Level;\n     Id, Id_with_case :        Defs.Alfa;\n     K                :        Co_Defs.Entity_Kind;\n     Forward_Decl_Id  :    out Natural);\n\n  procedure Enter\n    (CD               : in out Co_Defs.Compiler_Data;\n     Level            :        Defs.Nesting_Level;\n     prefixed         :        Boolean;\n     Id, Id_with_case :        Defs.Alfa;\n     K                :        Co_Defs.Entity_Kind;\n     Forward_Decl_Id  :    out Natural);\n\n  procedure Enter_Array\n    (CD        : in out Co_Defs.Compiler_Data;\n     Index_STP :        Co_Defs.Exact_Subtyp);\n\n  procedure Enter_Variables\n    (CD       : in out Co_Defs.Compiler_Data;\n     Level    :        Defs.Nesting_Level;\n     prefixed :        Boolean);\n     --  For instance, fields in a record must be non-prefixed.\n\nend HAC_Sys.Parser.Enter_Def;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-expressions.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit;\nwith HAC_Sys.Parser.Attributes;\nwith HAC_Sys.Parser.Calls;\nwith HAC_Sys.Parser.Helpers;\nwith HAC_Sys.Parser.Ranges;\nwith HAC_Sys.Parser.Standard_Functions;\nwith HAC_Sys.Parser.Type_Conversion;\nwith HAC_Sys.PCode;\nwith HAC_Sys.Scanner;\nwith HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Expressions is\n\n  use Compiler.PCode_Emit, Co_Defs, Defs, Helpers, PCode, Scanner, Errors;\n\n  procedure Static_Scalar_Expression\n    (CD      : in out Co_Defs.Compiler_Data;\n     Level   : in     Defs.Nesting_Level;\n     FSys_ND : in     Defs.Symset;\n     C       :    out Co_Defs.Constant_Rec)\n  is\n    --  This covers number declarations (RM 3.3.2) and enumeration items (RM 3.5.1).\n    --  Additionally this compiler does on-the-fly declarations for static values:\n    --  bounds in ranges (FOR, ARRAY), and values in CASE statements.\n    --  Was: Constant in the Pascal compiler.\n    X : Integer;\n    Sign : HAC_Integer;\n    use type HAC_Float, HAC_Integer;\n    signed : Boolean := False;\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n  begin\n    C.TP := undefined_subtyp;\n    C.I  := 0;\n    Test (CD, Constant_Definition_Begin_Symbol, FSys_ND, err_illegal_symbol_for_a_number_declaration);\n    if not Constant_Definition_Begin_Symbol (CD.Sy) then\n      return;\n    end if;\n    if CD.Sy = character_literal then  --  Untyped character constant, occurs only in ranges.\n      Construct_Root (C.TP, Chars);\n      C.I  := CD.INum;\n      In_Symbol;\n    else\n      Sign := 1;\n      if CD.Sy in Plus_Minus then\n        signed := True;\n        if CD.Sy = Minus then\n          Sign := -1;\n        end if;\n        In_Symbol;\n      end if;\n      case CD.Sy is\n        when IDent =>\n          --  Number defined using another one: \"minus_pi : constant := -pi;\"\n          --  ... or, we have an enumeration item.\n          X := Locate_CD_Id (CD, Level);\n          if X /= 0 then\n            if CD.id_table (X).entity = declared_number_or_enum_item then\n              C.TP := CD.id_table (X).xtyp;\n              if C.TP.TYP = Floats then\n                C.R := HAC_Float (Sign) * CD.Float_Constants_Table (Integer (CD.id_table (X).adr_or_sz));\n              else\n                C.I := Sign * CD.id_table (X).adr_or_sz;\n                if signed and then C.TP.TYP not in Numeric_Typ then\n                  Error (CD, err_numeric_constant_expected);\n                end if;\n              end if;\n            else\n              Error (CD, err_illegal_constant_or_constant_identifier, severity => major);\n            end if;\n          end if;  --  X /= 0\n          In_Symbol;\n\n        when integer_literal =>\n          C.TP.Construct_Root (Ints);\n          C.I := Sign * CD.INum;\n          In_Symbol;\n\n        when real_literal =>\n          C.TP.Construct_Root (Floats);\n          C.R := HAC_Float (Sign) * CD.RNum;\n          In_Symbol;\n\n        when others =>\n          Error_then_Skip (CD, FSys_ND, err_illegal_symbol_for_a_number_declaration);\n      end case;\n    end if;\n    Test (CD, FSys_ND, empty_symset, err_incorrectly_used_symbol);\n  end Static_Scalar_Expression;\n\n  ------------------------------------------------------------------\n  ---------------------------------------------------------Selector-\n  procedure Selector\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     V       : in out Co_Defs.Exact_Subtyp)\n  is\n\n    procedure Record_Field_Selector is\n      Field_Offset, Field_Id : Integer;\n      use type Alfa;\n    begin\n      if V.TYP = Records then\n        Field_Id := CD.Blocks_Table (V.Ref).Last_Id_Idx;\n        CD.id_table (0).name := CD.Id;\n        while CD.id_table (Field_Id).name /= CD.Id loop  --  Search field identifier\n          Field_Id := CD.id_table (Field_Id).link;\n        end loop;\n        if Field_Id = No_Id then\n          Error (CD, err_undefined_identifier, A2S (CD.Id_with_case), severity => major);\n        else\n          CD.target.Mark_Reference (Field_Id);\n          CD.id_table (Field_Id).is_referenced := True;\n          Elevate_to_Maybe (CD.id_table (Field_Id).is_read);\n          V := CD.id_table (Field_Id).xtyp;\n          Field_Offset := Integer (CD.id_table (Field_Id).adr_or_sz);\n          if Field_Offset /= 0 then\n            Emit_1 (CD, k_Record_Field_Offset, Operand_2_Type (Field_Offset));\n          end if;\n        end if;\n      else\n        Error (CD, err_var_with_field_selector_must_be_record);\n      end if;\n      In_Symbol (CD);\n    end Record_Field_Selector;\n\n    procedure Array_Coordinates_Selector is\n      Array_Index_Typ : Exact_Subtyp;  --  Evaluation of \"i\", \"j+7\", \"k*2\" in \"a (i, j+7, k*2)\".\n      use type HAC_Integer;\n\n      procedure Emit_Index_Instructions (ATI : Integer; ATE : Array_Table_Entry) is\n        range_check_needed : constant Boolean :=\n          Array_Index_Typ.Discrete_First < ATE.Index_xTyp.Discrete_First or else\n          Array_Index_Typ.Discrete_Last  > ATE.Index_xTyp.Discrete_Last;\n      begin\n        if ATE.Element_Size = 1 then\n          if range_check_needed then\n            Emit_1 (CD, k_Array_Index_Element_Size_1, Operand_2_Type (ATI));\n          else\n            Emit_1 (CD, k_Array_Index_No_Check_Element_Size_1, Operand_2_Type (ATI));\n          end if;\n        else\n          if range_check_needed then\n            Emit_1 (CD, k_Array_Index, Operand_2_Type (ATI));\n          else\n            Emit_1 (CD, k_Array_Index_No_Check, Operand_2_Type (ATI));\n          end if;\n        end if;\n      end Emit_Index_Instructions;\n\n      procedure Show_Range_Error (ATE : Array_Table_Entry) is\n      begin\n        Error\n          (CD, err_range_constraint_error,\n           \"value of index (\" &\n           (if Ranges.Is_Singleton_Range (Array_Index_Typ) then\n              --  More understandable message part for a single value\n              Discrete_Image\n               (CD,\n                Array_Index_Typ.Discrete_First,\n                ATE.Index_xTyp.TYP,\n                ATE.Index_xTyp.Ref)\n            else\n              \"range: \" &\n              Discrete_Range_Image\n                (CD,\n                 Array_Index_Typ.Discrete_First,\n                 Array_Index_Typ.Discrete_Last,\n                 ATE.Index_xTyp.TYP,\n                 ATE.Index_xTyp.Ref)) &\n              \") is out of the array's range, \" &\n              Discrete_Range_Image\n                (CD,\n                 ATE.Index_xTyp.Discrete_First,\n                 ATE.Index_xTyp.Discrete_Last,\n                 ATE.Index_xTyp.TYP,\n                 ATE.Index_xTyp.Ref),\n              severity => minor);\n      end Show_Range_Error;\n\n      procedure Show_Type_Mismatch_Error (ATE : Array_Table_Entry) is\n      begin\n        Type_Mismatch\n          (CD,\n           err_wrong_type_for_array_index,\n           Found    => Array_Index_Typ,\n           Expected => ATE.Index_xTyp);\n      end Show_Type_Mismatch_Error;\n\n      indices : Natural := 0;\n      first_dimension : Boolean := True;\n      dims : Integer;\n\n    begin\n      Array_Indices :\n      loop\n        In_Symbol (CD);  --  Consume '(', (wrongly) '[', or ',' symbol.\n        Expression (CD, context, FSys + Comma_RParent + RBrack, Array_Index_Typ);\n        indices := indices + 1;\n        if V.TYP = Arrays then\n          declare\n            ATI : constant Integer := V.Ref;\n            ATE : Array_Table_Entry renames CD.Arrays_Table (ATI);\n          begin\n            if first_dimension then\n              dims := ATE.dimensions;\n              first_dimension := False;\n            end if;\n            if Exact_Typ (ATE.Index_xTyp) /= Exact_Typ (Array_Index_Typ) then\n              Show_Type_Mismatch_Error (ATE);\n            elsif Ranges.Do_Ranges_Overlap (Array_Index_Typ,  ATE.Index_xTyp) then\n              Emit_Index_Instructions (ATI, ATE);\n            else\n              Show_Range_Error (ATE);\n            end if;\n            V := ATE.Element_xTyp;\n          end;\n        else\n          Error (CD, err_indexed_variable_must_be_an_array);\n        end if;\n        exit Array_Indices when CD.Sy /= Comma;\n      end loop Array_Indices;\n      if indices < dims then\n        Error (CD, err_too_few_array_indices, indices'Image, dims'Image);\n      elsif indices > dims then\n        Error (CD, err_too_many_array_indices, indices'Image, dims'Image);\n      end if;\n    end Array_Coordinates_Selector;\n\n  begin\n    pragma Assert (Selector_Symbol_Loose (CD.Sy));  --  '.' or '(' or (wrongly) '['\n    loop\n      if CD.Sy = Period then\n        --  Record field selector.\n        In_Symbol (CD);  --  Consume '.' symbol.\n        if CD.Sy = IDent then\n          Record_Field_Selector;\n        else\n          Error (CD, err_identifier_missing);\n        end if;\n      else\n        --  Array element selector.\n        if CD.Sy = LBrack then  --  '['\n          --  Common mistake by Pascal, Python or R programmers.\n          Error (CD, err_left_bracket_instead_of_parenthesis);\n        end if;\n        Array_Coordinates_Selector;\n        if CD.Sy = RBrack then  --  ']' : same kind of mistake as for '[' ...\n          Error (CD, err_right_bracket_instead_of_parenthesis);\n          In_Symbol (CD);\n        else\n          Need (CD, RParent, err_closing_parenthesis_missing);\n        end if;\n      end if;\n      exit when not Selector_Symbol_Loose (CD.Sy);\n    end loop;\n    --\n    Test\n      (CD, FSys, empty_symset,\n       (if FSys = Semicolon_Set then err_semicolon_missing else err_incorrectly_used_symbol));\n  end Selector;\n\n  is_logical_operator : constant Symset :=          --  RM 4.5 (2)\n    (AND_Symbol | OR_Symbol | XOR_Symbol => True,\n     others => False);\n\n  relational_operator : constant Symset :=          --  RM 4.5 (3)\n    (Comparison_Operator => True, others => False);\n\n  binary_adding_operator : constant Symset :=       --  RM 4.5 (4)\n    (Plus | Minus | Ampersand_Symbol => True,\n     others => False);\n\n  multiplying_operator : constant Symset :=         --  RM 4.5 (6)\n    (Times | Divide | MOD_Symbol | REM_Symbol => True,\n     others => False);\n\n  highest_precedence_operator : constant Symset :=  --  RM 4.5 (7)\n    (ABS_Symbol | NOT_Symbol | Power => True,\n     others => False);\n\n  ------------------------------------------------------------------\n  -------------------------------------------------------Expression-\n  procedure Expression\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     X       :    out Co_Defs.Exact_Subtyp)\n  is\n    procedure Relation (FSys_Rel : Symset; X : out Exact_Subtyp) is  --  RM 4.4 (3)\n      Y : Exact_Subtyp;\n\n      procedure Issue_Comparison_Type_Mismatch_Error is\n      begin\n        Type_Mismatch (CD, err_incompatible_types_for_comparison, Found => Y, Expected => X);\n      end Issue_Comparison_Type_Mismatch_Error;\n\n      Rel_OP : Symbol;\n      Not_In : Boolean;\n\n    begin  --  Relation\n      --\n      --  Single  simple_expression,  or:  simple_expression OPERATOR simple_expression\n      --\n      Simple_Expression (CD, context, FSys_Rel + relational_operator + IN_Symbol + NOT_Symbol, X);\n      --\n      case CD.Sy is\n        when Comparison_Operator =>\n          --\n          --  We collect here a comparison (relational) operator, e.g.: x < y\n          --\n          Rel_OP := CD.Sy;\n          In_Symbol (CD);\n          Simple_Expression (CD, context, FSys_Rel, Y);\n          if Internally_VString_Set (X.TYP) and then Internally_VString_Set (Y.TYP) then\n            --  The internal type is actually a VString on both sides.\n            Emit_Comparison_Instruction (CD, Rel_OP, VStrings);\n          elsif Is_Char_Array (CD, X) and Is_Char_Array (CD, Y) then\n            --  String object comparison, e.g. sx = sy\n            Emit (CD, k_Swap);\n            Emit_Std_Funct\n              (CD,\n               SF_String_to_VString,\n               Operand_1_Type (CD.Arrays_Table (X.Ref).Array_Size));\n            Emit (CD, k_Swap);\n            Emit_Std_Funct\n              (CD,\n               SF_String_to_VString,\n               Operand_1_Type (CD.Arrays_Table (Y.Ref).Array_Size));\n            Emit_Comparison_Instruction (CD, Rel_OP, VStrings);\n          elsif X.TYP = Y.TYP then\n            if X.TYP = Enums and then X.Ref /= Y.Ref then\n              Issue_Comparison_Type_Mismatch_Error;\n            elsif PCode_Atomic_Comparable_Typ (X.TYP) then\n              Emit_Comparison_Instruction (CD, Rel_OP, X.TYP);\n            else\n              Issue_Undefined_Operator_Error (CD, Rel_OP, X, Y);\n            end if;\n          elsif Is_Char_Array (CD, X) and Y.TYP = String_Literals then\n            --  s = \"abc\"\n            --  We needs convert the literal before anything else,\n            --  since it takes two elements on the stack.\n            Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n            Emit (CD, k_Swap);\n            Emit_Std_Funct\n              (CD,\n               SF_String_to_VString,\n               Operand_1_Type (CD.Arrays_Table (X.Ref).Array_Size));\n            Emit (CD, k_Swap);\n            Emit_Comparison_Instruction (CD, Rel_OP, VStrings);\n          elsif Internally_VString_Set (X.TYP) and then Y.TYP = String_Literals then\n            --  E.g., X < \"World\".\n            --  Y is on top of the stack, we turn it into a VString.\n            --  If this becomes a perfomance issue we could consider\n            --  a new Standard Function (SF_Code) for (VStr op Lit_Str).\n            Emit_Std_Funct (CD, SF_String_Literal_to_VString);     --  Now we have X < +\"World\".\n            Emit_Comparison_Instruction (CD, Rel_OP, VStrings);    --  Emit \"<\" (X, +Y).\n          elsif X.TYP = Ints and Y.TYP = Floats then\n            Forbid_Type_Coercion (CD, Rel_OP, X, Y);\n            X.TYP := Floats;\n            Emit_1 (CD, k_Integer_to_Float, 1);\n          elsif X.TYP = Floats and Y.TYP = Ints then\n            Forbid_Type_Coercion (CD, Rel_OP, X, Y);\n            Y.TYP := Floats;\n            Emit_1 (CD, k_Integer_to_Float, 0);\n          else\n            Issue_Comparison_Type_Mismatch_Error;\n          end if;\n          Construct_Root (X, Bools);  --  The result of the comparison is always Boolean.\n        when IN_Symbol | NOT_Symbol =>\n          --\n          --  We collect here a membership test, e.g.: x [not] in a .. b\n          --\n          Not_In := CD.Sy = NOT_Symbol;\n          In_Symbol (CD);\n          if Not_In then\n            Need (CD, IN_Symbol, err_IN_missing);\n          end if;\n          if CD.error_count = 0 then\n            Ranges.Dynamic_Range (CD, context, FSys_Rel, err_discrete_type_expected, Y);\n            if Exact_Typ (X) /= Exact_Typ (Y) then\n              Type_Mismatch (CD, err_membership_test_type_mismatch, Found => Y, Expected => X);\n              --  The RM 4.5.2 (2) seems to accept any types for X and Y. The test would be False\n              --  if types were incompatible. However, in that situation, GNAT says\n              --  \"incompatible types\", ObjectAda says \"LRM:8.6(28), Inappropriate operands\n              --  for \"IN\" operation\".\n            end if;\n            if Not_In then\n              Emit_Std_Funct (CD, SF_not_in_discrete_Interval);\n            else\n              Emit_Std_Funct (CD, SF_in_discrete_Interval);\n            end if;\n            Construct_Root (X, Bools);  --  The result of the membership test is always Boolean.\n          end if;\n        when others =>\n          null;\n      end case;\n    end Relation;\n\n    logical_operator  : Symbol;\n    previous_operator : Symbol;\n    Y                 : Exact_Subtyp;\n    short_circuit     : Boolean;\n    LC_Cond_Jump      : Integer;\n\n    procedure Process_Short_Circuit (Cond_Jump : Opcode) is\n    begin\n      In_Symbol (CD);\n      short_circuit := True;\n      LC_Cond_Jump := CD.LC;\n      Emit (CD, Cond_Jump);\n      Emit (CD, k_Pop);      --  Discard X value from stack. Top item will be Y.\n    end Process_Short_Circuit;\n\n  begin  --  Expression\n    Relation (FSys + is_logical_operator, X);\n    --\n    --  RM 4.4 (2): we collect here possible relations, connected by\n    --              logical operators: X {and Y}.\n    --\n    previous_operator := Dummy_Symbol;\n    while is_logical_operator (CD.Sy) loop\n      logical_operator := CD.Sy;\n      In_Symbol (CD);\n      --\n      --  Short-circuit forms of AND, OR.\n      --\n      short_circuit := False;\n      if logical_operator = AND_Symbol and CD.Sy = THEN_Symbol then\n        Process_Short_Circuit (k_Jump_If_Zero_No_Pop);\n        --\n        --    Jump on X = False (i.e. 0). If X = True, then X and Y = Y.\n        --\n        --       X          :    0      0      1      1\n        --                         \\      \\\n        --       Y          :    0  |   1  |   0      1\n        --                         /      /    |      |\n        --       X and Y    :    0      0      0      1\n        --\n        logical_operator := AND_THEN_Symbol;\n      elsif logical_operator = OR_Symbol and CD.Sy = ELSE_Symbol then\n        Process_Short_Circuit (k_Jump_If_Non_Zero_No_Pop);\n        --\n        --    Jump on X = True (i.e. 1). If X = False, then X or Y = Y.\n        --\n        --       X          :    0      0      1      1\n        --                                       \\      \\\n        --       Y          :    0      1      0  |   1  |\n        --                       |      |        /      /\n        --       X or Y     :    0      1      1      1\n        --\n        logical_operator := OR_ELSE_Symbol;\n      end if;\n      if previous_operator /= Dummy_Symbol and then logical_operator /= previous_operator then\n        Error (CD, err_mixed_logical_operators, severity => minor);\n      end if;\n      --\n      --  Right side of the logical operator.\n      --\n      Relation (FSys + is_logical_operator, Y);\n      --\n      if X.TYP = Bools and Y.TYP = Bools then\n        if short_circuit then\n          --  Patch the address for the conditional jump, with the place\n          --  right after the evaluation of relation Y:\n          CD.ObjCode (LC_Cond_Jump).Y := Operand_2_Type (CD.LC);\n        else\n          case logical_operator is\n            when AND_Symbol => Emit (CD, k_AND_Boolean);\n            when OR_Symbol  => Emit (CD, k_OR_Boolean);\n            when XOR_Symbol => Emit (CD, k_XOR_Boolean);\n            when others     => null;\n          end case;\n        end if;\n      else\n        Error (CD, err_resulting_type_should_be_Boolean);\n        X.TYP := NOTYP;\n      end if;\n      previous_operator := logical_operator;\n    end loop;\n    if X.TYP = NOTYP and then CD.error_count = 0 then\n      Error (CD, err_object_used_before_end_own_declaration, severity => major);\n    end if;\n  end Expression;\n\n  procedure Simple_Expression                                            --  RM 4.4 (4)\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     X       :    out Co_Defs.Exact_Subtyp)\n  is\n\n    procedure Term (FSys_Term : Symset; X : out Exact_Subtyp) is         --  RM 4.4 (5)\n\n      procedure Factor (FSys_Fact : Symset; X : out Exact_Subtyp) is     --  RM 4.4 (6)\n\n        procedure Primary (FSys_Prim : Symset; X : out Exact_Subtyp) is  --  RM 4.4 (7)\n\n          procedure Process_Identifier is\n            ident_index : constant Integer := Locate_CD_Id (CD, context.level);\n            r : Identifier_Table_Entry renames CD.id_table (ident_index);\n\n            procedure Process_Object_Identifier is\n              LC_Mem : constant Integer := CD.LC;\n            begin\n              if Selector_Symbol_Loose (CD.Sy) then  --  '.' or '(' or (wrongly) '['\n                Emit_2\n                  (CD,\n                   (if r.normal then\n                      k_Push_Address           --  Composite: push \"v'Access\".\n                    else\n                      k_Push_Discrete_Value),  --  Composite: push \"(a.all)'Access\", that is, a.\n                   Operand_1_Type (r.lev),\n                   Operand_2_Type (r.adr_or_sz));\n\n                Selector (CD, context, FSys_Prim + Apostrophe, X);\n\n                if Standard_or_Enum_Typ (X.TYP) then\n                  --  We are at a leaf point of composite type selection,\n                  --  so the stack top is expected to contain a value, not\n                  --  an address (for an expression).\n                  Emit (CD, k_Dereference);\n                end if;\n              else\n                --  No selector.\n                Emit_2\n                  (CD,\n                   (if Standard_or_Enum_Typ (X.TYP) then\n                     (if r.normal then\n                       (if Discrete_Typ (r.xtyp.TYP) then\n                          k_Push_Discrete_Value   --  Push variable v's discrete value.\n                        else\n                          k_Push_Value)           --  Push variable v's value.\n                      else\n                        k_Push_Indirect_Value)    --  Push \"a.all\" (a is an access).\n                    elsif r.normal then\n                      k_Push_Address              --  Composite: push \"v'Access\".\n                    else\n                      k_Push_Discrete_Value),     --  Composite: push \"(a.all)'Access, that is, a.\n                   Operand_1_Type (r.lev),\n                   Operand_2_Type (r.adr_or_sz));\n              end if;\n\n              if CD.Sy = Apostrophe then  --  Attribute on an object.\n                In_Symbol (CD);\n                Attributes.Object_Attribute (CD, context.level, FSys_Prim, X, LC_Mem, X);\n              else\n                --  The variable or parameter itself, not an attribute on it, has been read.\n                --  We check that it has been even written on the way to this expression.\n                Mark_Read_and_Check_Read_before_Written (CD, context, r);\n              end if;\n            end Process_Object_Identifier;\n\n          begin\n            In_Symbol (CD);\n            X := r.xtyp;\n\n            case r.entity is\n\n              when Object_Kind =>\n                Process_Object_Identifier;\n\n              when declared_number_or_enum_item =>\n                if X.TYP = Floats then\n                  --  Address is an index in the float constants table.\n                  Emit_1 (CD, k_Push_Float_Literal, Operand_2_Type (r.adr_or_sz));\n                else\n                  --  Here the address is actually the immediate (discrete) value.\n                  Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (r.adr_or_sz));\n                  --  The local subtype for the value V is the range V .. V.\n                  Ranges.Set_Singleton_Range (X, r.adr_or_sz);\n                end if;\n\n              when prozedure | prozedure_intrinsic =>\n                Error (CD, err_expected_constant_function_variable_or_subtype);\n\n              when funktion =>\n                Calls.Subprogram_or_Entry_Call\n                  (CD, context, FSys_Prim, ident_index, Normal_Procedure_Call);\n\n              when funktion_intrinsic =>\n                Standard_Functions.Standard_Function\n                  (CD, context, FSys_Prim, ident_index, SF_Code'Val (r.adr_or_sz), X);\n\n              when type_mark =>\n                Subtype_Prefixed_Expression (CD, context, FSys_Prim, ident_index, X);\n\n              when others =>\n                null;\n            end case;\n\n            if X.TYP = NOTYP and then CD.error_count = 0 then\n              Error\n                (CD, err_object_used_before_end_own_declaration,\n                 '\"' & A2S (r.name_with_case) & \"\"\" \", severity => major);\n            end if;\n          end Process_Identifier;\n\n        begin\n          X := undefined_subtyp;\n          Test (CD, Primary_Begin_Symbol, FSys_Prim, err_primary_unexpected_symbol);\n\n          case CD.Sy is\n\n            when IDent =>\n              Process_Identifier;\n\n            when character_literal | integer_literal =>\n              --  Here we have a discrete literal.\n              X.Construct_Root (if CD.Sy = character_literal then Chars else Ints);\n              CD.target.Emit_Push_Discrete_Literal (CD.INum);\n              --  The local subtype for the value V is the range V .. V.\n              Ranges.Set_Singleton_Range (X, CD.INum);\n              In_Symbol (CD);\n\n            when real_literal =>\n              X.Construct_Root (Floats);\n              Emit_Push_Float_Literal (CD, CD.RNum);\n              In_Symbol (CD);\n\n            when string_literal =>\n              Construct_Root (X, String_Literals);\n              CD.target.Emit_Push_Discrete_Literals\n                (Operand_1_Type (CD.SLeng),  --  String Literal Length\n                 Operand_2_Type (CD.INum));  --  Index To String IdTab\n              In_Symbol (CD);\n\n            when LParent =>\n              --  '(' : what is inside the parentheses is an\n              --        expression of the lowest level.\n              In_Symbol (CD);\n              Expression (CD, context, FSys_Prim + RParent, X);\n              if CD.Sy = Comma then\n                Error (CD, err_not_yet_implemented, \"aggregates (RM 4.3)\", severity => major);\n              end if;\n              Need (CD, RParent, err_closing_parenthesis_missing);\n\n            when others =>\n              null;\n\n          end case;\n\n          if X.TYP = NOTYP and then CD.error_count = 0 then\n            Error (CD, err_object_used_before_end_own_declaration, severity => major);\n          end if;\n        end Primary;\n\n        Y : Exact_Subtyp;\n\n      begin  --  Factor\n        case CD.Sy is\n\n          when ABS_Symbol =>\n            In_Symbol (CD);\n            Primary (FSys_Fact, X);\n            case X.TYP is\n              when Ints   => Emit_Std_Funct (CD, SF_Abs_Int);\n              when Floats => Emit_Std_Funct (CD, SF_Abs_Float);\n              when NOTYP  => null;  --  Another error before.\n              when others => Error (CD, err_argument_to_std_function_of_wrong_type);\n            end case;\n            X.Construct_Root (X.TYP);  --  Forget subtype bounds\n\n          when NOT_Symbol =>\n            In_Symbol (CD);\n            Primary (FSys_Fact, X);\n            case X.TYP is\n              when Bools => Emit (CD, k_NOT_Boolean);\n              when NOTYP  => null;  --  Another error before.\n              when others => Error (CD, err_resulting_type_should_be_Boolean);\n            end case;\n\n          when others =>\n            Primary (FSys_Fact + highest_precedence_operator, X);\n            if CD.Sy = Power then\n              In_Symbol (CD);\n              Primary (FSys_Fact, Y);\n              if X.TYP in Numeric_Typ and then X.TYP = Y.TYP then\n                CD.target.Emit_Arithmetic_Binary_Instruction (Power, X.TYP);\n              elsif X.TYP = Floats and Y.TYP = Ints then\n                Emit (CD, k_Power_Float_Integer);\n              else\n                Issue_Undefined_Operator_Error (CD, Power, X, Y);\n              end if;\n              X.Construct_Root (X.TYP);  --  Forget subtype bounds\n            end if;\n        end case;\n      end Factor;\n\n      use type HAC_Integer;\n      Mult_OP : Symbol;\n      Y       : Exact_Subtyp;\n    begin  --  Term\n      Factor (FSys_Term + multiplying_operator, X);\n      --\n      --  We collect here possible factors: a {* b}\n      --\n      while multiplying_operator (CD.Sy) loop\n        Mult_OP := CD.Sy;\n        In_Symbol (CD);\n        Factor (FSys_Term + multiplying_operator, Y);\n        if X.TYP = NOTYP or Y.TYP = NOTYP then\n          null;  --  Something is already wrong at this point; nothing to check or emit.\n        else\n          case Mult_OP is\n\n            when Times =>     --  *\n              if X.TYP in Numeric_Typ and then Y.TYP in Numeric_Typ then\n                if X.TYP = Y.TYP then\n                  CD.target.Emit_Arithmetic_Binary_Instruction (Times, X.TYP);\n                else\n                  Forbid_Type_Coercion (CD, Mult_OP, X, Y);\n                end if;\n                --  Figure out the subtype range after the\n                --  multiplication, if possible. NB: beyond trivial cases,\n                --  compile-time overflow checks would be needed.\n                if X.TYP = Ints then\n                  --  Find some possible static values.\n                  if Ranges.Is_Singleton_Range (X, 0) then\n                    --  0 * Y = 0.\n                    null;  --  Keep X's range, which is [0; 0].\n                  elsif Ranges.Is_Singleton_Range (Y, 0) then\n                    --  X * 0 = 0.\n                    Ranges.Set_Singleton_Range (X, 0);\n                  elsif Ranges.Is_Singleton_Range (X, 1) then\n                    --  1 * Y = Y.\n                    X.Discrete_First := Y.Discrete_First;\n                    X.Discrete_Last  := Y.Discrete_Last;\n                  elsif Ranges.Is_Singleton_Range (Y, 1) then\n                    --  X * 1 = X.\n                    null;  --  Keep X's range.\n                  else\n                    X.Construct_Root (X.TYP);  --  Forget subtype bounds\n                  end if;\n                end if;\n              elsif X.TYP = Ints then\n                --  N * (something non-numeric)\n                case Y.TYP is\n                  when Chars =>\n                    Emit_Std_Funct (CD, SF_Int_Times_Char);  --  N * Some_Char\n                    Construct_Root (X, VStrings);\n                  when String_Literals =>\n                    --  Y is on top of the stack, we turn it into a VString.\n                    Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n                    Emit_Std_Funct (CD, SF_Int_Times_VStr);  --  N * Some_String_Literal\n                    Construct_Root (X, VStrings);\n                  when VStrings | Strings_as_VStrings =>\n                    Emit_Std_Funct (CD, SF_Int_Times_VStr);  --  N * Some_VString\n                    Construct_Root (X, VStrings);\n                  when others =>\n                    Issue_Undefined_Operator_Error (CD, Mult_OP, X, Y);\n                end case;\n              else\n                Issue_Undefined_Operator_Error (CD, Mult_OP, X, Y);\n              end if;\n\n            when Divide =>    --  /\n              if X.TYP in Numeric_Typ and then X.TYP = Y.TYP then\n                CD.target.Emit_Arithmetic_Binary_Instruction (Divide, X.TYP);\n                X.Construct_Root (X.TYP);  --  Forget subtype bounds\n              else\n                if X.TYP = Ints then\n                  Forbid_Type_Coercion (CD, Mult_OP, X, Y);\n                  Emit_1 (CD, k_Integer_to_Float, 1);  --  NB: this assumed Y.TYP was Floats!\n                  X.TYP := Floats;\n                end if;\n                if Y.TYP = Ints then\n                  Forbid_Type_Coercion (CD, Mult_OP, X, Y);\n                  Emit_1 (CD, k_Integer_to_Float, 0);  --  NB: this assumed Y.TYP was Floats!\n                  Y.TYP := Floats;\n                end if;\n                Error (CD, err_illegal_type_for_arithmetic_expression);\n                X.TYP := NOTYP;\n              end if;\n\n            when MOD_Symbol | REM_Symbol =>\n              if X.TYP = Ints and Y.TYP = Ints then\n                if Mult_OP = MOD_Symbol then\n                  Emit (CD, k_MOD_Integer);\n                else\n                  Emit (CD, k_REM_Integer);\n                end if;\n              else\n                Error (CD, err_mod_requires_integer_arguments);\n                X.TYP := NOTYP;\n              end if;\n\n            when others =>\n              raise Internal_error with \"Unknown operator in Term\";\n          end case;\n        end if;\n      end loop;\n    end Term;\n\n    procedure Check_HAT_Operator_Visibility (op : Symbol) is\n    begin\n      if not CD.CUD.Use_HAT_Stack (CD.CUD.use_hat_stack_top) then\n        --  HAT is not USE-visible\n        Error\n          (CD,\n           err_general_error,\n           \"operator (\" & Op_Hint (op) &\n           \") not visible (missing a \"\"use \" & HAT_Name & \"\"\" clause)\",\n           severity => major);\n      end if;\n    end Check_HAT_Operator_Visibility;\n\n    additive_operator : Symbol;\n    y                 : Exact_Subtyp;\n\n    function Do_VString_Concatenation return Boolean is\n    begin\n      if X.TYP /= VStrings and y.TYP /= VStrings then\n        return False;\n      end if;\n      --  Below this line, at least X or Y is a VString, defined in the HAT package.\n      Check_HAT_Operator_Visibility (Ampersand_Symbol);\n      --  RM References are about Unbounded_String (A.4.5).\n      if Internally_VString_Set (X.TYP) and then Internally_VString_Set (y.TYP) then\n        --  v1 & v2              A.4.5 (15)\n        --  v & Enum'Image (x)   A.4.5 (16),\n        --  Enum'Image (x) & v   A.4.5 (17)\n        Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n      elsif y.TYP = String_Literals then                          --  v & \"x\"  A.4.5 (16)\n        --  Y is on top of the stack, we turn it into a VString.\n        --  If this becomes a perfomance issue we could consider\n        --  adding a Standard Function (SF_Code) for (VStr op Lit_Str).\n        Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n        --  Now we concatenate both VStrings.\n        Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n      elsif X.TYP = String_Literals then                          --  \"x\" & v  A.4.5 (17)\n        Emit_Std_Funct (CD, SF_LStr_VString_Concat);\n      elsif Is_Char_Array (CD, y) then                            --  v & s    A.4.5 (16)\n        Emit_Std_Funct (CD,\n          SF_String_to_VString,\n          Operand_1_Type (CD.Arrays_Table (y.Ref).Array_Size)\n        );\n        Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n      elsif Is_Char_Array (CD, X) then                            --  s & v    A.4.5 (17)\n        Emit (CD, k_Swap);   --  v, then s on the stack\n        Emit_Std_Funct (CD,  --  s -> +s\n          SF_String_to_VString,\n          Operand_1_Type (CD.Arrays_Table (X.Ref).Array_Size)\n        );\n        Emit (CD, k_Swap);   --  +s, then v on the stack\n        Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n      elsif y.TYP = Chars then                                    --  v & 'x'  A.4.5 (18)\n        Emit_Std_Funct (CD, SF_VString_Char_Concat);\n      elsif X.TYP = Chars then                                    --  'x' & v  A.4.5 (19)\n        Emit_Std_Funct (CD, SF_Char_VString_Concat);\n      --\n      --  Hereafter, we have \"&\" operators on VString provided only by HAT\n      --  and not by Ada.Unbounded_Strings\n      --\n      elsif y.TYP = Ints then      Emit_Std_Funct (CD, SF_VString_Int_Concat);       --  v & 123\n      elsif X.TYP = Ints then      Emit_Std_Funct (CD, SF_Int_VString_Concat);       --  123 & v\n      elsif y.TYP = Floats then    Emit_Std_Funct (CD, SF_VString_Float_Concat);     --  v & 3.14159\n      elsif X.TYP = Floats then    Emit_Std_Funct (CD, SF_Float_VString_Concat);     --  3.14159 & v\n      elsif y.TYP = Durations then Emit_Std_Funct (CD, SF_VString_Duration_Concat);  --  v & dur\n      elsif X.TYP = Durations then Emit_Std_Funct (CD, SF_Duration_VString_Concat);  --  dur & v\n      elsif y.TYP = Bools then     Emit_Std_Funct (CD, SF_VString_Boolean_Concat);   --  v & is_found\n      elsif X.TYP = Bools then     Emit_Std_Funct (CD, SF_Boolean_VString_Concat);   --  is_found & v\n      else\n        return False;\n      end if;\n      Construct_Root (X, VStrings);\n      return True;\n    end Do_VString_Concatenation;\n\n    function Do_String_Concatenation return Boolean is\n      --  Arguments can be one of the three internal representations of String:\n      --      1)  sv  : VString (the parser sees the TYP Strings_as_VStrings)\n      --      2)  sc  : constrained array of character\n      --      3) \"xy\" : literal string\n      --  Additionally, we can have a character:\n      --      4)  'x' : character (value or literal)\n      --\n      --  So, it makes 16 argument combinations. We note them [ab].\n      --  For example, a concatenation of a Strings_as_VStrings and a Literal\n      --  is noted [13].\n      --\n      --  Result is always Strings_as_VStrings.\n      --  RM Reference: the predefined \"&\" operator 4.5.3(3), applied to String.\n\n      procedure Emit_sc1_amp_sv2 is  --  Emit code for: sc1 & sv2\n      begin\n        Emit (CD, k_Swap);   --  sv2, then sc1 on the stack\n        Emit_Std_Funct\n          (CD,  --  sv1 := To_VString (sc1)\n           SF_String_to_VString,\n           Operand_1_Type (CD.Arrays_Table (X.Ref).Array_Size));\n        Emit (CD, k_Swap);   --  sv1, then sv2 on the stack\n        Emit_Std_Funct (CD, SF_Two_VStrings_Concat);  --  sv1 & sv2\n      end Emit_sc1_amp_sv2;\n\n      procedure Emit_sc2_to_sv2 is\n      begin\n        Emit_Std_Funct\n          (CD,  --  sv2 := To_VString (sc2)\n           SF_String_to_VString,\n           Operand_1_Type (CD.Arrays_Table (y.Ref).Array_Size));\n      end Emit_sc2_to_sv2;\n\n    begin\n      if X.TYP = Strings_as_VStrings then\n        if y.TYP = Strings_as_VStrings then     --  [11] sv1 & sv2\n          Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n        elsif Is_Char_Array (CD, y) then        --  [12] sv1 & sc2\n          Emit_sc2_to_sv2;\n          --  Back to case [11]:\n          Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n        elsif y.TYP = String_Literals then      --  [13] sv1 & \"xy\"\n          Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n          --  Back to case [11]:\n          Emit_Std_Funct (CD, SF_Two_VStrings_Concat);\n        elsif y.TYP = Chars then                --  [14] sv1 & 'x'\n          Emit_Std_Funct (CD, SF_VString_Char_Concat);\n        else\n          return False;\n        end if;\n      elsif Is_Char_Array (CD, X) then\n        if y.TYP = Strings_as_VStrings then     --  [21] sc1 & sv2\n          Emit_sc1_amp_sv2;\n        elsif Is_Char_Array (CD, y) then        --  [22] sc1 & sc2\n          Emit_sc2_to_sv2;\n          Emit_sc1_amp_sv2;\n        elsif y.TYP = String_Literals then      --  [23] sc1 & \"xy\"\n          Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n          Emit_sc1_amp_sv2;\n        elsif y.TYP = Chars then                --  [24] sc1 & 'x'\n          Emit_Std_Funct (CD, SF_Char_to_VString);\n          Emit_sc1_amp_sv2;\n        else\n          return False;\n        end if;\n      elsif X.TYP = String_Literals then\n        if y.TYP = Strings_as_VStrings then     --  [31] \"xy\" & sv2\n          Emit_Std_Funct (CD, SF_LStr_VString_Concat);\n        elsif Is_Char_Array (CD, y) then        --  [32] \"xy\" & sc2\n          Emit_sc2_to_sv2;\n          Emit_Std_Funct (CD, SF_LStr_VString_Concat);\n        elsif y.TYP = String_Literals then      --  [33] \"ab\" & \"cd\"\n          Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n          Emit_Std_Funct (CD, SF_LStr_VString_Concat);\n        elsif y.TYP = Chars then                --  [34] \"ab\" & 'c'\n          Emit_Std_Funct (CD, SF_Char_to_VString);\n          Emit_Std_Funct (CD, SF_LStr_VString_Concat);\n        else\n          return False;\n        end if;\n      elsif X.TYP = Chars then\n        if y.TYP = Strings_as_VStrings then     --  [41] 'x' & sv2\n          Emit_Std_Funct (CD, SF_Char_VString_Concat);\n        elsif Is_Char_Array (CD, y) then        --  [42] 'x' & sc2\n          Emit_sc2_to_sv2;\n          Emit_Std_Funct (CD, SF_Char_VString_Concat);\n        elsif y.TYP = String_Literals then      --  [43] 'a' & \"bc\"\n          Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n          Emit_Std_Funct (CD, SF_Char_VString_Concat);\n        elsif y.TYP = Chars then                --  [34] 'a' & 'b'\n          Emit_Std_Funct (CD, SF_Char_to_VString);\n          Emit_Std_Funct (CD, SF_Char_VString_Concat);\n        else\n          return False;\n        end if;\n      else\n        return False;\n      end if;\n      Construct_Root (X, Strings_as_VStrings);\n      return True;\n    end Do_String_Concatenation;\n\n  begin  --  Simple_Expression\n    if CD.Sy in Plus_Minus then\n      --\n      --  Unary + , -      RM 4.5 (5), 4.4 (4)\n      --\n      additive_operator := CD.Sy;\n      In_Symbol (CD);\n      Term (FSys + Plus_Minus_Set, X);\n      --  At this point we have consumed \"+X\" or \"-X\".\n      if X.TYP in String_Literals | Strings_as_VStrings | Chars | VStrings\n        or else Is_Char_Array (CD, X)\n      then\n        Check_HAT_Operator_Visibility (additive_operator);\n        case Plus_Minus (additive_operator) is\n\n          when Plus =>\n            case X.TYP is\n              when String_Literals =>                              --  +\"Hello\"\n                Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n              when Strings_as_VStrings =>                          --  +Enum'Image (x)\n                --  Nothing to do, except setting X's\n                --  subtype as an \"official\" VString.\n                null;\n              when Chars =>                                        --  +'H'\n                Emit_Std_Funct (CD, SF_Char_to_VString);\n              when Arrays =>\n                if Is_Char_Array (CD, X) then                      --  +S\n                  Emit_Std_Funct\n                    (CD,\n                     SF_String_to_VString,\n                     Operand_1_Type (CD.Arrays_Table (X.Ref).Array_Size));\n                else\n                  Issue_Undefined_Operator_Error (CD, additive_operator, X);\n                end if;\n              when others =>\n                Issue_Undefined_Operator_Error (CD, additive_operator, X);\n            end case;\n            Construct_Root (X, VStrings);\n\n          when Minus =>\n            if X.TYP = VStrings then                               --  -v\n              Construct_Root (X, Strings_as_VStrings);\n            else\n              Issue_Undefined_Operator_Error (CD, additive_operator, X);\n            end if;\n        end case;\n      elsif X.TYP not in Numeric_Typ then\n        Error (CD, err_illegal_type_for_arithmetic_expression);\n      elsif additive_operator = Minus then\n        Emit_Unary_Minus (CD, X.TYP);\n        if X.TYP = Ints then\n          Ranges.Negate_Range (CD, X);\n        end if;\n      end if;\n    else\n      Term (FSys + binary_adding_operator, X);\n    end if;\n    --\n    --  Binary operators: we collect here possible terms: a {+ b}      RM 4.4 (4)\n    --\n    while binary_adding_operator (CD.Sy) loop\n      additive_operator := CD.Sy;\n      In_Symbol (CD);\n      Term (FSys + binary_adding_operator, y);\n      if X.TYP = NOTYP or y.TYP = NOTYP then\n        null;  --  Something is already wrong at this point; nothing to check or emit.\n      else\n        case additive_operator is\n\n          when OR_Symbol =>\n            if X.TYP = Bools and y.TYP = Bools then\n              Emit (CD, k_OR_Boolean);\n            else\n              Error (CD, err_resulting_type_should_be_Boolean);\n              X.TYP := NOTYP;\n            end if;\n\n          when XOR_Symbol =>\n            if X.TYP = Bools and y.TYP = Bools then\n              Emit (CD, k_XOR_Boolean);\n            else\n              Error (CD, err_resulting_type_should_be_Boolean);\n              X.TYP := NOTYP;\n            end if;\n\n          when Plus | Minus =>\n            if X.TYP in Numeric_Typ and then y.TYP in Numeric_Typ then\n              if X.TYP = y.TYP then\n                CD.target.Emit_Arithmetic_Binary_Instruction (additive_operator, X.TYP);\n              else\n                Forbid_Type_Coercion (CD, additive_operator, X, y);\n              end if;\n              if X.TYP = Ints then\n                if Ranges.Is_Singleton_Range (y, 0) then\n                  --  X +/- 0 = X.\n                  null;  --  Keep X's range.\n                else\n                  X.Construct_Root (X.TYP);  --  Forget subtype bounds\n                end if;\n              end if;\n            elsif X.TYP = Times and y.TYP = Times and additive_operator = Minus then\n              Emit_Std_Funct (CD, SF_Time_Subtract);  --  T2 - T1\n              Construct_Root (X, Durations);\n            elsif X.TYP = Durations then\n              if y.TYP = Floats then\n                --  Duration hack for \"X + 1.234\" (see Delay_Statement\n                --  for full explanation).\n                Emit_Std_Funct (CD, SF_Float_to_Duration);\n                Construct_Root (y, Durations);  --  Now X and Y have the type Duration.\n              end if;\n              if y.TYP = Durations then\n                if additive_operator = Plus then\n                  Emit_Std_Funct (CD, SF_Duration_Add);\n                else\n                  Emit_Std_Funct (CD, SF_Duration_Subtract);\n                end if;\n              else\n                Issue_Undefined_Operator_Error (CD, additive_operator, X, y);\n              end if;\n            else\n              Issue_Undefined_Operator_Error (CD, additive_operator, X, y);\n            end if;\n\n          when Ampersand_Symbol =>\n            if not (Do_VString_Concatenation or else Do_String_Concatenation) then\n              Issue_Undefined_Operator_Error (CD, additive_operator, X, y);\n            end if;\n\n          when others =>\n            --  Doesn't happen: Binary_Adding_Operators(OP) is True.\n            null;\n        end case;\n      end if;\n    end loop;\n  end Simple_Expression;\n\n  procedure Boolean_Expression\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     X       :    out Co_Defs.Exact_Subtyp)\n  is\n  begin\n    Expression (CD, context, FSys, X);\n    Check_Boolean (CD, X.TYP);\n  end Boolean_Expression;\n\n  procedure Subtype_Prefixed_Expression\n    (CD           : in out Co_Defs.Compiler_Data;\n     context      : in     Defs.Flow_Context;\n     FSys         : in     Defs.Symset;\n     Typ_ID_Index : in     Natural;\n     X            : in out Co_Defs.Exact_Subtyp)\n  is\n    Mem_Sy : constant Symbol := CD.Sy;\n  begin\n    pragma Assert (CD.id_table (Typ_ID_Index).entity = type_mark);\n    In_Symbol (CD);\n    case Mem_Sy is\n      when LParent    =>  --  S (...)\n        Type_Conversion (CD, context, FSys, CD.id_table (Typ_ID_Index), X);\n      when Apostrophe =>  --  S'First, S'Image, ...\n        Attributes.Subtype_Attribute (CD, context, FSys, Typ_ID_Index, X);\n      when others =>\n        Error (CD, err_general_error, \"expected \"\"'\"\" or \"\"(\"\" here\", severity => major);\n    end case;\n  end Subtype_Prefixed_Expression;\n\nend HAC_Sys.Parser.Expressions;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-expressions.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nprivate package HAC_Sys.Parser.Expressions is\n\n  procedure Static_Scalar_Expression\n    (CD      : in out Co_Defs.Compiler_Data;\n     Level   : in     Defs.Nesting_Level;\n     FSys_ND : in     Defs.Symset;\n     C       :    out Co_Defs.Constant_Rec);\n\n  --  For all dynamic expressions:\n  --   - the appropriate machine code is emitted;\n  --   - in the machine code, the expression is pushed on the stack\n  --   - for parsing: the type of the expression is set in X.\n\n  procedure Boolean_Expression\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     X       :    out Co_Defs.Exact_Subtyp);\n\n  procedure Expression                        --  RM 4.4 (2)\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     X       :    out Co_Defs.Exact_Subtyp);\n\n  procedure Simple_Expression                 --  RM 4.4 (4)\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     X       :    out Co_Defs.Exact_Subtyp);\n\n  procedure Selector\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     V       : in out Co_Defs.Exact_Subtyp);\n\n  --  Conversion, like ` Integer (123.456) `\n  --  or attribute, like  ` Integer'Image (123) `.\n  --\n  procedure Subtype_Prefixed_Expression\n    (CD           : in out Co_Defs.Compiler_Data;\n     context      : in     Defs.Flow_Context;\n     FSys         : in     Defs.Symset;\n     Typ_ID_Index : in     Natural;\n     X            : in out Co_Defs.Exact_Subtyp);\n\nend HAC_Sys.Parser.Expressions;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-helpers.adb",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\nwith HAT;\n\npackage body HAC_Sys.Parser.Helpers is\n\n  use Scanner, Errors;\n  use type HAC_Integer;\n\n  procedure Need\n    (CD      : in out Compiler_Data;\n     S       :        Symbol;\n     E       :        Compile_Diagnostic;\n     Forgive :        Symbol := Dummy_Symbol)\n  is\n    severity : Error_Severity := medium;\n  begin\n    if CD.Sy = S then\n      In_Symbol (CD);\n    else\n      if Forgive = Dummy_Symbol then\n        severity := major;\n      end if;\n      Error (CD, E, \": \" & Symbol'Image (S) & \" expected\", severity => severity);\n      if CD.Sy = Forgive then\n        In_Symbol (CD);\n      end if;\n    end if;\n  end Need;\n\n  procedure Error_then_Skip\n    (CD   : in out Compiler_Data;\n     FSys :        Symset;\n     N    :        Compile_Diagnostic;\n     hint :        String := \"\")\n  is\n\n    function StopMe return Boolean is\n    begin\n      return False;\n    end StopMe;\n\n  begin\n    Error (CD, N, hint);\n    --\n    while not FSys (CD.Sy) loop\n      In_Symbol (CD);\n      if StopMe then\n        raise Failure_1_0;\n      end if;\n    end loop;\n\n    In_Symbol (CD);\n    --  Manuel:  If this In_Symbol call is\n    --  omitted, the system will get in an\n    --  infinite loop on the statement:\n    --  put_lin(\"Typo is on purpose\");\n\n    if StopMe then\n      raise Failure_1_0;\n    end if;\n  end Error_then_Skip;\n\n  procedure Error_then_Skip\n    (CD   : in out Compiler_Data;\n     S    :        Symbol;\n     N    :        Compile_Diagnostic;\n     hint :        String := \"\")\n  is\n  begin\n    Error_then_Skip (CD, Singleton (S), N, hint);\n  end Error_then_Skip;\n\n  procedure Test\n    (CD            : in out Compiler_Data;\n     S1, S2        :        Symset;\n     N             :        Compile_Diagnostic;\n     stop_on_error :        Boolean := False)\n  is\n    use HAT;\n  begin\n    if not S1 (CD.Sy) then\n      declare\n        hint  : VString;\n        first : Boolean := True;\n      begin\n        for s in S1'Range loop\n          if S1 (s) then\n            if not first then\n              hint := hint & \", \";\n            end if;\n            first := False;\n            hint := hint & Symbol'Image (s);\n          end if;\n        end loop;\n        hint := \"Found: \" & Symbol'Image (CD.Sy) & \"; expected: \" & hint;\n        if stop_on_error then\n          Error (CD, N, HAT.VStr_Pkg.To_String (hint), severity => major);\n        end if;\n        Error_then_Skip (CD, S1 + S2, N, HAT.VStr_Pkg.To_String (hint));\n      end;\n    end if;\n  end Test;\n\n  After_Semicolon_after_Declaration : constant Symset :=\n    Declaration_X_Subprogram_Symbol +\n    Block_Begin_Symbol +\n    END_Symbol +\n    PRIVATE_Symbol;\n\n  Comma_or_colon : constant Symset :=\n    Symset'(Comma | Colon => True, others => False);\n\n  procedure Need_Semicolon_after_Declaration (CD : in out Compiler_Data; FSys : Symset) is\n  begin\n    if CD.Sy = Semicolon then\n      In_Symbol (CD);\n      Ignore_Extra_Semicolons (CD);\n    else\n      Error (CD, err_semicolon_missing);\n      if Comma_or_colon (CD.Sy) then\n        In_Symbol (CD);\n      end if;\n    end if;\n    Test (CD, After_Semicolon_after_Declaration, FSys, err_incorrectly_used_symbol);\n  end Need_Semicolon_after_Declaration;\n\n  procedure Need_END_Symbol (CD : in out Compiler_Data) is\n  begin\n    if CD.Sy = END_Symbol then\n      In_Symbol (CD);\n    else\n      Error_then_Skip (CD, Semicolon, err_END_missing);\n    end if;\n  end Need_END_Symbol;\n\n  procedure Check_Boolean (CD : in out Compiler_Data; T : Typen) is\n  begin\n    if T /= Bools then\n      Error (CD, err_expecting_a_boolean_expression);\n    end if;\n  end Check_Boolean;\n\n  procedure Check_Integer (CD : in out Compiler_Data; T : Typen) is\n  begin\n    if T /= Ints then\n      Error (CD, err_parameter_must_be_Integer);\n    end if;\n  end Check_Integer;\n\n  procedure Ignore_Extra_Semicolons (CD : in out Compiler_Data) is\n  begin\n    if CD.Sy = Semicolon then\n      Error (CD, err_duplicate_semicolon, severity => minor);\n      while CD.Sy = Semicolon loop\n        In_Symbol (CD);\n      end loop;\n    end if;\n  end Ignore_Extra_Semicolons;\n\n  procedure Need_Semicolon (CD : in out Compiler_Data) is\n  begin\n    if CD.Sy = RParent and then CD.prev_sy = RParent then\n      Error (CD, err_extra_right_parenthesis, severity => minor);\n      while CD.Sy = RParent loop\n        In_Symbol (CD);\n      end loop;\n    end if;\n    Need (CD, Semicolon, err_semicolon_missing, Forgive => Comma);\n    Ignore_Extra_Semicolons (CD);\n  end Need_Semicolon;\n\n  procedure Argument_Type_Not_Supported (CD : in out Compiler_Data) is\n  begin\n    Error (CD, err_type_conversion_not_supported, \"argument type not supported\");\n  end Argument_Type_Not_Supported;\n\n  function Nice_Image (T : Typen) return String is\n  begin\n    case T is\n      when NOTYP               => return \"(undefined type)\";\n      when Ints                => return \"an integer type\";\n      when Chars               => return \"Character\";        -- \"the\" Character type\n      when Bools               => return \"Boolean\";          -- \"the\" Boolean type\n      when Floats              => return \"a floating-point type\";\n      when Arrays              => return \"an array type\";\n      when Records             => return \"a record type\";\n      when Enums               => return \"an enumeration type\";\n      when String_Literals     => return \"String [literal]\";\n      when Strings_as_VStrings => return \"String [pseudo-unconstrained]\";\n      when VStrings            => return \"VString\";\n      when Times               => return \"Time\";             --  \"the\" Time type\n      when Durations           => return \"Duration\";         --  \"the\" Duration type\n      when Text_Files          => return \"File_Type\";\n    end case;\n  end Nice_Image;\n\n  function Enum_Name (CD : Compiler_Data; E_Ref : Index) return String is\n    (A2S (CD.id_table (E_Ref).name_with_case));\n\n  function Nice_Exact_Image (CD : Compiler_Data; xT : Exact_Typ'Class) return String is\n    (Nice_Image (xT.TYP) &\n      (if xT.TYP = Enums then \" (\" & Enum_Name (CD, xT.Ref) & ')' else \"\"));\n\n  procedure Type_Mismatch\n    (CD               : in out Compiler_Data;\n     Err              :        Compile_Diagnostic;\n     Found, Expected  :        Exact_Typ'Class)\n  is\n  begin\n    if Found.TYP /= Expected.TYP then\n      Error (CD,\n        Err,\n        \"found \"      & Nice_Exact_Image (CD, Found) &\n        \", expected \" & Nice_Exact_Image (CD, Expected),\n        severity => major);\n    elsif Found.TYP = Enums then\n      Error (CD,\n        Err,\n        \"found \"\"\"        & Enum_Name (CD, Found.Ref) &\n        \"\"\", expected \"\"\" & Enum_Name (CD, Expected.Ref) & '\"',\n        severity => major);\n    else\n      Error (CD,\n        Err,\n        \"not exactly the same \" & Nice_Image (Found.TYP),\n        severity => major);\n      --  Possible improvement: find the possible array or record\n      --  names using X.Ref, Y.Ref ... if they have names!\n      --  (same for Issue_Undefined_Operator_Error)\n    end if;\n  end Type_Mismatch;\n\n  procedure Type_Mismatch\n    (CD       : in out Compiler_Data;\n     Err      :        Compile_Diagnostic;\n     Found    :        Exact_Subtyp;\n     Expected :        Typ_Set)\n  is\n    function Types_List (TS : Typ_Set) return String is\n      use HAT;\n      hint  : VString;\n      first : Boolean := True;\n    begin\n      for s in TS'Range loop\n        if TS (s) then\n          if not first then\n            hint := hint & \", \";\n          end if;\n          first := False;\n          hint := hint & Nice_Image (s);\n        end if;\n      end loop;\n      return HAT.VStr_Pkg.To_String (hint);\n    end Types_List;\n  begin\n    Error\n      (CD, Err,\n       \"found: \"      & Nice_Exact_Image (CD, Found) &\n       \", expected: \" & Types_List (Expected),\n       severity => major);\n  end Type_Mismatch;\n\n  function Op_Hint (OP : Symbol) return String is\n  --  Displayed as \"operator (+) is not defined...\"\n  begin\n    case OP is\n      when Plus             => return \"+\";\n      when Minus            => return \"-\";\n      when Times            => return \"*\";\n      when Divide           => return \"/\";\n      when Power            => return \"**\";\n      when Ampersand_Symbol => return \"&\";\n      when EQL              => return \"=\";\n      when NEQ              => return \"/=\";\n      when GTR              => return \">\";\n      when GEQ              => return \">=\";\n      when LSS              => return \"<\";\n      when LEQ              => return \"<=\";\n      when others           => return \"?\";\n    end case;\n  end Op_Hint;\n\n  procedure Issue_Undefined_Operator_Error\n    (CD       : in out Compiler_Data;\n     Operator :        Symbol;\n     Right    :        Exact_Subtyp)\n  is\n  begin\n    if Right.TYP = Enums then\n      Error\n        (CD, err_operator_not_defined_for_types,\n         Op_Hint (Operator),\n         Enum_Name (CD, Right.Ref));\n    else\n      Error\n        (CD, err_operator_not_defined_for_types,\n         Op_Hint (Operator),\n         Nice_Image (Right.TYP));\n    end if;\n  end Issue_Undefined_Operator_Error;\n\n  procedure Issue_Undefined_Operator_Error\n    (CD          : in out Compiler_Data;\n     Operator    :        Symbol;\n     Left, Right :        Exact_Subtyp)\n  is\n  begin\n    if Left.TYP /= Right.TYP then\n      Error\n        (CD, err_operator_not_defined_for_types,\n         Op_Hint (Operator),\n         \"left is \"    & Nice_Exact_Image (CD, Left) &\n         \", right is \" & Nice_Exact_Image (CD, Right));\n    elsif Left.TYP = Enums then\n      if Left.Ref = Right.Ref then\n        Error\n          (CD, err_operator_not_defined_for_types,\n           Op_Hint (Operator),\n           Enum_Name (CD, Left.Ref));\n      else\n        Error\n          (CD, err_operator_not_defined_for_types,\n           Op_Hint (Operator),\n           \"left is \"    & Enum_Name (CD, Left.Ref) &\n           \", right is \" & Enum_Name (CD, Right.Ref));\n      end if;\n    else\n      Error\n        (CD, err_operator_not_defined_for_types,\n         Op_Hint (Operator),\n         Nice_Image (Left.TYP));\n         --  Possible improvement: find the possible array or record\n         --  names using X.Ref, Y.Ref ... if they have names!\n         --  (same for Type_Mismatch)\n    end if;\n  end Issue_Undefined_Operator_Error;\n\n  procedure Forbid_Type_Coercion\n    (CD          : in out Compiler_Data;\n     Operator    :        Symbol;\n     Left, Right :        Exact_Subtyp)\n  is\n  begin\n    Error\n      (CD,\n       err_numeric_type_coercion_operator,\n       Op_Hint (Operator),\n       \"left is \"    & Nice_Exact_Image (CD, Left) &\n       \", right is \" & Nice_Exact_Image (CD, Right),\n       major);\n  end Forbid_Type_Coercion;\n\n  procedure Forbid_Type_Coercion\n    (CD              : in out Compiler_Data;\n     Found, Expected :        Exact_Subtyp)\n  is\n  begin\n    Error\n      (CD, err_numeric_type_coercion,\n       \"found \"    & Nice_Exact_Image (CD, Found) &\n       \", expected \" & Nice_Exact_Image (CD, Expected),\n       severity => major);\n  end Forbid_Type_Coercion;\n\n  function Singleton (s : Symbol) return Symset is\n    res : Symset := empty_symset;\n  begin\n    res (s) := True;\n    return res;\n  end Singleton;\n\n  function Singleton (t : Typen) return Typ_Set is\n    res : Typ_Set := empty_typ_set;\n  begin\n    res (t) := True;\n    return res;\n  end Singleton;\n\n  function Is_Char_Array (CD : Compiler_Data; T : Exact_Subtyp) return Boolean is\n  begin\n    return\n      T.TYP = Arrays\n        and then T.Ref in Arrays_Table_Type'Range\n                 --  ^ Filter out invalid reference due to an error\n                 --    that has occurred previously in the parsing.\n        and then CD.Arrays_Table (T.Ref).Element_xTyp.TYP = Chars;\n  end Is_Char_Array;\n\n  procedure Check_any_String_and_promote_to_VString\n    (CD : in out Compiler_Data; X : in out Exact_Subtyp; include_characters : Boolean)\n  is\n    use Compiler.PCode_Emit, PCode;\n    expected_set : Typ_Set :=  VStrings_Set or Str_Lit_Set or Str_as_VStr_Set or Arrays_Set;\n  begin\n    if include_characters then\n      expected_set := expected_set or Chars_Set;\n    end if;\n    if X.TYP = String_Literals then\n      Emit_Std_Funct (CD, SF_String_Literal_to_VString);\n    elsif Is_Char_Array (CD, X) then\n      Emit_Std_Funct (CD,\n        SF_String_to_VString,\n        Operand_1_Type (CD.Arrays_Table (X.Ref).Array_Size)\n      );\n    elsif Internally_VString_Set (X.TYP) then\n      null;  --  Already a VString.\n    elsif include_characters and then X.TYP = Chars then\n      Emit_Std_Funct (CD, SF_Char_to_VString);\n    else\n      Type_Mismatch\n        (CD,\n         err_parameter_types_do_not_match,\n         Found    => X,\n         Expected => expected_set);\n    end if;\n    X.Construct_Root (VStrings);\n  end Check_any_String_and_promote_to_VString;\n\n  ------------------------------------------------------------------\n  ------------------------------------------------Locate_Identifier-\n\n  function Locate_Identifier_Internal\n    (CD               : in out Compiler_Data;\n     Id               : in     Alfa;\n     using_parsed_Id  : in     Boolean;\n     Prefix_Id        : in     Alfa;\n     Level            : in     Defs.Nesting_Level;\n     Fail_when_No_Id  : in     Boolean;\n     Alias_Resolution : in     Boolean;\n     Level_0_Filter   : in     Boolean;\n     Public_Filter    : in     Index)\n  return Natural\n  is\n    L : Defs.Nesting_Level'Base;\n    J : Integer := No_Id;\n    ID_Copy : Alfa;\n    is_name_matched : Boolean;\n    dot_pos : Integer;\n    l0_def : Id_Maps.Cursor;\n    use HAT, Id_Maps;\n    trace_search : constant Boolean := False;\n  begin\n    L := Level;\n    if trace_search then\n      Put_Line\n        (+\"  Start Id search, at level\" & L'Image & \" for Id = \"\"\" & Id & '\"');\n    end if;\n\n    --  Scan all Id's from level L down to level 0:\n  Scan :\n    loop\n\n      if L = 0 and then Level_0_Filter then\n        l0_def := CD.CUD.level_0_def.Find (Id);\n        if l0_def /= No_Element then\n          --  Global definition found, within a library package, or in the\n          --  WITH context clauses.\n          --  In this case there is no point doing a tedious linear search :-) .\n          J := Element (l0_def);\n          if trace_search then\n            Put_Line\n              (+\"    Shortcut! Found global (level 0) definition with value # \" & J);\n          end if;\n          exit Scan;\n        end if;\n      end if;\n      J := CD.Blocks_Table (CD.Display (L)).Last_Id_Idx;\n      if trace_search then\n        Put_Line\n          (+\"    Reset index for level\" & L'Image &\n            \" with value # \" & J);\n      end if;\n\n    Scan_level_L :\n      loop\n        exit Scan_level_L when J = No_Id;  --  Beginning of ID table reached.\n\n        if CD.id_table (J).entity /= paquetage_body then\n          --  ^ A package body is invisible as a declaration.\n          if CD.id_table (J).entity = paquetage\n            and then Length (Prefix_Id) > 0\n            and then Prefix_Id = CD.id_table (J).name\n          then\n            --  We have reached the defining package.\n            --  Example: we are looking for HAT.PUT, but we just hit a\n            --  local HAT package's specification. Logically that local HAT\n            --  doesn't contain a PUT item, otherwise we would have found\n            --  it already.\n            --  Other packages with the same name at upper levels are hidden.\n            J := No_Id;\n            exit Scan;\n          end if;\n          dot_pos := Length (CD.pkg_prefix);\n          if dot_pos = 0 then\n            is_name_matched := CD.id_table (J).name = Id;\n          else\n            --  We are within a package declaration.\n            --  Things are a bit more complicated: the package's items\n            --  are visible to the package itself. So we simulate a hidden USE.\n            --\n            --  Say we are within `Pkg.Child_1.Subpackage_2` declaration.\n            --  For entry `Pkg.Child_1.Subpackage_2.Item` in the identifier\n            --  table, `Item` is visible, as well as `Subpackage_2[.Item]`\n            --  `Child_1[.Subpackage_2[.Item]]`.\n            --  NB : the stuff with [] is resolved at the end of Locate_Identifier_Internal.\n            loop\n              is_name_matched :=\n                CD.id_table (J).name =\n                  Slice (CD.pkg_prefix, 1, dot_pos) & Id;\n              exit when is_name_matched;\n              exit when dot_pos = 0;\n              loop\n                dot_pos := dot_pos - 1;\n                exit when dot_pos = 0;\n                exit when Element (CD.pkg_prefix, dot_pos) = '.';\n              end loop;\n            end loop;\n          end if;\n\n          if trace_search then\n            Put_Line\n              (+\"      Id search level\" & L'Image &\n               \"; candidate # \" & J & \" named \" & CD.id_table (J).name &\n               \"; matched : \" & is_name_matched'Image);\n          end if;\n\n          if is_name_matched then\n            --  Reasons to consider the matched identifier:\n            --    * Not library-level: we have a local subprogram\n            --        identifier (possibly wrapped in a local package):\n            exit Scan_level_L when L > 0;\n            --    * Filter for library-level definition is disabled:\n            exit Scan_level_L when not Level_0_Filter;\n            --    * Activated library-level definition:\n            exit Scan_level_L when CD.CUD.level_0_def.Contains (CD.id_table (J).name);\n          end if;\n        end if;\n\n        if trace_search then\n          Put (+\"      Chained list: identifier index goes from J = \" & J);\n        end if;\n        J := CD.id_table (J).link;  --  Skip this identifier.\n        if trace_search then\n          Put_Line (+\" to J = \" & J);\n        end if;\n\n      end loop Scan_level_L;\n\n      L := L - 1;  --  Decrease nesting level.\n      if trace_search then\n        Put_Line (+\"    Level decreases to L =\" & L'Image);\n      end if;\n      exit Scan when L < 0 or J /= No_Id;\n    end loop Scan;\n\n    if J = No_Id then\n      if not Fail_when_No_Id then\n        return No_Id;\n      end if;\n      --  Issue an error, severity: major (an exception is raised).\n      ID_Copy := CD.Id_with_case;\n      In_Symbol (CD);\n      if CD.Sy = Finger then\n        Error\n          (CD,\n           err_not_yet_implemented,\n           \"positional association\",\n           severity => major);\n      else\n        Error (CD, err_undefined_identifier, A2S (ID_Copy), severity => major);\n      end if;\n    end if;\n    --\n    --  From this point, the identifier ID is matched with\n    --  element J in the identifier table.\n    --\n\n    --  Name aliasing resolution (brought by a use clause\n    --  or a simple renames clause):\n    while Alias_Resolution and then CD.id_table (J).entity = alias loop\n      J := Integer (CD.id_table (J).adr_or_sz);  --  E.g. True -> Standard.True\n    end loop;\n\n    if J > Public_Filter then\n      Error (CD, err_non_public_entity, A2S (Id), severity => major);\n    end if;\n\n    --  Prefixed package resolution: `Pkg.Item`, `Pkg.Child_1.Item`, ...\n    if using_parsed_Id and then CD.id_table (J).entity = paquetage then\n      Skip_Blanks (CD);\n      if CD.CUD.c = '.' then  --  We sneak a look at the next symbol.\n        ID_Copy := Id;\n        CD.target.Mark_Reference (J);\n        CD.id_table (J).is_referenced := True;\n        --  Here some parsing: entity is a package and there is a dot waiting.\n        In_Symbol (CD);  --  Consume prefix package identifier.\n        Need (CD, Period, err_general_error);  --  Accept \"Pkg.\", reject \"Pkg..\"\n        if CD.Sy = IDent then\n          return Locate_Identifier_Internal\n            (CD,\n             ID_Copy & '.' & CD.Id,\n             True,\n             ID_Copy,\n             Level,\n             Fail_when_No_Id,\n             Alias_Resolution,\n             Level_0_Filter,\n             CD.Packages_Table (CD.id_table (J).block_or_pkg_ref).last_public_declaration);\n        end if;\n        Error (CD, err_identifier_missing, severity => major);\n      end if;\n    end if;\n\n    if J /= No_Id then\n      CD.target.Mark_Reference (J);\n      CD.id_table (J).is_referenced := True;\n    end if;\n\n    if trace_search then\n      Put_Line (+\"  Found identifier # \" & J);\n    end if;\n    return J;\n  end Locate_Identifier_Internal;\n\n  function Locate_Identifier\n    (CD               : in out Compiler_Data;\n     Id               : in     Alfa;\n     Level            : in     Defs.Nesting_Level;\n     Fail_when_No_Id  : in     Boolean := True;\n     Alias_Resolution : in     Boolean := True;\n     Level_0_Filter   : in     Boolean := True;\n     Public_Filter    : in     Index   := Index'Last)\n  return Natural\n  is\n  begin\n    return\n      Locate_Identifier_Internal\n        (CD               => CD,\n         Id               => Id,\n         using_parsed_Id  => False,       --  Extra parameter\n         Prefix_Id        => Empty_Alfa,  --  Extra parameter\n         Level            => Level,\n         Fail_when_No_Id  => Fail_when_No_Id,\n         Alias_Resolution => Alias_Resolution,\n         Level_0_Filter   => Level_0_Filter,\n         Public_Filter    => Public_Filter);\n  end Locate_Identifier;\n\n  function Locate_CD_Id\n    (CD               : in out Compiler_Data;\n     Level            : in     Defs.Nesting_Level;\n     Fail_when_No_Id  : in     Boolean := True;\n     Alias_Resolution : in     Boolean := True;\n     Level_0_Filter   : in     Boolean := True;\n     Public_Filter    : in     Index   := Index'Last)\n  return Natural\n  is\n  begin\n    if CD.Id_location = No_Id_Cache then\n      CD.Id_location :=\n        --  Note that the following call might consume several\n        --  identifiers in the case of, e.g., Pkg_1.Sub_Pkg_2.Item.\n        Locate_Identifier_Internal\n          (CD               => CD,\n           Id               => CD.Id,       --  Here we use the Id just parsed.\n           using_parsed_Id  => True,        --  Extra parameter\n           Prefix_Id        => Empty_Alfa,  --  Extra parameter\n           Level            => Level,\n           Fail_when_No_Id  => Fail_when_No_Id,\n           Alias_Resolution => Alias_Resolution,\n           Level_0_Filter   => Level_0_Filter,\n           Public_Filter    => Public_Filter);\n    else\n      --  In some cases, the same identifier token, at the same location in\n      --  source text, is parsed twice or more times.\n      --  Example:\n      --    \"for i in some_array'Range loop\": some_array is checked for\n      --     begin a subtype (in Static_Subtype_Indication) then for being\n      --     a variable (in Simple_Expression). Finally, a pair of values\n      --     are detected via the 'Range attribute.\n      null;\n    end if;\n    return CD.Id_location;\n  end Locate_CD_Id;\n\n  procedure Check_Duplicate_Specification\n    (CD         : in out Compiler_Data;\n     old_id_idx :        Natural;\n     id_current :        Alfa)\n  is\n  begin\n    if old_id_idx = No_Id then\n      return;  --  First occurrence of the specification.\n    end if;\n    Error\n      (CD, err_duplicate_identifier, \"specification of \" & A2S (id_current), severity => major);\n  end Check_Duplicate_Specification;\n\n  procedure Check_Subprogram_Spec_Body_Consistency\n    (CD         : in out Compiler_Data;\n     old_id_idx :        Natural;\n     new_id_idx :        Natural;\n     id_current :        Alfa)\n  is\n    sub_sub_last_param_idx, forward_last_param_idx,\n    sub_sub_params, forward_params : Natural;\n    use type Alfa;\n\n    procedure Check_Formal_Parameter_List is\n      procedure Check_One_to_One\n        (prefix       : String;\n         is_identical : Boolean;\n         topic        : String)\n      is\n      begin\n        if not is_identical then\n          Error\n            (CD, err_spec_body_mismatch,\n             prefix & \" has a different \" & topic,\n             severity => major);  --  This raises an exception.\n        end if;\n      end Check_One_to_One;\n\n      procedure Check_Parameter_One_to_One\n        (count        : Positive;\n         is_identical : Boolean;\n         topic        : String)\n      is\n      begin\n        Check_One_to_One\n          (\"parameter #\" & count'Image, is_identical, topic);\n      end Check_Parameter_One_to_One;\n\n      version_1, version_2 : Natural;\n    begin\n      version_1 := old_id_idx + 1;\n      version_2 := new_id_idx + 1;\n\n      for count in 1 .. sub_sub_params loop\n        Check_Parameter_One_to_One\n          (count,\n           CD.id_table (version_1).name = CD.id_table (version_2).name,\n           \"name\");\n        Check_Parameter_One_to_One\n          (count,\n           CD.id_table (version_1).xtyp = CD.id_table (version_2).xtyp,\n           \"type\");\n        Check_Parameter_One_to_One\n          (count,\n           CD.id_table (version_1).decl_kind = CD.id_table (version_2).decl_kind,\n           \"mode\");\n\n        version_1 := version_1 + 1;\n        version_2 := version_2 + 1;\n      end loop;\n\n      if CD.id_table (new_id_idx).entity = funktion then\n        Check_One_to_One\n          (\"result of function\",\n           CD.id_table (new_id_idx).xtyp = CD.id_table (old_id_idx).xtyp,\n           \"type\");\n      end if;\n    end Check_Formal_Parameter_List;\n  begin\n    if old_id_idx = No_Id then\n      return;\n    end if;\n    CD.id_table (old_id_idx).decl_kind := spec_resolved;\n    --  The following is only for making the compiler dump\n    --  easier to understand:\n    CD.Blocks_Table (CD.id_table (old_id_idx).block_or_pkg_ref).Id :=\n      S2A (\"Unused (was from a subprogram spec)\");\n    --  Check that the formal parameter list is identical:\n    sub_sub_last_param_idx :=\n      CD.Blocks_Table (CD.id_table (new_id_idx).block_or_pkg_ref).Last_Param_Id_Idx;\n    forward_last_param_idx :=\n      CD.Blocks_Table (CD.id_table (old_id_idx).block_or_pkg_ref).Last_Param_Id_Idx;\n    sub_sub_params := sub_sub_last_param_idx - new_id_idx;\n    forward_params := forward_last_param_idx - old_id_idx;\n    if sub_sub_params > forward_params then\n      Error (CD, err_number_of_parameters_do_not_match,\n             \": specification of \" & A2S (id_current) & \" has less parameters\",\n             severity => major);\n    elsif sub_sub_params < forward_params then\n      Error (CD, err_number_of_parameters_do_not_match,\n             \": specification of \" & A2S (id_current) & \" has more parameters\",\n             severity => major);\n    else\n      Check_Formal_Parameter_List;\n    end if;\n  end Check_Subprogram_Spec_Body_Consistency;\n\n  procedure Link_Forward_Declaration\n    (CD         : in out Compiler_Data;\n     old_id_idx :        Positive;\n     new_id_idx :        Positive)\n  is\n  begin\n    --  Clone key information at the new id's index (the body)\n    --  onto the data at old id's index (the specification):\n    --    * Subprogram's machine code address\n    --    * The block_ref (hence, the correct VSize\n    --        is used for reserving the stack)\n    --\n    CD.id_table (old_id_idx).adr_or_sz        := CD.id_table (new_id_idx).adr_or_sz;\n    CD.id_table (old_id_idx).block_or_pkg_ref := CD.id_table (new_id_idx).block_or_pkg_ref;\n    --\n    --  The linking is done!\n    --\n    CD.target.Mark_Spec_Body_Cross_References\n      (spec_id => old_id_idx, body_id => new_id_idx);\n  end Link_Forward_Declaration;\n\n  procedure Check_Incomplete_Definitions\n    (CD    : in out Co_Defs.Compiler_Data;\n     level :        Defs.Nesting_Level)\n  is\n    id_index : Integer := CD.Blocks_Table (CD.Display (level)).Last_Id_Idx;\n  begin\n    --  Follow the chain of identifiers for given Level:\n    while id_index /= No_Id loop\n      if CD.id_table (id_index).decl_kind = spec_unresolved\n         and then CD.id_table (id_index).entity /= entree\n      then\n        Error (CD, err_incomplete_declaration, A2S (CD.id_table (id_index).name_with_case));\n      end if;\n      id_index := CD.id_table (id_index).link;\n    end loop;\n  end Check_Incomplete_Definitions;\n\n  function Nice_Image (item : Identifier_Table_Entry) return String is\n  ((if item.decl_kind in Parameter_Kind then\n      \"parameter\"\n    else\n      (case item.entity is\n         when variable_object => \"variable\",\n         when constant_object => \"constant\",\n         when type_mark       => \"type\",\n         when prozedure       => \"procedure\",\n         when funktion        => \"function\",\n         when paquetage       => \"package\",\n         when tache           => \"task\",\n         when others          => \"item\")) &\n   \" \"\"\" & A2S (item.name_with_case) & '\"');\n\n  procedure Mark_Read_and_Check_Read_before_Written\n    (CD      : in out Compiler_Data;\n     context : in     Flow_Context;\n     item    : in out Identifier_Table_Entry)\n  is\n  begin\n    --  This is for the variable's overall lifetime analysis:\n    --\n    Elevate_to_Maybe_or_Yes (item.is_read, context);\n\n    if item.is_written_after_init = no      --  Not overwritten in a subprogram, nor in the above statements.\n       and then item.is_initialized = none  --  Not initialized, even implicitly.\n       and then context.level = item.lev    --  Not a within subprogram (uncertainty since call sequence is unknown).\n    then\n      --  By following the top-down flow, we notice that the variable or parameter\n      --  was never written until this point, including in any nested subprogram.\n      --\n      Remark\n        (CD,\n         warn_read_but_not_written,\n         Nice_Image (item) &\n         (if context.is_in_cond_within_loop then\n            --  We are within a condition, itself within a loop.\n            --  Then, we cannot be not sure that the expression is\n            --  evaluated in the first iteration of all loops.\n            \" may be\"\n          else\n            --  We are sure that the expression is evaluated\n            --  at the first iteration of all loops (if any).\n            \" is\") &\n         \" read before it is ever written\");\n    end if;\n  end Mark_Read_and_Check_Read_before_Written;\n\n  function Has_Dummy_Name (name : Alfa) return Boolean is\n  (HAT.Starts_With (name, \"DUMMY\") or else\n   HAT.Starts_With (name, \"UNUSED\") or else\n   HAT.Starts_With (name, \"JUNK\") or else\n   HAT.Starts_With (name, \"IGNORE\"));\n\n  procedure Check_Unused_or_Uninitialized_Items\n    (CD    : in out Compiler_Data;\n     level : in     Defs.Nesting_Level)\n  is\n    procedure Check_Item (item : Identifier_Table_Entry) is\n\n      already_insulted : Natural := 0;\n\n      procedure Remark_for_Declared_Item (diag : Compile_Diagnostic; text : String) is\n        remark_made : Boolean;\n      begin\n        if already_insulted < 2 then\n          Remark\n            (CD,\n             diag,\n             text,\n             location_method   => explicit,\n             explicit_location => item.location,\n             remark_made       => remark_made);\n          --\n          if remark_made then\n            already_insulted := already_insulted + 1;\n          end if;\n        end if;\n      end Remark_for_Declared_Item;\n\n      procedure Handle_Variables_and_Parameters is\n      begin\n        case item.is_written_after_init is\n\n          when no =>\n            --  Not written.\n\n            case item.is_initialized is\n\n              when none =>\n                if item.is_read = no\n                  and then item.decl_kind /= param_out\n                then\n                  --  Neither read, not written, nor initialized, and not an \"out\" parameter.\n                  --  Issue no warning. The note \"-ru\" will catch the item as unused.\n                  null;\n                else\n                  --  Neither written, nor initialized, but is maybe or surely read,\n                  --  or is an \"out\" parameter.\n                  Remark_for_Declared_Item\n                    (warn_read_but_not_written,\n                     Nice_Image (item) &\n                     (case item.is_read is\n                        when no    => \" is never written\",  --  Case reached for an \"out\" parameter.\n                        when maybe => \" is never written, but is possibly read\",\n                        when yes   => \" is read but never written\") &\n                     \"\");\n                end if;\n\n              when explicit =>\n                Remark_for_Declared_Item\n                  (note_constant_variable, Nice_Image (item) & \" is not modified, could be declared constant\");\n\n              when implicit =>\n                --  Implicitly initialized -> we don't care.\n                null;\n            end case;\n\n          when maybe .. yes =>\n\n            if item.is_read = no                    --  Maybe written after init., but not read.\n              and then item.decl_kind /= param_out  --  Don't care about \"out\" param no being read.\n              and then not Has_Dummy_Name (item.name)\n            then\n              Remark_for_Declared_Item (note_unused_item, Nice_Image (item) & \" is never read\");\n            end if;\n\n        end case;\n      end Handle_Variables_and_Parameters;\n\n      procedure Handle_Unused is\n      begin\n        --  Here we can have any explicit declaration\n        --  (object, type, subprogram, ...)\n        Remark_for_Declared_Item (note_unused_item, Nice_Image (item) & \" is not referenced\");\n      end Handle_Unused;\n\n      use type Alfa;\n\n    begin\n      if item.name = Empty_Alfa then\n        --  Zombie item, for instance a loop parameter.\n        return;\n      end if;\n\n      --  See table in \"hac_work.xls\", sheet \"Remarks\".\n\n      if item.entity = variable_object then\n        Handle_Variables_and_Parameters;\n      end if;\n\n      if item.is_referenced or else item.entity in loop_identifier | alias then\n        --  Item is used somewhere, or is a loop identifier or an alias.\n        --  In this case, don't make a note for it.\n        null;\n      else\n        Handle_Unused;\n      end if;\n    end Check_Item;\n\n    id_index : Integer := CD.Blocks_Table (CD.Display (level)).Last_Id_Idx;\n\n  begin\n    --  Follow the chain of identifiers for given Level:\n    while id_index /= No_Id loop\n      Check_Item (CD.id_table (id_index));\n      id_index := CD.id_table (id_index).link;\n    end loop;\n  end Check_Unused_or_Uninitialized_Items;\n\n  function Number_of_Parameters\n    (CD         : in out Compiler_Data;\n     id_idx     : in     Natural)\n  return Natural\n  is\n    id_table_entry : Identifier_Table_Entry renames CD.id_table (id_idx);\n    block_idx : constant Integer := id_table_entry.block_or_pkg_ref;\n  begin\n    pragma Assert (id_table_entry.entity in prozedure | funktion);\n    declare\n      block : Block_Table_Entry renames CD.Blocks_Table (block_idx);\n    begin\n      return\n        (if block.First_Param_Id_Idx > block.Last_Param_Id_Idx then\n           0\n         else\n           block.Last_Param_Id_Idx - block.First_Param_Id_Idx + 1);\n    end;\n  end Number_of_Parameters;\n\nend HAC_Sys.Parser.Helpers;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-helpers.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\npackage HAC_Sys.Parser.Helpers is\n\n  use Co_Defs, Defs;\n\n  ----------------------\n  --  Symbol testing  --\n  ----------------------\n\n  --  If needed symbol S is correct, consume it;\n  --  otherwise output error code E.\n  --\n  --  Optionally, we consume a symbol Forgive that\n  --  the programmer may have written instead of S.\n  --  For instance '[' instead of '('.\n  --\n  procedure Need\n    (CD      : in out Compiler_Data;\n     S       :        Symbol;\n     E       :        Compile_Diagnostic;\n     Forgive :        Symbol := Dummy_Symbol);\n\n  --  Issue error N, then skip all subsequent symbols\n  --  that are not in the FSys set.\n  --\n  procedure Error_then_Skip\n    (CD   : in out Compiler_Data;\n     FSys :        Symset;\n     N    :        Compile_Diagnostic;\n     hint :        String := \"\");\n\n  --  Issue error N, then skip all subsequent symbols\n  --  that are not equal to S.\n  --\n  procedure Error_then_Skip\n    (CD   : in out Compiler_Data;\n     S    :        Symbol;\n     N    :        Compile_Diagnostic;\n     hint :        String := \"\");\n\n  --  Test if current symbol is in the S1 set, otherwise\n  --  issue error N. If stop_on_error = False, we skip\n  --  subsequent symbols that are not in the union (S1 + S2).\n  --\n  procedure Test\n    (CD            : in out Compiler_Data;\n     S1, S2        :        Symset;\n     N             :        Compile_Diagnostic;\n     stop_on_error :        Boolean := False);\n\n  procedure Need_Semicolon_after_Declaration (CD : in out Compiler_Data; FSys : Symset);\n\n  procedure Need_END_Symbol (CD : in out Compiler_Data);\n\n  procedure Ignore_Extra_Semicolons (CD : in out Compiler_Data);\n\n  procedure Need_Semicolon (CD : in out Compiler_Data);\n\n  -----------------------------------\n  --  Data type checks and errors  --\n  -----------------------------------\n\n  procedure Check_Boolean (CD : in out Compiler_Data; T : Typen);\n\n  procedure Check_Integer (CD : in out Compiler_Data; T : Typen);\n\n  procedure Argument_Type_Not_Supported (CD : in out Compiler_Data);\n\n  function Nice_Exact_Image (CD : Compiler_Data; xT : Exact_Typ'Class) return String;\n\n  procedure Type_Mismatch\n    (CD               : in out Compiler_Data;\n     Err              :        Compile_Diagnostic;\n     Found, Expected  :        Exact_Typ'Class);\n\n  procedure Type_Mismatch\n    (CD       : in out Compiler_Data;\n     Err      :        Compile_Diagnostic;\n     Found    :        Exact_Subtyp;\n     Expected :        Typ_Set);\n\n  function Op_Hint (OP : Symbol) return String;\n\n  procedure Issue_Undefined_Operator_Error  --  Unary\n    (CD       : in out Compiler_Data;\n     Operator :        Symbol;\n     Right    :        Exact_Subtyp);\n\n  procedure Issue_Undefined_Operator_Error  --  Binary\n    (CD          : in out Compiler_Data;\n     Operator    :        Symbol;\n     Left, Right :        Exact_Subtyp);\n\n  --  https://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion\n  --  One of the most useful feature of Ada is the absence of type coercion.\n  --  Note from the Python 2.5 doc:\n  --  \"In Python 3.0, coercion will not be supported.\"\n  --\n  procedure Forbid_Type_Coercion\n    (CD          : in out Compiler_Data;\n     Operator    :        Symbol;\n     Left, Right :        Exact_Subtyp);\n\n  procedure Forbid_Type_Coercion\n    (CD              : in out Compiler_Data;\n     Found, Expected :        Exact_Subtyp);\n\n  ------------------------------------\n  --  Symbol sets used for parsing  --\n  ------------------------------------\n\n  --  Singletons:\n\n  function Singleton (s : Symbol) return Symset;\n\n  --  Specific singletons:\n\n  Becomes_Set   : constant Symset := (Becomes    => True, others => False);\n  Colon_Set     : constant Symset := (Colon      => True, others => False);\n  END_Set       : constant Symset := (END_Symbol => True, others => False);\n  IDent_Set     : constant Symset := (IDent      => True, others => False);\n  RParent_Set   : constant Symset := (RParent    => True, others => False);\n  Semicolon_Set : constant Symset := (Semicolon  => True, others => False);\n\n  --  Specific sets:\n\n  Alt_Finger_THEN : constant Symset :=\n    --  For \"WHEN\" in CASE statements (\"THEN\" is wrong,\n    --  but that error is processed specifically).\n    (Alt | Finger | THEN_Symbol => True, others => False);\n\n  Becomes_Comma_IDent_Semicolon : constant Symset :=\n    (Semicolon | Comma | IDent | Becomes => True, others => False);\n\n  Becomes_EQL_Semicolon : constant Symset :=\n    (Becomes | EQL | Semicolon => True, others => False);\n\n  Becomes_EQL : constant Symset :=\n    (Becomes | EQL => True, others => False);\n\n  Colon_Comma_LParent_RParent_Semicolon : constant Symset :=\n    (Colon | Comma | LParent | RParent | Semicolon => True, others => False);\n\n  Colon_Comma_RParent : constant Symset :=\n    (Colon | Comma | RParent => True, others => False);\n\n  Colon_Comma_IS_OF : constant Symset :=\n    (Colon | Comma | IS_Symbol | OF_Symbol => True, others => False);\n\n  Comma_END_IDent_Semicolon : constant Symset :=\n    (Comma | END_Symbol | IDent | Semicolon => True, others => False);\n\n  Comma_IDent_Semicolon : constant Symset :=\n    (Comma | IDent | Semicolon => True, others => False);\n\n  Comma_IDent_RParent_Semicolon : constant Symset :=\n    (Comma | IDent | RParent | Semicolon => True, others => False);\n\n  Comma_OF_RParent : constant Symset :=\n    (Comma | RParent | OF_Symbol => True, others => False);\n\n  Comma_RParent : constant Symset :=\n    (Comma | RParent => True, others => False);\n\n  DO_LOOP : constant Symset :=\n    (DO_Symbol | LOOP_Symbol => True, others => False);\n\n  DO_THEN : constant Symset :=\n    (DO_Symbol | THEN_Symbol => True, others => False);\n\n  ELSE_ELSIF_END : constant Symset :=\n    (ELSE_Symbol | ELSIF_Symbol | END_Symbol => True, others => False);\n\n  ELSE_END_OR : constant Symset :=\n    (ELSE_Symbol | END_Symbol | OR_Symbol => True, others => False);\n\n  ELSE_OR : constant Symset :=\n    (ELSE_Symbol | OR_Symbol => True, others => False);\n\n  END_IDent_Semicolon : constant Symset :=\n    (END_Symbol | IDent | Semicolon => True, others => False);\n\n  END_LOOP_RANGE_Double_Dot : constant Symset :=\n    (END_Symbol | LOOP_Symbol | Range_Double_Dot_Symbol => True, others => False);\n\n  END_LOOP_Semicolon : constant Symset :=\n    (END_Symbol | LOOP_Symbol | Semicolon => True, others => False);\n\n  END_WHEN : constant Symset :=\n    (END_Symbol | WHEN_Symbol => True, others => False);\n\n  OF_RANGE_Double_Dot_RParent : constant Symset :=\n    (OF_Symbol | Range_Double_Dot_Symbol | RParent => True, others => False);\n\n  --  Other sets, named by their context:\n\n  After_Subprogram_Parameters : constant Symset :=\n    (IS_Symbol | RETURN_Symbol | Semicolon | WITH_Symbol => True, others => False);\n\n  Block_Begin_Symbol : constant Symset :=\n   (PROCEDURE_Symbol |\n    FUNCTION_Symbol  |\n    TASK_Symbol      |\n    ENTRY_Symbol     |\n    BEGIN_Symbol     |\n    DECLARE_Symbol   => True,\n    others           => False);\n\n  Constant_Definition_Begin_Symbol : constant Symset :=\n   (Plus              |\n    Minus             |\n    integer_literal   |\n    real_literal      |\n    character_literal |\n    IDent             => True,\n    others            => False);\n\n  Declaration_X_Subprogram_Symbol : constant Symset :=\n    (IDent          |\n     PACKAGE_Symbol |\n     SUBTYPE_Symbol |\n     TYPE_Symbol    |\n     TASK_Symbol    |\n     USE_Symbol     => True,\n     others         => False);\n\n  Declaration_Symbol : constant Symset :=\n    Declaration_X_Subprogram_Symbol +\n    (PROCEDURE_Symbol |\n     FUNCTION_Symbol  => True,\n     others           => False);\n\n  Primary_Begin_Symbol : constant Symset :=\n   (integer_literal   |\n    real_literal      |\n    character_literal |\n    string_literal    |\n    IDent             |\n    LParent           => True,\n    others            => False);\n\n  Fail_after_FOR : constant Symset :=\n    (IN_Symbol               |\n     Range_Double_Dot_Symbol |\n     LOOP_Symbol             |\n     END_Symbol              => True,\n     others                  => False);\n\n  Plus_Minus_Set : constant Symset :=\n    (Plus_Minus => True, others => False);\n\n  Selector_Symbol : constant Symset :=\n    (LParent | Period => True, others => False);\n\n  Selector_Symbol_Loose : constant Symset :=\n    (LBrack | LParent | Period => True, others => False);\n\n  Statement_Begin_Symbol : constant Symset :=\n   (IDent          |\n    BEGIN_Symbol   |\n    DECLARE_Symbol |\n    IF_Symbol      |\n    WHILE_Symbol   |\n    LOOP_Symbol    |\n    FOR_Symbol     |\n    CASE_Symbol    |\n    EXIT_Symbol    |\n    NULL_Symbol    |\n    RETURN_Symbol  |\n    SELECT_Symbol  |\n    ACCEPT_Symbol  |\n    DELAY_Symbol   => True,\n    others         => False);\n\n  Symbols_after_Subprogram_Identifier : constant Symset :=\n    (LParent | RETURN_Symbol | IS_Symbol | Semicolon |\n     WITH_Symbol  --  Aspect\n     => True,\n     others => False);\n\n  Type_Begin_Symbol : constant Symset :=\n   (ABSTRACT_Symbol | ACCESS_Symbol | ARRAY_Symbol |\n    DIGITS_Symbol | DELTA_Symbol |\n    INTERFACE_Symbol | LIMITED_Symbol |\n    NOT_Symbol |  --  For \"not null\" (null_exclusion)\n    NEW_Symbol |\n    PRIVATE_Symbol | PROTECTED_Symbol |\n    RANGE_Keyword_Symbol | RECORD_Symbol |\n    SYNCHRONIZED_Symbol |\n    TASK_Symbol | TAGGED_Symbol |\n    LParent        => True,\n    others         => False);\n\n  Subtype_Begin_Symbol : constant Symset :=\n   (IDent      |\n    NOT_Symbol => True,  --  For \"not null\" (null_exclusion)\n    others     => False);\n\n  ------------------\n  --  Types sets  --\n  ------------------\n\n  function Singleton (t : Typen) return Typ_Set with Inline;\n\n  Numeric_Typ_Set  : constant Typ_Set := (Numeric_Typ         => True, others => False);\n  Bools_Set        : constant Typ_Set := (Bools               => True, others => False);\n  Chars_Set        : constant Typ_Set := (Chars               => True, others => False);\n  Ints_Set         : constant Typ_Set := (Ints                => True, others => False);\n  Floats_Set       : constant Typ_Set := (Floats              => True, others => False);\n  Arrays_Set       : constant Typ_Set := (Arrays              => True, others => False);\n  VStrings_Set     : constant Typ_Set := (VStrings            => True, others => False);\n  Times_Set        : constant Typ_Set := (Times               => True, others => False);\n  Durations_Set    : constant Typ_Set := (Durations           => True, others => False);\n  Text_Files_Set   : constant Typ_Set := (Text_Files          => True, others => False);\n  Str_Lit_Set      : constant Typ_Set := (String_Literals     => True, others => False);\n  Str_as_VStr_Set  : constant Typ_Set := (Strings_as_VStrings => True, others => False);\n\n  Standard_Set                : constant Typ_Set := (Standard_Typ => True, others => False);\n  PCode_Atomic_Comparable_Typ : constant Typ_Set := Discrete_Typ or Numeric_Typ_Set or VStrings_Set;\n  PCode_Atomic_Nonlimited_Typ : constant Typ_Set := (Standard_Set or Discrete_Typ) and not Text_Files_Set;\n  Text_IO_Get_Item_Set        : constant Typ_Set := (Standard_Set and not Bools_Set) or Arrays_Set;\n\n  --  RM 3.2 (3):\n  Scalar_Set : constant Typ_Set :=\n    (Ints | Floats | Durations | Chars | Bools | Enums => True, others => False);\n\n  Internally_VString_Set : constant Typ_Set := VStrings_Set or Str_as_VStr_Set;\n\n  ------------------\n  --  Base types  --\n  ------------------\n\n  Standard_Integer : constant Exact_Subtyp := (Ints, 0, False, HAC_Integer'First, HAC_Integer'Last);\n\n  -------------\n  --  Misc.  --\n  -------------\n\n  --  Check if we have an \"array of Character\", for instance a String.\n  --\n  function Is_Char_Array (CD : Compiler_Data; T : Exact_Subtyp) return Boolean;\n\n  --  Convert a string of any kind sitting on stack top to VString.\n  procedure Check_any_String_and_promote_to_VString\n    (CD : in out Compiler_Data; X : in out Exact_Subtyp; include_characters : Boolean);\n\n  ------------------------------------------------------------------\n  ------------------------------------------------Locate_Identifier-\n  --\n  --   - Aliases are resolved (True -> Standard.True).\n  --   - Parsing continues on each \"package_name.\": e.g. on \"Pkg.\",\n  --       parser will parse \"Pkg.Child_Pkg.Sub_pkg.Var.X\" until the\n  --       non-package entity: \"Var\".\n  --\n  function Locate_Identifier\n    (CD               : in out Compiler_Data;\n     Id               : in     Alfa;\n     Level            : in     Defs.Nesting_Level;\n     Fail_when_No_Id  : in     Boolean := True;\n     Alias_Resolution : in     Boolean := True;\n     Level_0_Filter   : in     Boolean := True;\n     Public_Filter    : in     Index   := Index'Last)\n  return Natural;\n\n  function Locate_CD_Id\n    (CD               : in out Compiler_Data;\n     Level            : in     Defs.Nesting_Level;\n     Fail_when_No_Id  : in     Boolean := True;\n     Alias_Resolution : in     Boolean := True;\n     Level_0_Filter   : in     Boolean := True;\n     Public_Filter    : in     Index   := Index'Last)\n  return Natural;\n\n  procedure Check_Duplicate_Specification\n    (CD         : in out Compiler_Data;\n     old_id_idx :        Natural;\n     id_current :        Alfa);\n\n  procedure Check_Subprogram_Spec_Body_Consistency\n    (CD         : in out Compiler_Data;\n     old_id_idx :        Natural;\n     new_id_idx :        Natural;\n     id_current :        Alfa);\n\n  procedure Link_Forward_Declaration\n    (CD         : in out Compiler_Data;\n     old_id_idx :        Positive;\n     new_id_idx :        Positive);\n\n  procedure Check_Incomplete_Definitions\n    (CD    : in out Co_Defs.Compiler_Data;\n     level :        Defs.Nesting_Level);\n\n  --  Check initialization of a variable or parameter\n  --  when read in an expression.\n  --\n  procedure Mark_Read_and_Check_Read_before_Written\n    (CD      : in out Compiler_Data;\n     context : in     Flow_Context;\n     item    : in out Identifier_Table_Entry);\n\n  --  Check usage of variables and parameters\n  --  after the last statement.\n  --\n  procedure Check_Unused_or_Uninitialized_Items\n    (CD    : in out Compiler_Data;\n     level : in     Defs.Nesting_Level);\n\n  function Number_of_Parameters\n    (CD         : in out Compiler_Data;\n     id_idx     : in     Natural)\n  return Natural;\n\nend HAC_Sys.Parser.Helpers;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-modularity.adb",
    "content": "with HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Packages,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Modularity is\n\n  procedure With_Clause   --  10.1.2 (4)\n    (CD : in out Co_Defs.Compiler_Data;\n     LD : in out Librarian.Library_Data)\n  is\n    use Defs, Scanner, Errors;\n  begin\n    In_Symbol (CD);  --  Consume \"with\".\n    loop\n      if CD.Sy /= IDent then\n        Error (CD, err_identifier_missing, severity => major);\n      end if;\n      --\n      --  TBD: parse '.' for child units, like Locate_Identifier_Internal\n      --  with `using_parsed_Id` = True\n      --\n      Librarian.Apply_WITH (CD, LD, A2S (CD.Id));\n      In_Symbol (CD);  --  Consume the identifier.\n      exit when CD.Sy = Semicolon;\n      Helpers.Need (CD, Comma, err_general_error);\n    end loop;\n    In_Symbol (CD);  --  Consume the ';'.\n  end With_Clause;\n\n  procedure Context_Clause\n    (CD : in out Co_Defs.Compiler_Data;\n     LD : in out Librarian.Library_Data)\n  is\n    use Defs, Librarian;\n  begin\n    loop\n      case CD.Sy is\n        when WITH_Symbol => With_Clause (CD, LD);\n        when USE_Symbol  => Packages.Use_Clause (CD, Library_Level, False);\n        when others => exit;\n      end case;\n    end loop;\n  end Context_Clause;\n\nend HAC_Sys.Parser.Modularity;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-modularity.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Librarian;\n\npackage HAC_Sys.Parser.Modularity is\n\n  --  Context clause, 10.1.2.\n  --\n  --  Parse the bunch of \"with\" and \"use\" before a library level\n  --  unit (which can be a subprogram or a package).\n  --  Referenced units (specifications or body-only) are compiled if\n  --  necessary, or reactivated as library level definitions.\n  --\n  procedure Context_Clause\n    (CD : in out Co_Defs.Compiler_Data;\n     LD : in out Librarian.Library_Data);\n\nend HAC_Sys.Parser.Modularity;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-packages.adb",
    "content": "with HAC_Sys.Errors,\n     HAC_Sys.Parser.Const_Var,\n     HAC_Sys.Parser.Enter_Def,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Tasking,\n     HAC_Sys.Parser.Type_Def,\n     HAC_Sys.Scanner;\n\nwith HAT;\n\npackage body HAC_Sys.Parser.Packages is\n\n  ---------------------------\n  --  Package_Declaration  --\n  ---------------------------\n\n  procedure Package_Declaration (\n    CD         : in out Co_Defs.Compiler_Data;\n    FSys       :        Defs.Symset;\n    block_data : in out Block_Data_Type;\n    needs_body :    out Boolean\n  )\n  is\n    use Co_Defs, Defs, Errors, HAT, Helpers;\n    use type HAC_Integer;\n    package_name           : constant Alfa    := CD.Id;\n    package_name_with_case : constant Alfa    := CD.Id_with_case;\n    package_id_index       : constant Natural := CD.Id_Count;\n    previous_pkg_prefix    : constant VString := CD.pkg_prefix;\n    subpkg_needs_body : Boolean;\n    in_private : Boolean := False;\n    dummy_forward : Natural;\n    current_pkg_table_index : Positive;\n    subprogram_kind : Declaration_Kind;\n    --\n    procedure Mark_Last_Declaration is\n    begin\n      if CD.Id_Count > package_id_index then\n        if in_private then\n          CD.Packages_Table (current_pkg_table_index).last_private_declaration := CD.Id_Count;\n        else\n          CD.Packages_Table (current_pkg_table_index).last_public_declaration := CD.Id_Count;\n        end if;\n      end if;\n    end Mark_Last_Declaration;\n    --\n  begin\n    Feed_Packages_Table (CD);\n    --  CD.Packages_Count can be incremented further during\n    --  this procedure due to subpackages, so we need to memorize it.\n    current_pkg_table_index := CD.Packages_Count;\n    --\n    Scanner.In_Symbol (CD);  --  Absorb the identifier symbol. !! We need more for child packages.\n    Need (CD, IS_Symbol, err_IS_missing);\n    --  Set new prefix, support also possible subpackages:\n    CD.pkg_prefix := CD.pkg_prefix & A2S (package_name) & '.';\n    Increment_Nesting_or_Descending_Level (CD);\n    needs_body := False;\n    loop\n      Test (\n        CD, Declaration_Symbol + END_Symbol + PRIVATE_Symbol,\n        empty_symset,\n        err_incorrectly_used_symbol,\n        stop_on_error => True  --  Exception is raised there if there is an error.\n      );\n      case CD.Sy is\n\n        when IDent =>\n          if block_data.context.level = 0 then\n            Error\n              (CD,\n               err_not_yet_implemented,\n               \"variables and constants in packages at library level\",\n               severity => major);\n          end if;\n          Const_Var.Var_Declaration (CD, FSys, block_data);\n          Mark_Last_Declaration;\n\n        when TYPE_Symbol | SUBTYPE_Symbol =>\n          Type_Def.Type_or_Subtype_Declaration (CD, block_data.context.level, FSys + END_Symbol);\n          Mark_Last_Declaration;\n\n        when TASK_Symbol =>\n          Tasking.Task_Declaration (CD, FSys, block_data.context.level);\n          Mark_Last_Declaration;\n\n        when USE_Symbol =>\n          Use_Clause (CD, block_data.context.level, True);\n\n        when PROCEDURE_Symbol | FUNCTION_Symbol =>\n          Subprogram_Declaration_or_Body (CD, FSys, block_data.context.level, subprogram_kind);\n          if subprogram_kind = complete then\n            Error\n              (CD, err_general_error,\n               \"subprogram body not allowed in package specification\",\n               severity => major);\n          end if;\n          if block_data.context.level = 0 then\n            Scanner.In_Symbol (CD);  --  Consume ';' symbol after END [Subprogram_Id].\n          end if;\n          needs_body := True;\n          Mark_Last_Declaration;\n        when PACKAGE_Symbol =>\n          --  Subpackage:\n          Scanner.In_Symbol (CD);\n          case CD.Sy is\n            when BODY_Symbol =>\n              Error\n                (CD, err_general_error,\n                 \"subpackage body not allowed in package specification\",\n                 severity => major);\n            when IDent =>\n              null;  --  Good!\n            when others =>\n              Error (CD, err_identifier_missing, severity => major);\n          end case;\n          Enter_Def.Enter_Prefixed (CD, block_data.context.level, CD.Id, CD.Id_with_case, paquetage, dummy_forward);\n          CD.id_table (CD.Id_Count).decl_kind := spec_resolved;\n          --  Why spec_resolved ? missing bodies for possible suprograms\n          --  in that package are checked anyway.\n          Package_Declaration (CD, FSys, block_data, subpkg_needs_body);\n          Need_Semicolon_after_Declaration (CD, FSys);\n          needs_body := needs_body or subpkg_needs_body;\n          Mark_Last_Declaration;\n        when PRIVATE_Symbol =>\n          Scanner.In_Symbol (CD);\n          if in_private then\n            Error (CD, err_general_error, \"only one private part allowed per package\");\n          end if;\n          in_private := True;\n        when others => null;\n      end case;\n      exit when CD.Sy = END_Symbol;\n    end loop;\n    Scanner.In_Symbol (CD);  --  Absorb END symbol\n    if CD.Sy = IDent then\n      --  !! For supporting child package names (\"x.y.z\"), reuse/share Check_ident_after_END\n      if CD.Id /= package_name then\n        Error\n          (CD, err_incorrect_name_after_END,\n           hint_1 => A2S (package_name_with_case),\n           severity => minor\n          );\n      end if;\n      Scanner.In_Symbol (CD);  --  Absorb identifier symbol\n    end if;\n    --  Test semicolon but don't absorb it (we might be at the end of the stream).\n    Test\n       (CD, Semicolon_Set,\n        empty_symset,\n        err_incorrectly_used_symbol,\n        stop_on_error => True);  --  Exception is raised there if there is an error.\n    CD.pkg_prefix := previous_pkg_prefix;\n    Decrement_Nesting_or_Descending_Level (CD);\n  end Package_Declaration;\n\n  --------------------\n  --  Package_Body  --\n  --------------------\n\n  procedure Package_Body (\n    CD         : in out Co_Defs.Compiler_Data;\n    FSys       :        Defs.Symset;\n    block_data : in out Block_Data_Type\n  )\n  is\n    use Co_Defs, Defs, Errors, HAT, Helpers;\n    use type HAC_Integer;\n    package_name           : constant Alfa    := CD.Id;\n    package_name_with_case : constant Alfa    := CD.Id_with_case;\n    previous_pkg_prefix    : constant VString := CD.pkg_prefix;\n    --\n    last_id : constant Defs.Index := CD.Blocks_Table (CD.Display (block_data.context.level)).Last_Id_Idx;\n    --\n    subprogram_kind                    : Declaration_Kind;\n    pkg_spec_index                     : Natural;\n    subpkg_needs_body, subpackage_body : Boolean;\n    subpkg_kind                        : Entity_Kind;\n  begin\n    Scanner.In_Symbol (CD);  --  Absorb the identifier symbol. !! We need more for child packages.\n    Need (CD, IS_Symbol, err_IS_missing);\n    CD.pkg_prefix := CD.pkg_prefix & A2S (package_name) & '.';\n    Increment_Nesting_or_Descending_Level (CD);\n    loop\n      Test (\n        CD, Declaration_Symbol + BEGIN_Symbol + END_Symbol + PRIVATE_Symbol,\n        empty_symset,\n        err_incorrectly_used_symbol,\n        stop_on_error => True  --  Exception is raised there if there is an error.\n      );\n      case CD.Sy is\n        when IDent =>\n          if block_data.context.level = 0 then\n            Error\n              (CD,\n               err_not_yet_implemented,\n               \"variables and constants in packages at library level\",\n               severity => major);\n          end if;\n          Const_Var.Var_Declaration (CD, FSys, block_data);\n\n        when TYPE_Symbol |\n             SUBTYPE_Symbol =>\n          Type_Def.Type_or_Subtype_Declaration (CD, block_data.context.level, FSys + END_Symbol);\n\n        when TASK_Symbol =>\n          Tasking.Task_Declaration (CD, FSys, block_data.context.level);\n\n        when USE_Symbol =>\n          Use_Clause (CD, block_data.context.level, False);\n\n        when PROCEDURE_Symbol | FUNCTION_Symbol =>\n          Subprogram_Declaration_or_Body (CD, FSys, block_data.context.level, subprogram_kind);\n          if block_data.context.level = 0 then\n            Scanner.In_Symbol (CD);  --  Consume ';' symbol after END [Subprogram_Id].\n          end if;\n\n        when PACKAGE_Symbol =>\n          --  Subpackage inside a package body.\n          --  Subpackage can be spec & body, or just a spec, or the body of\n          --  a spec defined in the parent package...\n          Scanner.In_Symbol (CD);\n          subpackage_body := False;\n          subpkg_kind := paquetage;\n          if CD.Sy = BODY_Symbol then\n            Scanner.In_Symbol (CD);\n            subpackage_body := True;\n            subpkg_kind := paquetage_body;\n          end if;\n          if CD.Sy /= IDent then\n            Error (CD, err_identifier_missing, severity => major);\n          end if;\n          Enter_Def.Enter_Prefixed (CD, block_data.context.level, CD.Id, CD.Id_with_case, subpkg_kind, pkg_spec_index);\n          if subpackage_body then\n            if pkg_spec_index = No_Id then\n              Error\n                (CD, err_general_error,\n                 \"missing specification for package body\", severity => major);\n            end if;\n            CD.id_table (CD.Id_Count).block_or_pkg_ref := CD.id_table (pkg_spec_index).block_or_pkg_ref;\n            Package_Body (CD, FSys, block_data);\n          else\n            CD.id_table (CD.Id_Count).decl_kind := spec_resolved;\n            --  Why spec_resolved ? missing bodies for possible suprograms\n            --  in that package are checked anyway.\n            Package_Declaration (CD, FSys, block_data, subpkg_needs_body);\n          end if;\n          --  !!  Do something with subpkg_needs_body ...\n          Need_Semicolon_after_Declaration (CD, FSys);\n        when PRIVATE_Symbol =>\n          Error (CD, err_general_error, \"\"\"private\"\" belongs to specification\");\n          Scanner.In_Symbol (CD);\n        when others => null;\n      end case;\n      exit when CD.Sy = BEGIN_Symbol or CD.Sy = END_Symbol;\n    end loop;\n    if CD.Sy = BEGIN_Symbol then\n      Error (CD, err_not_yet_implemented, \"initialisation part in packages\", severity => major);\n    end if;\n    Scanner.In_Symbol (CD);  --  Absorb END symbol\n    if CD.Sy = IDent then\n      --  !! For supporting child package names (\"x.y.z\"), reuse/share Check_ident_after_END\n      if CD.Id /= package_name then\n        Error\n          (CD, err_incorrect_name_after_END,\n           hint_1 => A2S (package_name_with_case),\n           severity => minor\n          );\n      end if;\n      Scanner.In_Symbol (CD);  --  Absorb identifier symbol\n    end if;\n    --  Test semicolon but don't absorb it (we might be at the end of the stream).\n    Test\n       (CD, Semicolon_Set,\n        empty_symset,\n        err_incorrectly_used_symbol,\n        stop_on_error => True);  --  Exception is raised there if there is an error.\n\n    CD.pkg_prefix := previous_pkg_prefix;\n    --  Make body's declarations unreachable in identifier chain.\n    CD.Blocks_Table (CD.Display (block_data.context.level)).Last_Id_Idx := last_id;\n    Decrement_Nesting_or_Descending_Level (CD);\n  end Package_Body;\n\n  procedure Use_Clause\n    (CD       : in out Co_Defs.Compiler_Data;\n     Level    :        Defs.Nesting_Level;\n     prefixed :        Boolean)\n  is  --  8.4 (2)\n    use Defs, Scanner, Errors;\n  begin\n    In_Symbol (CD);  --  Consume \"use\".\n    loop\n      if CD.Sy /= IDent then\n        Error (CD, err_identifier_missing, severity => major);\n      end if;\n      Apply_USE_Clause (CD, Level, prefixed, Helpers.Locate_CD_Id (CD, Level));\n      In_Symbol (CD);  --  Consume the identifier.\n      exit when CD.Sy = Semicolon;\n      Helpers.Need (CD, Comma, err_general_error);\n    end loop;\n    In_Symbol (CD);  --  Consume the ';'.\n  end Use_Clause;\n\n  procedure Apply_USE_Clause\n    (CD       : in out Co_Defs.Compiler_Data;\n     Level    : in     Defs.Nesting_Level;\n     prefixed :        Boolean;\n     Pkg_Idx  : in     Natural)  --  Index in the identifier table for USEd package.\n  is\n    use Co_Defs, Defs, Parser.Enter_Def, Errors;\n    use type Nesting_Level;\n    Pkg_UName : constant String := A2S (CD.id_table (Pkg_Idx).name);\n    Id_Alias, dummy_id_idx : Natural;\n    pkg_table_index : Positive;\n    pkg_level : Nesting_Level;\n    --\n    procedure Issue_Duplicate_Use_Note is\n    begin\n      if Pkg_UName = \"STANDARD\" then\n        --  For a unit's body, a \"USE Standard\" is applied while it\n        --  was already applied for its spec (so it is superfluous).\n        --  We still choose to do the USE because some unit bodies\n        --  may not have a spec.\n        null;\n      else\n        Remark\n          (CD,\n           note_redundant_construct,\n           \"\"\"use\"\" clause already applied, in same declarative part, for\" &\n           \" package \"\"\" & A2S (CD.id_table (Pkg_Idx).name_with_case) & '\"');\n      end if;\n    end Issue_Duplicate_Use_Note;\n  begin\n    pragma Assert (Pkg_Idx > No_Id);\n    if CD.id_table (Pkg_Idx).entity /= paquetage then\n      Error (CD, err_general_error, \"package name expected\", severity => major);\n    end if;\n    if CD.id_table (Pkg_Idx).lev = 0 and then Pkg_UName = HAT_Name then\n      --  We are USE-ing the HAT package, thus opening the visibility of operators.\n      CD.CUD.Use_HAT_Stack (CD.CUD.use_hat_stack_top) := True;\n    end if;\n    pkg_level := CD.id_table (Pkg_Idx).lev;\n    --  The package specification's definitions begins immediately after the\n    --  package's identifier.\n    --  E.g. HAT: PAQUETAGE; HAT.File_Type: TYPEMARK; ...\n    --\n    pkg_table_index := CD.id_table (Pkg_Idx).block_or_pkg_ref;\n    --\n    for i in CD.Packages_Table (pkg_table_index).first_public_declaration ..\n             CD.Packages_Table (pkg_table_index).last_public_declaration\n    loop\n      if CD.id_table (i).lev = pkg_level then\n        --  Subprogram parameters are not declarations of\n        --  the package and have a higher nesting level.\n        declare\n          Full_UName : constant String := A2S (CD.id_table (i).name);\n          Full_Name  : String (Full_UName'Range);\n          Start : Positive;\n        begin\n          --  We have spotted an item with the correct prefix.\n          --  E.g. \"STANDARD.FALSE\" has the matching prefix \"STANDARD.\",\n          --  or we have the item \"ADA.STRINGS.FIXED.INDEX\" and\n          --  the prefix \"ADA.STRINGS.FIXED.\".\n          Start := Full_UName'First + Pkg_UName'Length + 1;\n          Full_Name := A2S (CD.id_table (i).name_with_case);\n          declare\n            Short_Id_str : constant String := Full_UName (Start .. Full_UName'Last);\n            Short_Id     : constant Alfa := S2A (Short_Id_str);  --  Id as visible after USE.\n          begin\n            --  Check if there is already this identifier, even as\n            --  a library level invisible definition.\n            --  If not, we do a \"FROM Pkg IMPORT Short_Id\" as you\n            --  would do in Modula-2 or Python.\n            Id_Alias := Parser.Helpers.Locate_Identifier\n              (CD               => CD,\n               Id               => Short_Id,\n               Level            => Level,\n               Fail_when_No_Id  => False,\n               Alias_Resolution => False,\n               Level_0_Filter   => False);\n              --  ^ We search any matching name, including an inactive\n              --    name at library level.\n\n            if Id_Alias = No_Id or else CD.id_table (Id_Alias).lev < Level then\n              --  Name was not found, or was defined at a lower nesting level.\n              --  We enter, e.g. the \"FALSE\", \"False\" pair.\n              Enter\n                (CD,\n                 Level,\n                 prefixed,\n                 Short_Id,\n                 S2A (Full_Name (Start .. Full_Name'Last)),\n                 alias,\n                 dummy_id_idx);\n              CD.id_table (CD.Id_Count).adr_or_sz := HAC_Integer (i);\n              --  ^ i = Aliased entity's index.\n            else\n              --  Here we have found an identical and\n              --  visible short identifier at the same level.\n              if CD.id_table (Id_Alias).entity = alias\n                and then CD.id_table (Id_Alias).adr_or_sz = HAC_Integer (i)\n              then\n                --  Here we have an identical alias (same name, and points\n                --  to the same definition).\n                if Level > 0 then\n                  Issue_Duplicate_Use_Note;\n                  exit;\n                else\n                  --  Level 0 here.\n                  if CD.CUD.level_0_def.Contains (Short_Id) then\n                    Issue_Duplicate_Use_Note;\n                    exit;\n                  else\n                    --  Re-activate definition at zero level (context clause).\n                    CD.CUD.level_0_def.Include (Short_Id, Id_Alias);\n                    --  HAT.PUT_LINE (\"Activate USEd item: \" & Short_Id_str);\n                  end if;\n                end if;\n              end if;\n            end if;\n          end;\n        end;\n      end if;\n    end loop;\n  end Apply_USE_Clause;\n\n  procedure Feed_Packages_Table (CD : in out Co_Defs.Compiler_Data) is\n  begin\n    CD.Packages_Count := CD.Packages_Count + 1;\n    CD.id_table (CD.Id_Count).block_or_pkg_ref := CD.Packages_Count;\n    declare\n      p : Co_Defs.Package_Table_Entry renames CD.Packages_Table (CD.Packages_Count);\n    begin\n      p.first_public_declaration := CD.Id_Count + 1;\n      p.last_public_declaration  := 0;\n      p.last_private_declaration := 0;\n    end;\n  end Feed_Packages_Table;\n\nend HAC_Sys.Parser.Packages;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-packages.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Co_Defs,\n     HAC_Sys.Defs;\n\npackage HAC_Sys.Parser.Packages is\n\n  --------------------------------------------------------------------------\n  --  Parse a package right after the \"PACKAGE name\" symbol sequence.     --\n  --  `name` has been entered in the identifier table as \"Paquetage\"      --\n  --  kind, either as a library-level declaration and library item,       --\n  --  or a declaration which is local to a subprogram.                    --\n  --------------------------------------------------------------------------\n\n  procedure Package_Declaration (\n    CD         : in out Co_Defs.Compiler_Data;\n    FSys       :        Defs.Symset;\n    block_data : in out Block_Data_Type;\n    needs_body :    out Boolean\n  );\n\n  ------------------------------------------------------------------\n  --  Parse a package's body right after the \"PACKAGE BODY name\"  --\n  --  symbol sequence.                                            --\n  ------------------------------------------------------------------\n\n  procedure Package_Body (\n    CD         : in out Co_Defs.Compiler_Data;\n    FSys       :        Defs.Symset;\n    block_data : in out Block_Data_Type\n  );\n\n  ----------------------------------------------------------------------\n  --  Parse Use clause.                                               --\n  --  It is either part of a context clause, or a local declaration.  --\n  --  RM 8.4 (2)                                                      --\n  ----------------------------------------------------------------------\n\n  procedure Use_Clause\n    (CD       : in out Co_Defs.Compiler_Data;\n     Level    :        Defs.Nesting_Level;\n     prefixed :        Boolean);\n\n  -------------------------------------------------\n  --  Apply the USE clause at any nesting level  --\n  -------------------------------------------------\n\n  procedure Apply_USE_Clause\n    (CD       : in out Co_Defs.Compiler_Data;\n     Level    : in     Defs.Nesting_Level;\n     prefixed :        Boolean;\n     Pkg_Idx  : in     Natural);  --  Index in the identifier table for USEd package.\n\n  ------------------------------------------\n  --  Feed the compiler's packages table  --\n  ------------------------------------------\n\n  procedure Feed_Packages_Table (CD : in out Co_Defs.Compiler_Data);\n\nend HAC_Sys.Parser.Packages;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-ranges.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Ranges is\n\n  --  Are we sitting on the identifier of a discrete subtype\n  --  like \"Color\" in \"Color [range red .. blue]\" ?\n  --  In that case, we return the range red .. blue.\n  --\n  procedure Static_Subtype_Indication  --  RM 3.2.2\n    (CD        : in out Co_Defs.Compiler_Data;\n     Level     : in     Defs.Nesting_Level;\n     Low, High :    out Co_Defs.Constant_Rec;\n     Found     :    out Boolean)\n  is\n    Idx : Integer;\n    use Co_Defs, Defs, Helpers, Scanner;\n  begin\n    Found := False;\n    if CD.Sy /= IDent then\n      return;  --  Perhaps we have a number like \"1\" in \"1 .. 3\", or something wrong.\n    end if;\n    Idx := Locate_CD_Id (CD, Level);\n    if Idx /= No_Id then\n      declare\n        Id_T : Identifier_Table_Entry renames CD.id_table (Idx);\n      begin\n        if Id_T.entity = type_mark and then Discrete_Typ (Id_T.xtyp.TYP) then\n          --  Subtype S, but need to exclude the attribute case: S'First, S'Image, ...\n          Skip_Blanks (CD);\n          --  We sneak a look at the next symbol:\n          if CD.CUD.c /= ''' then\n            --  Not a S'... attribute here.\n            In_Symbol (CD);  --  Consume the identifier.\n            --  Do we have a subtype of a subtype?\n            if CD.Sy = RANGE_Keyword_Symbol then\n              --  Here comes the optional `  range 'a' .. 'z'  ` constraint.\n              In_Symbol (CD);\n              Explicit_Static_Range (CD, Level, empty_symset + LOOP_Symbol, err_range_constraint_error, Low, High);\n              Check_Explicit_Static_Range_Against_Parent_Type (CD, Low, High, Id_T.xtyp, False);\n            else\n              --  We can use the subtype identifier as a range.\n              Low.TP  := Id_T.xtyp;\n              Low.I   := Id_T.xtyp.Discrete_First;\n              --\n              High.TP := Id_T.xtyp;\n              High.I  := Id_T.xtyp.Discrete_Last;\n            end if;\n            --\n            Found   := True;\n          end if;\n        end if;\n      end;\n    end if;\n  end Static_Subtype_Indication;\n\n  -------------------------------------------------------\n  --  Check_Explicit_Static_Range_Against_Parent_Type  --\n  -------------------------------------------------------\n\n  procedure Check_Explicit_Static_Range_Against_Parent_Type\n    (CD                : in out Co_Defs.Compiler_Data;\n     low, high         : in     Co_Defs.Constant_Rec;\n     parent            : in out Co_Defs.Exact_Subtyp;\n     narrow_the_parent : in     Boolean)\n  is\n    use Co_Defs, Defs, Errors;\n  begin\n    if high.TP /= low.TP then\n      Error (CD, err_bounds_type_mismatch, \"types in range bounds do not match\", severity => major);\n    elsif Exact_Typ (low.TP) /= Exact_Typ (parent) then\n      Error\n        (CD, err_bounds_type_mismatch,\n         \"type of bounds don't match with the parent type\", severity => major);\n    elsif low.I not in parent.Discrete_First .. parent.Discrete_Last then\n      Error\n        (CD,\n         err_range_constraint_error,\n         \"lower bound, \" & Discrete_Image (CD, low.I, parent.TYP, parent.Ref) &\n         \", is out of parent type's range, \" &\n         Discrete_Range_Image (CD, parent.Discrete_First, parent.Discrete_Last, parent.TYP, parent.Ref),\n         severity => major);\n    elsif high.I not in parent.Discrete_First .. parent.Discrete_Last then\n      Error\n        (CD,\n         err_range_constraint_error,\n         \"higher bound, \" & Discrete_Image (CD, high.I, parent.TYP, parent.Ref) &\n         \", is out of parent type's range, \" &\n         Discrete_Range_Image (CD, parent.Discrete_First, parent.Discrete_Last, parent.TYP, parent.Ref),\n         severity => major);\n    elsif narrow_the_parent then\n      parent.Discrete_First := low.I;\n      parent.Discrete_Last  := high.I;\n    end if;\n  end Check_Explicit_Static_Range_Against_Parent_Type;\n\n  ---------------------------\n  -- Explicit_Static_Range --\n  ---------------------------\n\n  procedure Explicit_Static_Range\n    (CD             : in out Co_Defs.Compiler_Data;\n     Level          : in     Defs.Nesting_Level;\n     FSys           : in     Defs.Symset;\n     Specific_Error : in     Defs.Compile_Diagnostic;\n     Lower_Bound    :    out Co_Defs.Constant_Rec;\n     Higher_Bound   :    out Co_Defs.Constant_Rec)\n  is\n    use Co_Defs, Defs, Expressions, Helpers, Errors;\n  begin\n    Static_Scalar_Expression (CD, Level, OF_RANGE_Double_Dot_RParent + FSys, Lower_Bound);\n    --\n    if Lower_Bound.TP.TYP = Floats then\n      Error (CD, Specific_Error, \"a float type is not expected here\");\n      Construct_Root (Lower_Bound.TP, Ints);\n      Lower_Bound.I  := 0;\n    end if;\n    --\n    Need (CD, Range_Double_Dot_Symbol, err_expecting_double_dot);  --  \" .. \"\n    --\n    Static_Scalar_Expression (CD, Level, Comma_OF_RParent + FSys, Higher_Bound);\n    --\n    if Higher_Bound.TP /= Lower_Bound.TP then\n      Error (CD, Specific_Error, \"types in range bounds do not match\");\n      Higher_Bound.I := Lower_Bound.I;\n    end if;\n  end Explicit_Static_Range;\n\n  ------------------\n  -- Static_Range --\n  ------------------\n\n  procedure Static_Range\n    (CD             : in out Co_Defs.Compiler_Data;\n     Level          : in     Defs.Nesting_Level;\n     FSys           : in     Defs.Symset;\n     Specific_Error : in     Defs.Compile_Diagnostic;\n     Lower_Bound    :    out Co_Defs.Constant_Rec;\n     Higher_Bound   :    out Co_Defs.Constant_Rec)\n  is\n    --  The variant \"Low .. High\" was initially\n    --  in HAC.Parser <= 0.07 for array bounds.\n    Is_SI_Found : Boolean;\n  begin\n    Static_Subtype_Indication (CD, Level, Lower_Bound, Higher_Bound, Is_SI_Found);\n    if Is_SI_Found then\n      return;\n      --  All right, we have parsed, e.g., \"Boolean\" and\n      --  pass further \"False .. True\".\n    end if;\n    --\n    --  We try an explicit static range, like: `1 .. N` (N declared number),\n    --  `red .. blue` or `Base_Colour'First .. Colour'Last`.\n    --\n    Explicit_Static_Range (CD, Level, FSys, Specific_Error, Lower_Bound, Higher_Bound);\n  end Static_Range;\n\n  -------------------\n  -- Dynamic_Range --\n  -------------------\n\n  procedure Dynamic_Range\n    (CD                 : in out Co_Defs.Compiler_Data;\n     context            : in     Defs.Flow_Context;\n     FSys               : in     Defs.Symset;\n     Non_Discrete_Error : in     Defs.Compile_Diagnostic;\n     Range_Typ          :    out Co_Defs.Exact_Subtyp)\n  is\n    use Compiler.PCode_Emit, Co_Defs, Defs, Expressions, Helpers, PCode, Scanner, Errors;\n    --  The explicit range \"Low_Expr .. High_Expr\" was initially\n    --  the only possibility in HAC.Parser version<= 0.07 for FOR statements.\n    Lower_Bound_Typ, Upper_Bound_Typ        : Exact_Subtyp;\n    Lower_Bound_Static, Higher_Bound_Static : Constant_Rec;\n    Is_SI_Found                             : Boolean;\n  begin\n    --\n    --  !!  To do: replace by a dynamic subtype indication parser.\n    --\n    Static_Subtype_Indication (CD, context.level, Lower_Bound_Static, Higher_Bound_Static, Is_SI_Found);\n    --\n    if Is_SI_Found then\n      --  All right, we have parsed a subtype indication, e.g., \"Boolean\".\n      --  Since we are in a dynamic context, we need to push\n      --  the bounds on the stack (E.g., \"False .. True\").\n      Emit_1 (CD, k_Push_Discrete_Literal, Lower_Bound_Static.I);\n      Emit_1 (CD, k_Push_Discrete_Literal, Higher_Bound_Static.I);\n      Range_Typ := Lower_Bound_Static.TP;\n      return;\n    end if;\n    --\n    --  We try an explicit dynamic range, like: \"f (z) + j .. n * 2\"  or  \"1 .. 6\".\n    --  See RM 3.5 (3).\n    --\n    Simple_Expression (CD, context, END_LOOP_RANGE_Double_Dot + FSys, Lower_Bound_Typ);\n    --  You may ask: why did the Ada standard authors take Simple_Expression\n    --  instead of Expression for the range bounds ?\n    --  It's for stopping the parsing on relational and logical operators.\n    --  Consider the following example (in exm/aoc/2021/aoc_2021_11.adb ).\n    --  With Expression for bounds, you need brackets for the membership tests:\n    --\n    --      if (xx in 1 .. sx) and then (yy in 1 .. sy) and then map (xx, yy) <= 9 then\n    --\n    --  With Simple_Expression, you can write, instead, the more intuitive:\n    --\n    --      if xx in 1 .. sx and then yy in 1 .. sy and then map (xx, yy) <= 9 then\n    --\n    Range_Typ          := Lower_Bound_Typ;\n    Range_Typ.Is_Range := False;\n    --\n    if not Discrete_Typ (Range_Typ.TYP) then\n      Error (CD, Non_Discrete_Error, Nice_Exact_Image (CD, Range_Typ));\n    end if;\n    --\n    if Lower_Bound_Typ.Is_Range then\n      --  We got a ` X'Range ` expression which is a shortcut for ` X'First .. X'Last `.\n      --  The ` .. X'Last ` part has been implicitly parsed with ` X'Range ` .\n      null;\n    elsif CD.Sy = Range_Double_Dot_Symbol then  --  \"..\"\n      In_Symbol (CD);\n      --\n      Simple_Expression (CD, context, FSys + LOOP_Symbol, Upper_Bound_Typ);\n      --\n      if Exact_Typ (Upper_Bound_Typ) /= Exact_Typ (Lower_Bound_Typ) then\n        Type_Mismatch\n          (CD, err_bounds_type_mismatch,\n           Found    => Upper_Bound_Typ,\n           Expected => Lower_Bound_Typ);\n      end if;\n      Range_Typ.Discrete_Last := Upper_Bound_Typ.Discrete_Last;\n    else\n      Error_then_Skip (CD, END_LOOP_Semicolon + FSys, err_expecting_double_dot);\n    end if;\n  end Dynamic_Range;\n\n  procedure Set_Singleton_Range (X : in out Co_Defs.Exact_Subtyp; Value : Defs.HAC_Integer) is\n  begin\n    X.Discrete_First := Value;\n    X.Discrete_Last  := Value;\n  end Set_Singleton_Range;\n\n  function Is_Singleton_Range (X : Co_Defs.Exact_Subtyp) return Boolean is\n    use type Defs.HAC_Integer;\n  begin\n    return X.Discrete_First = X.Discrete_Last;\n  end Is_Singleton_Range;\n\n  function Is_Singleton_Range (X : Co_Defs.Exact_Subtyp; Value : Defs.HAC_Integer) return Boolean is\n    use type Defs.HAC_Integer;\n  begin\n    return Is_Singleton_Range (X) and then X.Discrete_First = Value;\n  end Is_Singleton_Range;\n\n  procedure Negate_Range\n    (CD : in out Co_Defs.Compiler_Data;\n     X  : in out Co_Defs.Exact_Subtyp)\n  is\n    use Defs;\n    use type HAC_Integer;\n    temp : HAC_Integer;\n  begin\n    pragma Assert (X.TYP = Ints);\n    if X.Discrete_Last = HAC_Integer'First then\n      --  *Upper* bound is -2**(bits-1) -> overflow guaranteed on negating.\n      Errors.Error (CD, err_range_constraint_error, \": overflow on applying \"\"-\"\"\");\n    end if;\n    temp := X.Discrete_Last;\n    if X.Discrete_First = HAC_Integer'First then  --  Compile-time overflow if we negate that!\n      X.Discrete_Last := HAC_Integer'Last;  -- one off\n    else\n      X.Discrete_Last := -X.Discrete_First;\n    end if;\n    X.Discrete_First := -temp;\n  end Negate_Range;\n\n  function Do_Ranges_Overlap (X_min, X_max, Y_min, Y_max : Defs.HAC_Integer) return Boolean is\n    use type Defs.HAC_Integer;\n  begin\n    pragma Assert (X_min <= X_max and then Y_min <= Y_max);\n    --\n    --  The following is logically identical to: \"not (Y_max < X_min or X_max < Y_min)\",\n    --  which means we don't have this situation:\n    --       [X_min .. X_max] ... a gap ... [Y_min .. Y_max].\n    --  or   [Y_min .. Y_max] ... a gap ... [X_min .. X_max].\n    --\n    return Y_max >= X_min and then\n           X_max >= Y_min;\n  end Do_Ranges_Overlap;\n\n  function Do_Ranges_Overlap (X, Y : Co_Defs.Exact_Subtyp) return Boolean is\n  begin\n    return Do_Ranges_Overlap\n             (X.Discrete_First, X.Discrete_Last,\n              Y.Discrete_First, Y.Discrete_Last);\n  end Do_Ranges_Overlap;\n\nend HAC_Sys.Parser.Ranges;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-ranges.ads",
    "content": "with HAC_Sys.Defs;\n\nprivate package HAC_Sys.Parser.Ranges is\n\n  --  This package has two families (Static_Range, Dynamic_Range) of\n  --  discrete_subtype_definition RM 3.6 (6). In a distant future we could\n  --  have a variant of Dynamic_Range which detects that the bounds are\n  --  actually static and optimizes the code accordingly.\n\n  --      which is either:\n  --        a subtype_indication 3.2.2 (3) : name [constraint]\n  --        like \"Color [range red .. blue]\"\n  --      or\n  --        a range 3.5 (3)\n  --        which is either:\n  --          simple_expression .. simple_expression : \"low .. high\"\n  --        or\n  --          range_attribute_reference 4.1.4 (4): A'Range[(2)]\n\n  ---------------------\n  --  Static ranges  --\n  ---------------------\n\n  --  A range with static bounds is parsed.\n  --  The bounds are known at compile-time.\n  --  At least, HAC is expecting the bounds to be static...\n  --\n  --    Examples of static bounds:\n  --      type T is range 1 .. 10;              --  Must be static\n  --      type T is new Integer range 1 .. 10;  --  Could be dynamic as well\n  --      subtype S is T range 2 .. 9;          --  Could be dynamic as well\n  --\n  --  As long as HAC has static-only arrays, this is also used for:\n  --      type A is array (1 .. 5);\n  --\n  --  Purely static discrete_subtype_definition in \"full\" Ada seem\n  --  to be restricted to:\n  --    - range types\n  --    - case statements\n  --    - record type declarations with variant parts.\n  --  CF answer by Niklas Holsti to\n  --    \"Q: discrete_subtype_definition: static only cases?\"\n  --    on comp.lang.ada, 2020-06-07.\n\n  ---------------------------\n  -- Explicit_Static_Range --\n  ---------------------------\n  --\n  --  `1 .. 3`\n  --\n  procedure Explicit_Static_Range\n    (CD             : in out Co_Defs.Compiler_Data;\n     Level          : in     Defs.Nesting_Level;\n     FSys           : in     Defs.Symset;\n     Specific_Error : in     Defs.Compile_Diagnostic;\n     Lower_Bound    :    out Co_Defs.Constant_Rec;\n     Higher_Bound   :    out Co_Defs.Constant_Rec);\n\n  -------------------------------------------------------\n  --  Check_Explicit_Static_Range_Against_Parent_Type  --\n  -------------------------------------------------------\n\n  procedure Check_Explicit_Static_Range_Against_Parent_Type\n    (CD                : in out Co_Defs.Compiler_Data;\n     low, high         : in     Co_Defs.Constant_Rec;\n     parent            : in out Co_Defs.Exact_Subtyp;\n     narrow_the_parent : in     Boolean);\n\n  ------------------\n  -- Static_Range --\n  ------------------\n  --\n  --  So far: either `1 .. 3` (that is, Explicit_Static_Range) or `Character`.\n  --\n  procedure Static_Range\n    (CD             : in out Co_Defs.Compiler_Data;\n     Level          : in     Defs.Nesting_Level;\n     FSys           : in     Defs.Symset;\n     Specific_Error : in     Defs.Compile_Diagnostic;\n     Lower_Bound    :    out Co_Defs.Constant_Rec;\n     Higher_Bound   :    out Co_Defs.Constant_Rec);\n\n  -------------------\n  -- Dynamic_Range --\n  -------------------\n  --\n  --  A range with dynamic bounds is parsed.\n  --  The bounds are pushed on the stack.\n  --    Example:\n  --      --  FOR statement (RM 5.5 (4)).\n  --      for I in J .. N loop\n  --\n  procedure Dynamic_Range\n    (CD                 : in out Co_Defs.Compiler_Data;\n     context            : in     Defs.Flow_Context;\n     FSys               : in     Defs.Symset;\n     Non_Discrete_Error : in     Defs.Compile_Diagnostic;\n     Range_Typ          :    out Co_Defs.Exact_Subtyp);\n\n  procedure Set_Singleton_Range (X : in out Co_Defs.Exact_Subtyp; Value : Defs.HAC_Integer);\n\n  function Is_Singleton_Range (X : Co_Defs.Exact_Subtyp) return Boolean;\n  pragma Inline (Is_Singleton_Range);\n\n  function Is_Singleton_Range (X : Co_Defs.Exact_Subtyp; Value : Defs.HAC_Integer) return Boolean;\n  pragma Inline (Is_Singleton_Range);\n\n  procedure Negate_Range\n    (CD : in out Co_Defs.Compiler_Data;\n     X  : in out Co_Defs.Exact_Subtyp);\n\n  --  Check whether ranges [X_min .. X_max] and [Y_min .. Y_max] overlap.\n  --\n  function Do_Ranges_Overlap (X_min, X_max, Y_min, Y_max : Defs.HAC_Integer) return Boolean;\n  pragma Inline (Do_Ranges_Overlap);\n\n  function Do_Ranges_Overlap (X, Y : Co_Defs.Exact_Subtyp) return Boolean;\n  pragma Inline (Do_Ranges_Overlap);\n\nend HAC_Sys.Parser.Ranges;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-standard_functions.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner;\n\npackage body HAC_Sys.Parser.Standard_Functions is\n\n  use Compiler.PCode_Emit, Defs, Expressions, Helpers, PCode, Scanner;\n\n  SF_Args : constant array (SF_Code) of Natural :=\n     (SF_Niladic            => 0,\n      SF_Min_Max_Int |\n      SF_Element |\n      SF_Head | SF_Tail |\n      SF_Head_Before_Match |\n      SF_Tail_After_Match |\n      SF_Starts_With |\n      SF_Ends_With |\n      SF_Int_Times_Char |\n      SF_Int_Times_VStr     => 2,\n      SF_Index |\n      SF_Index_Backward |\n      SF_Slice              => 3,\n      others                => 1\n     );\n\n  procedure Standard_Function\n    (CD          : in out Co_Defs.Compiler_Data;\n     context     : in     Defs.Flow_Context;\n     FSys        :        Defs.Symset;\n     Ident_Index :        Integer;\n     Code        :        Defs.SF_Code;\n     Return_Typ  :    out Co_Defs.Exact_Subtyp)\n  is\n    use Co_Defs;\n    Max_Args : constant := 3;\n    Args : Natural := SF_Args (Code);\n    Expected : array (1 .. Max_Args) of Typ_Set;       --  Expected type of the function's arguments\n    Actual   : array (1 .. Max_Args) of Exact_Subtyp;  --  Actual type from argument expression\n    Code_Adjusted : SF_Code := Code;\n    do_SF_emit : Boolean := True;\n    X : Exact_Subtyp;\n    --\n    procedure Prepare_Accepted_Parameter_Types is\n      VString_or_Chars_Set     : constant Typ_Set := VStrings_Set or Chars_Set;\n      Strings_Set              : constant Typ_Set := Arrays_Set or Str_Lit_Set or Str_as_VStr_Set;\n      Any_String_Set           : constant Typ_Set := VStrings_Set or Strings_Set;\n      Any_String_or_Chars_Set  : constant Typ_Set := Any_String_Set or Chars_Set;\n      Chars_or_Strings_Set     : constant Typ_Set := Chars_Set or Strings_Set;\n    begin\n      case Code is\n        when SF_Abs_Int =>\n          Expected (1) := Numeric_Typ_Set;\n        when SF_T_Val =>  --  S'Val : RM 3.5.5 (5)\n          Expected (1) := Ints_Set;\n        when SF_T_Pos =>  --  S'Pos : RM 3.5.5 (2)\n          Expected (1) := Discrete_Typ;\n        when SF_T_Succ | SF_T_Pred =>  -- S'Succ, S'Pred : RM 3.5 (22, 25)\n          Expected (1) := Discrete_Typ;\n        when SF_Round_Float_to_Int | SF_Trunc_Float_to_Int |\n             SF_Sin | SF_Cos | SF_Exp | SF_Log | SF_Sqrt | SF_Arctan |\n             SF_Sgn_Int\n          =>\n          Expected (1) := Numeric_Typ_Set;\n        when SF_Image_Ints =>\n          Expected (1) := Numeric_Typ_Set or Times_Set or Durations_Set;\n        when SF_Image_Attribute_Floats =>\n          Expected (1) := Floats_Set;\n        when SF_Random_Int | SF_Argument =>\n          Expected (1) := Ints_Set;\n        when SF_Min_Max_Int =>\n          Expected (1 .. 2) := (Numeric_Typ_Set, Numeric_Typ_Set);\n        when SF_Element | SF_Head | SF_Tail =>\n          Expected (1 .. 2) := (VStrings_Set, Ints_Set);\n        when SF_Length |\n             SF_Trim_Left .. SF_Trim_Both |\n             SF_Float_Value | SF_Integer_Value\n          =>\n          Expected (1) := VStrings_Set;\n        when SF_Slice =>\n          Expected (1 .. 3) := (VStrings_Set, Ints_Set, Ints_Set);\n        when SF_To_Lower_Char | SF_To_Upper_Char =>\n          Expected (1) := VString_or_Chars_Set;\n        when SF_String_Literal_to_VString =>\n          Expected (1) := Chars_or_Strings_Set;\n        when SF_VString_to_String =>\n          Expected (1) := VStrings_Set;\n        when SF_Index | SF_Index_Backward =>\n          --  Index (OS, +\"Windows\"[, 3]), Index (OS, \"Windows\"[, 3]) or Index (OS, 'W'[, 3])\n          Expected (1 .. 3) := (VStrings_Set, Any_String_or_Chars_Set, Ints_Set);\n        when SF_Starts_With | SF_Ends_With |\n             SF_Head_Before_Match | SF_Tail_After_Match =>\n          Expected (1 .. 2) := (VStrings_Set, Any_String_or_Chars_Set);\n        when SF_Year .. SF_Seconds =>\n          Expected (1) := Times_Set;\n        when SF_Directory_Exists | SF_Exists | SF_File_Exists |\n             SF_Get_Env  | SF_Get_VM_Variable =>\n          --  Get_Env (+\"PATH\")  _or_  Get_Env (\"PATH\")\n          Expected (1) := Any_String_Set;\n        when SF_Niladic =>\n          null;  --  Zero argument -> no argument type to check.\n        when SF_File_or_Console_Information =>\n          null;  --  Arguments are parsed separately.\n        when SF_Is_Open =>\n          Expected (1) := Text_Files_Set;\n        when others =>\n          null;\n          --  Here we have functions that are never parsed\n          --  E.g. SF_Abs_Float, parsed as SF_Abs_Int, or \"&\" operators.\n      end case;\n    end Prepare_Accepted_Parameter_Types;\n    --\n    procedure Parse_Arguments is\n      TYP_of_arg : Typen;\n    begin\n      for a in 1 .. Args loop\n        Expression (CD, context, FSys + RParent + Comma, Actual (a));\n        TYP_of_arg := Actual (a).TYP;\n        if Expected (a) (TYP_of_arg) then\n          null;  --  All right so far: argument type is in the admitted set of types.\n        elsif Actual (a).TYP /= NOTYP then\n          Type_Mismatch (\n            CD, err_argument_to_std_function_of_wrong_type,\n            Found    => Actual (a),\n            Expected => Expected (a)\n          );\n        end if;\n        if (Code = SF_Index or Code = SF_Index_Backward)\n           and then a = 2\n           and then CD.Sy = RParent\n        then\n          Args := 2;  --  Alright: Index, Index_Backard without From.\n          exit;\n        elsif a < Args then\n          Need (CD, Comma, err_COMMA_missing);\n        end if;\n      end loop;\n    end Parse_Arguments;\n    --\n    procedure Parse_File_Information_Function (FIF_Code : SF_Code) is\n      file_parameter : Boolean;\n    begin\n      if CD.Sy = LParent then\n        --  End_Of_File (...), End_Of_Line (...).\n        In_Symbol (CD);\n        Expression (CD, context, FSys + RParent + Comma, X);\n        if X.TYP /= Text_Files then\n          Type_Mismatch (CD, err_general_error, Found => X, Expected => Text_Files_Set);\n        end if;\n        file_parameter := True;\n        Need (CD, RParent, err_closing_parenthesis_missing);\n      else\n        --  Niladic End_Of_File, End_Of_Line without parameter.\n        file_parameter := False;\n      end if;\n      Emit_2 (CD, k_HAT_Function, Boolean'Pos (file_parameter), SF_Code'Pos (FIF_Code));\n    end Parse_File_Information_Function;\n    --\n    procedure Adjustments_to_Parameter_Types is  --  Here is the actual overloading implemented.\n    begin\n      case Code is\n        when SF_Abs_Int =>  --  Abs (NB: in Ada it's an operator, not a function)\n          Return_Typ := Actual (1);\n          if Actual (1).TYP = Floats then\n            Code_Adjusted := SF_Abs_Float;\n          end if;\n        when SF_T_Succ | SF_T_Pred =>  -- S'Succ, S'Pred : RM 3.5 (22, 25)\n          Return_Typ := Actual (1);\n        when SF_Round_Float_to_Int | SF_Trunc_Float_to_Int |\n             SF_Sin | SF_Cos | SF_Exp | SF_Log | SF_Sqrt | SF_Arctan\n          =>\n          if Ints_Set (Actual (1).TYP) then\n            Forbid_Type_Coercion (CD, Found => Actual (1), Expected => Construct_Root (Floats));\n            Emit_1 (CD, k_Integer_to_Float, 0);  --  Ghost of SmallAda\n          end if;\n        when SF_Min_Max_Int =>\n          Return_Typ := Actual (1);\n          if Actual (1).TYP = Floats then\n            Code_Adjusted := (if Code = SF_Min_Int then SF_Min_Float else SF_Max_Float);\n          end if;\n          if Actual (2).TYP /= Actual (1).TYP then\n            Type_Mismatch (CD, err_parameter_types_do_not_match, Actual (2), Actual (1));\n          end if;\n        when SF_Sgn_Int =>\n          Return_Typ := Actual (1);\n          if Actual (1).TYP = Floats then\n            Code_Adjusted := SF_Sgn_Float;\n          end if;\n        when SF_Image_Ints =>\n          case Actual (1).TYP is\n            when Floats    => Code_Adjusted := SF_Image_Floats;\n            when Times     => Code_Adjusted := SF_Image_Times;\n            when Durations => Code_Adjusted := SF_Image_Durations;\n            when others => null;\n          end case;\n        when SF_To_Lower_Char =>               --  To_Lower (Item : Character) return Character;\n          Return_Typ := Actual (1);\n          if Actual (1).TYP = VStrings then    --  To_Lower (Item : VString) return VString;\n            Code_Adjusted := SF_To_Lower_VStr;\n          end if;\n        when SF_To_Upper_Char =>               --  To_Upper (Item : Character) return Character;\n          Return_Typ := Actual (1);\n          if Actual (1).TYP = VStrings then    --  To_Upper (Item : VString) return VString;\n            Code_Adjusted := SF_To_Upper_VStr;\n          end if;\n        when SF_Index | SF_Index_Backward |\n             SF_Starts_With | SF_Ends_With |\n             SF_Head_Before_Match | SF_Tail_After_Match =>\n          if Code in SF_Index_Any_Direction then\n            if Args = 2 then\n              Emit_1 (CD, k_Push_Discrete_Literal, 0);  --  We push a non-positive value for `From`.\n            end if;\n            Emit (CD, k_Pop_to_Temp);\n            --  `From` is now temporarily removed from the stack. `Pattern` is at the top.\n          end if;\n          --  Second parameter can be a Character, a String, or a VString.\n          Check_any_String_and_promote_to_VString (CD, Actual (2), True);\n          if Code in SF_Index_Any_Direction then\n            Emit (CD, k_Push_Temp);\n            --  `From` is now back at the stack top.\n          end if;\n        when SF_Directory_Exists | SF_Exists | SF_File_Exists |\n             SF_Get_Env | SF_Get_VM_Variable =>\n          --  Get_Env (\"PATH\")  becomes  Get_Env (+\"PATH\")\n          Check_any_String_and_promote_to_VString (CD, Actual (1), False);\n        when SF_String_Literal_to_VString =>\n          --  Explicit call to the `To_VString` function, identical to the unary \"+\".\n          --  See Simple_Expression in Parser.Expressions\n          Check_any_String_and_promote_to_VString (CD, Actual (1), True);\n          do_SF_emit := False;  --  Conversion code is already emitted.\n        when SF_Niladic =>\n          null;  --  No arguments, nothing to adjust\n        when others =>\n          null;  --  Nothing to adjust regarding parameter types.\n      end case;\n    end Adjustments_to_Parameter_Types;\n    --\n  begin\n    Return_Typ := CD.id_table (Ident_Index).xtyp;\n    --\n    Prepare_Accepted_Parameter_Types;\n    --\n    if Code in SF_File_or_Console_Information then\n      Parse_File_Information_Function (Code);\n    else\n      if Args > 0 then\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Parse_Arguments;\n      end if;\n      Adjustments_to_Parameter_Types;\n      if do_SF_emit then\n        Emit_Std_Funct (CD, Code_Adjusted);\n      end if;\n      if Args > 0 then\n        Need (CD, RParent, err_closing_parenthesis_missing);\n      end if;\n    end if;\n  end Standard_Function;\n\nend HAC_Sys.Parser.Standard_Functions;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-standard_functions.ads",
    "content": "private package HAC_Sys.Parser.Standard_Functions is\n\n  --  NB: Some of the supplied subprograms may disappear when modularity,\n  --  Ada.Text_IO etc. will be implemented, as well as overloading.\n\n  procedure Standard_Function\n    (CD          : in out Co_Defs.Compiler_Data;\n     context     : in     Defs.Flow_Context;\n     FSys        :        Defs.Symset;\n     Ident_Index :        Integer;\n     Code        :        Defs.SF_Code;\n     Return_Typ  :    out Co_Defs.Exact_Subtyp);\n\nend HAC_Sys.Parser.Standard_Functions;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-standard_procedures.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Calls,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Standard_Procedures is\n\n  use Calls, Compiler.PCode_Emit, Co_Defs, Defs, Expressions, Helpers, PCode, Scanner, Errors;\n\n  type Default_Extra_Put_Parameter_Type is array (Typen, 1 .. 3) of Integer;\n\n  invalid : constant := -1;\n\n  default_extra_put_param : constant Default_Extra_Put_Parameter_Type :=\n    (Ints    =>  (IIO.Default_Width,   IIO.Default_Base,   invalid),\n     Floats  =>  (RIO.Default_Fore,    RIO.Default_Aft,    RIO.Default_Exp),\n     Bools   =>  (BIO.Default_Width,   invalid,            invalid),\n     others  =>  (others => invalid));\n  --  NB: for String_Literals on the target HAC VM, two values are pushed on the stack.\n\n  procedure Standard_Procedure\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     Code    : in     Defs.SP_Code)\n  is\n\n    procedure HAT_Procedure_Call (FIO_Code : SP_Code; Param : Operand_2_Type := 0) is\n    begin\n      CD.target.Emit_HAT_Builtin_Procedure (FIO_Code, Param);\n    end HAT_Procedure_Call;\n    --\n    procedure Set_Abstract_Console is\n    begin\n      HAT_Procedure_Call (SP_Push_Abstract_Console);\n    end Set_Abstract_Console;\n    --\n    procedure Parse_Gets (Code : SP_Code) is\n      --  Parse Get & Co including an possible File parameter\n      Found : Exact_Subtyp;\n      with_file : Boolean;\n      String_Length_Encoding : Operand_2_Type := 0;\n      use type Operand_2_Type;\n    begin\n      Need (CD, LParent, err_missing_an_opening_parenthesis);\n      Push_Parameter_by_Reference (CD, context, FSys, \"File\", param_in_out, Found);\n      with_file := Found.TYP = Text_Files;\n      if with_file then\n        --  We place the file handle's value on the stack:\n        Emit (CD, k_Dereference);\n        Need (CD, Comma, err_COMMA_missing);\n        --  Now the variable for \"Get (file, variable);\":\n        Push_Parameter_by_Reference (CD, context, FSys, \"\", param_out, Found);\n      end if;\n      --  The \"out\" variable for Get, Get_Immediate, Get_Line\n      --  has been pushed by reference now.\n      if Found.TYP = NOTYP then\n        null;  --  Error(s) already appeared in the parsing.\n      elsif Text_IO_Get_Item_Set (Found.TYP) then\n        if Found.TYP = Arrays then\n          --  Array: it must be a fixed-sized String here.\n          if Is_Char_Array (CD, Found) then\n            String_Length_Encoding := (2 ** Typen'Size) *\n              Operand_2_Type (CD.Arrays_Table (Found.Ref).Array_Size);\n          else\n            Error (CD, err_illegal_parameters_to_Get);\n          end if;\n        end if;\n        HAT_Procedure_Call\n          ((if with_file then\n              (if Code = SP_Get_Line then SP_Get_Line_File else SP_Get_File)\n            else Code),\n           Typen'Pos (Found.TYP) + String_Length_Encoding);\n      else\n        Error (CD, err_illegal_parameters_to_Get);\n      end if;\n      Need (CD, RParent, err_closing_parenthesis_missing);\n    end Parse_Gets;\n    --\n    procedure Parse_Puts (Code : SP_Code) is\n      --  Parse Put & Co including an possible File parameter\n      Item_Typ, Format_Param_Typ : Exact_Subtyp;\n      Format_Params : Natural := 0;\n      with_file : Boolean;\n    begin\n      Need (CD, LParent, err_missing_an_opening_parenthesis);\n      Expression (CD, context, FSys + Colon_Comma_RParent, Item_Typ);\n      with_file := Item_Typ.TYP = Text_Files;\n      if with_file then\n        Need (CD, Comma, err_COMMA_missing);\n        Expression (CD, context, FSys + Colon_Comma_RParent, Item_Typ);\n      end if;\n      --\n      --  Here we have tha actual thing to \"Put\": a character, (v)string, a number.\n      --\n      if Item_Typ.TYP in Standard_Typ | Special_Strings then\n        null;  --  Good, Put[_Line] can do it all \"as is\"!\n      elsif Is_Char_Array (CD, Item_Typ) then\n        --  Address is already pushed; we need to push the string's length.\n        Emit_1 (CD, k_Push_Discrete_Literal, Operand_2_Type (CD.Arrays_Table (Item_Typ.Ref).Array_Size));\n      else\n        Error (CD, err_illegal_parameters_to_Put);\n      end if;\n      for Param in 1 .. 3 loop\n        exit when CD.Sy /= Comma;\n        In_Symbol (CD);\n        Format_Params := Format_Params + 1;\n        --  Here we parse:\n        --    Width, Base    for Put ([F,] I [, Width [, Base]]);\n        --    Fore, Aft, Exp for Put ([F,] R [, Fore[, Aft[, Exp]]]);\n        --    Width          for Put ([F,] B [, Width]);\n        Expression (CD, context, FSys + Colon_Comma_RParent, Format_Param_Typ);\n        Check_Integer (CD, Format_Param_Typ.TYP);\n      end loop;\n      --  Check given / default parameters (nice short common solution, isn't it ?)\n      for Param in 1 .. Format_Params loop\n        --  First we check if the programmer didn't put too many\n        --  (then, undefined) parameters.\n        if default_extra_put_param (Item_Typ.TYP, Param) = invalid then\n          Error (CD, err_illegal_parameters_to_Put);\n        end if;\n      end loop;\n      if Item_Typ.TYP = String_Literals or else Is_Char_Array (CD, Item_Typ) then\n        --  With String_Literals and String's, we have *two* values pushed on the stack.\n        Format_Params := Format_Params + 1;\n      end if;\n      for Param in Format_Params + 1 .. 3 loop\n        --  Send default parameters to the stack.\n        exit when default_extra_put_param (Item_Typ.TYP, Param) = invalid;\n        --  See Do_Write_Formatted on HAC VM or the code associated with SP_Put on\n        --  other targets via Emit_HAT_Builtin_Procedure to have an idea on how\n        --  everybody is retrieved from the stack.\n        CD.target.Emit_Push_Discrete_Literal\n          (Operand_2_Type (default_extra_put_param (Item_Typ.TYP, Param)));\n      end loop;\n      HAT_Procedure_Call\n       ((if with_file then\n           (if Code = SP_Put_Line then SP_Put_Line_File else SP_Put_File)\n         else Code),\n        Typen'Pos (Item_Typ.TYP));\n      Need (CD, RParent, err_closing_parenthesis_missing);\n    end Parse_Puts;\n\n    type Param_Passing_Mode is (by_value, by_reference);\n\n    type Param is record\n      mode : Param_Passing_Mode;\n      typ  : Typen;\n    end record;\n\n    type Param_List is array (Positive range <>) of Param;\n\n    procedure Parse_Call_to_Single_Profile_Procedure (pl : Param_List) is\n      --  This fits non-overloaded procedures.\n      X : Exact_Subtyp;\n    begin\n      if pl'Length = 0 then\n        return;  --  No parameter\n      else\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        for i in pl'Range loop\n          --  Parse the passed parameter's variable (when by reference)\n          --  or expression (when by value) and emit corresponding VM code\n          --  that will have in fine an address or a value pushed on the stack.\n          case pl (i).mode is\n            when by_reference =>\n              Push_Parameter_by_Reference (CD, context, FSys, \"\", param_in_out, X);\n            when by_value =>\n              Expression (CD, context, Comma_RParent, X);\n          end case;\n          --  Check the base type.\n          if X.TYP /= pl (i).typ then\n            Type_Mismatch\n              (CD, err_parameter_types_do_not_match,\n               Found => X, Expected => Singleton (pl (i).typ));\n          end if;\n          --  Parse the comma separating current parameter from next one.\n          if i < pl'Last then\n            Need (CD, Comma, err_COMMA_missing);\n          end if;\n        end loop;\n        Need (CD, RParent, err_closing_parenthesis_missing);\n      end if;\n    end Parse_Call_to_Single_Profile_Procedure;\n\n    procedure Parse_Call_to_Single_Profile_HAT_Procedure (pl : Param_List) is\n    begin\n      Parse_Call_to_Single_Profile_Procedure (pl);\n      HAT_Procedure_Call (Code);\n    end Parse_Call_to_Single_Profile_HAT_Procedure;\n\n    X, Y, Z : Exact_Subtyp;\n\n  begin\n    case Code is\n      when SP_Get | SP_Get_Immediate | SP_Get_Line =>\n        Parse_Gets (Code);\n\n      when SP_Put | SP_Put_Line =>\n        Parse_Puts (Code);\n\n      when SP_New_Line | SP_Skip_Line =>\n        if CD.Sy = LParent then\n          In_Symbol (CD);\n          Expression (CD, context, FSys + Colon_Comma_RParent, X);\n          case X.TYP is\n            when Text_Files =>\n              if CD.Sy = Comma then\n                --  \"New_Line (File, Spacing);\"\n                In_Symbol (CD);\n                Expression (CD, context, FSys + RParent, Y);\n                Check_Integer (CD, Y.TYP);\n              else\n                --  \"New_Line (File);\"\n                Emit_1 (CD, k_Push_Discrete_Literal, 1);  --  Push default value, Spacing := 1\n              end if;\n            when Ints =>\n              --  \"New_Line (Spacing);\"\n              Set_Abstract_Console;\n              Emit (CD, k_Swap);  --  File (the console) has to be before Spacing on the stack.\n            when others =>\n              Type_Mismatch (CD, err_general_error, Found => X, Expected => Text_Files_Set or Ints_Set);\n          end case;\n          Need (CD, RParent, err_closing_parenthesis_missing);\n        else  --  \"New_Line;\"\n          Set_Abstract_Console;\n          Emit_1 (CD, k_Push_Discrete_Literal, 1);  --  Push default value, Spacing := 1\n        end if;\n        HAT_Procedure_Call (Code);\n\n      when SP_Randomize =>\n        HAT_Procedure_Call (Code);\n\n      when SP_Random_Seed =>\n        Parse_Call_to_Single_Profile_HAT_Procedure ((1 => (by_value, Ints)));\n\n      when SP_Wait | SP_Signal =>\n        Parse_Call_to_Single_Profile_Procedure ((1 => (by_value, Ints)));\n        if Code = SP_Wait then\n          Emit (CD, k_Wait_Semaphore);\n        else\n          Emit (CD, k_Signal_Semaphore);\n        end if;\n\n      when SP_Open | SP_Create | SP_Append | SP_Close =>\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Push_Parameter_by_Reference\n          (CD, context, FSys + Colon_Comma_RParent, \"File\", param_in_out, X);\n        if X.TYP /= Text_Files then\n          Type_Mismatch (CD, err_general_error, Found => X, Expected => Text_Files_Set);\n        end if;\n        if Code in SP_Open | SP_Create | SP_Append then\n          --  Parse file name.\n          Need (CD, Comma, err_COMMA_missing);\n          Expression (CD, context, FSys + Colon_Comma_RParent, X);\n          Check_any_String_and_promote_to_VString (CD, X, False);\n        end if;\n        HAT_Procedure_Call (Code);\n        Need (CD, RParent, err_closing_parenthesis_missing);\n\n      when SP_Quantum =>\n        --  Cramer\n        Parse_Call_to_Single_Profile_Procedure ((1 => (by_value, Floats)));\n        Emit (CD, k_Set_Quantum_Task);\n\n      when SP_Priority =>\n        --  Cramer\n        Parse_Call_to_Single_Profile_Procedure ((1 => (by_value, Ints)));\n        Emit (CD, k_Set_Task_Priority);\n\n      when SP_InheritP =>\n        --  Cramer\n        Parse_Call_to_Single_Profile_Procedure ((1 => (by_value, Bools)));\n        Emit (CD, k_Set_Task_Priority_Inheritance);\n        --\n      when SP_Set_Env | SP_Set_VM_Variable | SP_Copy_File | SP_Rename =>\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        for arg in 1 .. 2 loop\n          Expression (CD, context, Colon_Comma_RParent, X);  --  We push the arguments in the stack.\n          --  Set_Env ( \"HAC_Var\",  \"Hello\");     <-  2 String's\n          --  Set_Env (+\"HAC_Var\", +\"Hello\");     <-  2 VString's\n          --  Set_Env (+\"HAC_Var\",  \"Hello\");\n          --  Set_Env ( \"HAC_Var\", +\"Hello\");\n          Check_any_String_and_promote_to_VString (CD, X, False);\n          if arg < 2 then\n            Need (CD, Comma, err_COMMA_missing);\n          end if;\n        end loop;\n        HAT_Procedure_Call (Code);\n        Need (CD, RParent, err_closing_parenthesis_missing);\n\n      when SP_Create_Directory | SP_Create_Path | SP_Delete_Directory |\n           SP_Delete_File | SP_Set_Directory\n           =>\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Expression (CD, context, RParent_Set, X);  --  We push the argument in the stack.\n        Check_any_String_and_promote_to_VString (CD, X, False);\n        HAT_Procedure_Call (Code);\n        Need (CD, RParent, err_closing_parenthesis_missing);\n\n      when SP_Shell_Execute =>\n        Need (CD, LParent, err_missing_an_opening_parenthesis);\n        Expression (CD, context, Comma_RParent, X);  --  We push the argument in the stack.\n        Check_any_String_and_promote_to_VString (CD, X, False);\n        --  ` Shell_Execute (cmd `  has been parsed at this point.\n        if CD.Sy = Comma then\n          In_Symbol (CD);\n          Push_Parameter_by_Reference\n            (CD, context, RParent_Set, \"Command\", param_in_out, Y);\n          case Y.TYP is\n            when VStrings =>\n              --  Shell_Execute (cmd, output);\n              HAT_Procedure_Call (SP_Shell_Execute_Output);\n            when Ints =>\n              if CD.Sy = Comma then\n                In_Symbol (CD);\n                Push_Parameter_by_Reference\n                  (CD, context, RParent_Set, \"Result\", param_out, Z);\n                --  Shell_Execute (cmd, result, output);\n                HAT_Procedure_Call (SP_Shell_Execute_Result_Output);\n                if Z.TYP /= VStrings then\n                  Type_Mismatch (CD, err_parameter_types_do_not_match,\n                    Found => Z, Expected => VStrings_Set);\n                end if;\n              else\n                --  Shell_Execute (cmd, result);\n                HAT_Procedure_Call (SP_Shell_Execute_with_Result);\n              end if;\n            when others =>\n              Type_Mismatch (CD, err_parameter_types_do_not_match,\n                Found => Y, Expected => VStrings_Set or Ints_Set);\n          end case;\n        else\n          --  Shell_Execute (cmd);\n          HAT_Procedure_Call (SP_Shell_Execute_without_Result);\n        end if;\n        Need (CD, RParent, err_closing_parenthesis_missing);\n\n      when SP_Set_Exit_Status =>\n        Parse_Call_to_Single_Profile_HAT_Procedure\n          ((1 => (by_value, Ints)));  --  Exit code\n\n      when SP_Delete =>\n        Parse_Call_to_Single_Profile_HAT_Procedure\n          (((by_reference, VStrings),  --  Source\n            (by_value,     Ints),      --  From\n            (by_value,     Ints)));    --  Through\n\n      when SP_Push_Abstract_Console =>\n        null;  --  Internal: used by Get, Put, etc. without file parameter.\n\n      when SP_Get_File | SP_Get_Line_File |\n           SP_Put_File | SP_Put_Line_File =>\n        --  Theses cases are \"fronted\" by SP_Get, SP_Get_Line,...\n        --  They are used by the VM.\n        null;\n    end case;\n\n  end Standard_Procedure;\n\nend HAC_Sys.Parser.Standard_Procedures;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-standard_procedures.ads",
    "content": "private package HAC_Sys.Parser.Standard_Procedures is\n\n  --  NB: Some of the supplied subprograms may disappear when modularity,\n  --  Ada.Text_IO etc. will be implemented, as well as overloading.\n\n  procedure Standard_Procedure\n    (CD      : in out Co_Defs.Compiler_Data;\n     context : in     Defs.Flow_Context;\n     FSys    : in     Defs.Symset;\n     Code    : in     Defs.SP_Code);\n\nend HAC_Sys.Parser.Standard_Procedures;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-statements-case_statement.adb",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Defs,\n     HAC_Sys.Multi_Precision_Integers,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Ranges,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\nprocedure HAC_Sys.Parser.Statements.CASE_Statement  --  Ada RM 5.4\n  (CD         : in out Co_Defs.Compiler_Data;\n   fsys       : in     Defs.Symset;\n   block_data : in out Block_Data_Type)\nis\n  use Defs, Co_Defs, Compiler.PCode_Emit, Errors, Expressions, Helpers, PCode;\n  use type HAC_Integer;\n\n  type CASE_Label_Value is record\n    value_1, value_2 : HAC_Integer;  --  value of a choice in a CASE statement\n    LC               : Index;        --  instruction address\n    Is_others        : Boolean;\n  end record;\n\n  case_table : array (1 .. Cases_Max) of CASE_Label_Value;\n  exit_table : array (1 .. Cases_Max) of Integer;\n\n  X : Exact_Subtyp;\n  choice_counter : Integer := 0;  --  This counts the various choices separated by '|'.\n  exit_counter   : Integer := 0;  --  This will correspond to the number of \"=>\".\n  LC1 : Integer;\n  WHEN_OTHERS_flag : Boolean := False;\n\n  use Multi_Precision_Integers;\n  subtype Choice_Count_Type is Multi_Int (4);\n  parsed_choices : Choice_Count_Type;\n\n  procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n\n  function Count_Choice_Values (Low, High : HAC_Integer) return Choice_Count_Type is\n    result : Choice_Count_Type;\n  begin\n    pragma Assert (Low <= High);\n    Fill (result, Multi (High) - Multi (Low) + 1);\n    return result;\n  end Count_Choice_Values;\n\n  procedure Discrete_Choice is  --  Ada RM 3.8.1 (5)\n    label_1, label_2 : Constant_Rec;\n    K : Integer;\n    choice_symbol_set : constant Symset := fsys + Alt_Finger_THEN + Range_Double_Dot_Symbol;\n  begin\n    Static_Scalar_Expression (CD, block_data.context.level, choice_symbol_set, label_1);\n    if CD.Sy = Range_Double_Dot_Symbol then\n      --  !!  To do: non-explicit ranges, like a subtype name, a 'Range, ... .\n      --      Ranges.Static_Range.\n      In_Symbol;\n      Static_Scalar_Expression (CD, block_data.context.level, choice_symbol_set, label_2);\n      if label_2.TP /= label_1.TP then\n        Type_Mismatch (\n          CD, err_case_label_not_same_type_as_case_clause,\n          Found    => label_2.TP,\n          Expected => label_1.TP\n        );\n      end if;\n    else\n      label_2 := label_1;\n    end if;\n    if Exact_Typ (label_1.TP) /= Exact_Typ (X) then\n      Type_Mismatch (\n        CD, err_case_label_not_same_type_as_case_clause,\n        Found    => label_1.TP,\n        Expected => X\n      );\n    elsif choice_counter = Cases_Max then\n      Fatal (Case_Labels);  --  Exception is raised there.\n    else\n      if        (label_1.I not in X.Discrete_First .. X.Discrete_Last)\n        or else (label_2.I not in X.Discrete_First .. X.Discrete_Last)\n      then\n        Error (CD, err_choice_out_of_range, severity => minor);\n      end if;\n      choice_counter := choice_counter + 1;\n      case_table (choice_counter) :=\n        (value_1   => label_1.I,\n         value_2   => label_2.I,\n         LC        => CD.LC,\n         Is_others => False);\n      K := 0;\n      loop\n        K := K + 1;\n        --  Detect any range overlap:\n        exit when\n          Ranges.Do_Ranges_Overlap (label_1.I, label_2.I, case_table (K).value_1, case_table (K).value_2);\n      end loop;\n      if K < choice_counter then\n        Error (CD, err_duplicate_case_choice_value, severity => major);\n      end if;\n      --  Since single choices or ranges do not overlap,\n      --  we can simply add the number of covered values in order to check\n      --  at the end that everything is covered.\n      Fill (parsed_choices, parsed_choices + Count_Choice_Values (label_1.I, label_2.I));\n    end if;\n  end Discrete_Choice;\n\n  procedure WHEN_Discrete_Choice_List is\n  begin\n    pragma Assert (CD.Sy = WHEN_Symbol);  --  This subprogram is called only on WHEN_Symbol.\n    In_Symbol;  --  Consume `WHEN`\n    --  Here, a discrete_choice_list (Ada RM 3.8.1 (4)) following WHEN.\n    if Constant_Definition_Begin_Symbol (CD.Sy) then\n      if WHEN_OTHERS_flag then  --  Normal choice list *atfer* the \"others\" choice.\n        Error (CD, err_case_others_alone_last);\n      end if;\n      Discrete_Choice;\n      while CD.Sy = Alt loop\n        In_Symbol;  --  Consume '|' symbol.\n        if CD.Sy = OTHERS_Symbol then  --  \"others\" mixed with normal choices.\n          Error (CD, err_case_others_alone_last);\n        else\n          Discrete_Choice;\n        end if;\n      end loop;\n    elsif CD.Sy = OTHERS_Symbol then        -- Hathorn\n      if WHEN_OTHERS_flag then  --  Duplicate \"others\".\n        Error (CD, err_case_others_alone_last);\n      end if;\n      WHEN_OTHERS_flag := True;\n      if choice_counter = Cases_Max then\n        Fatal (Case_Labels);  --  Exception is raised there.\n      end if;\n      choice_counter := choice_counter + 1;\n      case_table (choice_counter) :=\n        (value_1 | value_2 => 0,\n         LC                => CD.LC,\n         Is_others         => True);\n      In_Symbol;\n    end if;\n    if CD.Sy = THEN_Symbol then  --  Mistake happens when converting IF statements to CASE.\n      Error (CD, err_THEN_instead_of_Arrow, severity => major);\n      In_Symbol;\n    else\n      Need (CD, Finger, err_FINGER_missing);\n    end if;\n    Sequence_of_Statements_in_a_Conditional_Statement (CD, END_WHEN, block_data);\n    exit_counter := exit_counter + 1;\n    exit_table (exit_counter) := CD.LC;\n    Emit (CD, k_Jump);\n  end WHEN_Discrete_Choice_List;\n\n  procedure Check_Coverage is\n    expected_choices, difference : Choice_Count_Type;\n  begin\n    pragma Assert (Choice_Count_Type'Size >= HAC_Integer'Size);\n    Fill (expected_choices, Count_Choice_Values (X.Discrete_First, X.Discrete_Last));\n    Fill (difference, expected_choices - parsed_choices);\n    if Equal (difference, 0) then\n      if WHEN_OTHERS_flag then\n        if CD.remarks (note_redundant_construct) then\n          Remark\n            (CD,\n             note_redundant_construct,\n             \"\"\"when others\"\" is redundant here: all values\" &\n             \" are already explicitly covered\");\n        end if;\n      end if;\n    else\n      pragma Assert (difference > 0);\n      --  ^ NB: if the difference was negative, there would be more parsed\n      --    choices than possible choices. Thus at least one choice\n      --    would be out of range. But that error would have been detected\n      --    on parsing and this procedure would not have been called.\n      if not WHEN_OTHERS_flag then\n        Error\n          (CD, err_choices_not_covered,\n           (if difference > 99 then \"\"  --  Too many omissions for display...\n            elsif Equal (difference, 1) then \": one case is missing\"\n            else \":\" & Basic_Int'Image (Basic (difference)) &\n              \" cases are missing\"),\n           severity => minor);\n      end if;\n    end if;\n  end Check_Coverage;\n\nbegin  --  CASE_Statement\n  pragma Assert (CD.Sy = CASE_Symbol);\n  block_data.context.is_within_condition := True;\n  block_data.context.is_in_cond_within_loop := block_data.context.is_within_loop;\n  Fill (parsed_choices, 0);\n  In_Symbol;\n  Expression (CD, block_data.context, fsys + Colon_Comma_IS_OF, X);\n  if not Discrete_Typ (X.TYP) then\n    Error (CD, err_bad_type_for_a_case_statement);\n  end if;\n  LC1 := CD.LC;\n  Emit (CD, k_CASE_Switch);\n  case CD.Sy is\n    when IS_Symbol =>\n      In_Symbol;\n    when OF_Symbol =>\n      Error (CD, err_OF_instead_of_IS);\n      --  ^ Common mistake by Pascal programmers.\n      --  Historical note: \"OF\" and not \"IS\" was expected by SmallAda!\n      --  For instance, \"case x OF  when 1 => ...\"\n      In_Symbol;\n    when others =>\n      Error (CD, err_IS_missing);\n  end case;\n  if CD.Sy /= WHEN_Symbol then\n    Error (CD, err_WHEN_missing, severity => major);\n  end if;\n  loop\n    --  All cases are parsed in this loop.\n    WHEN_Discrete_Choice_List;\n    exit when CD.Sy /= WHEN_Symbol;\n  end loop;\n  if CD.error_count + CD.minor_error_count = 0 then\n    Check_Coverage;\n  end if;\n  CD.ObjCode (LC1).Y := Operand_2_Type (CD.LC);\n  --  ^ Set correct address for k_CASE_Switch above.\n  --  This is the address of the following bunch of\n  --  instructions.\n\n  --  Output the case table as (CASE_Any_Choice, k_CASE_Match_Jump)\n  --  instruction pairs:\n  for K in 1 .. choice_counter loop\n    if case_table (K).Is_others then\n      Emit (CD, k_CASE_Choice_Others);\n    elsif case_table (K).value_1 = case_table (K).value_2 then\n      Emit_1 (CD, k_CASE_Choice_Value, case_table (K).value_1);\n    else\n      Emit_2 (CD, k_CASE_Choice_Range, case_table (K).value_1, case_table (K).value_2);\n    end if;\n    Emit_1 (CD, k_CASE_Match_Jump, Operand_2_Type (case_table (K).LC));\n  end loop;\n  --  The following is for having the interpreter exiting the k_CASE_Choice_Data loop.\n  --  Note: the k_CASE_No_Choice_Found allowed to check a missing \"when others\"\n  --  at run-time. Now this check is done at compile-time by Check_Coverage.\n  Emit (CD, k_CASE_No_Choice_Found);\n  --\n  for K in 1 .. exit_counter loop\n    --  Patch k_Jump addresses to the instruction coming after \"END CASE;\" :\n    CD.ObjCode (exit_table (K)).Y := Operand_2_Type (CD.LC);\n  end loop;\n  Need (CD, END_Symbol,  err_END_missing);             --  END (case)\n  if CD.Sy in LOOP_Symbol | IF_Symbol | IDent then\n    Error (CD, err_missing_closing_CASE_2, severity => minor);\n    In_Symbol;\n  else\n    Need (CD, CASE_Symbol, err_missing_closing_CASE);  --  (end) CASE\n  end if;\nend HAC_Sys.Parser.Statements.CASE_Statement;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-statements.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Calls,\n     HAC_Sys.Parser.Enter_Def,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Ranges,\n     HAC_Sys.PCode,\n     HAC_Sys.Parser.Standard_Procedures,\n     HAC_Sys.Parser.Statements.CASE_Statement,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Statements is\n\n  use type Defs.HAC_Integer;\n\n  procedure Assignment\n    (CD                : in out Co_Defs.Compiler_Data;\n     FSys              :        Defs.Symset;\n     context           :        Defs.Flow_Context;\n     var_id_index      :        Integer;\n     check_is_variable :        Boolean)\n  is\n    use Compiler.PCode_Emit, Co_Defs, Defs, Expressions, Helpers, PCode, Scanner, Errors;\n    var : Identifier_Table_Entry renames CD.id_table (var_id_index);\n    X, Y  : Exact_Subtyp;\n    X_Len : Natural;\n    --\n    procedure Issue_Type_Mismatch_Error is\n    begin\n      Type_Mismatch (CD, err_types_of_assignment_must_match, Found => Y, Expected => X);\n    end Issue_Type_Mismatch_Error;\n    --\n  begin\n    pragma Assert (var.entity in Object_Kind);\n    X := var.xtyp;\n    Emit_2\n     (CD,\n      (if var.normal then\n         k_Push_Address           --  Normal variable, we push its address\n       else\n         k_Push_Discrete_Value),  --  The value is a reference, we want that address.\n      Operand_1_Type (var.lev),\n      Operand_2_Type (var.adr_or_sz));\n    if Selector_Symbol_Loose (CD.Sy) then  --  '.' or '(' or (wrongly) '['\n      --  Resolve composite types' selectors (arrays and records).\n      Selector (CD, context, Becomes_EQL + FSys, X);\n      --  Now, X denotes the leaf type (which can be composite as well).\n    end if;\n    --  Parse the  \":=\"  of  \"X := Y;\"\n    case CD.Sy is\n      when Becomes =>\n        In_Symbol (CD);\n      when EQL =>\n        --  Common mistake by BASIC or C programmers.\n        Error (CD, err_EQUALS_instead_of_BECOMES);\n        In_Symbol (CD);\n      when others =>\n        Error (CD, err_BECOMES_missing);\n    end case;\n\n    if check_is_variable and then var.entity = constant_object then\n      Error (CD, err_cannot_modify_constant_or_in_parameter);\n    end if;\n\n    Expression (CD, context, Semicolon_Set, Y);\n    --\n    if X.TYP = Y.TYP and X.TYP /= NOTYP then\n      if Discrete_Typ (X.TYP) then\n        if Ranges.Do_Ranges_Overlap (X, Y) then\n          if X.Discrete_First > Y.Discrete_First then\n            Compiler.PCode_Emit.Emit_3\n              (CD, k_Check_Lower_Bound, X.Discrete_First, Typen'Pos (X.TYP), Operand_3_Type (X.Ref));\n          end if;\n          if X.Discrete_Last < Y.Discrete_Last then\n            Compiler.PCode_Emit.Emit_3\n              (CD, k_Check_Upper_Bound, X.Discrete_Last, Typen'Pos (X.TYP), Operand_3_Type (X.Ref));\n          end if;\n        else\n          Error\n            (CD, err_range_constraint_error,\n             \"value of expression (\" &\n             (if Ranges.Is_Singleton_Range (Y) then\n                --  More understandable message part for a single value\n                Discrete_Image (CD, Y.Discrete_First, X.TYP, X.Ref)\n              else\n                \"range: \" &\n                Discrete_Range_Image (CD, Y.Discrete_First, Y.Discrete_Last, X.TYP, X.Ref)) &\n             \") is out of destination's range, \" &\n             Discrete_Range_Image (CD, X.Discrete_First, X.Discrete_Last, X.TYP, X.Ref),\n             severity => minor);\n        end if;\n      end if;\n      if X.TYP in Standard_Typ then\n        Emit_1 (CD, k_Store, Typen'Pos (X.TYP));\n      elsif X.Ref /= Y.Ref then\n        Issue_Type_Mismatch_Error;  --  E.g. different arrays, enums, ...\n      else\n        case X.TYP is\n          when Arrays =>\n            Emit_1 (CD, k_Copy_Block, Operand_2_Type (CD.Arrays_Table (X.Ref).Array_Size));\n          when Records =>\n            Emit_1 (CD, k_Copy_Block, Operand_2_Type (CD.Blocks_Table (X.Ref).VSize));\n          when Enums =>\n            --  Behaves like a \"Standard_Typ\".\n            --  We have checked that X.Ref = Y.Ref (same actual type).\n            Emit_1 (CD, k_Store, Typen'Pos (X.TYP));\n          when others =>\n            raise Internal_error with \"Assignment: X := Y on unsupported Typ ?\";\n        end case;\n      end if;\n    else\n      --\n      --  Here, X.TYP and Y.TYP are different.\n      --\n      if X.TYP = Floats and Y.TYP = Ints then\n        Forbid_Type_Coercion (CD, Found => Y, Expected => X);\n      elsif X.TYP = Durations and Y.TYP = Floats then\n        --  Duration hack (see Delay_Statement for full explanation).\n        Emit_Std_Funct (CD, SF_Float_to_Duration);\n        Emit_1 (CD, k_Store, Typen'Pos (X.TYP));\n      elsif Is_Char_Array (CD, X) and Y.TYP = String_Literals then\n        X_Len := CD.Arrays_Table (X.Ref).Array_Size;\n        if X_Len = CD.SLeng then\n          Emit_1 (CD, k_String_Literal_Assignment, Operand_2_Type (X_Len));\n        else\n          Error (CD, err_string_lengths_do_not_match,\n            \"variable has length\" & Integer'Image (X_Len) &\n            \", literal has length\" & Integer'Image (CD.SLeng),\n            severity => minor);\n        end if;\n      elsif X.TYP = VStrings\n        and then\n          (Y.TYP in String_Literals | Strings_as_VStrings\n           or else Is_Char_Array (CD, Y))\n      then\n        Error (CD, err_string_to_vstring_assignment);\n      elsif X.TYP = NOTYP then\n        if CD.error_count = 0 then\n          raise Internal_error with \"Assignment: assigned variable (X) is typeless\";\n        end if;\n        --  All right, there were already enough compilation error messages...\n      elsif Y.TYP = NOTYP then\n        if CD.error_count = 0 then\n          raise Internal_error with \"Assignment: assigned value (Y) is typeless\";\n        end if;\n        --  All right, there were already enough compilation error messages...\n      else\n        Issue_Type_Mismatch_Error;\n        --  NB: We are in the X.TYP /= Y.TYP case.\n      end if;\n    end if;\n  end Assignment;\n\n  procedure Statement  --  Ada RM 5.1 (3)\n    (CD         : in out Co_Defs.Compiler_Data;\n     FSys_St    :        Defs.Symset;\n     block_data : in out Block_Data_Type);\n\n  procedure Sequence_of_Statements  --  Ada RM 5.1 (2)\n    (CD         : in out Co_Defs.Compiler_Data;\n     sentinel   :        Defs.Symset;\n     block_data : in out Block_Data_Type;\n     optional   :        Boolean := False)\n  is\n    use Defs, Helpers, Errors;\n    statement_or_sentinel : constant Symset := Statement_Begin_Symbol or sentinel;\n  begin\n    if sentinel (CD.Sy) and then not optional then\n      --  GdM 15-Aug-2014: there should be at least one statement.\n      --\n      --  But in some places in the grammar the sequence is optional:\n      --  in an accept_alternative and in a delay_alternative.\n      --  In both cases the sequence follow a first statement (accept or delay).\n      Error (CD, err_statement_expected, severity => minor);\n    else\n      loop\n        Statement (CD, statement_or_sentinel, block_data);\n        exit when sentinel (CD.Sy) or else CD.error_count > 0;\n      end loop;\n    end if;\n  end Sequence_of_Statements;\n\n  procedure Sequence_of_Statements_in_a_Conditional_Statement\n    (CD         : in out Co_Defs.Compiler_Data;\n     sentinel   :        Defs.Symset;\n     block_data : in out Block_Data_Type;\n     optional   :        Boolean := False)\n  is\n    old_context : constant Defs.Flow_Context := block_data.context;\n  begin\n    block_data.context.is_within_condition := True;\n    block_data.context.is_in_cond_within_loop := block_data.context.is_within_loop;\n    --\n    Sequence_of_Statements (CD, sentinel, block_data, optional);\n    --\n    block_data.context := old_context;\n  end Sequence_of_Statements_in_a_Conditional_Statement;\n\n  ------------------------------------------------------------------\n  --------------------------------------Statement - Ada RM 5.1 (3)--\n  procedure Statement\n    (CD         : in out Co_Defs.Compiler_Data;\n     FSys_St    :        Defs.Symset;\n     block_data : in out Block_Data_Type)\n  is\n    use Compiler.PCode_Emit, Calls, Co_Defs, Defs, Enter_Def, Expressions,\n        Helpers, PCode, Errors;\n    use type Alfa;\n\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n\n    procedure Accept_Statement is            -- Hathorn\n\n      procedure Accept_Call is\n      begin   --  !!  Check to make sure parameters match with Entry Statement\n        if CD.Sy = Semicolon then\n          return;\n        end if;\n        if CD.Sy = LParent then          -- <--- temporary\n          while not (CD.Sy = DO_Symbol or CD.Sy = RParent) loop\n            In_Symbol;\n          end loop; -- !! should check no. and\n        end if;    -- Types of parms.\n        if CD.Sy = RParent then\n          In_Symbol;\n        end if;\n      end Accept_Call;\n\n      I_Entry : Integer;\n    begin  --  Accept_Statement\n      In_Symbol;\n      I_Entry := Locate_CD_Id (CD, block_data.context.level);\n      if CD.id_table (I_Entry).entity /= entree then\n        Error (CD, err_general_error, \"an entry name is expected here\");\n      else\n        CD.target.Mark_Reference (I_Entry);\n      end if;\n      In_Symbol;\n      Accept_Call;\n      Emit_1 (CD, k_Accept_Rendezvous, Operand_2_Type (I_Entry));\n      if CD.Sy = DO_Symbol then\n        if block_data.context.level = nesting_level_max then\n          Fatal (LEVELS);  --  Exception is raised there.\n        end if;\n        block_data.context.level := block_data.context.level + 1;\n        CD.Display (block_data.context.level) := CD.id_table (I_Entry).block_or_pkg_ref;\n        In_Symbol;\n        Sequence_of_Statements (CD, END_Set, block_data);\n        Need_END_Symbol (CD);\n        if CD.Sy = IDent then\n          if CD.Id /= CD.id_table (I_Entry).name then\n            Error (CD, err_incorrect_name_after_END);\n          else\n            CD.target.Mark_Reference (I_Entry);\n          end if;\n          In_Symbol;\n        end if;\n        block_data.context.level := block_data.context.level - 1;\n      end if;\n      Emit_1 (CD, k_End_Rendezvous, Operand_2_Type (I_Entry));\n    end Accept_Statement;\n\n    procedure Exit_Statement is  --  RM 5.7\n      --  Generate an absolute branch statement with a dummy end loop address\n      X : Exact_Subtyp;\n      exit_level : Natural := CD.loop_nesting_level;\n      id_found : Boolean;\n      count_FOR_loops : Natural := 0;\n      landing_after_jump : Integer;\n      conditional : Boolean := False;\n    begin\n      pragma Assert (CD.Sy = EXIT_Symbol);\n      In_Symbol;  --  Consume EXIT symbol.\n      if CD.loop_nesting_level = 0 then\n        Error\n          (CD,\n           err_general_error,\n           \"\"\"exit\"\" without a \"\"loop\"\" - was \"\"return\"\" intended?\",\n           severity => major);\n        --  Exception raised, compilation stopped.\n      end if;\n      --  Possible name:\n      if CD.Sy = IDent then\n        id_found := False;\n        for level in reverse 1 .. CD.loop_nesting_level loop\n          if CD.Nested_Loop_Table (level).is_FOR_loop then\n            count_FOR_loops := count_FOR_loops + 1;\n          end if;\n          if CD.Nested_Loop_Table (level).loop_Id /= No_Id\n            and then CD.Id = CD.id_table (CD.Nested_Loop_Table (level).loop_Id).name\n          then\n            id_found := True;\n            exit_level := level;\n            exit;\n          end if;\n        end loop;\n        if not id_found then\n          Error (CD, err_general_error, \"loop name not matched: \" & A2S (CD.Id_with_case));\n        end if;\n        In_Symbol;  --  Consume the identifier.\n      else\n        --  EXIT without a name.\n        if CD.Nested_Loop_Table (CD.loop_nesting_level).is_FOR_loop then\n          count_FOR_loops := 1;\n        end if;\n      end if;\n      if CD.Sy = WHEN_Symbol then  --  Conditional Exit\n        In_Symbol;  --  Consume WHEN symbol.\n        Boolean_Expression (CD, block_data.context, Semicolon_Set, X);\n        --  On False, conditional jump around Exit:\n        if count_FOR_loops = 0 then\n          landing_after_jump := CD.LC + 2;\n        else\n          landing_after_jump := CD.LC + 3;\n        end if;\n        Emit_1 (CD, k_Jump_If_Zero_With_Pop, Operand_2_Type (landing_after_jump));\n        conditional := True;\n      end if;\n      --  De-stacking for all FOR loops.\n      if count_FOR_loops > 0 then\n        Emit_1 (CD, k_FOR_Release_Stack, Operand_2_Type (count_FOR_loops));\n      end if;\n      --  Unconditional jump with dummy address to be patched:\n      Emit_1 (CD, k_Jump, dummy_address_loop - Operand_2_Type (exit_level));\n      pragma Assert ((not conditional) or else CD.LC = landing_after_jump);\n    end Exit_Statement;\n\n    procedure IF_Statement is\n      X        : Exact_Subtyp;\n      LC0, LC1 : Integer;\n    begin\n      In_Symbol;\n      Boolean_Expression (CD, block_data.context, FSys_St + DO_THEN, X);\n      LC1 := CD.LC;\n      Emit (CD, k_Jump_If_Zero_With_Pop);\n      Need (CD, THEN_Symbol, err_THEN_missing, Forgive => DO_Symbol);\n      --  Statements after \"THEN\":\n      Sequence_of_Statements_in_a_Conditional_Statement (CD, ELSE_ELSIF_END, block_data);\n      LC0 := CD.LC;\n      --\n      while CD.Sy = ELSIF_Symbol loop\n        In_Symbol;\n        Emit_1 (CD, k_Jump, dummy_address_if);  --  Unconditional jump with dummy address to be patched\n        CD.ObjCode (LC1).Y := Operand_2_Type (CD.LC);       --  Patch the previous conditional jump\n        Boolean_Expression (CD, block_data.context, FSys_St + DO_THEN, X);\n        LC1 := CD.LC;\n        Emit (CD, k_Jump_If_Zero_With_Pop);\n        Need (CD, THEN_Symbol, err_THEN_missing, Forgive => DO_Symbol);\n        --  Statements after \"ELSIF .. THEN\":\n        Sequence_of_Statements_in_a_Conditional_Statement (CD, ELSE_ELSIF_END, block_data);\n      end loop;\n      --\n      if CD.Sy = ELSE_Symbol then\n        In_Symbol;\n        Emit_1 (CD, k_Jump, dummy_address_if);  --  Jump to \"END IF\" - dummy address to be patched.\n        CD.ObjCode (LC1).Y := Operand_2_Type (CD.LC);\n        --  Statements after \"ELSE\":\n        Sequence_of_Statements_in_a_Conditional_Statement (CD, END_Set, block_data);\n      else\n        CD.ObjCode (LC1).Y := Operand_2_Type (CD.LC);\n      end if;\n      Need (CD, END_Symbol, err_END_missing);           --  END (if)\n      if CD.Sy in CASE_Symbol | LOOP_Symbol | IDent then\n        Error (CD, err_missing_closing_IF_2, severity => minor);\n        In_Symbol;\n      else\n        Need (CD, IF_Symbol,  err_missing_closing_IF);  --  (end) IF\n      end if;\n      --  Go back and patch the dummy addresses in unconditional jumps\n      Patch_Addresses (CD.ObjCode (LC0 .. CD.LC), dummy_address_if);\n    end IF_Statement;\n\n    procedure LOOP_Statement\n      (FCT_Loop_End : Opcode;  --  Instruction for jumping back to loop begin.\n       LC_At_Begin  : Integer;\n       info         : Loop_Info)\n    is\n      LC0 : constant Integer := CD.LC;\n      old_is_within_loop : constant Boolean := block_data.context.is_within_loop;\n    begin\n      CD.loop_nesting_level := CD.loop_nesting_level + 1;\n      if CD.loop_nesting_level > loop_nesting_max then\n        Fatal (Loop_Nesting_Levels);  --  Exception is raised there.\n      end if;\n      CD.Nested_Loop_Table (CD.loop_nesting_level) := info;\n      if CD.Sy = LOOP_Symbol then\n        In_Symbol;\n      else\n        Error_then_Skip (CD, Statement_Begin_Symbol, err_missing_closing_IF);\n      end if;\n      block_data.context.is_within_loop := True;\n      Sequence_of_Statements (CD, END_Set, block_data);\n      block_data.context.is_within_loop := old_is_within_loop;\n      Emit_1 (CD, FCT_Loop_End, Operand_2_Type (LC_At_Begin));\n      Need (CD, END_Symbol,  err_END_missing);             --  END (loop)\n      if CD.Sy in CASE_Symbol | IF_Symbol | IDent then\n        Error (CD, err_missing_closing_LOOP_2, severity => minor);\n        In_Symbol;\n      else\n        Need (CD, LOOP_Symbol, err_missing_closing_LOOP);  --  (end) LOOP\n      end if;\n      --  Go back and patch the dummy addresses generated by Exit statements.\n      Patch_Addresses\n        (CD.ObjCode (LC0 .. CD.LC), dummy_address_loop - Operand_2_Type (CD.loop_nesting_level));\n      CD.loop_nesting_level := CD.loop_nesting_level - 1;\n    end LOOP_Statement;\n\n    procedure RETURN_Statement is           -- Hathorn\n      --  Generate a procedure or function return Statement, calculate return value if req'D.\n      X, Y : Exact_Subtyp;\n      procedure Issue_Type_Mismatch_Error is\n      begin\n        Type_Mismatch (CD, err_type_of_return_statement_doesnt_match, Found => Y, Expected => X);\n      end Issue_Type_Mismatch_Error;\n    begin\n      In_Symbol;\n      if CD.Sy = Semicolon then\n        --  RETURN;\n        if block_data.entity = funktion then\n          Error (CD, err_functions_must_return_a_value);\n        end if;\n      else\n        --  RETURN x;\n        if block_data.entity = prozedure then\n          Error (CD, err_procedures_cannot_return_a_value, severity => major);\n        end if;\n        block_data.return_statement_seen := True;\n        --  Calculate return value (destination: X; expression: Y).\n        if CD.id_table (block_data.block_id_index).block_or_pkg_ref /= CD.Display (block_data.context.level) then\n          raise Program_Error with\n            \"Is it `return x` from main? Issue should have been caught earlier: \" &\n            \"err_procedures_cannot_return_a_value.\";\n        end if;\n        X := CD.id_table (block_data.block_id_index).xtyp;\n        Emit_2\n          (CD,\n           (if CD.id_table (block_data.block_id_index).normal then\n              k_Push_Address\n            else\n              k_Push_Value),\n          Operand_1_Type (CD.id_table (block_data.block_id_index).lev + 1),\n          0);\n        --\n        Expression (CD, block_data.context, Semicolon_Set, Y);\n        if X.TYP = Y.TYP then\n          if (X.TYP in Standard_Typ)\n            or else (X.TYP = Enums and then Exact_Typ (X) = Exact_Typ (Y))\n          then\n            Emit_1 (CD, k_Store, Typen'Pos (X.TYP));\n          elsif X.Ref /= Y.Ref then\n            Issue_Type_Mismatch_Error;\n          end if;\n        elsif X.TYP = Floats and Y.TYP = Ints then\n          Forbid_Type_Coercion (CD, Found => Y, Expected => X);\n        elsif X.TYP /= NOTYP and Y.TYP /= NOTYP then\n          Issue_Type_Mismatch_Error;\n        end if;\n      end if;\n      if block_data.entity = funktion then\n        Emit_1 (CD, k_Return_Function, Normal_Procedure_Call);\n      elsif block_data.is_main then\n        CD.target.Emit_Halt;\n      else\n        Emit_1 (CD, k_Return_Call, Normal_Procedure_Call);\n      end if;\n    end RETURN_Statement;\n\n    procedure Delay_Statement is            -- Cramer. Generate a Task delay.\n      Y : Exact_Subtyp;\n    begin\n      In_Symbol;\n      if CD.Sy = Semicolon then\n        Error_then_Skip (CD, Semicolon, err_missing_expression_for_delay);\n      else\n        Expression (CD, block_data.context, Semicolon_Set, Y);\n        if Y.TYP /= Floats and Y.TYP /= Durations then\n          Error (CD, err_wrong_type_in_DELAY);\n        end if;\n        if Y.TYP = Floats then\n          --  Duration hack: for expressions like 2.0 * 3600.0, we don't\n          --  know in advance it's not a Duration. Check with a \"full\n          --  Ada\" compiler the type conformity of the expression.\n          Emit_Std_Funct (CD, SF_Float_to_Duration);\n        end if;\n      end if;\n      Emit (CD, k_Delay);\n    end Delay_Statement;\n\n    procedure WHILE_Statement (loop_Id : Natural) is  --  RM 5.5 (8)\n      X : Exact_Subtyp;\n      LC_Cond_Eval, LC_Cond_Jump : Integer;\n      line_number : constant Natural := CD.CUD.location.line;\n    begin\n      In_Symbol;  --  Consume WHILE symbol.\n      LC_Cond_Eval := CD.LC;\n      Boolean_Expression (CD, block_data.context, FSys_St + DO_LOOP, X);\n      LC_Cond_Jump := CD.LC;\n      Emit (CD, k_Jump_If_Zero_With_Pop);\n      LOOP_Statement (k_Jump, LC_Cond_Eval, (loop_Id, False, line_number));\n      CD.ObjCode (LC_Cond_Jump).Y := Operand_2_Type (CD.LC);\n    end WHILE_Statement;\n\n    procedure FOR_Statement (label_Id : Natural) is  --  RM 5.5 (9)\n      FOR_Begin_Instruction : Opcode;  --  Forward  or  Reverse\n      LC_FOR_Begin,\n      loop_param_id_index,\n      previous_last : Index;\n      loop_param_id, loop_param_id_with_case : Alfa;\n      line_number : constant Natural := CD.CUD.location.line;\n    begin\n      --\n      --  Pushed on the stack:\n      --     - address of the loop parameter (a temporary iterator variable)\n      --     - lower bound value\n      --     - upper bound value\n      --\n      In_Symbol;  --  Consume FOR symbol.\n      if CD.Sy = IDent then\n\n        if CD.Id_Count = Id_Table_Max then\n          Fatal (IDENTIFIERS);  --  Exception is raised there.\n        end if;\n\n        --  Declare local loop control Variable  --  added Hathorn\n        previous_last := CD.Blocks_Table (CD.Display (block_data.context.level)).Last_Id_Idx;\n        CD.Id_Count := CD.Id_Count + 1;\n\n        loop_param_id_index     := CD.Id_Count;\n        loop_param_id           := CD.Id;\n        loop_param_id_with_case := CD.Id_with_case;\n\n        CD.id_table (loop_param_id_index) :=  --  Loop parameter: the \"i\" in  \"for i in 1..10 loop\"\n          (name                  => Empty_Alfa,  --  Hide name because of \"for i in 1 .. i loop\"\n           name_with_case        => Empty_Alfa,\n           link                  => previous_last,\n           entity                => constant_object,\n           decl_kind             => complete,\n           xtyp                  => undefined_subtyp,  --  Subtype is determined by the range.\n           block_or_pkg_ref      => 0,\n           normal                => True,\n           lev                   => block_data.context.level,\n           adr_or_sz             => HAC_Integer (block_data.data_allocation_index),\n           is_referenced         => False,\n           is_read               => no,\n           is_written_after_init => yes,\n           is_initialized        => explicit,\n           location              => (0, 0, 0));\n\n        CD.target.Mark_Declaration;\n        CD.Blocks_Table (CD.Display (block_data.context.level)).Last_Id_Idx  := loop_param_id_index;\n        block_data.data_allocation_index := block_data.data_allocation_index + 1;\n        block_data.max_data_allocation_index :=\n          Integer'Max (block_data.max_data_allocation_index, block_data.data_allocation_index);\n        CD.Blocks_Table (CD.Display (block_data.context.level)).VSize := block_data.max_data_allocation_index;\n      else\n        Error (CD, err_identifier_missing, severity => major);\n      end if;\n\n      Emit_2\n        (CD, k_Push_Address,\n         Operand_1_Type (CD.id_table (loop_param_id_index).lev),\n         Operand_2_Type (CD.id_table (loop_param_id_index).adr_or_sz));\n      In_Symbol;\n      FOR_Begin_Instruction := k_FOR_Forward_Begin;\n      Need (CD, IN_Symbol, err_IN_missing);  --       \"IN\"  in  \"for i in reverse 1 .. 10 loop\"\n      if CD.Sy = REVERSE_Symbol then         --  \"REVERSE\"  in  \"for i in reverse 1 .. 10 loop\"\n        FOR_Begin_Instruction := k_FOR_Reverse_Begin;\n        In_Symbol;\n      end if;\n      Ranges.Dynamic_Range\n        (CD, block_data.context, FSys_St,\n         err_control_variable_of_the_wrong_type,\n         CD.id_table (loop_param_id_index).xtyp);\n         --  ^ Last parameter: set the subtype of \"c\" in \"for c in Red .. Blue loop\"\n      LC_FOR_Begin := CD.LC;\n      Emit (CD, FOR_Begin_Instruction);\n      CD.id_table (loop_param_id_index).name           := loop_param_id;            --  Unhide name\n      CD.id_table (loop_param_id_index).name_with_case := loop_param_id_with_case;  --  Unhide name\n\n      LOOP_Statement\n        (For_END_Instruction (FOR_Begin_Instruction), CD.LC, (label_Id, True, line_number));\n\n      --  Patch the loop control exit address; points to the code\n      --  just after the loop's end:\n      CD.ObjCode (LC_FOR_Begin).Y := Operand_2_Type (CD.LC);\n      block_data.data_allocation_index := block_data.data_allocation_index - 1;\n      --\n      --  Make the loop parameter unusable. The .name_with_case is still\n      --  visible for the compiler dump. Previously, the identifier counter\n      --  was decreased, but that method conflicted with the necessity of\n      --  keeping all loop names within a block.\n      CD.id_table (loop_param_id_index).name := Empty_Alfa;\n    end FOR_Statement;\n\n    procedure Select_Statement is\n      procedure Select_Error (N : Compile_Diagnostic) is\n      begin\n        Error_then_Skip (CD, Semicolon, N);\n      end Select_Error;\n\n      --  Either a Timed or Conditional Entry Call.\n\n      procedure Qualified_Entry_Call is\n        I, J, IStart, IEnd : Integer;\n        patch              : array (0 .. 4) of Integer;\n        O                  : Order;\n        Y                  : Exact_Subtyp;\n      begin\n        I := Locate_CD_Id (CD, block_data.context.level);\n        if CD.id_table (I).entity = tache then\n          In_Symbol;\n          Entry_Call (CD, block_data.context, FSys_St, I, -1);\n          if CD.ObjCode (CD.LC - 2).F = k_Call then  --  Need to patch CallType later\n            patch (0) := CD.LC - 2;\n          else\n            patch (0) := CD.LC - 3;\n          end if;       -- LC-1 must be OP=3, update Display\n          patch (1) := CD.LC;  --  Need to patch in JMPC address later\n          Emit_1 (CD, k_Jump_If_Zero_With_Pop, dummy_address_if);  --  JMPC, address patched in after ELSE\n                                    --  or OR\n          if CD.Sy = Semicolon then\n            In_Symbol;\n          else\n            Error_then_Skip (CD, Semicolon, err_semicolon_missing);\n          end if;\n          if CD.Sy not in OR_Symbol | ELSE_Symbol then\n            Sequence_of_Statements (CD, ELSE_OR, block_data);\n          end if;\n          if CD.Sy = OR_Symbol then  --  =====================> Timed Entry Call\n            CD.ObjCode (patch (0)).X     := Timed_Entry_Call;\n            CD.ObjCode (patch (0) + 1).Y := Timed_Entry_Call;  --  Exit type matches Entry type\n            In_Symbol;\n            if CD.Sy = DELAY_Symbol then\n              In_Symbol;\n              if CD.Sy = Semicolon then\n                Select_Error (err_missing_expression_for_delay);\n              else          --  Calculate delay value\n                patch (2) := CD.LC;\n                Expression (CD, block_data.context, Semicolon_Set, Y);\n                patch (3) := CD.LC - 1;\n                if Y.TYP /= Floats then\n                  Select_Error (err_wrong_type_in_DELAY);\n                else        --  End of timed Entry select ObjCode, do patching\n                  CD.ObjCode (patch (1)).Y := Operand_2_Type (CD.LC);  --  if Entry not made, skip rest\n                  J                      := patch (3) - patch (2) + 1;\n                  IStart                 := patch (0);\n                  IEnd                   := CD.LC - 1;\n                  while J > 0 loop           --  Move delay time ObjCode To before\n                    O := CD.ObjCode (IEnd);  --  opcodes k_Call, k_Return_Call.\n                    for I in reverse IEnd - 1 .. IStart loop\n                      CD.ObjCode (I + 1) := CD.ObjCode (I);\n                    end loop;\n                    CD.ObjCode (IStart) := O;\n                    J                   := J - 1;\n                  end loop;\n                  In_Symbol;\n                end if;\n              end if;\n            else\n              Select_Error (err_expecting_DELAY);\n            end if;\n          --  end Sy = OrSy\n          else              -- Sy = ELSE_Symbol, ===============> Conditional Entry Call\n            CD.ObjCode (patch (0)).X     := Conditional_Entry_Call;\n            CD.ObjCode (patch (0) + 1).Y := Conditional_Entry_Call;\n            patch (2)                    := CD.LC;\n            Emit_1 (CD, k_Jump, dummy_address_if);  -- JMP, address patched in after END SELECT\n            patch (3) := CD.LC;\n            In_Symbol;\n            Sequence_of_Statements (CD, END_Set, block_data);\n            CD.ObjCode (patch (1)).Y  := Operand_2_Type (patch (3));\n            CD.ObjCode (patch (2)).Y  := Operand_2_Type (CD.LC);\n          end if;\n          if CD.Sy /= END_Symbol then\n            Select_Error (err_END_missing);\n          end if;\n          In_Symbol;\n          if CD.Sy /= SELECT_Symbol then\n            Select_Error (err_SELECT_missing);\n          end if;\n        else\n          Select_Error (err_expecting_task_entry);\n        end if;          -- Task.Entry Call expected\n      end Qualified_Entry_Call;\n\n      procedure Selective_Wait is         -- Kurtz <===================\n        --  Jay, this Buds for you !!\n        JSD, Alt_Patch      : Fixed_Size_Patch_Table;\n        ISD, IAlt, StartSel : Integer;\n        SelectDone          : Boolean;\n        X, Y                : Exact_Subtyp;\n        do_terminate        : Boolean;\n\n        procedure Accept_Statement_2 is      -- Kurtz\n\n          procedure Accept_Call_2 is\n          begin\n            --  Check to make sure parameters match with Entry Statement\n            if CD.Sy = Semicolon then\n              return;\n            end if;\n            if CD.Sy = LParent then      -- should be modified\n              --  To check no. and\n              while not (CD.Sy = DO_Symbol or CD.Sy = RParent) loop\n                In_Symbol;\n              end loop;\n            end if;        -- of parameters.\n            if CD.Sy = RParent then\n              In_Symbol;\n            end if;\n          end Accept_Call_2;\n\n          I : Integer;\n        begin         -- Accept_Statment_2\n          In_Symbol;\n          I := Locate_CD_Id (CD, block_data.context.level);\n          if CD.id_table (I).entity /= entree then\n            Select_Error (err_general_error);\n          else\n            CD.target.Mark_Reference (I);\n          end if;\n          In_Symbol;\n          Accept_Call_2;\n          Emit_2 (CD, k_Selective_Wait, 2, Operand_2_Type (I));      --  Retain Entry Index\n          Feed_Patch_Table (Alt_Patch, IAlt, CD.LC);\n          Emit_2 (CD, k_Selective_Wait, 3, Operand_2_Type (CD.LC));  --  ACCEPT IF Ready ELSE Skip To LC\n          --  CONDITIONAL ACCEPT MUST BE ATOMIC\n          if CD.Sy = DO_Symbol then\n            if block_data.context.level = nesting_level_max then\n              Fatal (LEVELS);  --  Exception is raised there.\n            end if;\n            block_data.context.level := block_data.context.level + 1;\n            CD.Display (block_data.context.level) := CD.id_table (I).block_or_pkg_ref;\n            In_Symbol;\n            Sequence_of_Statements (CD, END_Set, block_data);\n            Need_END_Symbol (CD);\n            if CD.Sy = IDent then\n              if CD.Id /= CD.id_table (I).name then\n                Select_Error (err_incorrect_name_after_END);\n              else\n                CD.target.Mark_Reference (I);\n              end if;\n            end if;\n            block_data.context.level := block_data.context.level - 1;\n            In_Symbol;\n          end if;\n          Emit_1 (CD, k_End_Rendezvous, Operand_2_Type (I));\n        end Accept_Statement_2;\n\n      begin  --  Selective_Wait ===============================> Kurtz\n        ISD          := 0;\n        IAlt         := 0;\n        SelectDone   := False;\n        do_terminate := False;\n        StartSel     := CD.LC;\n        Emit_2 (CD, k_Selective_Wait, 1, 0);  --  START OF SELECT SELECTIVE Wait SEQUENCE\n        loop\n          case CD.Sy is\n            when WHEN_Symbol =>\n              Patch_Addresses (CD.ObjCode (CD.ObjCode'First .. CD.LC), Alt_Patch, IAlt);\n              In_Symbol;  --  Consume WHEN symbol.\n              Boolean_Expression (CD, block_data.context, FSys_St + Finger, X);\n              In_Symbol;\n              case CD.Sy is\n                when ACCEPT_Symbol =>\n                  Feed_Patch_Table (Alt_Patch, IAlt, CD.LC);\n                  Emit (CD, k_Jump_If_Zero_With_Pop);\n                  Accept_Statement_2;\n                when DELAY_Symbol =>\n                  Feed_Patch_Table (Alt_Patch, IAlt, CD.LC);\n                  Emit (CD, k_Jump_If_Zero_With_Pop);\n                  In_Symbol;\n                  Expression (CD, block_data.context, FSys_St + Semicolon, Y);\n                  Emit_2 (CD, k_Selective_Wait, 4, Operand_2_Type (CD.LC + 2));  --  Update delay time\n                  if Y.TYP /= Floats then\n                    Select_Error (err_wrong_type_in_DELAY);\n                  end if;\n                  Feed_Patch_Table (Alt_Patch, IAlt, CD.LC);\n                  Emit (CD, k_Jump);\n                when others =>\n                  Select_Error (err_missing_a_procedure_declaration);  --  ??\n              end case;\n              In_Symbol;\n              Sequence_of_Statements (CD, ELSE_END_OR, block_data, True);\n              Feed_Patch_Table (JSD, ISD, CD.LC);\n              Emit (CD, k_Jump);          --  patch JMP ADDRESS AT EndSy\n            --  end WHEN_Symbol\n\n            when ACCEPT_Symbol =>\n              Patch_Addresses (CD.ObjCode (CD.ObjCode'First .. CD.LC), Alt_Patch, IAlt);\n              Accept_Statement_2;\n              In_Symbol;\n              Sequence_of_Statements (CD, ELSE_END_OR, block_data, True);\n              Feed_Patch_Table (JSD, ISD, CD.LC);\n              Emit (CD, k_Jump);\n\n            when OR_Symbol =>\n              In_Symbol;  --  Consume OR symbol.\n\n            when ELSE_Symbol =>\n              Patch_Addresses (CD.ObjCode (CD.ObjCode'First .. CD.LC), Alt_Patch, IAlt);\n              In_Symbol;\n              Sequence_of_Statements (CD, END_Set, block_data);\n              Feed_Patch_Table (JSD, ISD, CD.LC);\n              Emit (CD, k_Jump);\n\n            when DELAY_Symbol =>\n              Patch_Addresses (CD.ObjCode (CD.ObjCode'First .. CD.LC), Alt_Patch, IAlt);\n              --  Generate a Task delay, calculate return value if req'D\n              In_Symbol;\n              if CD.Sy = Semicolon then\n                Error_then_Skip (CD, Semicolon, err_missing_expression_for_delay);\n              else          -- calculate return value\n                Expression (CD, block_data.context, Semicolon_Set, Y);\n                Emit_2 (CD, k_Selective_Wait, 4, Operand_2_Type (CD.LC + 2));  --  Update delay time\n                if Y.TYP /= Floats then\n                  Select_Error (err_wrong_type_in_DELAY);\n                end if;\n                Feed_Patch_Table (Alt_Patch, IAlt, CD.LC);\n                Emit (CD, k_Jump);\n              end if;\n              In_Symbol;\n              Sequence_of_Statements (CD, ELSE_END_OR, block_data, True);\n              Feed_Patch_Table (JSD, ISD, CD.LC);\n              Emit (CD, k_Jump);\n\n            when TERMINATE_Symbol =>\n              In_Symbol;\n              if CD.Sy /= Semicolon then\n                Select_Error (err_semicolon_missing);\n              end if;\n              do_terminate := True;        -- Oguz\n              In_Symbol;\n\n            when END_Symbol =>\n              In_Symbol;\n              if CD.Sy /= SELECT_Symbol then\n                Select_Error (err_END_missing);\n              end if;\n              SelectDone := True;\n              Patch_Addresses (CD.ObjCode (CD.ObjCode'First .. CD.LC), Alt_Patch, IAlt);\n              if do_terminate then\n                Emit_2 (CD, k_Selective_Wait, 5, Operand_2_Type (StartSel));\n              else\n                Emit_2 (CD, k_Selective_Wait, 6, Operand_2_Type (StartSel));\n              end if;   -- Suspend\n              Patch_Addresses (CD.ObjCode (CD.ObjCode'First .. CD.LC), JSD, ISD);\n\n            when others =>\n              SelectDone := True;\n          end case;\n          exit when SelectDone;\n        end loop;\n      end Selective_Wait;\n\n    begin\n      In_Symbol;  --  Consume SELECT symbol.\n      case CD.Sy is\n        when ACCEPT_Symbol | WHEN_Symbol =>\n          Selective_Wait;\n          In_Symbol;\n        when IDent =>  --  Task Entry objectName.\n          Qualified_Entry_Call;\n          In_Symbol;\n          --  Timed or Conditional Entry Call (?)\n        when others =>\n          Select_Error (err_expecting_accept_when_or_entry_id);\n      end case;\n    end Select_Statement;\n\n    procedure Block_Statement (block_name : Alfa) is  --  RM: 5.6\n      block_statement_data : Block_Data_Type;\n    begin\n      Error (\n        CD, err_not_yet_implemented,\n        hint_1 => \"Block statements don't work yet\",\n        severity => major\n      );\n      --\n      block_statement_data.context.level                 := block_data.context.level + 1;\n      block_statement_data.block_id_index                := CD.Id_Count;\n      block_statement_data.entity                        := block_data.entity;\n      block_statement_data.is_main                       := False;\n      block_statement_data.previous_declaration_id_index := No_Id;\n      Block (CD, FSys_St, True, block_statement_data, block_name, block_name);  --  !! up/low case\n      --\n      --  !! to check:\n      --  !! * stack management of variables when entering / quitting the block\n      --  !! * object code and nesting... works on some cases at least (test.adb) !...\n      --  !! Perhaps keep same level but have local declarations as for the\n      --    variable in a FOR_Statement.\n      --  !! Either both FOR and Block statements forget their definitions, or there\n      --    is perhaps a problem with the stack (DX).\n      --  !! Local bodies of subprograms surely mess the object code.\n    end Block_Statement;\n\n    procedure Named_Statement is\n      --  Block_Statement or loop, named by a label, like this:\n      --    \"name : loop\".\n      --  We remember the identifier for checking purposes.\n      new_ident_for_statement           : constant Alfa := CD.Id;\n      new_ident_for_statement_with_case : constant Alfa := CD.Id_with_case;\n      --\n      procedure Check_ID_after_END_LOOP is  --  RM 5.5 (5)\n        procedure Boom (err : Compile_Diagnostic) is\n        begin\n          Error (CD, err, A2S (new_ident_for_statement_with_case));\n        end Boom;\n      begin\n        if CD.Sy = IDent then\n          if CD.Id /= new_ident_for_statement then\n            Boom (err_END_LOOP_ident_wrong);\n          end if;\n          In_Symbol;  --  Consume identifier.\n        else\n          Boom (err_END_LOOP_ident_missing);\n        end if;\n      end Check_ID_after_END_LOOP;\n      --\n      dummy_idx : Natural;\n    begin\n      Enter_Simple\n        (CD,\n         block_data.context.level,\n         new_ident_for_statement,\n         new_ident_for_statement_with_case,\n         loop_identifier,\n         dummy_idx);\n      if CD.Sy /= Colon then\n        Error\n          (CD,\n           err_colon_missing_for_named_statement,\n           A2S (new_ident_for_statement_with_case),\n           severity => major);\n      end if;\n      In_Symbol;  --  Consume ':' symbol.\n      case CD.Sy is\n        when BEGIN_Symbol | DECLARE_Symbol => -- Named Block_Statement\n          Block_Statement (new_ident_for_statement);\n        when FOR_Symbol =>\n          FOR_Statement (CD.Id_Count);\n          Check_ID_after_END_LOOP;\n        when LOOP_Symbol =>\n          LOOP_Statement (k_Jump, CD.LC, (CD.Id_Count, False, CD.CUD.location.line));\n          Check_ID_after_END_LOOP;\n        when WHILE_Symbol =>\n          WHILE_Statement (CD.Id_Count);\n          Check_ID_after_END_LOOP;\n        when others =>\n          Error (CD, err_general_error);\n      end case;\n    end Named_Statement;\n\n    procedure Statement_starting_with_an_Identifier is\n      I_Statement : constant Integer :=\n        Locate_CD_Id (CD, block_data.context.level, Fail_when_No_Id => False);\n    begin\n      In_Symbol;\n      if I_Statement = No_Id then\n        --  Unknown identifier: must be an identifier for a named Block_Statement or loop.\n        Named_Statement;\n      else\n        case CD.id_table (I_Statement).entity is\n          when Object_Kind =>\n            Assignment (CD, FSys_St, block_data.context, I_Statement, check_is_variable => True);\n            Elevate_to_Maybe_or_Yes\n              (CD.id_table (I_Statement).is_written_after_init, block_data.context);\n\n          when declared_number_or_enum_item =>\n            Error (CD, err_illegal_statement_start_symbol, \"constant or an enumeration item\",\n                   severity => major);\n\n          when type_mark =>\n            Error (CD, err_illegal_statement_start_symbol, \"type name\", severity => major);\n\n          when funktion | funktion_intrinsic =>\n            Error (CD, err_illegal_statement_start_symbol, \"function name\", severity => major);\n\n          when tache =>\n            Entry_Call (CD, block_data.context, FSys_St, I_Statement, Normal_Entry_Call);\n\n          when prozedure =>\n            Subprogram_or_Entry_Call\n              (CD, block_data.context, FSys_St, I_Statement, Normal_Procedure_Call);\n\n          when prozedure_intrinsic =>\n            Standard_Procedures.Standard_Procedure\n              (CD, block_data.context, FSys_St, SP_Code'Val (CD.id_table (I_Statement).adr_or_sz));\n\n          when loop_identifier =>\n            Error (CD, err_duplicate_loop_identifier, A2S (CD.Id), severity => major);\n\n          when paquetage =>\n            Error (CD, err_illegal_statement_start_symbol, \"package name\", severity => major);\n\n          when others =>\n            Error\n              (CD, err_illegal_statement_start_symbol,\n               \". Entity found: \" &\n               Entity_Kind'Image (CD.id_table (I_Statement).entity), severity => major);\n        end case;\n      end if;\n    end Statement_starting_with_an_Identifier;\n\n    procedure Process_Name_for_Unnamed_Loop is\n    begin\n      if CD.Sy = IDent then\n        Error\n          (CD, err_general_error,\n           \"loop starting at line\" &\n           CD.Nested_Loop_Table (CD.loop_nesting_level + 1).start_line'Image &\n           \" has no name\");\n        In_Symbol;  --  Recovery.\n      end if;\n    end Process_Name_for_Unnamed_Loop;\n\n  begin  --  Statement\n    if CD.error_count > 0 then\n      return;\n    end if;\n    if Statement_Begin_Symbol (CD.Sy) then\n      case CD.Sy is\n        when IDent =>\n          Statement_starting_with_an_Identifier;\n        when ACCEPT_Symbol =>\n          Accept_Statement;\n        when BEGIN_Symbol | DECLARE_Symbol =>\n          --  Anonymous Block Statement\n          Block_Statement (Empty_Alfa);\n        when CASE_Symbol =>\n          CASE_Statement (CD, FSys_St, block_data);\n        when DELAY_Symbol =>\n          Delay_Statement;\n        when EXIT_Symbol =>\n          Exit_Statement;\n        when FOR_Symbol =>\n          FOR_Statement (No_Id);\n          Process_Name_for_Unnamed_Loop;\n        when IF_Symbol =>\n          IF_Statement;\n        when LOOP_Symbol =>\n          LOOP_Statement (k_Jump, CD.LC, (No_Id, False, CD.CUD.location.line));\n          Process_Name_for_Unnamed_Loop;\n        when NULL_Symbol =>\n          In_Symbol;  --  Just consume the NULL symbol.\n        when RETURN_Symbol =>\n          RETURN_Statement;\n        when SELECT_Symbol =>\n          Select_Statement;\n        when WHILE_Symbol =>\n          WHILE_Statement (No_Id);\n          Process_Name_for_Unnamed_Loop;\n        when others =>\n          null;\n      end case;\n      --\n      Need_Semicolon (CD);\n    end if;  --  CD.Sy in Statement_Begin_Symbol\n    --\n    Test (CD, FSys_St - Semicolon, Semicolon_Set, err_incorrectly_used_symbol);\n  end Statement;\n\nend HAC_Sys.Parser.Statements;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-statements.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nprivate package HAC_Sys.Parser.Statements is\n\n  procedure Assignment\n    (CD                : in out Co_Defs.Compiler_Data;\n     FSys              :        Defs.Symset;\n     context           :        Defs.Flow_Context;\n     var_id_index      :        Integer;\n     check_is_variable :        Boolean);\n\n  procedure Sequence_of_Statements  --  Ada RM 5.1 (2)\n    (CD         : in out Co_Defs.Compiler_Data;\n     sentinel   :        Defs.Symset;\n     block_data : in out Block_Data_Type;\n     optional   :        Boolean := False);\n\n  procedure Sequence_of_Statements_in_a_Conditional_Statement\n    (CD         : in out Co_Defs.Compiler_Data;\n     sentinel   :        Defs.Symset;\n     block_data : in out Block_Data_Type;\n     optional   :        Boolean := False);\n\nend HAC_Sys.Parser.Statements;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-tasking.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Enter_Def,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\npackage body HAC_Sys.Parser.Tasking is\n\n  use Compiler, Compiler.PCode_Emit, Co_Defs, Defs, Enter_Def, Helpers, PCode, Errors;\n  use type HAC_Integer;\n\n  ------------------------------------------------------------------\n  -------------------------------------------------Task_Declaration-\n  --  Hathorn\n  procedure Task_Declaration (\n    CD            : in out Co_Defs.Compiler_Data;\n    FSys          :        Defs.Symset;\n    Initial_Level :        Defs.Nesting_Level\n  )\n  is\n    Level : Nesting_Level := Initial_Level;\n    saveLineCount : constant Integer := CD.CUD.location.line;  --  Source line where Task appeared\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n    I, T0  : Integer;\n    TaskID, TaskID_with_case : Alfa;\n    task_block : Block_Data_Type;\n    forward_id_idx : Natural;\n    use type Alfa;\n  begin\n    In_Symbol;\n    if CD.Sy = BODY_Symbol then  --  Task Body\n      In_Symbol;\n      I                := Locate_CD_Id (CD, Level);\n      TaskID           := CD.id_table (I).name;\n      TaskID_with_case := CD.id_table (I).name_with_case;\n      CD.Blocks_Table (CD.id_table (I).block_or_pkg_ref).SrcFrom := saveLineCount;  --  (* Manuel *)\n      In_Symbol;\n      task_block.context.level                 := Level + 1;\n      task_block.block_id_index                := I;\n      task_block.entity                        := entree;\n      task_block.is_main                       := False;\n      task_block.previous_declaration_id_index := No_Id;\n      Block (CD, FSys, False, task_block, TaskID, TaskID_with_case);\n      Emit_1 (CD, k_Return_Call, Normal_Procedure_Call);\n    else                         --  Task Specification\n      if CD.Sy = IDent then\n        TaskID           := CD.Id;\n        TaskID_with_case := CD.Id_with_case;\n      else\n        Error (CD, err_identifier_missing);\n        CD.Id            := Empty_Alfa;\n        TaskID           := Empty_Alfa;\n        TaskID_with_case := Empty_Alfa;\n      end if;\n      CD.Tasks_Definitions_Count := CD.Tasks_Definitions_Count + 1;\n      if CD.Tasks_Definitions_Count > TaskMax then\n        Fatal (TASKS);  --  Exception is raised there.\n      end if;\n      Enter_Prefixed (CD, Level, TaskID, TaskID_with_case, tache, forward_id_idx);\n      CD.Tasks_Definitions_Table (CD.Tasks_Definitions_Count) := CD.Id_Count;\n      Enter_Block (CD, CD.Id_Count);\n      CD.id_table (CD.Id_Count).block_or_pkg_ref := CD.Blocks_Count;\n      In_Symbol;\n      if CD.Sy = Semicolon then\n        In_Symbol;  --  Task with no entries\n      else  --  Parsing the Entry specs\n        Need (CD, IS_Symbol, err_IS_missing);\n        if Level = nesting_level_max then\n          Fatal (LEVELS);  --  Exception is raised there.\n        end if;\n        Level              := Level + 1;\n        CD.Display (Level) := CD.Blocks_Count;\n        while CD.Sy = ENTRY_Symbol loop\n          In_Symbol;\n          if CD.Sy /= IDent then\n            Error (CD, err_identifier_missing);\n            CD.Id := Empty_Alfa;\n          end if;\n          CD.Entries_Count := CD.Entries_Count + 1;\n          if CD.Entries_Count > entry_table_max then\n            Fatal (ENTRIES);  --  Exception is raised there.\n          end if;\n          Enter_Prefixed (CD, Level, CD.Id, CD.Id_with_case, entree, forward_id_idx);\n          CD.Entries_Table (CD.Entries_Count) := CD.Id_Count;  --  point to identifier table location\n          T0                                  := CD.Id_Count;  --  of TaskID\n          In_Symbol;\n          task_block.context.level                 := Level + 1;\n          task_block.block_id_index                := CD.Id_Count;\n          task_block.entity                        := entree;\n          task_block.is_main                       := False;\n          task_block.previous_declaration_id_index := No_Id;\n          Block (CD, FSys, False, task_block,\n                 CD.id_table (CD.Id_Count).name, CD.id_table (CD.Id_Count).name_with_case);\n          CD.id_table (T0).adr_or_sz := HAC_Integer (CD.Tasks_Definitions_Count);\n          if CD.Sy = Semicolon then\n            In_Symbol;\n          else\n            Error (CD, err_semicolon_missing);\n          end if;\n        end loop;  --  while CD.Sy = ENTRY_Symbol\n\n        Level := Level - 1;\n        Need_END_Symbol (CD);\n        if CD.Sy = IDent and then CD.Id = TaskID then\n          In_Symbol;\n        else\n          Error_then_Skip (CD, Semicolon, err_incorrect_name_after_END);\n        end if;\n        Need_Semicolon_after_Declaration (CD, FSys);\n      end if;\n    end if;\n    pragma Assert (Level = Initial_Level);\n  end Task_Declaration;\n\nend HAC_Sys.Parser.Tasking;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-tasking.ads",
    "content": "private package HAC_Sys.Parser.Tasking is\n\n  ------------------------------------------------------------------\n  -------------------------------------------------Task_Declaration-\n  --  Hathorn\n  procedure Task_Declaration (\n    CD            : in out Co_Defs.Compiler_Data;\n    FSys          :        Defs.Symset;\n    Initial_Level :        Defs.Nesting_Level\n  );\n\nend HAC_Sys.Parser.Tasking;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-type_conversion.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Expressions,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.PCode,\n     HAC_Sys.Errors;\n\nprocedure HAC_Sys.Parser.Type_Conversion  --  Ada RM 4.6\n  (CD      : in out Co_Defs.Compiler_Data;\n   context : in     Defs.Flow_Context;\n   FSys    : in     Defs.Symset;\n   Typ_ID  : in     Co_Defs.Identifier_Table_Entry;\n   X       : in     Co_Defs.Exact_Subtyp)\nis\n  use Defs, Helpers, PCode, Errors;\n  type Type_Conversion_Kind is\n    (To_Float, To_Integer, To_Duration, To_Bools, Unknown);\n  kind : Type_Conversion_Kind;\n  T_Expr : Co_Defs.Exact_Subtyp;\nbegin\n  --  X is the type of the name just parsed, as in the identifier table.\n  --  E.g.:  \"Natural (12.34)\"  ->  X is from Standard.Natural as entered by the librarian.\n  case X.TYP is\n    when Floats    => kind := To_Float;\n    when Ints      => kind := To_Integer;\n    when Durations => kind := To_Duration;\n    when Bools     => kind := To_Bools;\n    when others    => kind := Unknown;\n  end case;\n  --\n  Expressions.Expression (CD, context, FSys + RParent, T_Expr);\n  --  T_Expr is the type of the expression between the parentheses.\n  --  E.g.:  \"Natural (12.34)\"  ->  X.TYP is Floats because of 12.34.\n  --\n  case kind is\n    when To_Float =>\n      case T_Expr.TYP is\n        when Floats =>\n          null;  --  Useless conversion if we have the same named subtype\n        when Ints =>\n          Compiler.PCode_Emit.Emit_1 (CD, k_Integer_to_Float, 0);\n        when Durations =>\n          Compiler.PCode_Emit.Emit_Std_Funct (CD, SF_Duration_to_Float);\n        when others =>\n          Argument_Type_Not_Supported (CD);\n      end case;\n      --\n    when To_Integer =>\n      case T_Expr.TYP is\n        when Floats =>  --  Rounding to closest integer (Ada RM 4.6 (33)).\n          Compiler.PCode_Emit.Emit_Std_Funct (CD, SF_Round_Float_to_Int);\n        when Durations =>\n          Compiler.PCode_Emit.Emit_Std_Funct (CD, SF_Duration_to_Int);\n        when Ints =>\n          null;  --  Useless conversion if we have the same named subtype\n        when others =>\n          Argument_Type_Not_Supported (CD);\n      end case;\n      Compiler.PCode_Emit.Emit_Lower_Bound_Check (CD, X);\n      Compiler.PCode_Emit.Emit_Upper_Bound_Check (CD, X);\n      --\n    when To_Duration =>\n      case T_Expr.TYP is\n        when Floats =>\n          Compiler.PCode_Emit.Emit_Std_Funct (CD, SF_Float_to_Duration);\n        when Ints =>\n          Compiler.PCode_Emit.Emit_Std_Funct (CD, SF_Int_to_Duration);\n        when Durations =>\n          null;  --  Useless conversion if we have the same named subtype\n        when others =>\n          Argument_Type_Not_Supported (CD);\n      end case;\n    when To_Bools =>\n      if T_Expr.TYP = Bools then\n        Remark\n          (CD,\n           note_redundant_construct,\n           \"redundant conversion to type \"\"Boolean\"\"\");\n      else\n        Argument_Type_Not_Supported (CD);\n      end if;\n    when Unknown =>\n      Error (\n        CD,\n        err_type_conversion_not_supported,\n        \"no support for target type \" & A2S (Typ_ID.name_with_case)\n      );\n  end case;\n  Need (CD, RParent, err_closing_parenthesis_missing);\nend HAC_Sys.Parser.Type_Conversion;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-type_conversion.ads",
    "content": "--  The subtype name has just been parsed, its identifier is in Type_ID.\n--  This identification method works only for standard types,\n--  which is currently the only option.\n--  The symbol \"(\" has been parsed too.\n\nprivate procedure HAC_Sys.Parser.Type_Conversion  --  Ada RM 4.6\n  (CD      : in out Co_Defs.Compiler_Data;\n   context : in     Defs.Flow_Context;\n   FSys    : in     Defs.Symset;\n   Typ_ID  : in     Co_Defs.Identifier_Table_Entry;\n   X       : in     Co_Defs.Exact_Subtyp);\n"
  },
  {
    "path": "src/compile/hac_sys-parser-type_def.adb",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Parser.Enter_Def,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Ranges,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\nwith HAT;\n\nwith Ada.Characters.Handling;\n\npackage body HAC_Sys.Parser.Type_Def is\n\n  use Co_Defs, Defs, Enter_Def, Helpers, Errors;\n  use type HAC_Integer;\n\n  procedure Type_or_Subtype_Declaration\n    (CD         : in out Co_Defs.Compiler_Data;\n     Level      : in     Defs.Nesting_Level;\n     FSys_NTD   : in     Defs.Symset)\n  is\n    T1 : Integer;\n    forward_id_idx : Natural;\n    is_subtype : constant Boolean := CD.Sy = SUBTYPE_Symbol;\n  begin\n    Scanner.In_Symbol (CD);  --  Consume TYPE or SUBTYPE symbol.\n    Test (CD, IDent_Set, Semicolon_Set, err_identifier_missing);\n    Enter_Prefixed (CD, Level, CD.Id, CD.Id_with_case, type_mark, forward_id_idx);\n    T1 := CD.Id_Count;\n    Scanner.In_Symbol (CD);\n    if CD.Sy = LParent then\n      Error\n        (CD,\n         err_not_yet_implemented,\n         \"discriminants (type parameters), Ada RM 3.7\",\n         severity => major);\n    end if;\n    Need (CD, IS_Symbol, err_IS_missing);\n    declare\n      New_T : Identifier_Table_Entry renames CD.id_table (T1);\n    begin\n      if is_subtype then\n        Subtype_Indication\n          (CD, Level,\n           FSys_TD => Comma_IDent_Semicolon + FSys_NTD,\n           xTP     => New_T.xtyp,\n           Size    => Integer (New_T.adr_or_sz));\n      else\n        Type_Definition\n          (CD, Level,\n           FSys_TD => Comma_IDent_Semicolon + FSys_NTD,\n           xTP     => New_T.xtyp,\n           Size    => Integer (New_T.adr_or_sz));\n      end if;\n    end;\n    --\n    Need_Semicolon_after_Declaration (CD, FSys_NTD);\n  end Type_or_Subtype_Declaration;\n\n  log_max_index : constant HAT.Real := HAT.Log (HAT.Real (Index'Last));\n\n  --  constrained_array_definition 3.6 (5) : \"array (1 .. 2, 3 .. 4) of Integer;\"\n  --  index_constraint 3.6.1 (2)           : \"Matrix (1 .. 2, 3 .. 4);\"\n  --\n  procedure Array_Typ\n    (CD            : in out Co_Defs.Compiler_Data;\n     Level : in     Defs.Nesting_Level;\n     FSys_TD       : in     Defs.Symset;\n     arr_tab_ref, arr_size, arr_dimensions : out Integer;\n     string_constrained_subtype            :     Boolean)\n  is\n    Element_Exact_Subtyp, Index_Exact_Subtyp : Exact_Subtyp;\n    Element_Size                             : Integer;\n    recursive_dimensions                     : Natural := 0;\n    Lower_Bound, Higher_Bound                : Constant_Rec;\n    new_dim_size                             : HAC_Integer;\n    use HAT, Ranges;\n  begin\n    Static_Range (CD, Level, FSys_TD, err_illegal_array_bounds, Lower_Bound, Higher_Bound);\n    Index_Exact_Subtyp := Lower_Bound.TP;\n    Index_Exact_Subtyp.Discrete_First := Lower_Bound.I;\n    Index_Exact_Subtyp.Discrete_Last  := Higher_Bound.I;\n    Enter_Array (CD, Index_Exact_Subtyp);\n    arr_tab_ref := CD.Arrays_Count;\n    if string_constrained_subtype then\n      --  We define String (L .. H) exactly as an \"array (L .. H) of Character\".\n      Construct_Root (Element_Exact_Subtyp, Chars);\n      Element_Exact_Subtyp.Discrete_First := 0;\n      Element_Exact_Subtyp.Discrete_Last  := 255;\n      Element_Size := 1;\n      Need (CD, RParent, err_closing_parenthesis_missing, Forgive => RBrack);\n    elsif CD.Sy = Comma then\n      --  Multidimensional array is equivalant to:  array (range_1) of array (range_2,...).\n      Scanner.In_Symbol (CD);  --  Consume ',' symbol.\n      Construct_Root (Element_Exact_Subtyp, Arrays);  --  Recursion for next array dimension.\n      Array_Typ (CD, Level, FSys_TD, Element_Exact_Subtyp.Ref, Element_Size, recursive_dimensions, False);\n    else\n      Need (CD, RParent, err_closing_parenthesis_missing, Forgive => RBrack);\n      Need (CD, OF_Symbol, err_missing_OF);         --  \"of\"  in  \"array (...) of Some_Type\"\n      if Type_Begin_Symbol (CD.Sy) then\n        Error (CD, err_general_error, \"anonymous definition not permitted here\");\n        --  Recovery:\n        Type_Definition (CD, Level, FSys_TD, Element_Exact_Subtyp, Element_Size);\n      else\n        --  RM 3.6 (2)\n        --  Here is a component_definition, which is a\n        --  subtype indication (possibly aliased).\n        Subtype_Indication (CD, Level, FSys_TD, Element_Exact_Subtyp, Element_Size);\n      end if;\n    end if;\n    if Element_Size = 0 then\n      --  Happens when the element type is undefined (source is already in error) or\n      --  if the element type is an empty array type.\n      arr_size := 0;\n    else\n      new_dim_size := Higher_Bound.I - Lower_Bound.I + 1;\n      if new_dim_size <= 0 then\n        --  This dimension is empty.\n        arr_size := 0;\n      elsif Log (Real (new_dim_size)) + Log (Real (Element_Size)) < log_max_index then\n        arr_size := Integer (new_dim_size) * Element_Size;\n      else\n        Error\n          (CD,\n           err_illegal_array_bounds,\n           \"array is too large (more than\" & Defs.Index'Last'Image & \" elements)\");\n        arr_size := 0;\n      end if;\n    end if;\n    arr_dimensions := 1 + recursive_dimensions;\n    declare\n      New_A : Array_Table_Entry renames CD.Arrays_Table (arr_tab_ref);\n    begin\n      --  New_A.Index_xTyp already set by Enter_Array.\n      New_A.Array_Size   := arr_size;\n      New_A.Element_xTyp := Element_Exact_Subtyp;\n      New_A.Element_Size := Element_Size;\n      New_A.dimensions   := arr_dimensions;\n    end;\n  end Array_Typ;\n\n  procedure Type_Definition\n    (CD            : in out Co_Defs.Compiler_Data;\n     Initial_Level : in     Defs.Nesting_Level;\n     FSys_TD       : in     Defs.Symset;\n     xTP           :    out Co_Defs.Exact_Subtyp;\n     Size          :    out Integer)\n  is\n    Level : Nesting_Level := Initial_Level;\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n\n    procedure Enumeration_Typ is  --  RM 3.5.1 Enumeration Types\n      enum_count : Natural := 0;\n      forward_id_idx : Natural;\n    begin\n      xTP.Construct_Root (Enums);\n      xTP.Ref := CD.Id_Count;\n      loop\n        In_Symbol;  --  Consume '(' symbol.\n        if CD.Sy = IDent then\n          enum_count := enum_count + 1;\n          Enter_Prefixed (CD, Level, CD.Id, CD.Id_with_case, declared_number_or_enum_item, forward_id_idx);\n          declare\n            new_enum_item : Identifier_Table_Entry renames CD.id_table (CD.Id_Count);\n          begin\n            new_enum_item.xtyp          := xTP;\n            new_enum_item.adr_or_sz     := HAC_Integer (enum_count - 1);  --  RM 3.5.1 (7): position begins with 0.\n            new_enum_item.is_referenced := False;\n          end;\n        else\n          Error (CD, err_identifier_missing);\n        end if;\n        In_Symbol;\n        exit when CD.Sy /= Comma;\n      end loop;\n      Size  := 1;\n      xTP.Discrete_First := 0;\n      xTP.Discrete_Last  := HAC_Integer (enum_count - 1);\n      Need (CD, RParent, err_closing_parenthesis_missing);\n    end Enumeration_Typ;\n\n    procedure Record_Typ is  --  RM 3.8\n      Field_Exact_Subtyp : Exact_Subtyp;\n      Field_Size, Offset, T0, T1 : Integer;\n    begin\n      In_Symbol;  --  Consume RECORD symbol.\n      Enter_Block (CD, CD.Id_Count);\n      Construct_Root (xTP, Records);\n      xTP.Ref := CD.Blocks_Count;\n      if Level = nesting_level_max then\n        Fatal (LEVELS);  --  Exception is raised there.\n      end if;\n      Level              := Level + 1;\n      CD.Display (Level) := CD.Blocks_Count;\n      Offset             := 0;\n      --\n      loop\n        if CD.Sy = IDent then\n          --  RM 3.8: Record component declaration\n          T0 := CD.Id_Count;\n          Enter_Variables (CD, Level, False);\n          Need (CD, Colon, err_colon_missing);  --  ':'  in  \"a, b, c : Integer;\"\n          T1 := CD.Id_Count;\n          if Type_Begin_Symbol (CD.Sy) then\n            Error (CD, err_general_error, \"anonymous definition not permitted here\");\n            --  Recovery:\n            Type_Definition\n              (CD, Level, FSys_TD + Comma_END_IDent_Semicolon,\n               Field_Exact_Subtyp, Field_Size);\n          else\n            --  RM 3.6 (2)\n            --  Here is a component_definition, which is a\n            --  subtype indication (possibly aliased).\n            Subtype_Indication\n              (CD, Level, FSys_TD + Comma_END_IDent_Semicolon,\n               Field_Exact_Subtyp, Field_Size);\n          end if;\n          while T0 < T1 loop\n            T0                      := T0 + 1;\n            CD.id_table (T0).xtyp      := Field_Exact_Subtyp;\n            CD.id_table (T0).adr_or_sz := HAC_Integer (Offset);\n            Offset                  := Offset + Field_Size;\n          end loop;\n        else\n          Error (CD, err_identifier_missing, severity => major);\n        end if;\n        Need_Semicolon (CD);\n        exit when CD.Sy = END_Symbol;\n      end loop;\n      --\n      CD.Blocks_Table (xTP.Ref).VSize := Offset;\n      Size                            := Offset;\n      CD.Blocks_Table (xTP.Ref).PSize := 0;\n      In_Symbol;\n      Need (CD, RECORD_Symbol, err_RECORD_missing);  --  (END) RECORD\n      Level := Level - 1;\n    end Record_Typ;\n\n    dummy_dims : Natural;\n  begin\n    xTP  := undefined_subtyp;\n    Size := 0;\n    if CD.Sy in\n      ABSTRACT_Symbol | ACCESS_Symbol |\n      DIGITS_Symbol | DELTA_Symbol |\n      INTERFACE_Symbol | LIMITED_Symbol |\n      NOT_Symbol | NEW_Symbol |\n      PRIVATE_Symbol | PROTECTED_Symbol |\n      RANGE_Keyword_Symbol | SYNCHRONIZED_Symbol |\n      TASK_Symbol | TAGGED_Symbol\n    then\n      Error\n        (CD, err_not_yet_implemented,\n         \": type definitions starting with \"\"\" &\n         Ada.Characters.Handling.To_Lower (A2S (CD.Id)) & '\"',\n         severity => major);\n    end if;\n    Test (CD, Type_Begin_Symbol, FSys_TD, err_missing_type_begin_symbol);\n    if Type_Begin_Symbol (CD.Sy) then\n      case CD.Sy is\n        when ARRAY_Symbol =>\n          In_Symbol;\n          Need (CD, LParent, err_missing_an_opening_parenthesis, Forgive => LBrack);\n          Construct_Root (xTP, Arrays);\n          Array_Typ (CD, Level, FSys_TD, xTP.Ref, Size, dummy_dims, string_constrained_subtype => False);\n        when RECORD_Symbol =>\n          Record_Typ;\n        when LParent =>\n          Enumeration_Typ;\n        when others =>\n          null;\n      end case;\n      Test (CD, FSys_TD, empty_symset, err_incorrectly_used_symbol);\n    end if;\n    if CD.error_count = 0 then\n      pragma Assert (Level = Initial_Level);\n    end if;\n  end Type_Definition;\n\n  procedure Subtype_Indication\n    (CD      : in out Co_Defs.Compiler_Data;\n     Level   : in     Defs.Nesting_Level;\n     FSys_TD : in     Defs.Symset;\n     xTP     :    out Co_Defs.Exact_Subtyp;\n     Size    :    out Integer)\n  is\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n\n    dummy_dims : Natural;\n\n    procedure String_Sub_Typ is\n      --  Prototype of constraining an array type: String -> String (1 .. 26)\n      --  We need to implement general constraints one day...\n    begin\n      In_Symbol;\n      Need (CD, LParent, err_missing_an_opening_parenthesis, Forgive => LBrack);\n      Construct_Root (xTP, Arrays);\n      Array_Typ (CD, Level, FSys_TD, xTP.Ref, Size, dummy_dims, string_constrained_subtype => True);\n    end String_Sub_Typ;\n\n    Ident_Index : Integer;\n\n    --  Here we are sitting, say, on `Character` in `subtype My_Chars is Character` [range 'a' .. 'z']\n    --\n    procedure Sub_Typ is\n      Low, High : Constant_Rec;\n    begin\n      if Ident_Index = No_Id then\n        return;  --  Error already issued due to undefined identifier\n      end if;\n      declare\n        Id_T : Identifier_Table_Entry renames CD.id_table (Ident_Index);\n      begin\n        if Id_T.entity = type_mark then\n          xTP   := Id_T.xtyp;\n          Size  := Integer (Id_T.adr_or_sz);\n          if xTP.TYP = NOTYP then\n            Error (CD, err_undefined_type);\n          end if;\n        else\n          Error (CD, err_missing_a_type_identifier);\n        end if;\n      end;\n      In_Symbol;\n      if CD.Sy = RANGE_Keyword_Symbol then\n        --  Here comes the optional `  range 'a' .. 'z'  ` constraint.\n        In_Symbol;\n        Ranges.Explicit_Static_Range (CD, Level, FSys_TD, err_range_constraint_error, Low, High);\n        Ranges.Check_Explicit_Static_Range_Against_Parent_Type (CD, Low, High, xTP, True);\n      end if;\n    end Sub_Typ;\n\n  begin\n    xTP  := undefined_subtyp;\n    Size := 0;\n    if CD.Sy = NOT_Symbol then\n      Error\n        (CD, err_not_yet_implemented,\n         \": subtype indications starting with \"\"\" &\n         Ada.Characters.Handling.To_Lower (A2S (CD.Id)) & '\"',\n         severity => major);\n    end if;\n    Test (CD, Subtype_Begin_Symbol, FSys_TD, err_identifier_missing);\n    if CD.Sy /= IDent then\n      --  Normally this case should have been filtered out before.\n      Error (CD, err_general_error, severity => major);\n    end if;\n    Ident_Index := Locate_CD_Id (CD, Level);\n    if Ident_Index = CD.String_Id_Index then\n      String_Sub_Typ;\n    else\n      Sub_Typ;\n    end if;\n    Test (CD, FSys_TD, empty_symset, err_incorrectly_used_symbol);\n  end Subtype_Indication;\n\nend HAC_Sys.Parser.Type_Def;\n"
  },
  {
    "path": "src/compile/hac_sys-parser-type_def.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nprivate package HAC_Sys.Parser.Type_Def is  --  Package around type definitions.\n\n  ------------------------------------------------------------------\n  --------------------------------------Type_or_Subtype_Declaration-\n  --  Type Declarations   : RM 3.2.1\n  --  Subtype Declarations: RM 3.2.2\n  --\n  --  Parses \"[sub]type T is ...\" right after the \"[sub]type\" symbol.\n  --  Depending on the symbol (SUBTYPE or TYPE), the parser will\n  --  look for either a Subtype_Indication or a Type_Definition.\n  --\n  procedure Type_or_Subtype_Declaration\n    (CD         : in out Co_Defs.Compiler_Data;\n     Level      : in     Defs.Nesting_Level;\n     FSys_NTD   : in     Defs.Symset);\n\n  ------------------------------------------------------------------\n  -----------------------------------Type_Definition - RM 3.2.1 (4)-\n  --\n  procedure Type_Definition\n    (CD            : in out Co_Defs.Compiler_Data;\n     Initial_Level : in     Defs.Nesting_Level;\n     FSys_TD       : in     Defs.Symset;\n     xTP           :    out Co_Defs.Exact_Subtyp;\n     Size          :    out Integer);\n\n  ------------------------------------------------------------------\n  --------------------------------Subtype_Indication - RM 3.2.2 (2)-\n  --\n  procedure Subtype_Indication\n    (CD      : in out Co_Defs.Compiler_Data;\n     Level   : in     Defs.Nesting_Level;\n     FSys_TD : in     Defs.Symset;\n     xTP     :    out Co_Defs.Exact_Subtyp;\n     Size    :    out Integer);\n\nend HAC_Sys.Parser.Type_Def;\n"
  },
  {
    "path": "src/compile/hac_sys-parser.adb",
    "content": "with HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Enter_Def,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Packages,\n     HAC_Sys.Parser.Statements,\n     HAC_Sys.Parser.Tasking,\n     HAC_Sys.Parser.Const_Var,\n     HAC_Sys.Parser.Type_Def,\n     HAC_Sys.PCode,\n     HAC_Sys.Scanner,\n     HAC_Sys.Errors;\n\nwith HAT;\n\npackage body HAC_Sys.Parser is\n\n  ------------------------------------------------------------------\n  ------------------------------------------------------------Block-\n\n  procedure Block\n    (CD                   : in out Co_Defs.Compiler_Data;\n     FSys                 :        Defs.Symset;\n     Is_a_block_statement :        Boolean;        --  5.6 Block Statements\n     Initial_Block_Data   :        Block_Data_Type;\n     Block_Id             :        Defs.Alfa;      --  Name of this block (if any)\n     Block_Id_with_case   :        Defs.Alfa)\n  is\n    use Co_Defs, Defs, Enter_Def, Errors, Helpers;\n    use type HAC_Integer;\n    --\n    block_data : Block_Data_Type := Initial_Block_Data;\n    subprogram_block_index : Integer;  --  Was: PRB\n\n    procedure In_Symbol is begin Scanner.In_Symbol (CD); end In_Symbol;\n\n    ------------------------------------------------------------------\n    --------------------------------------------Formal_Parameter_List-\n    procedure Formal_Parameter_List is\n      Sz, X, T0  : Integer;\n      ValParam   : Boolean;\n      xTP        : Exact_Subtyp := undefined_subtyp;\n      param_kind : Parameter_Kind;\n      in_keyword : Boolean;\n    begin\n      In_Symbol;  --  Consume '(' symbol.\n      Sz := 0;\n      Test (CD, IDent_Set, FSys + RParent, err_identifier_missing, stop_on_error => True);\n      --\n      while CD.Sy = IDent loop\n        T0 := CD.Id_Count;\n        Enter_Variables (CD, block_data.context.level, False);\n        --\n        if CD.Sy = Colon then  --  The ':'  in  \"function F (x, y : in Real) return Real;\"\n          In_Symbol;\n          param_kind := param_in;\n          in_keyword := False;\n          if CD.Sy = IN_Symbol then\n            In_Symbol;\n            in_keyword := True;\n          end if;\n          if block_data.entity = funktion then  --  If I am a function, no In Out params allowed\n            ValParam := True;\n          elsif CD.Sy = OUT_Symbol then\n            In_Symbol;\n            ValParam := False;\n            param_kind := (if in_keyword then param_in_out else param_out);\n          else\n            ValParam := True;\n          end if;\n          if CD.Sy = IDent then\n            X := Locate_CD_Id (CD, block_data.context.level);\n            In_Symbol;\n            if X = CD.String_Id_Index then\n              --  We could pass string literals as \"in\" parameter\n              --  if we replaced String_Literals by a record wrapping\n              --  the string length and the index into the string table.\n              Error (CD, err_string_not_supported_as_parameter, severity => major);\n            elsif X /= No_Id then\n              if CD.id_table (X).entity = type_mark then\n                xTP := CD.id_table (X).xtyp;\n                Sz := Integer (if ValParam then CD.id_table (X).adr_or_sz else 1);\n              else\n                Error (CD, err_missing_a_type_identifier, severity => major);\n              end if;\n            end if;  --  X /= No_Id\n          else\n            Error (CD, err_identifier_missing);\n          end if;\n          Test (CD, Comma_IDent_RParent_Semicolon, FSys, err_semicolon_missing, stop_on_error => True);\n          --  Update information\n          while T0 < CD.Id_Count loop\n            T0 := T0 + 1;\n            declare\n              r : Identifier_Table_Entry renames CD.id_table (T0);\n            begin\n              r.xtyp                  := xTP;\n              r.normal                := ValParam;\n              r.entity                := (if param_kind = param_in then constant_object else variable_object);\n              r.decl_kind             := param_kind;\n              r.adr_or_sz             := HAC_Integer (block_data.data_allocation_index);\n              r.lev                   := block_data.context.level;\n              r.is_referenced         := False;\n              r.is_read               := no;\n              r.is_written_after_init := no;\n              r.is_initialized        := (if param_kind = param_out then none else implicit);\n            end;\n            block_data.data_allocation_index := block_data.data_allocation_index + Sz;\n          end loop;  --  while T0 < CD.Id_Count\n        else\n          Error (CD, err_colon_missing, severity => major);\n        end if;\n        if CD.Sy /= RParent then\n          Need_Semicolon (CD);\n          Test (CD, IDent_Set, FSys + RParent, err_incorrectly_used_symbol);\n        end if;\n      end loop;  --  while Sy = IDent\n      --\n      if CD.Sy = RParent then\n        In_Symbol;\n        Test (CD, After_Subprogram_Parameters, FSys, err_incorrectly_used_symbol);\n      else\n        Error (CD, err_closing_parenthesis_missing);\n      end if;\n    end Formal_Parameter_List;\n\n    procedure Declarative_Part is\n      ignored_kind : Declaration_Kind;\n      ignored_needs_body, is_body : Boolean;\n      pkg_spec_index : Index;\n      pkg_kind : Entity_Kind;\n    begin\n      loop\n        Test (  --  Added 17-Apr-2018 to avoid infinite loop on erroneous code\n          CD, Declaration_Symbol + BEGIN_Symbol,\n          empty_symset,\n          err_incorrectly_used_symbol,\n          stop_on_error => True  --  Exception is raised there if there is an error.\n        );\n        case CD.Sy is\n          when IDent              => Const_Var.Var_Declaration (CD, FSys, block_data);\n          when TYPE_Symbol |\n               SUBTYPE_Symbol\n            =>\n            Type_Def.Type_or_Subtype_Declaration (CD, block_data.context.level, FSys);\n\n          when TASK_Symbol\n            =>\n            Tasking.Task_Declaration (CD, FSys, block_data.context.level);\n          when USE_Symbol\n            =>\n            Packages.Use_Clause (CD, block_data.context.level, False);\n\n          when PROCEDURE_Symbol |\n               FUNCTION_Symbol\n            =>\n            Subprogram_Declaration_or_Body (CD, FSys, block_data.context.level, ignored_kind);\n\n          when PACKAGE_Symbol =>\n            --  Local package (local to a block or subprogram).\n            In_Symbol;\n            is_body := CD.Sy = BODY_Symbol;\n            pkg_kind := paquetage;\n            if is_body then\n              In_Symbol;\n              pkg_kind := paquetage_body;\n            end if;\n            if CD.Sy /= IDent then\n              Error (CD, err_identifier_missing, severity => major);\n            end if;\n            Enter_Prefixed (CD, block_data.context.level, CD.Id, CD.Id_with_case, pkg_kind, pkg_spec_index);\n            if is_body then\n              if pkg_spec_index = No_Id then\n                Error\n                  (CD, err_general_error,\n                   \"missing specification for package body\", severity => major);\n              end if;\n              CD.id_table (CD.Id_Count).block_or_pkg_ref := CD.id_table (pkg_spec_index).block_or_pkg_ref;\n              Parser.Packages.Package_Body (CD, empty_symset, block_data);\n            else\n              CD.id_table (CD.Id_Count).decl_kind := spec_resolved;\n              --  Why spec_resolved ? missing bodies for possible suprograms\n              --  in that package are checked anyway.\n              Parser.Packages.Package_Declaration (CD, empty_symset, block_data, ignored_needs_body);\n            end if;\n            In_Symbol;  --  Absorb ';'\n          when others => null;\n        end case;\n        CD.Blocks_Table (subprogram_block_index).VSize := block_data.data_allocation_index;\n        exit when CD.Sy = BEGIN_Symbol;\n      end loop;\n      Check_Incomplete_Definitions (CD, block_data.context.level);\n    end Declarative_Part;\n\n    procedure Statements_Part_Setup is\n    begin\n      block_data.max_data_allocation_index := block_data.data_allocation_index;\n      CD.id_table (block_data.block_id_index).adr_or_sz := HAC_Integer (CD.LC);\n      if block_data.previous_declaration_id_index > No_Id then\n        Link_Forward_Declaration\n          (CD, block_data.previous_declaration_id_index, block_data.block_id_index);\n      end if;\n      --  Copy initialization (elaboration) ObjCode from end of ObjCode table\n      for Init_Code_Idx in reverse CD.CMax + 1 .. CD.CMax + block_data.initialization_object_code_size loop\n        CD.ObjCode (CD.LC) := CD.ObjCode (Init_Code_Idx);\n        CD.LC              := CD.LC + 1;\n      end loop;\n      --  Restore CMax to the initial max.\n      --  At lowest nesting level, it will be CDMax.\n      --  For higher levels, it will be CDMax minus the sum of\n      --  current values of ICode for all lower levels.\n      CD.CMax := CD.CMax + block_data.initialization_object_code_size;\n    end Statements_Part_Setup;\n\n    procedure Statements_Part_Closing is\n    begin\n      CD.Blocks_Table (subprogram_block_index).SrcTo := CD.CUD.location.line;\n    end Statements_Part_Closing;\n\n    procedure Function_Result_Profile is\n      I_Res_Type : Integer;\n    begin\n      if CD.Sy = RETURN_Symbol then\n        In_Symbol;  --  FUNCTION TYPE\n        if CD.Sy = IDent then\n          I_Res_Type := Locate_CD_Id (CD, block_data.context.level);\n          In_Symbol;\n          if I_Res_Type /= 0 then\n            if CD.id_table (I_Res_Type).entity /= type_mark then\n              Error (CD, err_missing_a_type_identifier, severity => major);\n            elsif PCode_Atomic_Nonlimited_Typ (CD.id_table (I_Res_Type).xtyp.TYP) then\n              CD.id_table (block_data.block_id_index).xtyp := CD.id_table (I_Res_Type).xtyp;\n            else\n              Error (CD, err_bad_result_type_for_a_function, severity => major);\n            end if;\n          end if;\n        else\n          Error (CD, err_identifier_missing, severity => major);\n        end if;\n        block_data.return_statement_seen := False;\n      else\n        Error (CD, err_RETURN_missing, severity => major);\n      end if;\n    end Function_Result_Profile;\n\n    Restore_Block_ID : constant HAT.VString := CD.Full_Block_Id;\n    use HAT;\n\n    procedure Check_ident_after_END is\n      full_name : VString;\n      --  ^ It can be a library unit name, like: \"Parent_1.Child_3.Grandchild_5\".\n    begin\n      pragma Assert (CD.Sy = IDent);\n      CD.target.Mark_Reference (Initial_Block_Data.block_id_index);\n      loop\n        full_name := full_name & CD.Id;\n        In_Symbol;\n        exit when CD.Sy /= Period;\n        full_name := full_name & '.';\n        In_Symbol;\n        if CD.Sy /= IDent then\n          Error (CD, err_identifier_missing);\n        end if;\n      end loop;\n      if full_name /= Block_Id then\n        Error\n          (CD, err_incorrect_name_after_END,\n           hint_1 => A2S (Block_Id_with_case),\n           severity => minor,\n           location_method => previous_symbol);\n           --  ^ Ideally we would enclose the whole wrong full name (x.y.z),\n           --    possibly spanning on several lines.\n           --    But the method is correct on a single wrong identifier,\n           --    the most frequent case.\n      end if;\n    end Check_ident_after_END;\n\n    procedure Subprogram_Aspect is\n      use Compiler.PCode_Emit, PCode;\n    begin\n      In_Symbol;        --  Consume WITH\n      if CD.Sy = IDent then\n        if CD.Id = \"IMPORT\" then\n          In_Symbol;    --  Consume Import\n          Need (CD, Finger, err_general_error);\n          if CD.Id = \"TRUE\" then\n            In_Symbol;  --  Consume True\n            CD.id_table (block_data.block_id_index).adr_or_sz := HAC_Integer (CD.LC);\n            CD.id_table (block_data.block_id_index).decl_kind := spec_resolved;\n            Emit_1 (CD, k_Exchange_with_External, Operand_2_Type (block_data.block_id_index));\n            Emit_1 (CD, k_Return_Call, Normal_Procedure_Call);\n          else\n            Error (CD, err_general_error, \"value True expected here\");\n          end if;\n        end if;\n      else\n        Error (CD, err_general_error);\n      end if;\n    end Subprogram_Aspect;\n\n    procedure Process_Spec is\n    begin\n      CD.id_table (block_data.block_id_index).decl_kind := spec_unresolved;\n      CD.id_table (block_data.block_id_index).adr_or_sz := -1;\n      --  ^ This invalid address will raise VM_Subprogram_Spec.\n      Check_Duplicate_Specification (CD, block_data.previous_declaration_id_index, Block_Id_with_case);\n      CD.Blocks_Table (subprogram_block_index).VSize := block_data.data_allocation_index;\n      --\n      if CD.Sy = WITH_Symbol then\n        Subprogram_Aspect;\n      end if;\n      if block_data.context.level > 1 and then block_data.entity /= entree  then\n        In_Symbol;  --  Consume ';'\n      end if;\n      --  End of subprogram specification part (forward declaration).\n      --  Body is declared later in the containing block or elsewhere in the library.\n    end Process_Spec;\n\n    procedure Process_Body is\n    begin\n      CD.id_table (block_data.block_id_index).decl_kind := complete;\n      Check_Subprogram_Spec_Body_Consistency\n        (CD,\n         block_data.previous_declaration_id_index,\n         block_data.block_id_index,\n         Block_Id_with_case);\n      --\n      if Is_a_block_statement then\n        case CD.Sy is\n          when DECLARE_Symbol => In_Symbol;\n          when BEGIN_Symbol   => null;\n          when others         => raise Internal_error with \"Unexpected \" & Symbol'Image (CD.Sy);\n        end case;\n      elsif CD.Sy = IS_Symbol then  --  The \"IS\" in \"procedure ABC (param : T_Type) IS\"\n        In_Symbol;\n      else\n        Error (CD, err_IS_missing);\n        return;\n      end if;\n      --\n      if CD.Sy = NULL_Symbol and not Is_a_block_statement then\n        --  RM 6.7 Null Procedures (Ada 2005)\n        --  E.g.: \"procedure Not_Yet_Done (a : Integer) is null;\"\n        In_Symbol;  --  Consume NULL symbol.\n        Statements_Part_Setup;\n        if block_data.entity = funktion then\n          --  There are no null functions: what would be the result?\n          Error (CD, err_no_null_functions);\n        else\n          null;  --  No statement -> no instruction, like for the NULL statement.\n        end if;\n        Statements_Part_Closing;\n      else\n        Declarative_Part;\n        In_Symbol;  --  Consume BEGIN symbol.\n        Statements_Part_Setup;\n        Statements.Sequence_of_Statements (CD, END_Set, block_data);\n        Statements_Part_Closing;\n        --\n        if CD.remarks (note_unused_item)\n          or CD.remarks (note_constant_variable)\n          or CD.remarks (warn_read_but_not_written)\n        then\n          Check_Unused_or_Uninitialized_Items (CD, block_data.context.level);\n        end if;\n        --\n        if CD.Sy = END_Symbol then\n          In_Symbol;\n        elsif CD.error_count > 0 then\n          return;  --  At this point the program is already FUBAR.\n        else\n          Error (CD, err_END_missing);\n          return;\n        end if;\n        if block_data.entity = funktion and not Is_a_block_statement then\n          if not block_data.return_statement_seen then\n            Error\n              (CD,\n               err_general_error,\n               \"missing \"\"return\"\" statement in function body\",\n               severity => major);\n          end if;\n        end if;\n        --\n        case CD.Sy is\n          when IDent =>\n            --  Found an identifier after \"END\". Verify that the name matches the unit name.\n            Check_ident_after_END;\n          when CASE_Symbol | IF_Symbol | LOOP_Symbol =>\n            --  An extra END CASE, END IF, or END LOOP was found.\n            Error\n              (CD,\n               err_no_X_for_END_X,\n               (case CD.Sy is\n                  when CASE_Symbol => \"case\",\n                  when IF_Symbol   => \"if\",\n                  when LOOP_Symbol => \"loop\",\n                  when others      => \"\"),\n               severity => major);\n          when others =>\n            if Is_a_block_statement and Block_Id /= Empty_Alfa then\n              --  No identifier after \"end\", but \"end [label]\" is required in this case.\n              Error (CD, err_incorrect_name_after_END, hint_1 => A2S (Block_Id_with_case));\n            end if;\n        end case;\n      end if;\n      --\n      if CD.Sy /= Semicolon then\n        Error (CD, err_semicolon_missing);\n        return;\n      end if;\n      --\n      if block_data.context.level <= 1 or Is_a_block_statement then\n        --  Time to count the minor errors as errors.\n        CD.error_count := CD.error_count + CD.minor_error_count;\n        CD.minor_error_count := 0;\n      else\n        In_Symbol;  --  Consume ';' symbol after END [Subprogram_Id].\n        Ignore_Extra_Semicolons (CD);\n        --\n        --  Now we have either another declaration,\n        --  or BEGIN or, if it's a package body, the END symbol.\n        Test\n          (CD, FSys + Declaration_Symbol + BEGIN_Symbol + END_Symbol,\n           empty_symset,\n           err_incorrectly_used_symbol);\n      end if;\n    end Process_Body;\n\n  begin  --  Block\n    if CD.error_count > 0 then\n      return;\n    end if;\n    Increment_Nesting_or_Descending_Level (CD);\n    if CD.Full_Block_Id = Universe then\n      CD.Full_Block_Id := Block_Id_with_case;\n    else\n      CD.Full_Block_Id := CD.Full_Block_Id & '.' & Block_Id_with_case;\n    end if;\n    block_data.data_allocation_index := fixed_area_size;  --  Fixed area of the subprogram activation record.\n    block_data.initialization_object_code_size := 0;\n    if Is_a_block_statement then\n      null;  --  We should be here with Sy = BEGIN_Symbol or Sy = DECLARE_Symbol.\n    else\n      Test (CD, Symbols_after_Subprogram_Identifier, FSys, err_incorrectly_used_symbol);\n    end if;\n    if CD.id_table (block_data.block_id_index).block_or_pkg_ref > 0 then\n      subprogram_block_index := CD.id_table (block_data.block_id_index).block_or_pkg_ref;\n    else\n      Enter_Block (CD, block_data.block_id_index);\n      subprogram_block_index := CD.Blocks_Count;\n      CD.id_table (block_data.block_id_index).block_or_pkg_ref := subprogram_block_index;\n    end if;\n    CD.Display (block_data.context.level) := subprogram_block_index;\n    CD.id_table (block_data.block_id_index).xtyp := undefined_subtyp;\n    CD.Blocks_Table (subprogram_block_index).First_Param_Id_Idx := CD.Id_Count + 1;\n    if CD.Sy = LParent then\n      Formal_Parameter_List;\n    end if;\n    --\n    if CD.error_count > 0 then\n      return;\n    end if;\n    --\n    CD.Blocks_Table (subprogram_block_index).Last_Param_Id_Idx := CD.Id_Count;\n    CD.Blocks_Table (subprogram_block_index).PSize := block_data.data_allocation_index;\n    --\n    if block_data.entity = funktion and not Is_a_block_statement then\n      Function_Result_Profile;\n    end if;\n    --\n    if CD.Sy = Semicolon or CD.Sy = WITH_Symbol  --  Aspect\n    then\n      Process_Spec;\n    else\n      Process_Body;\n    end if;\n    CD.Full_Block_Id := Restore_Block_ID;\n    Decrement_Nesting_or_Descending_Level (CD);\n    if CD.error_count = 0 then\n      pragma Assert (block_data.context.level = Initial_Block_Data.context.level);\n    end if;\n  end Block;\n\n  procedure Subprogram_Declaration_or_Body\n    (CD            : in out Co_Defs.Compiler_Data;\n     FSys          : in     Defs.Symset;\n     current_level : in     Defs.Nesting_Level;\n     kind          :    out Co_Defs.Declaration_Kind)\n  is\n    use Co_Defs, Compiler.PCode_Emit, Defs, Enter_Def, Errors, PCode;\n    use type HAC_Integer;\n    --\n    new_id_idx, old_id_idx : Natural;\n    IsFun : constant Boolean := CD.Sy = FUNCTION_Symbol;\n    sub_sub_prog_block_data : Block_Data_Type;\n  begin\n    Scanner.In_Symbol (CD);\n    if CD.Sy /= IDent then\n      Error (CD, err_identifier_missing);\n      CD.Id := Empty_Alfa;\n    end if;\n    declare\n      id_subprog           : constant Alfa := CD.Id;\n      id_subprog_with_case : constant Alfa := CD.Id_with_case;\n    begin\n      Enter_Prefixed\n        (CD,\n         current_level,\n         CD.Id,\n         id_subprog_with_case,\n         (if IsFun then funktion else prozedure),\n         old_id_idx);\n      --  NB: now old_id_idx, if different than No_Id, points to the\n      --  possible previous declaration of the subprogram with that name.\n      Scanner.In_Symbol (CD);\n      sub_sub_prog_block_data.context.level                 := current_level + 1;\n      sub_sub_prog_block_data.block_id_index                := CD.Id_Count;\n      sub_sub_prog_block_data.entity                        := (if IsFun then funktion else prozedure);\n      sub_sub_prog_block_data.is_main                       := False;\n      sub_sub_prog_block_data.previous_declaration_id_index := old_id_idx;\n      new_id_idx := CD.Id_Count;\n      Block\n        (CD, FSys, False,\n         sub_sub_prog_block_data,\n         id_subprog,\n         id_subprog_with_case);\n      kind := CD.id_table (new_id_idx).decl_kind;\n      if kind = complete then\n        if IsFun then\n          Emit_1 (CD, k_Return_Function, End_Function_without_Return);\n        else\n          Emit_1 (CD, k_Return_Call, Normal_Procedure_Call);\n        end if;\n      end if;\n    end;\n  end Subprogram_Declaration_or_Body;\n\nend HAC_Sys.Parser;\n"
  },
  {
    "path": "src/compile/hac_sys-parser.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Co_Defs,\n     HAC_Sys.Defs;\n\npackage HAC_Sys.Parser is\n\n  type Block_Data_Type is record\n    context                         : Defs.Flow_Context;    --  When context.level = 0, the rest\n                                                            --    of this record is garbage.\n    entity                          : Co_Defs.Entity_Kind;  --  Procedure, function or entry.\n    return_statement_seen           : Boolean;\n    is_main                         : Boolean;\n    block_id_index                  : Natural;\n    previous_declaration_id_index   : Natural;              --  Subprogram \"forward\" declaration\n    initialization_object_code_size : Integer;              --  Was: ICode\n    data_allocation_index           : Integer;              --  Was: DX\n    max_data_allocation_index       : Integer;              --  Was: MaxDX\n    --  ^ includes the maximum space needed\n    --    for parameters of FOR loops.\n  end record;\n\n  --------------------------------------------\n  --  Block: subprogram or block statement  --\n  --------------------------------------------\n\n  procedure Block\n    (CD                   : in out Co_Defs.Compiler_Data;\n     FSys                 :        Defs.Symset;\n     Is_a_block_statement :        Boolean;        --  RM: 5.6 Block Statements\n     Initial_Block_Data   :        Block_Data_Type;\n     Block_Id             :        Defs.Alfa;      --  Name of this block (if any)\n     Block_Id_with_case   :        Defs.Alfa);\n\n  --  E.g. : in the case of a block statement within a function, the value\n  --  True will be passed for both Is_a_function and Is_a_block_statement.\n  --  When Is_a_block_statement = True, the current symbol Sy must be either\n  --  DECLARE_symbol or BEGIN_symbol\n\n  --------------------------------------------------------\n  --  Subprogram declaration or body (Ada RM 6.1, 6.3)  --\n  --------------------------------------------------------\n\n  procedure Subprogram_Declaration_or_Body\n    (CD            : in out Co_Defs.Compiler_Data;\n     FSys          : in     Defs.Symset;\n     current_level : in     Defs.Nesting_Level;\n     kind          :    out Co_Defs.Declaration_Kind);\n\nend HAC_Sys.Parser;\n"
  },
  {
    "path": "src/compile/hac_sys-scanner.adb",
    "content": "with HAC_Sys.Defs,\n     HAC_Sys.Errors;\n\nwith HAT;\n\nwith Ada.Directories,\n     Ada.IO_Exceptions,\n     Ada.Streams,\n     Ada.Strings.Fixed;\n\npackage body HAC_Sys.Scanner is\n\n  use Co_Defs, Defs, Errors, HAT;\n\n  type Special_Symbol_Mapping is array (Character'(' ') .. ']') of Symbol;\n\n  Special_Symbols : constant Special_Symbol_Mapping :=\n   ('+'    => Plus,\n    '-'    => Minus,\n    '*'    => Times,\n    '/'    => Divide,\n    '('    => LParent,\n    ')'    => RParent,\n    '['    => LBrack,\n    ']'    => RBrack,\n    ','    => Comma,\n    ';'    => Semicolon,\n    '&'    => Ampersand_Symbol,\n    others => NULL_Symbol);\n\n  type Character_Category is (Letter, Number, Special, Illegal);\n\n  type Set_of_Character_Category is array (Character_Category) of Boolean;\n\n  special_or_illegal : constant Set_of_Character_Category :=\n   (Letter  |  Number  => False,\n    Special | Illegal  => True);\n\n  c128 : constant Character := Character'Val (128);\n\n  Character_Types : constant array (Character) of Character_Category :=\n       ('A' .. 'Z' | 'a' .. 'z' => Letter,\n        '0' .. '9' => Number,\n        '#' |\n        '+' | '-' | '*' | '/' |\n        '(' | ')' |\n        '[' | ']' |\n        '&' |\n        '=' |\n        ' ' |\n        ',' |\n        '.' |\n        ''' |\n        ':' |\n        '_' |\n        ';' |\n        '|' |\n        '<' |\n        '>' |\n        '\"' => Special,\n        c128 => Special,\n        others => Illegal);\n\n  type Ada_Keyword_Mapping_Pair is record\n    st : VString;\n    sy : Symbol;\n  end record;\n\n  type Ada_Keyword_Mapping_List is\n    array (Positive range <>) of Ada_Keyword_Mapping_Pair;\n\n  ada_keyword : constant Ada_Keyword_Mapping_List :=\n       ((+\"ABORT\",        ABORT_Symbol),\n        (+\"ABS\",          ABS_Symbol),\n        (+\"ABSTRACT\",     ABSTRACT_Symbol),     -- [added in] Ada 95\n        (+\"ACCEPT\",       ACCEPT_Symbol),\n        (+\"ACCESS\",       ACCESS_Symbol),\n        (+\"ALIASED\",      ALIASED_Symbol),      -- Ada 95\n        (+\"ALL\",          ALL_Symbol),          -- Ada 95\n        (+\"AND\",          AND_Symbol),\n        (+\"ARRAY\",        ARRAY_Symbol),\n        (+\"AT\",           AT_Symbol),\n        (+\"BEGIN\",        BEGIN_Symbol),\n        (+\"BODY\",         BODY_Symbol),\n        (+\"CASE\",         CASE_Symbol),\n        (+\"CONSTANT\",     CONSTANT_Symbol),\n        (+\"DECLARE\",      DECLARE_Symbol),\n        (+\"DELAY\",        DELAY_Symbol),\n        (+\"DELTA\",        DELTA_Symbol),\n        (+\"DIGITS\",       DIGITS_Symbol),\n        (+\"DO\",           DO_Symbol),\n        (+\"ELSE\",         ELSE_Symbol),\n        (+\"ELSIF\",        ELSIF_Symbol),\n        (+\"END\",          END_Symbol),\n        (+\"ENTRY\",        ENTRY_Symbol),\n        (+\"EXCEPTION\",    EXCEPTION_Symbol),\n        (+\"EXIT\",         EXIT_Symbol),\n        (+\"FOR\",          FOR_Symbol),\n        (+\"FUNCTION\",     FUNCTION_Symbol),\n        (+\"GENERIC\",      GENERIC_Symbol),\n        (+\"GOTO\",         GOTO_Symbol),\n        (+\"IF\",           IF_Symbol),\n        (+\"IN\",           IN_Symbol),\n        (+\"INTERFACE\",    INTERFACE_Symbol),    -- Ada 2005\n        (+\"IS\",           IS_Symbol),\n        (+\"LIMITED\",      LIMITED_Symbol),\n        (+\"LOOP\",         LOOP_Symbol),\n        (+\"MOD\",          MOD_Symbol),\n        (+\"NEW\",          NEW_Symbol),\n        (+\"NOT\",          NOT_Symbol),\n        (+\"NULL\",         NULL_Symbol),\n        (+\"OF\",           OF_Symbol),\n        (+\"OR\",           OR_Symbol),\n        (+\"OTHERS\",       OTHERS_Symbol),\n        (+\"OUT\",          OUT_Symbol),\n        (+\"OVERRIDING\",   OVERRIDING_Symbol),   -- Ada 2005\n        (+\"PACKAGE\",      PACKAGE_Symbol),\n        (+\"PARALLEL\",     PARALLEL_Symbol),     -- Ada 2022\n        (+\"PRAGMA\",       PRAGMA_Symbol),\n        (+\"PRIVATE\",      PRIVATE_Symbol),\n        (+\"PROCEDURE\",    PROCEDURE_Symbol),\n        (+\"PROTECTED\",    PROTECTED_Symbol),    -- Ada 95\n        (+\"RAISE\",        RAISE_Symbol),\n        (+\"RANGE\",        RANGE_Keyword_Symbol),\n        (+\"RECORD\",       RECORD_Symbol),\n        (+\"REM\",          REM_Symbol),\n        (+\"RENAMES\",      RENAMES_Symbol),\n        (+\"REQUEUE\",      REQUEUE_Symbol),      -- Ada 95\n        (+\"RETURN\",       RETURN_Symbol),\n        (+\"REVERSE\",      REVERSE_Symbol),\n        (+\"SELECT\",       SELECT_Symbol),\n        (+\"SEPARATE\",     SEPARATE_Symbol),\n        (+\"SOME\",         SOME_Symbol),         -- Ada 2012\n        (+\"SUBTYPE\",      SUBTYPE_Symbol),\n        (+\"SYNCHRONIZED\", SYNCHRONIZED_Symbol), -- Ada 2005\n        (+\"TAGGED\",       TAGGED_Symbol),       -- Ada 95\n        (+\"TASK\",         TASK_Symbol),\n        (+\"TERMINATE\",    TERMINATE_Symbol),\n        (+\"THEN\",         THEN_Symbol),\n        (+\"TYPE\",         TYPE_Symbol),\n        (+\"UNTIL\",        UNTIL_Symbol),        -- Ada 95\n        (+\"USE\",          USE_Symbol),\n        (+\"WHEN\",         WHEN_Symbol),\n        (+\"WHILE\",        WHILE_Symbol),\n        (+\"WITH\",         WITH_Symbol),\n        (+\"XOR\",          XOR_Symbol)\n       );\n\n  subtype Size_test_a is String (1 .. 19);\n  subtype Size_test_b is Ada.Streams.Stream_Element_Array (1 .. 19);\n  se_equivalent_to_character : constant Boolean :=\n    Size_test_a'Size = Size_test_b'Size and\n    Size_test_a'Alignment = Size_test_b'Alignment;\n\n  procedure Next_Character (CD : in out Compiler_Data) is\n\n    procedure Get_Next_Line is\n      idx : Integer := CD.CUD.input_line'First - 1;\n      c   : Character;\n\n      procedure Get_Character_from_Buffer with Inline is\n\n        actually_read : Natural;\n\n        procedure Refill_Buffer is\n          use Ada.Streams;\n          se_buffer : Stream_Element_Array (1 .. Source_Buffer_String'Length);\n          for se_buffer'Address use CD.CUD.buffer'Address;\n          pragma Import (Ada, se_buffer);\n          last_read : Stream_Element_Offset;\n        begin\n          if se_equivalent_to_character then\n            --  Fast method:\n            CD.CUD.compiler_stream.Read (se_buffer, last_read);\n            actually_read := Natural (last_read);\n          else\n            --  Slow method:\n            actually_read := 0;\n            for cb of CD.CUD.buffer loop\n              Character'Read (CD.CUD.compiler_stream, cb);\n              actually_read := actually_read + 1;\n            end loop;\n          end if;\n        exception\n          when Ada.IO_Exceptions.End_Error =>\n            --  Happens with the slow method.\n            --  `actually_read` has been incremented correctly.\n            null;\n        end Refill_Buffer;\n\n      begin\n        if CD.CUD.buffer_position > CD.CUD.buffer_length then\n          Refill_Buffer;\n          if actually_read = 0 then\n            --  Refill failed, even a partial one -> the\n            --  stream is exhausted.\n            raise Ada.IO_Exceptions.End_Error;\n          end if;\n          CD.CUD.buffer_length := actually_read;\n          CD.CUD.buffer_position := 1;\n        end if;\n        c := CD.CUD.buffer (CD.CUD.buffer_position);\n        CD.CUD.buffer_position := CD.CUD.buffer_position + 1;\n      end Get_Character_from_Buffer;\n\n    begin\n      loop\n        Get_Character_from_Buffer;\n        --  Fast version of: Character'Read (CD.CUD.compiler_stream, c);\n        exit when c = ASCII.LF;\n        if c /= ASCII.CR then\n          idx := idx + 1;\n          CD.CUD.input_line (idx) := c;\n        end if;\n      end loop;\n      CD.CUD.LL := idx;\n    exception\n      when Ada.IO_Exceptions.End_Error =>\n        if idx < CD.CUD.input_line'First then\n          --  `idx` was not changed after its initialization.\n          raise;\n        end if;\n        CD.CUD.LL := idx;  --  Avoid trashing a non-empty line ending the stream.\n    end Get_Next_Line;\n\n  begin\n    if CD.CUD.CC = CD.CUD.LL then\n      if CD.listing_requested then\n        New_Line (CD.listing);\n      end if;\n      CD.CUD.location.line := CD.CUD.location.line + 1;\n      if CD.listing_requested then\n        HAC_Sys.Defs.IIO.Put (CD.listing, HAC_Integer (CD.CUD.location.line), 4);\n        Put (CD.listing, \"  \");\n      end if;\n      CD.CUD.LL := 0;\n      CD.CUD.CC := 0;\n      Get_Next_Line;\n      --  Append a space:\n      CD.CUD.LL := CD.CUD.LL + 1;\n      CD.CUD.input_line (CD.CUD.LL) := ' ';\n\n      if CD.listing_requested then\n        New_Line (CD.listing);\n        Put_Line (CD.listing, CD.CUD.input_line);\n      end if;\n    end if;\n\n    CD.CUD.CC     := CD.CUD.CC + 1;\n    CD.CUD.prev_c := CD.CUD.c;\n    CD.CUD.c      := CD.CUD.input_line (CD.CUD.CC);\n    --  Change tabs for spaces:\n    if Character'Pos (CD.CUD.c) = 9 then\n      CD.CUD.c := ' ';\n    end if;\n    if CD.CUD.c < ' ' then\n      Error (CD, err_scanner_control_character);\n    end if;\n  end Next_Character;\n\n  procedure Skip_Blanks (CD : in out Compiler_Data) is\n  begin\n    while CD.CUD.c = ' ' loop\n      Next_Character (CD);\n    end loop;\n  end Skip_Blanks;\n\n  procedure In_Symbol (CD : in out Compiler_Data) is\n    I, J, K, e : Integer;\n\n    procedure Read_Scale (allow_minus : Boolean) is\n      S, Sign : Integer;\n      digit_count : Natural := 0;\n    begin\n      Next_Character (CD);\n      Sign := 1;\n      S    := 0;\n      case CD.CUD.c is\n        when '+' =>\n          Next_Character (CD);\n        when '-' =>\n          Next_Character (CD);\n          if allow_minus then\n            Sign := -1;\n          else\n            Error\n              (CD, err_scanner_negative_exponent_for_integer_literal,\n               CD.INum'Image & \".0e- ...\",\n               severity => minor);  --  minor -> scanning & parsing go on unhindered.\n          end if;\n        when others =>\n          null;\n      end case;\n      if CD.CUD.c not in '0' .. '9' then\n        Error\n          (CD,\n           err_scanner_illegal_character_in_number,\n           \"; expected digit after 'E'\");\n      else\n        loop\n          if digit_count = integer_digits_max then\n            Error\n              (CD,\n               err_scanner_integer_literal_too_large,\n               severity => minor);  --  minor -> scanning & parsing go on unhindered.\n          elsif digit_count > integer_digits_max then\n            null;  --  The insult was already issued on digit_count = integer_digits_max...\n          else\n            S := S * 10 + Character'Pos (CD.CUD.c) - Character'Pos ('0');\n          end if;\n          digit_count := digit_count + 1;\n          Next_Character (CD);\n          exit when CD.CUD.c not in '0' .. '9';\n        end loop;\n      end if;\n      e := S * Sign + e;\n    end Read_Scale;\n\n    procedure Adjust_Scale is\n      S    : Integer;\n      D, T : HAC_Float;\n    begin\n      if K + e > EMax then\n        Error\n          (CD, err_scanner_exponent_too_large,\n           K'Image & \" +\" & e'Image & \" =\" & Integer'Image (K + e) &\n           \" > Max =\" & EMax'Image,\n           severity => minor);  --  minor -> scanning & parsing go on unhindered.\n      elsif K + e < EMin then\n        CD.RNum := 0.0;\n      else\n        S := abs e;\n        T := 1.0;\n        D := 10.0;\n        loop\n          while S rem 2 = 0 loop\n            S := S / 2;\n            D := D ** 2;\n          end loop;\n          S := S - 1;\n          T := D * T;\n          exit when S = 0;\n        end loop;\n        CD.RNum := (if e >= 0 then CD.RNum * T else CD.RNum / T);\n      end if;\n    end Adjust_Scale;\n\n    procedure Read_with_Sharp is\n      --  For numbers in bases other than 10, we fall back to Ada\n      --  library's parsing, at the price of a less detailed\n      --  error diagnostic.\n      s : Source_Line_String;\n      l : Natural := s'First - 1;\n      has_point : Boolean := False;\n    begin\n      --  Number has been read until the first '#'.\n      loop\n        Next_Character (CD);\n        l := l + 1;\n        s (l) := CD.CUD.c;\n        exit when CD.CUD.c = '#';  --  Second '#'.\n        has_point := has_point or CD.CUD.c = '.';\n      end loop;\n      Next_Character (CD);\n      if CD.CUD.c in 'E' | 'e' then\n        --  Exponent. Special case because of possible '+' or '-' which\n        --  are not operators (e.g. 8#123#e+5 vs. 8#123#+5, = 8#123# + 5)...\n        --  Otherwise we could have done it all in the previous loop.\n        for c in 1 .. 2 loop\n          l := l + 1;\n          s (l) := CD.CUD.c;  --  We concatenate \"e+\", \"e-\", \"e5\".\n          Next_Character (CD);\n        end loop;\n        while CD.CUD.c in '0' .. '9' loop\n          l := l + 1;\n          s (l) := CD.CUD.c;  --  We concatenate the rest of the exponent.\n          Next_Character (CD);\n        end loop;\n      end if;\n      declare\n        complete_string : constant String :=\n          HAC_Integer'Image (CD.INum) & '#' & s (s'First .. l);\n      begin\n        if has_point then\n          CD.Sy   := real_literal;\n          CD.RNum := HAC_Float'Value (complete_string);\n        else\n          CD.Sy   := integer_literal;\n          CD.INum := HAC_Integer'Value (complete_string);\n        end if;\n      exception\n        when others =>\n          Error (CD, err_scanner_illegal_character_in_number);\n      end;\n    end Read_with_Sharp;\n\n    procedure Skip_Possible_Underscore_in_Number is\n    begin\n      if CD.CUD.c = '_' then\n        Next_Character (CD);\n        if CD.CUD.c = '_' then\n          Error\n            (CD,\n             err_scanner_double_underline_not_permitted,\n             severity => major);\n        elsif Character_Types (CD.CUD.c) /= Number then\n          Error (CD, err_scanner_digit_expected, severity => major);\n        end if;\n      end if;\n    end Skip_Possible_Underscore_in_Number;\n\n    procedure Read_Decimal_Float is\n    begin\n      --  Floating-point number 123.456\n      --  Cursor is here -----------^\n      if CD.CUD.c = '.' then\n        --  After all, this is not a number with a decimal point,\n        --  but a double dot, like 123..456.\n        CD.CUD.c := c128;\n        return;\n      end if;\n      --  Read decimal part.\n      CD.Sy := real_literal;\n      CD.RNum := HAC_Float (CD.INum);\n      e := 0;\n      while Character_Types (CD.CUD.c) = Number loop\n        e := e - 1;\n        CD.RNum :=\n          10.0 * CD.RNum +\n            HAC_Float (Character'Pos (CD.CUD.c) - Character'Pos ('0'));\n        Next_Character (CD);\n        Skip_Possible_Underscore_in_Number;\n      end loop;\n      if e = 0 then\n        Error\n          (CD,\n           err_scanner_illegal_character_in_number,\n           \"; expected digit after '.'\");\n      end if;\n      if CD.CUD.c in 'E' | 'e' then\n        Read_Scale (allow_minus => True);\n      end if;\n      if e /= 0 then\n        Adjust_Scale;\n      end if;\n    end Read_Decimal_Float;\n\n    procedure Scan_Number (skip_leading_integer : Boolean) is\n      use type HAC_Integer;\n    begin\n      K       := 0;\n      CD.INum := 0;\n      CD.Sy   := integer_literal;\n      if skip_leading_integer then\n        --  Example: a naughty person has put \".123\" in his/her code.\n        --  An error is already emmitted at this point but we continue\n        --  the scanning and parsing.\n        Read_Decimal_Float;\n      else\n        --  Scan the integer part of the number.\n        loop\n          if K = integer_digits_max then\n            --  To do: read a multiprecision integer here, so the limitation\n            --         is not applied to floating-point numbers.\n            --         Challenge: convert accurately the multiprecision integer\n            --         to a floating-point number.\n            Error\n              (CD,\n               err_scanner_integer_literal_too_large,\n               severity => minor);  --  minor -> scanning & parsing go on unhindered.\n          elsif K > integer_digits_max then\n            null;  --  The insult was already issued on K = integer_digits_max...\n          else\n            CD.INum := CD.INum * 10 + (Character'Pos (CD.CUD.c) - Character'Pos ('0'));\n          end if;\n          K := K + 1;\n          Next_Character (CD);\n          Skip_Possible_Underscore_in_Number;\n          exit when Character_Types (CD.CUD.c) /= Number;\n        end loop;\n        --  Integer part is read (CD.INum).\n        case CD.CUD.c is\n          when '.' =>\n            Next_Character (CD);\n            Read_Decimal_Float;\n          when 'E' | 'e' =>\n            --  Integer with exponent: 123e4.\n            e := 0;\n            Read_Scale (allow_minus => False);\n            --  NB: a negative exponent issues an error, then e is set to 0.\n            if e > 0 then\n              if K + e > integer_digits_max then\n                Error\n                  (CD, err_scanner_exponent_too_large,\n                   Integer'Image (K) & \" +\" &\n                   Integer'Image (e) & \" =\" &\n                   Integer'Image (K + e) & \" > Max =\" &\n                   integer_digits_max'Image,\n                   severity => minor);  --  minor -> scanning & parsing go on unhindered.\n              else\n                CD.INum := CD.INum * 10 ** e;\n              end if;\n            end if;\n          when '#' =>\n            Read_with_Sharp;\n          when others =>\n            null;  --  Number was an integer in base 10.\n        end case;\n      end if;\n      if Character_Types (CD.CUD.c) = Letter then\n        CD.CUD.location.column_start := CD.CUD.CC;\n        CD.CUD.location.column_stop  := CD.CUD.CC;\n        Error\n          (CD,\n           err_scanner_space_missing_after_number,\n           severity => minor);  --  scanning & parsing go on unhindered.\n      end if;\n    end Scan_Number;\n\n    procedure Scan_Apostrophe_or_Character is\n      C1, C2 : Character;\n    begin\n      --  We scan a little bit further: 2 characters. Possible legal cases:\n      --      *  1 'c'      : character\n      --      *  2 '''      : character\n      --      *  3 'Image   : attribute (hope that no-one invents a 1-letter attribute)\n      --      *  4 '(...)   : qualified expression\n      --      *  5 '(       : (end of a line after last non-blank) start of a qualified expression\n      --  NB: all legal cases but the last have two characters\n      --      on the same line after the first '\n      --  Blatantly illegal cases:\n      --      *  6 ''x      where x is not an '\n      --      *  7 ''       (end of a line after last non-blank)\n      --      *  8 'c       (end of a line after last non-blank)  c being neither '' nor (\n      --      *  9 '        (end of a line after last non-blank)\n      --\n      if CD.CUD.CC = CD.CUD.LL then  --  Case (9) above\n        Error (CD, err_scanner_character_zero_chars, severity => major);\n      end if;\n      Next_Character (CD);\n      C1 := CD.CUD.c;\n      if CD.CUD.CC = CD.CUD.LL then  --  Cases (5), (7), (8)\n        if C1 = '(' then\n          --  Case (5)\n          CD.Sy := Apostrophe;\n          return;\n        end if;\n        --  Case (7), (8)\n        Error (CD, err_scanner_character_zero_chars, severity => major);\n      end if;\n      --  We peek the next character without moving.\n      --  Possible since CD.CC < CD.LL .\n      C2 := CD.CUD.input_line (CD.CUD.CC + 1);\n      if C1 = ''' and C2 /= ''' then  --  Case (6)\n        Error (CD, err_scanner_character_zero_chars, severity => major);\n      end if;\n      --  Until now, case (5) to (9) are treated.\n      if C2 = ''' then  --  Cases (1), (2)\n        CD.Sy := character_literal;\n        CD.INum := Character'Pos (C1);\n        Next_Character (CD);\n        Next_Character (CD);\n      else  --  Cases (3), (4)\n        CD.Sy := Apostrophe;\n      end if;\n    end Scan_Apostrophe_or_Character;\n\n    procedure Scan_String_Literal is\n      ST : String renames CD.Strings_Constants_Table;\n      lit_len : Integer;\n\n      procedure Try_String_Folding is\n        trace_folding : constant Boolean := False;\n        first_char : constant Character := ST (CD.Strings_Table_Top + 1);\n        len : Positive;\n      begin\n        pragma Assert (lit_len > 0);\n        for past_start in\n          Integer'Max\n            (Strings_Constants_Table_Type'First,\n             CD.Strings_Table_Top - string_folding_scan_limit)\n          ..\n          CD.Strings_Table_Top\n        loop\n          len := Integer'Min (lit_len, CD.Strings_Table_Top - past_start + 1);\n          --  NB: from the upper bound of the loop, we know that\n          --  CD.Strings_Table_Top >= past_start.\n          --  We also have assumed above that lit_len > 0.\n          --  Then, len is always > 0 (the substring to match is\n          --  at least one character long).\n          if ST (past_start) = first_char\n            and then\n              ST (past_start .. past_start + len - 1) =\n              ST (CD.Strings_Table_Top + 1 .. CD.Strings_Table_Top + len)\n          then\n            CD.INum  := HAC_Integer (past_start);\n            if trace_folding then\n              Put (\"Matched... [\" & ST (past_start .. past_start + len - 1) & \"] \");\n              if len = lit_len then\n                Put_Line (\"Full match\");\n                --  Entire new string was found in the existing string table.\n                --  CD.Strings_Table_Top won't be changed.\n              else\n                pragma Assert (len < lit_len);\n                Put_Line\n                  (\"Partial match; rest is: [\" &\n                   ST (CD.Strings_Table_Top + len + 1 .. CD.Strings_Table_Top + lit_len) &\n                   ']');\n                 --  A partial match makes sense only from the first characters\n                 --  rightwards and if the right limit is on CD.Strings_Table_Top.\n                 --  Then the table can be completed to the full string.\n              end if;\n            end if;\n            --  Partial match: append rest to last string in the table.\n            for i in 1 .. lit_len - len loop\n              ST (CD.Strings_Table_Top + i) :=      --  Extension.\n              ST (CD.Strings_Table_Top + i + len);  --  Rest of the newly scanned string\n            end loop;\n            --  We will extend the known part of the table only for `lit_len - len` characters.\n            --  In any case `len` is the \"compression\" gain.\n            lit_len := lit_len - len;\n            exit;\n          end if;\n        end loop;\n      end Try_String_Folding;\n\n    begin\n      lit_len := 0;\n      loop\n        Next_Character (CD);\n        if CD.CUD.c = '\"' then\n          Next_Character (CD);\n          if CD.CUD.c /= '\"' then\n            --  [\"x] case: we have reached the end of the string.\n            exit;\n          end if;\n          --  [\"\"] case: doubled double-quote which means a single one.\n        end if;\n        lit_len := lit_len + 1;\n        if CD.Strings_Table_Top + lit_len = SMax then\n          Fatal (STRING_CONSTANTS);\n        end if;\n        ST (CD.Strings_Table_Top + lit_len) := CD.CUD.c;\n        if CD.CUD.CC = 1 then\n          lit_len := 0;  --  END OF InpLine\n          CD.CUD.location.column_start := 1;\n          CD.CUD.location.column_stop  := 1;\n          Error\n            (CD,\n             err_general_error,\n             \"missing closing quote on previous line \",\n             severity => major);\n        else\n          null;  --  Continue\n        end if;\n      end loop;\n      CD.Sy    := string_literal;\n      CD.SLeng := lit_len;\n      CD.INum  := HAC_Integer (CD.Strings_Table_Top + 1);\n      --\n      if lit_len > 0 then\n        if CD.target.Null_Terminated_String_Literals then\n          --  Add a Character'Val (0) to the stored string.\n          lit_len := lit_len + 1;\n          if CD.Strings_Table_Top + lit_len = SMax then\n            Fatal (STRING_CONSTANTS);\n          end if;\n          ST (CD.Strings_Table_Top + lit_len) := Character'Val (0);\n        else\n          Try_String_Folding;\n        end if;\n        CD.Strings_Table_Top := CD.Strings_Table_Top + lit_len;\n      end if;\n    end Scan_String_Literal;\n\n    procedure Process_Special_Comment (annotation : String) is  --  Process \"--!\"\n\n      cmd_add_to_path : constant String := \"hac_add_to_path \";\n\n      procedure Add_to_Path (rel_or_abs_dir : String) is\n        use Ada.Directories;\n        cur_dir : constant String := Current_Directory;\n        src_dir : constant String := Containing_Directory (To_String (CD.CUD.source_file_name));\n      begin\n        --  Go to the specified directory, which is absolute or relative\n        --  to the source file's directory\n        --\n        --  Put_Line (\"Ah ha! [\" & rel_or_abs_dir & ']');\n        Ada.Directories.Set_Directory (src_dir);\n        --  Put_Line (\"src_dir [\" & src_dir & ']');\n        Ada.Directories.Set_Directory (rel_or_abs_dir);\n        --  Put_Line (\"abs_dir [\" & Ada.Directories.Current_Directory & ']');\n        CD.cat.Add_to_Source_Path (Ada.Directories.Current_Directory);\n\n        --  Restore current directory:\n        Ada.Directories.Set_Directory (cur_dir);\n      end Add_to_Path;\n\n    begin\n      if Ada.Strings.Fixed.Index (annotation, cmd_add_to_path) > 0 then\n        Add_to_Path\n          (Ada.Strings.Fixed.Trim\n            (annotation (annotation'First + cmd_add_to_path'Length .. annotation'Last),\n             Ada.Strings.Both));\n      end if;\n    end Process_Special_Comment;\n\n    exit_big_loop : Boolean;\n\n  begin  --  In_Symbol\n    CD.prev_sy     := CD.Sy;\n    CD.prev_sy_loc := CD.CUD.location;\n\n    Big_loop :\n    loop\n      Small_loop :\n      loop\n        Skip_Blanks (CD);\n\n        CD.CUD.location.column_start := CD.CUD.CC;\n        exit Small_loop when Character_Types (CD.CUD.c) /= Illegal;\n        Error (CD, err_scanner_illegal_character);\n        if CD.comp_dump_requested then\n          Put_Line\n           (CD.comp_dump,\n            \" Char is => \" & Integer'Image (Character'Pos (CD.CUD.c)));\n        end if;\n        if CD.listing_requested then\n          Put_Line\n           (CD.listing,\n            \" Char is => \" & Integer'Image (Character'Pos (CD.CUD.c)));\n        end if;\n        Next_Character (CD);\n      end loop Small_loop;\n\n      exit_big_loop := True;\n      case CD.CUD.c is\n        when 'A' .. 'Z' |   --  Identifier or keyword\n             'a' .. 'z' =>\n          K := 0;\n          HAT.VStr_Pkg.Set_Unbounded_String (CD.Id_with_case, \"\");\n          loop\n            if K < identifier_length_max then\n              K := K + 1;\n              HAT.VStr_Pkg.Append (CD.Id_with_case, CD.CUD.c);\n              if K > 1 and then (CD.CUD.c = '_' and CD.CUD.prev_c = '_') then\n                Error\n                  (CD,\n                   err_scanner_double_underline_not_permitted,\n                   severity => major);\n              end if;\n            else\n              Error (CD, err_scanner_identifier_too_long);\n            end if;\n            Next_Character (CD);\n            exit when CD.CUD.c /= '_'\n                     and then special_or_illegal (Character_Types (CD.CUD.c));\n          end loop;\n          if K > 0 and then CD.CUD.prev_c = '_' then\n            Error\n              (CD,\n               err_scanner_identifier_cannot_end_with_underline,\n               severity => major);\n          end if;\n          --\n          HAT.VStr_Pkg.Set_Unbounded_String\n            (CD.Id, HAT.ACH.To_Upper (To_String (CD.Id_with_case)));\n          CD.Id_location := No_Id_Cache;\n          --\n          --  Binary Search\n          --\n          I := 1;\n          J := ada_keyword'Last;\n          loop\n            K := (I + J) / 2;\n            if CD.Id <= ada_keyword (K).st then\n              J := K - 1;\n            end if;\n            if CD.Id >= ada_keyword (K).st then\n              I := K + 1;\n            end if;\n            exit when I > J;\n          end loop;\n          --\n          CD.Sy := (if I - 1 > J then ada_keyword (K).sy else IDent);\n\n        when '0' .. '9' => Scan_Number (skip_leading_integer => False);\n        when '\"'        => Scan_String_Literal;\n        when '''        => Scan_Apostrophe_or_Character;\n\n        when ':' =>\n          Next_Character (CD);\n          if CD.CUD.c = '=' then\n            CD.Sy := Becomes;\n            Next_Character (CD);\n          else\n            CD.Sy := Colon;\n          end if;\n\n        when '<' =>\n          Next_Character (CD);\n          if CD.CUD.c = '=' then\n            CD.Sy := LEQ;\n            Next_Character (CD);\n          else\n            CD.Sy := LSS;\n          end if;\n\n        when '>' =>\n          Next_Character (CD);\n          if CD.CUD.c = '=' then\n            CD.Sy := GEQ;\n            Next_Character (CD);\n          else\n            CD.Sy := GTR;\n          end if;\n\n        when '/' =>\n          Next_Character (CD);\n          if CD.CUD.c = '=' then\n            CD.Sy := NEQ;\n            Next_Character (CD);\n          else\n            CD.Sy := Divide;\n          end if;\n\n        when '.' =>\n          Next_Character (CD);\n          case CD.CUD.c is\n            when '.' =>\n              CD.Sy := Range_Double_Dot_Symbol;\n              Next_Character (CD);\n            when '0' .. '9' =>\n              Error\n                (CD, err_general_error,\n                 \"numeric literal cannot start with point\", severity => minor);\n              Scan_Number (skip_leading_integer => True);\n            when others =>\n              CD.Sy := Period;\n          end case;\n\n        when c128 =>  --  Hathorn\n          CD.Sy := Range_Double_Dot_Symbol;\n          Next_Character (CD);\n\n        when '-' =>\n          Next_Character (CD);\n          if CD.CUD.c = '-' then     --  Comment\n\n            if CD.CUD.CC < CD.CUD.LL\n              and then CD.CUD.input_line (CD.CUD.CC + 1) = '!'\n            then\n              Process_Special_Comment (CD.CUD.input_line (CD.CUD.CC + 2 .. CD.CUD.LL));\n            end if;\n\n            CD.CUD.CC := CD.CUD.LL;  --  Ignore rest of input line\n            Next_Character (CD);\n            exit_big_loop := False;\n          else\n            CD.Sy := Minus;\n          end if;\n\n        when '=' =>\n          Next_Character (CD);\n          if CD.CUD.c = '>' then\n            CD.Sy := Finger;\n            Next_Character (CD);\n          else\n            CD.Sy := EQL;\n          end if;\n\n        when '|' =>\n          CD.Sy := Alt;\n          Next_Character (CD);\n\n        when '+' | '*' | '(' | ')' | ',' | '[' | ']' | ';' | '&' =>\n          CD.Sy := Special_Symbols (CD.CUD.c);\n          Next_Character (CD);\n          if CD.Sy = Times and then CD.CUD.c = '*' then  --  Get the \"**\" operator symbol\n            CD.Sy := Power;\n            Next_Character (CD);\n          end if;\n\n        when '$' | '!' | '@' | '\\' | '^' | '_' | '?' | '%' | '#' =>\n          Error (CD, err_scanner_illegal_character);\n          if CD.comp_dump_requested then\n            Put_Line (CD.comp_dump, \" [ $!@\\^_?%# ]\");\n          end if;\n          if CD.listing_requested then\n            Put_Line (CD.listing,   \" [ $!@\\^_?%# ]\");\n          end if;\n          Next_Character (CD);\n          exit_big_loop := False;\n\n        when Character'Val (0) .. ' ' =>\n          null;\n        when others =>\n          null;\n\n      end case;  --  CD.SD.CH\n      exit Big_loop when exit_big_loop;\n    end loop Big_loop;\n\n    CD.CUD.location.column_stop := CD.CUD.CC - 1;\n\n    if CD.comp_dump_requested then\n      Put_Line (CD.comp_dump, CD.CUD.input_line (1 .. CD.CUD.LL));\n      Put_Line (CD.comp_dump, (CD.CUD.CC - 2) * '.' & '^');  --  Draw: \".......^\"\n      Put\n        (CD.comp_dump,\n         '[' & CD.CUD.location.line'Image & ':' & CD.CUD.CC'Image & \":] \" &\n         CD.Sy'Image);\n      case CD.Sy is\n        when IDent =>\n          Put (CD.comp_dump, \": \" & A2S (CD.Id));\n        when integer_literal =>\n          Put (CD.comp_dump, \": \" & HAC_Integer'Image (CD.INum));\n        when real_literal =>\n          Put (CD.comp_dump, \": \" & HAC_Float'Image (CD.RNum));\n        when string_literal =>\n          Put (CD.comp_dump, \": \"\"\");\n          for i in Integer (CD.INum) .. Integer (CD.INum) + CD.SLeng - 1 loop\n            Put (CD.comp_dump, CD.Strings_Constants_Table (i));\n          end loop;\n          Put (CD.comp_dump, '\"');\n        when Becomes =>\n          Put (CD.comp_dump, \" := \");\n        when Colon =>\n          Put (CD.comp_dump, \" : \");\n        when CONSTANT_Symbol =>\n          Put (CD.comp_dump, \" constant \");\n        when others =>\n          null;\n      end case;\n      New_Line (CD.comp_dump, 2);\n    end if;\n  end In_Symbol;\n\nend HAC_Sys.Scanner;\n"
  },
  {
    "path": "src/compile/hac_sys-scanner.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Co_Defs;\n\npackage HAC_Sys.Scanner is\n\n  --  Source code scanning for the compiler\n\n  procedure In_Symbol (CD : in out Co_Defs.Compiler_Data);\n\n  procedure Skip_Blanks (CD : in out Co_Defs.Compiler_Data);\n\nend HAC_Sys.Scanner;\n"
  },
  {
    "path": "src/execute/hac_sys-interfacing.adb",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.Defs;\n\nwith HAT;\n\nwith Ada.Characters.Handling,\n     Ada.Unchecked_Conversion;\n\npackage body HAC_Sys.Interfacing is\n\n  use HAT, Defs;\n\n  function To_HAC (Data : Integer) return HAC_Element is\n    new_element : HAC_Element;\n  begin\n    new_element.I := HAC_Integer (Data);\n    return new_element;\n  end To_HAC;\n\n  function To_HAC (Data : Long_Float) return HAC_Element is\n  begin\n    return GR_Real (HAT.Real (Data));\n  end To_HAC;\n\n  function To_HAC (Data : String) return HAC_Element is\n  begin\n    return GR_VString (Data);\n  end To_HAC;\n\n  function To_HAC_Any_Integer (Data : Any_Integer) return HAC_Element is\n    new_element : HAC_Element;\n  begin\n    new_element.I := HAC_Integer (Data);\n    return new_element;\n  end To_HAC_Any_Integer;\n\n  function To_HAC_Any_Enum (Data : Any_Enum) return HAC_Element is\n    new_element : HAC_Element;\n  begin\n    new_element.I := Any_Enum'Pos (Data);\n    return new_element;\n  end To_HAC_Any_Enum;\n\n  function To_HAC_Any_Float (Data : Any_Float) return HAC_Element is\n  begin\n    return GR_Real (HAT.Real (Data));\n  end To_HAC_Any_Float;\n\n  function To_Native (Data : HAC_Element) return Integer is\n  begin\n    return Integer (Data.I);\n  end To_Native;\n\n  function To_Native (Data : HAC_Element) return Long_Float is\n  begin\n    if Data.Special = Floats then\n      return Long_Float (Data.R);\n    end if;\n    raise HAC_Type_Error with \"Expected a HAT.Real, found Integer or \" & Typen'Image (Data.Special);\n  end To_Native;\n\n  function To_Native (Data : HAC_Element) return String is\n  begin\n    if Data.Special = VStrings then\n      return To_String (Data.V);\n    end if;\n    raise HAC_Type_Error with \"Expected a VString, found Integer or \" & Typen'Image (Data.Special);\n  end To_Native;\n\n  function To_Native_Any_Integer (Data : HAC_Element) return Any_Integer is\n  begin\n    return Any_Integer (Data.I);\n  end To_Native_Any_Integer;\n\n  function To_Native_Any_Enum (Data : HAC_Element) return Any_Enum is\n  begin\n    return Any_Enum'Val (Data.I);\n  end To_Native_Any_Enum;\n\n  function To_Native_Any_Float (Data : HAC_Element) return Any_Float is\n  begin\n    if Data.Special = Floats then\n      return Any_Float (Data.R);\n    end if;\n    raise HAC_Type_Error with \"Expected a HAT.Real, found Integer or \" & Typen'Image (Data.Special);\n  end To_Native_Any_Float;\n\n  function Get_VM_Variable (BD : Builder.Build_Data; Name : String) return String is\n    cur : constant Builder.String_Maps.Cursor := BD.global_VM_variables.Find (HAT.To_VString (Name));\n    use Builder.String_Maps;\n  begin\n    return\n      (if cur = Builder.String_Maps.No_Element then\n         \"\"\n       else\n         HAT.To_String (Builder.String_Maps.Element (cur)));\n  end Get_VM_Variable;\n\n  procedure Set_VM_Variable (BD : in out Builder.Build_Data; Name : String; Value : String) is\n  begin\n    BD.global_VM_variables.Include (HAT.To_VString (Name), HAT.To_VString (Value));\n  end Set_VM_Variable;\n\n  procedure Register\n    (BD : Builder.Build_Data; Callback : Exported_Procedure; Name : String)\n  is\n    function Convert is\n      new Ada.Unchecked_Conversion\n        (Exported_Procedure, Co_Defs.Dummy_Procedure_Access);\n    use Ada.Characters.Handling;\n  begin\n    if Callback /= null then\n      BD.CD.Exported_Procedures.Include (To_Upper (Name), Convert (Callback));\n    end if;\n  end Register;\n\n  procedure Deregister (BD : Builder.Build_Data; Name : String)\n  is\n    use Ada.Characters.Handling;\n  begin\n    BD.CD.Exported_Procedures.Exclude (To_Upper (Name));\n  end Deregister;\n\nend HAC_Sys.Interfacing;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-calls.adb",
    "content": "with HAC_Sys.Interfacing,\n     HAC_Sys.PCode.Interpreter.Exceptions,\n     HAC_Sys.PCode.Interpreter.Tasking;\n\nwith Ada.Calendar,\n     Ada.Exceptions,\n     Ada.Unchecked_Conversion;\n\npackage body HAC_Sys.PCode.Interpreter.Calls is\n\n  procedure Do_Calling_Operation (\n    CD :        Co_Defs.Compiler_Data;\n    ND : in out In_Defs.Interpreter_Data\n  )\n  is\n    use Defs, In_Defs;\n    Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n    IR : Order renames ND.IR;\n    use type HAC_Integer;\n\n    procedure Do_Mark_Stack is\n      --  VSize is the maximum stack room needed by the subprogram to be called.\n      VSize : constant Integer :=\n        Integer (CD.Blocks_Table (CD.id_table (Integer (IR.Y)).block_or_pkg_ref).VSize);\n    begin\n      if Curr_TCB.T + VSize > Curr_TCB.STACKSIZE then\n        raise Exceptions.VM_Stack_Overflow;\n      end if;\n      Curr_TCB.T := Curr_TCB.T + Co_Defs.fixed_area_size;  --  Make room for fixed area\n      ND.S (Curr_TCB.T - 1).I := HAC_Integer (VSize - 1);\n      ND.S (Curr_TCB.T).I     := IR.Y;                     --  CD.IdTab index of called procedure/entry\n    end Do_Mark_Stack;\n\n    trace_display : constant Boolean := False;\n\n    procedure Show_Display (D : Co_Defs.Display_Type; L_Max : Nesting_Level; T : String) is\n      use HAT;\n    begin\n      if trace_display then\n        New_Line;\n        Put_Line (\"Level   Stack base of variables  --  \" & T);\n        for i in 0 .. L_Max loop\n          Put (Integer (i), 5);\n          Put (D (i));\n          New_Line;\n        end loop;\n      end if;\n    end Show_Display;\n\n    procedure Do_Exchange_with_External is\n      use Co_Defs;\n      use Co_Defs.Exported_Procedure_Mapping;\n      proc_entry : Identifier_Table_Entry renames CD.id_table (Integer (IR.Y));\n      proc_name  : constant String := A2S (proc_entry.name);\n      block_idx  : constant Index  := proc_entry.block_or_pkg_ref;\n      block      : Block_Table_Entry renames CD.Blocks_Table (block_idx);\n      base       : constant Positive := Curr_TCB.T - block.PSize + 1;\n      --\n      --  The size of parameters' data can be larger that the size\n      --  taken on stack, as soon as a composite parameter of size\n      --  more than 1 is passed by reference (the reference takes 1 cell).\n      --\n      function param_data_size return Natural is\n        total : Natural := 0;\n      begin\n        for p in block.First_Param_Id_Idx .. block.Last_Param_Id_Idx loop\n          total := total + Size_of (CD, p);\n        end loop;\n        return total;\n      end param_data_size;\n      --\n      data : Interfacing.HAC_Element_Array (1 .. param_data_size);\n      --\n      procedure Data_Exchange (before_call : Boolean) is\n        function Convert is new Ada.Unchecked_Conversion (Interfacing.HAC_Element, Data_Type);\n        function Convert is new Ada.Unchecked_Conversion (Data_Type, Interfacing.HAC_Element);\n        data_idx  : Positive := 1;\n        stack_idx : Positive;\n      begin\n        for p in block.First_Param_Id_Idx .. block.Last_Param_Id_Idx loop\n          stack_idx := base + Integer (CD.id_table (p).adr_or_sz);\n          if not CD.id_table (p).normal then\n            --  Dereference.\n            stack_idx := Index (ND.S (stack_idx).I);\n          end if;\n          for count in 1 .. Size_of (CD, p) loop\n            if before_call then\n              if CD.id_table (p).decl_kind /= param_out then\n                data (data_idx) := Convert (ND.S (stack_idx));\n              end if;\n            else\n              if CD.id_table (p).decl_kind /= param_in then\n                ND.S (stack_idx) := Convert (data (data_idx));\n              end if;\n            end if;\n            data_idx  := data_idx + 1;\n            stack_idx := stack_idx + 1;\n          end loop;\n        end loop;\n      end Data_Exchange;\n      --\n      function Convert is\n        new Ada.Unchecked_Conversion\n          (Co_Defs.Dummy_Procedure_Access, Interfacing.Exported_Procedure);\n      cur : constant Cursor := CD.Exported_Procedures.Find (proc_name);\n    begin\n      --  Data exchange before call (in, in out)\n      Data_Exchange (before_call => True);\n      --\n      if cur = No_Element then\n        Exceptions.Raise_Standard\n          (ND, VME_Program_Error,\n           \"Import name \"\"\" & proc_name & \"\"\" not found. Was it registered ?\");\n      else\n        begin\n          Convert (Element (cur)) (data);  --  Call to external procedure\n        exception\n          when E : others =>\n            Exceptions.Raise_Standard\n              (ND,\n               VME_Program_Error,\n               \"Exception raised in callback, message: \" &\n               Ada.Exceptions.Exception_Message (E));\n        end;\n      end if;\n      --  Data exchange after call (in out, out)\n      Data_Exchange (before_call => False);\n    end Do_Exchange_with_External;\n\n    procedure Do_Call is\n      use Ada.Calendar;\n      F1 : HAC_Float;    --  Internal float registers\n      Activation_Record_Base, Ident_Index_of_Called,\n      New_Stack_Top, new_address : Index;\n      Called_Level : Nesting_Level;\n      Task_Entered : Integer;\n    begin\n      --  Procedure and task entry CALL  --  Cramer\n      if IR.X = Defs.Timed_Entry_Call then\n        --  Timed entry call\n        F1 := ND.S (Curr_TCB.T).R;  --  Pop delay time\n        Pop (ND);\n      end if;\n      Activation_Record_Base := Curr_TCB.T - Integer (IR.Y);\n      Ident_Index_of_Called := Index (ND.S (Activation_Record_Base + 4).I);\n      Called_Level := CD.id_table (Ident_Index_of_Called).lev;\n      Show_Display (Curr_TCB.DISPLAY, Called_Level, \"before call\");\n      Curr_TCB.DISPLAY (Called_Level + 1) := Activation_Record_Base;\n      Show_Display (Curr_TCB.DISPLAY, Called_Level + 1, \"on call\");\n      New_Stack_Top := Index (ND.S (Activation_Record_Base + 3).I) + Activation_Record_Base;\n      --\n      ND.S (Activation_Record_Base + 1).I := HAC_Integer (Curr_TCB.PC);                      --  return address\n      ND.S (Activation_Record_Base + 2).I := HAC_Integer (Curr_TCB.DISPLAY (Called_Level));  --  static link\n      ND.S (Activation_Record_Base + 3).I := HAC_Integer (Curr_TCB.B);                       --  dynamic link\n      --\n      Curr_TCB.B := Activation_Record_Base;\n      Curr_TCB.T := New_Stack_Top;\n      case IR.X is  --  Call type\n        when Defs.Normal_Procedure_Call =>\n          new_address := Index (CD.id_table (Ident_Index_of_Called).adr_or_sz);\n          if new_address < 0 then\n            raise Exceptions.VM_Subprogram_Spec;\n          end if;\n          Curr_TCB.PC := new_address;  --  Jump to subprogram start.\n        when Defs.Normal_Entry_Call =>\n          Tasking.Queue (CD, ND, Ident_Index_of_Called, ND.CurTask);  --  put self on entry queue\n          Curr_TCB.TS  := WaitRendzv;\n          Task_Entered := Integer (CD.id_table (Ident_Index_of_Called).adr_or_sz);  --  Task being entered\n          if ((ND.TCB (Task_Entered).TS = WaitRendzv) and then\n              (ND.TCB (Task_Entered).SUSPEND = Ident_Index_of_Called))\n             or else\n               ND.TCB (Task_Entered).TS = TimedWait\n          then\n            --  wake accepting task if necessary\n            ND.TCB (Task_Entered).TS      := Ready;\n            ND.TCB (Task_Entered).SUSPEND := 0;\n          end if;\n          ND.SWITCH := True;                 --  give up control\n\n        when Defs.Timed_Entry_Call =>\n          Tasking.Queue (CD, ND, Ident_Index_of_Called, ND.CurTask);  --  put self on entry queue\n          Task_Entered := Integer (CD.id_table (Ident_Index_of_Called).adr_or_sz);  --  Task being entered\n          --\n          if ((ND.TCB (Task_Entered).TS = WaitRendzv) and (ND.TCB (Task_Entered).SUSPEND = Ident_Index_of_Called)) or\n             (ND.TCB (Task_Entered).TS = TimedWait)\n          then\n            --  wake accepting task if necessary\n            Curr_TCB.TS := WaitRendzv;     --  suspend self\n            ND.TCB (Task_Entered).TS := Ready;       --  wake accepting task\n            ND.TCB (Task_Entered).SUSPEND := 0;\n          else\n            Curr_TCB.TS := TimedRendz;          --  Timed Wait For Rendezvous\n            Curr_TCB.R1.I := 1;                 --  Init R1 to specify NO timeout\n            Curr_TCB.R2.I := HAC_Integer (Ident_Index_of_Called);  --  Save address of queue for purge\n            ND.SYSCLOCK := Clock;               --  update System Clock\n            Curr_TCB.WAKETIME := ND.SYSCLOCK + Duration (F1);\n          end if;\n          ND.SWITCH := True;       --  give up control\n\n        when Defs.Conditional_Entry_Call =>\n          Task_Entered := Integer (CD.id_table (Ident_Index_of_Called).adr_or_sz);              --  Task being entered\n          if ((ND.TCB (Task_Entered).TS = WaitRendzv) and then\n              (ND.TCB (Task_Entered).SUSPEND = Ident_Index_of_Called)) or else\n             ND.TCB (Task_Entered).TS = TimedWait\n          then\n            Tasking.Queue (CD, ND, Ident_Index_of_Called, ND.CurTask);  --  put self on entry queue\n            Curr_TCB.R1.I := 1;        --  Indicate entry successful\n            Curr_TCB.TS := WaitRendzv;\n            ND.TCB (Task_Entered).TS      := Ready;  --  wake accepting task if required\n            ND.TCB (Task_Entered).SUSPEND := 0;\n            ND.SWITCH              := True;   --  give up control\n          else\n            --  can't wait, forget about entry call\n            Curr_TCB.R1.I := 0;   --  Indicate entry failed in R1 1\n            --  failure will be acknowledged by next instruction, 32\n          end if;\n        when others =>\n          null;  -- [P2Ada]: no otherwise / else in Pascal\n      end case;\n    end Do_Call;\n\n    procedure Do_Return_Call is\n    --  RETURN entry call or procedure call  --  Cramer\n    begin\n      --  Set back stack top as before call:\n      Curr_TCB.T := Curr_TCB.B - 1;\n      if IR.Y = Defs.Normal_Procedure_Call then\n        --  Set back program counter to position of Call:\n        Curr_TCB.PC := Integer (ND.S (Curr_TCB.B + 1).I);  --  Normal proc call return\n      end if;\n      if Curr_TCB.PC = 0 then\n        ND.TActive  := ND.TActive - 1;\n        Curr_TCB.TS := Completed;\n        ND.SWITCH   := True;\n      else\n        --  Set back base of caller:\n        Curr_TCB.B := Integer (ND.S (Curr_TCB.B + 3).I);\n        if IR.Y = Defs.Timed_Entry_Call or else IR.Y = Defs.Conditional_Entry_Call then\n          if IR.Y = Defs.Timed_Entry_Call and then Curr_TCB.R1.I = 0 then\n            Push (ND);\n          end if;\n          --  A JMPC instruction always follows (?)\n          --  timed and conditional entry call\n          --  returns (32).  Push entry call\n          ND.S (Curr_TCB.T).I := Curr_TCB.R1.I;    --  success indicator for JMPC.\n        end if;\n      end if;\n    end Do_Return_Call;\n\n    procedure Do_Return_Function is\n    begin\n      --  Set back stack top as before call, plus 1 item (the return value):\n      Curr_TCB.T  := Curr_TCB.B;\n      --  Set back program counter to position of Call:\n      Curr_TCB.PC := Integer (ND.S (Curr_TCB.B + 1).I);\n      --  Set back base of caller:\n      Curr_TCB.B  := Integer (ND.S (Curr_TCB.B + 3).I);\n      --\n      if IR.Y = Defs.End_Function_without_Return and then ND.PS /= Exception_Raised then\n        raise Exceptions.VM_Function_End_without_Return;\n      end if;\n    end Do_Return_Function;\n\n    procedure Do_Update_Display_Vector is\n      --  Emitted at the end of Subprogram_or_Entry_Call, when the\n      --  called subprogram's nesting level is *lower* than the\n      --  caller's block level. This includes the case where P and Q are\n      --  defined at the same level L: when Q calls P, Q's block level\n      --  is L + 1, so it's calling P of level L and the update is\n      --  needed after the call.\n      Low_Level  : constant Nesting_Level := Nesting_Level (ND.IR.X);  --  Called.\n      High_Level : constant Nesting_Level := Nesting_Level (ND.IR.Y);  --  Caller.\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      New_Base : Defs.Index := Curr_TCB.B;\n      --  ^ initial value: stack base of caller (dynamic link) after return from call.\n      Address_Base_Lower_Level : Defs.Index;\n      New_Base_Value : HAC_Integer;\n      L : Nesting_Level := High_Level;\n    begin\n      pragma Assert (Low_Level < High_Level);\n      loop\n        --  At this point: L is always >= 1 since L > Low_Level >= 0.\n        Curr_TCB.DISPLAY (L) := New_Base;\n        L := L - 1;\n        exit when L = Low_Level;\n        Address_Base_Lower_Level := New_Base + 2;  --  Written by Do_Call.\n        if Address_Base_Lower_Level not in ND.S'Range then\n          raise Constraint_Error with\n            \"Address_Base_Lower_Level = \" &\n            Defs.Index'Image (Address_Base_Lower_Level) &\n            \" out of stack range\";\n        end if;\n        New_Base_Value := ND.S (Address_Base_Lower_Level).I;\n        if New_Base_Value not in 0 .. HAC_Integer (MaxINT) then\n          raise Constraint_Error with\n            \"Invalid New_Base_Value =\" &\n            HAC_Integer'Image (New_Base_Value) &\n            \" found on stack @ index\" &\n            Defs.Index'Image (Address_Base_Lower_Level);\n        end if;\n        New_Base := Defs.Index (New_Base_Value);\n      end loop;\n      Show_Display (Curr_TCB.DISPLAY, High_Level, \"after Update_Display_Vector\");\n    end Do_Update_Display_Vector;\n\n  begin\n    case Calling_Opcode (ND.IR.F) is\n      when k_Mark_Stack             => Do_Mark_Stack;\n      when k_Call                   => Do_Call;\n      when k_Exchange_with_External => Do_Exchange_with_External;\n      when k_Return_Call              => Do_Return_Call;\n      when k_Return_Function          => Do_Return_Function;\n      when k_Update_Display_Vector  => Do_Update_Display_Vector;\n    end case;\n  end Do_Calling_Operation;\n\nend HAC_Sys.PCode.Interpreter.Calls;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-calls.ads",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\nprivate package HAC_Sys.PCode.Interpreter.Calls is\n\n  -----------------------\n  --  VM Instructions  --\n  -----------------------\n\n  --  Execute instruction stored as Opcode in ND.IR.F.\n  --  ND.IR.F is in the Calling_Opcode subtype range.\n  procedure Do_Calling_Operation (\n    CD :        Co_Defs.Compiler_Data;\n    ND : in out In_Defs.Interpreter_Data\n  );\n\nend HAC_Sys.PCode.Interpreter.Calls;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-composite_data.adb",
    "content": "with HAC_Sys.PCode.Interpreter.Exceptions;\n\npackage body HAC_Sys.PCode.Interpreter.Composite_Data is\n\n  procedure Do_Composite_Data_Operation (CD : Compiler_Data; ND : in out Interpreter_Data) is\n    Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n    IR : Order renames ND.IR;\n    use Defs;\n    use type HAC_Integer;\n\n    generic\n      size_1      : Boolean;\n      range_check : Boolean;\n    procedure Do_Array_Index;\n\n    procedure Do_Array_Index is\n      ATI  : constant Integer := Integer (IR.Y);\n      ATE  : Array_Table_Entry renames CD.Arrays_Table (ATI);\n      Low  : constant Index := Index (ATE.Index_xTyp.Discrete_First);\n      High : constant Index := Index (ATE.Index_xTyp.Discrete_Last);\n      Idx  : constant Index := Index (ND.S (Curr_TCB.T).I);\n      --\n      function Out_Message (bound : Defs.Index; excerpt : String) return String is\n      begin\n        return\n          \": index, \" &\n          Discrete_Image (CD, HAC_Integer (Idx), ATE.Index_xTyp.TYP, ATE.Index_xTyp.Ref) &\n          \", is \" &\n          excerpt &\n          \" bound, \" &\n          Discrete_Image (CD, HAC_Integer (bound), ATE.Index_xTyp.TYP, ATE.Index_xTyp.Ref);\n      end Out_Message;\n      --\n    begin\n      if range_check then\n        if Idx < Low then\n          raise Exceptions.VM_Out_of_Range with Out_Message (Low, \"below lower\");\n        elsif Idx > High then\n          raise Exceptions.VM_Out_of_Range with Out_Message (High, \"above upper\");\n        end if;\n      end if;\n      Pop (ND);  --  Pull array index, then adjust array element pointer.\n      ND.S (Curr_TCB.T).I :=\n        ND.S (Curr_TCB.T).I +\n          (if size_1 then HAC_Integer  (Idx - Low)\n                     else HAC_Integer ((Idx - Low) * ATE.Element_Size));\n    end Do_Array_Index;\n\n    procedure Do_Array_Index_Size_1 is            new Do_Array_Index (size_1 => True,  range_check => True);\n    procedure Do_Array_Index_Any_Size is          new Do_Array_Index (size_1 => False, range_check => True);\n    procedure Do_Array_Index_Size_1_No_Check is   new Do_Array_Index (size_1 => True,  range_check => False);\n    procedure Do_Array_Index_Any_Size_No_Check is new Do_Array_Index (size_1 => False, range_check => False);\n\n    procedure Do_Load_Block is\n      idx, new_top : Index;\n    begin\n      idx := Index (ND.S (Curr_TCB.T).I);      --  Pull source address\n      Pop (ND);\n      new_top := Index (IR.Y) + Curr_TCB.T;    --  Stack top after pushing block\n      if new_top > Curr_TCB.STACKSIZE then\n        raise Exceptions.VM_Stack_Overflow;\n      end if;\n      while Curr_TCB.T < new_top loop\n        Curr_TCB.T := Curr_TCB.T + 1;\n        ND.S (Curr_TCB.T) := ND.S (idx);\n        idx := idx + 1;\n      end loop;\n    end Do_Load_Block;\n\n    procedure Do_Load_String_Literal is\n      idx, len, new_top : Index;\n    begin\n      idx := Index (ND.S (Curr_TCB.T).I);      --  Index to string table\n      len := Index (ND.S (Curr_TCB.T - 1).I);  --  Length of string\n      Pop (ND, 2);\n      new_top := len + Curr_TCB.T;    --  Stack top after pushing block\n      if new_top > Curr_TCB.STACKSIZE then\n        raise Exceptions.VM_Stack_Overflow;\n      end if;\n      while Curr_TCB.T < new_top loop\n        Curr_TCB.T := Curr_TCB.T + 1;\n        ND.S (Curr_TCB.T).I := Character'Pos (CD.Strings_Constants_Table (idx));\n        idx := idx + 1;\n      end loop;\n    end Do_Load_String_Literal;\n\n    procedure Do_Copy_Block is\n      --  [T-1].all (0 .. IR.Y - 1) := [T].all (0 .. IR.Y - 1)\n      Dst_Addr, Src_Addr, Last : Index;\n    begin\n      Dst_Addr := Index (ND.S (Curr_TCB.T - 1).I);\n      Src_Addr := Index (ND.S (Curr_TCB.T).I);\n      Last := Index (IR.Y) - 1;\n      ND.S (Dst_Addr .. Dst_Addr + Last) := ND.S (Src_Addr .. Src_Addr + Last);\n      Pop (ND, 2);\n    end Do_Copy_Block;\n\n    procedure Do_String_Literal_Assignment is\n      H1, H2, H3, H4, H5 : Index;\n    begin\n      H1 := Index (ND.S (Curr_TCB.T - 2).I);  --  Address of array\n      H2 := Index (ND.S (Curr_TCB.T).I);      --  Index to string table\n      H3 := Index (IR.Y);                     --  Size of array\n      H4 := Index (ND.S (Curr_TCB.T - 1).I);  --  Length of string\n      H5 := H1 + (if H3 < H4 then H3 else H4);\n      while H1 < H5 loop\n        --  Copy H5-H1 characters to the stack\n        ND.S (H1).I := Character'Pos (CD.Strings_Constants_Table (H2));\n        H1 := H1 + 1;\n        H2 := H2 + 1;\n      end loop;\n      --  Padding (does not happen, since lengths are checked at compile-time)\n      H5 := Index (ND.S (Curr_TCB.T - 2).I) + H3;  --  H5 = H1 + H3\n      while H1 < H5 loop\n        --  Fill with blanks if req'd\n        ND.S (H1).I := Character'Pos (' ');\n        H1 := H1 + 1;\n      end loop;\n      Pop (ND, 3);\n    end Do_String_Literal_Assignment;\n\n  begin\n    case Composite_Data_Opcode (ND.IR.F) is\n      when k_Array_Index_Element_Size_1          => Do_Array_Index_Size_1;\n      when k_Array_Index                         => Do_Array_Index_Any_Size;\n      when k_Array_Index_No_Check_Element_Size_1 => Do_Array_Index_Size_1_No_Check;\n      when k_Array_Index_No_Check                => Do_Array_Index_Any_Size_No_Check;\n      when k_Record_Field_Offset                 => ND.S (Curr_TCB.T).I := ND.S (Curr_TCB.T).I + IR.Y;\n      when k_Load_Block                          => Do_Load_Block;\n      when k_Load_String_Literal                 => Do_Load_String_Literal;\n      when k_Copy_Block                          => Do_Copy_Block;\n      when k_String_Literal_Assignment           => Do_String_Literal_Assignment;\n    end case;\n  end Do_Composite_Data_Operation;\n\nend HAC_Sys.PCode.Interpreter.Composite_Data;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-composite_data.ads",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\nprivate package HAC_Sys.PCode.Interpreter.Composite_Data is\n  use Co_Defs, In_Defs;\n\n  -----------------------\n  --  VM Instructions  --\n  -----------------------\n\n  --  Execute instruction stored as Opcode in ND.IR.F.\n  --  ND.IR.F is in the Composite_Data_Opcode subtype range.\n  procedure Do_Composite_Data_Operation (CD : Compiler_Data; ND : in out Interpreter_Data);\n\nend HAC_Sys.PCode.Interpreter.Composite_Data;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-exceptions.adb",
    "content": "with Ada.Strings.Fixed;\n\npackage body HAC_Sys.PCode.Interpreter.Exceptions is\n\n  procedure Raise_Standard (\n    ND                       : in out In_Defs.Interpreter_Data;\n    SE                       :        Exception_Type;\n    Msg                      :        String  := \"\";\n    Stop_Current_Instruction :        Boolean := False\n  )\n  is\n    EI : Exception_Propagation_Data renames ND.TCB (ND.CurTask).Exception_Info;\n  begin\n    EI.Currently_Raised  := (SE, 0);\n    EI.Exception_Message := HAT.To_VString (Msg);\n    ND.PS := In_Defs.Exception_Raised;\n    if Stop_Current_Instruction then\n      --  Skip the rest of what the current instruction\n      --  does in the run-time library (e.g. I/O operations).\n      raise VM_Raised_Exception;\n    end if;\n  end Raise_Standard;\n\n  procedure Raise_VM_Exception_from_Constraint_Error (CE_Message : String) is\n    --  We guess specialized kinds of \"Constraint_Error\"'s using\n    --  the message provided by the host Ada system.\n    --  For instance on an overflow check failure, GNAT issues CE with the message\n    --  \"raised CONSTRAINT_ERROR : xyz.adb:123 overflow check failed\".\n  begin\n    if Ada.Strings.Fixed.Index (CE_Message, \"overflow check\") > 0 then\n      raise VM_Overflow_Error;\n    else\n      raise VM_Constraint_Error;\n    end if;\n  end Raise_VM_Exception_from_Constraint_Error;\n\nend HAC_Sys.PCode.Interpreter.Exceptions;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-exceptions.ads",
    "content": "with HAC_Sys.PCode.Interpreter.In_Defs;\n\npackage HAC_Sys.PCode.Interpreter.Exceptions is\n\n  ------------------------\n  --  HAC's exceptions  --\n  ------------------------\n\n  procedure Raise_Standard (\n    ND                       : in out In_Defs.Interpreter_Data;\n    SE                       :        Exception_Type;\n    Msg                      :        String  := \"\";\n    Stop_Current_Instruction :        Boolean := False\n  );\n\n  ---------------------------------------------------------\n  --  Exceptions raised in the host Ada system during    --\n  --  VM execution, leading to a call to Raise_Standard  --\n  ---------------------------------------------------------\n\n  VM_Case_Check_Error            : exception;\n  VM_Constraint_Error            : exception;\n  VM_Division_by_0               : exception;\n  VM_End_Error                   : exception;\n  VM_Function_End_without_Return : exception;\n  VM_Invalid_Data                : exception;\n  VM_Out_of_Range                : exception;\n  VM_Overflow_Error              : exception;\n  VM_Raised_Exception            : exception;  --  See Name_Error for an example.\n  VM_Stack_Overflow              : exception;\n  VM_Stack_Underflow             : exception;\n  VM_Subprogram_Spec             : exception;\n\n  procedure Raise_VM_Exception_from_Constraint_Error (CE_Message : String);\n\nend HAC_Sys.PCode.Interpreter.Exceptions;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-in_defs.adb",
    "content": "with HAC_Sys.PCode.Interpreter.Exceptions;\n\npackage body HAC_Sys.PCode.Interpreter.In_Defs is\n\n  procedure Allocate_Text_File (\n    ND : in out Interpreter_Data;\n    R  : in out General_Register\n  )\n  is\n    use Defs;\n  begin\n    if R.Special /= Text_Files then\n      R := GR_Abstract_Console;\n    end if;\n    if R.Txt = null\n      or else Ada.Text_IO.Is_Open (R.Txt.all)\n      --  ^ Uh oh, someone somewhere in the HAC program forgot to close\n      --    a file at the same VM address.\n    then\n      R.Txt := new Ada.Text_IO.File_Type;\n      ND.Files.Append (R.Txt);\n    end if;\n  end Allocate_Text_File;\n\n  procedure Free_Allocated_Contents (\n    ND         : in out Interpreter_Data;\n    Open_Files :    out Open_Files_Vectors.Vector\n  )\n  is\n    procedure Free is new Ada.Unchecked_Deallocation (Ada.Text_IO.File_Type, File_Ptr);\n    procedure Free is new Ada.Unchecked_Deallocation (Stack_Type, Stack_Type_Access);\n    open_file : Open_File_Data;\n    use Ada.Text_IO;\n  begin\n    for F of ND.Files loop\n      if F /= null then\n        if Is_Open (F.all) then\n          --  We close, for the distracted programmer,\n          --  all files that are still open.\n          --  In that respect, we do more than required by the RM (A.7(6)):\n          --     \"The language does not define what happens to external files\n          --      after the completion of the main program and all the library\n          --      tasks (in particular, if corresponding files have\n          --      not been closed).\"\n          open_file.Name := HAT.To_VString (Name (F.all));\n          open_file.Mode := Mode (F.all);\n          Open_Files.Append (open_file);\n          Ada.Text_IO.Close (F.all);\n        end if;\n        Free (F);\n      end if;\n    end loop;\n    Free (ND.S);\n  end Free_Allocated_Contents;\n\n  function Get_String_from_Stack (ND : Interpreter_Data; Idx, Size : Integer) return String is\n    Res : String (1 .. Size);\n    Number : Defs.HAC_Integer;\n  begin\n    for i in Res'Range loop\n      Number := ND.S (Idx + i - 1).I;\n      if Number not in Defs.OrdMinChar .. Defs.OrdMaxChar then\n        raise Exceptions.VM_Out_of_Range\n          with \": invalid data: element not in Character's range\";\n      end if;\n      Res (i) := Character'Val (Number);\n    end loop;\n    return Res;\n  end Get_String_from_Stack;\n\n  function GR_Real (R : Defs.HAC_Float) return General_Register is\n  begin\n    return (Special => Defs.Floats, I => 0, R => R);\n  end GR_Real;\n\n  function GR_Time (T : Ada.Calendar.Time) return General_Register is\n  begin\n    return (Special => Defs.Times, I => 0, Tim => T);\n  end GR_Time;\n\n  function GR_Duration (D : Duration) return General_Register is\n  begin\n    return (Special => Defs.Durations, I => 0, Dur => D);\n  end GR_Duration;\n\n  function GR_VString (S : String) return General_Register is\n  begin\n    return (Special => Defs.VStrings, I => 0, V => HAT.To_VString (S));\n  end GR_VString;\n\n  function GR_VString (V : HAT.VString) return General_Register is\n  begin\n    return (Special => Defs.VStrings, I => 0, V => V);\n  end GR_VString;\n\n  procedure Pop (ND : in out Interpreter_Data; Amount : Positive := 1) is\n    Curr_TCB_Top : Integer renames ND.TCB (ND.CurTask).T;\n  begin\n    Curr_TCB_Top := Curr_TCB_Top - Amount;\n    if Curr_TCB_Top < ND.S'First then\n      raise Exceptions.VM_Stack_Underflow;\n    end if;\n  end Pop;\n\n  procedure Push (ND : in out Interpreter_Data; Amount : Positive := 1) is\n    Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n  begin\n    Curr_TCB.T := Curr_TCB.T + Amount;\n    if Curr_TCB.T > Curr_TCB.STACKSIZE then\n      raise Exceptions.VM_Stack_Overflow;\n    end if;\n  end Push;\n\n  procedure Post_Mortem_Dump (CD : Co_Defs.Compiler_Data; ND : In_Defs.Interpreter_Data) is\n    use Ada.Text_IO, Co_Defs, Defs.IIO, Defs.RIO;\n    BLKCNT, H1, H2, H3 : Integer;\n    --  !! Should use a file for dump !!\n  begin\n    New_Line;\n    Put_Line (\"HAC - PCode - Post Mortem Dump\");\n    New_Line;\n    Put_Line (\"Processor state: \" & Processor_State'Image (ND.PS));\n    New_Line;\n    Put_Line (\n      \"Stack Variables of Task \" &\n      Defs.A2S (CD.id_table (CD.Tasks_Definitions_Table (ND.CurTask)).name)\n    );\n    H1 := ND.TCB (ND.CurTask).B;   --  current bottom of stack\n    BLKCNT := 10;\n    loop\n      New_Line;\n      BLKCNT := BLKCNT - 1;\n      if BLKCNT = 0 then\n        H1 := 0;\n      end if;\n      H2 := Integer (ND.S (H1 + 4).I);  --  index into HAC.Data.IdTab for this process\n      if H1 = 0 then\n        Put_Line (\"Task Variables\");\n      else\n        Put (Defs.A2S (CD.id_table (H2).name));\n        Put (\" CALLED AT\");\n        Put (ND.S (H1 + 1).I, 5);\n        New_Line;\n      end if;\n      H2 := CD.Blocks_Table (CD.id_table (H2).block_or_pkg_ref).Last_Id_Idx;\n      while H2 /= 0 loop\n        --  [P2Ada]: WITH instruction\n        declare\n          P2Ada_Var_7 : Identifier_Table_Entry renames CD.id_table (H2);\n          use Defs;\n        begin\n          if P2Ada_Var_7.entity in Object_Kind then\n            if Defs.Standard_or_Enum_Typ (P2Ada_Var_7.xtyp.TYP) then\n              if P2Ada_Var_7.normal then\n                H3 := H1 + Integer (P2Ada_Var_7.adr_or_sz);\n              else\n                H3 := Integer (ND.S (H1 + Integer (P2Ada_Var_7.adr_or_sz)).I);\n              end if;\n              Put (\"  \" & A2S (P2Ada_Var_7.name) & \" = \");\n              case P2Ada_Var_7.xtyp.TYP is\n                when Defs.Enums | Defs.Ints =>\n                  Put (ND.S (H3).I);\n                  New_Line;\n                when Defs.Bools =>\n                  BIO.Put (Boolean'Val (ND.S (H3).I));\n                  New_Line;\n                when Defs.Floats =>\n                  Put (ND.S (H3).R);\n                  New_Line;\n                when Defs.Chars =>\n                  Put (ND.S (H3).I);\n                  Put_Line (\" (ASCII)\");\n                when others =>\n                  null;  -- [P2Ada]: no otherwise / else in Pascal\n              end case;\n            end if;\n          end if;\n          H2 := P2Ada_Var_7.link;\n        end; -- [P2Ada]: end of WITH\n\n      end loop;\n      H1 := Integer (ND.S (H1 + 3).I);\n      exit when H1 < 0;\n    end loop;\n  end Post_Mortem_Dump;\n\n  procedure Check_Discriminant_Type (X : General_Register; Y : Defs.Typen) is\n    use Defs;\n  begin\n    if X.Special /= Y then\n      raise Exceptions.VM_Invalid_Data;\n    end if;\n  end Check_Discriminant_Type;\n\nend HAC_Sys.PCode.Interpreter.In_Defs;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-in_defs.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  In_Defs: Internal Interpreter Definitions\n\nwith HAC_Sys.Co_Defs, HAC_Sys.Defs;\n\nwith Ada.Calendar,\n     Ada.Containers.Vectors,\n     Ada.Numerics.Float_Random,\n     Ada.Unchecked_Deallocation;\n\npackage HAC_Sys.PCode.Interpreter.In_Defs is\n\n  NilTask : constant := -1;\n\n  subtype TRange is Integer range 0 .. Defs.TaskMax;  --  task index\n\n  type Processor_State is (\n    Running,           --  Normal processor state\n    Exception_Raised,\n    --\n    FIN,\n    DEADLOCK,\n    WAIT);\n\n  subtype Running_or_in_Exception is Processor_State range Running .. Exception_Raised;\n\n  type Task_State is (\n    --  SmallAda tasking stuff, not tested yet:\n    Completed,\n    Delayed,\n    Ready,\n    --  HAC is currently tested on this:\n    Running,\n    Exception_Raised,\n    --  SmallAda tasking stuff, not tested yet:\n    Critical,\n    WaitRendzv,\n    WaitSem,\n    TimedRendz,\n    TimedWait,\n    Terminated);\n\n  type PriCB is record  --  Priority Control Block\n    UPRI    : Integer;  --  User specified priority\n    INHERIT : Boolean;  --  Priority inheritance enabled\n  end record;\n\n  type File_Ptr is access Ada.Text_IO.File_Type;\n\n  Abstract_Console : constant File_Ptr := null;\n\n  type General_Register (Special : Defs.Typen := Defs.NOTYP) is record\n    --  I is used for most uses: indices in the stack, Integers, Bools, Chars and Enums.\n    I : Defs.HAC_Integer;\n    case Special is  --  This part is variant to save place.\n      when Defs.Floats     => R   : Defs.HAC_Float;\n      when Defs.VStrings   => V   : HAT.VString;\n      when Defs.Times      => Tim : Ada.Calendar.Time;\n      when Defs.Durations  => Dur : Duration;\n      when Defs.Text_Files => Txt : File_Ptr := Abstract_Console;\n      when others          => null;\n    end case;\n  end record;\n\n  GR_Abstract_Console : constant General_Register :=\n    (Special => Defs.Text_Files,\n     I       => 0,\n     Txt     => Abstract_Console);\n\n  function GR_Real (R : Defs.HAC_Float) return General_Register;\n  function GR_Time (T : Ada.Calendar.Time) return General_Register;\n  function GR_Duration (D : Duration) return General_Register;\n\n  function GR_VString (S : String) return General_Register;\n  function GR_VString (V : HAT.VString) return General_Register;\n\n  subtype Data_Type is General_Register;\n\n  type Stack_Type is array (1 .. Defs.StMax) of Data_Type;\n\n  type Stack_Type_Access is access Stack_Type;\n\n  type Task_Control_Block is record\n    T              : Defs.Index;            --  index of current top of stack\n    B              : Defs.Index;            --  index of current base of stack\n    PC             : Defs.Index;            --  program counter, next pcode\n    TS             : Task_State;            --  current task state\n    InRendzv       : Integer;               --  task in rendz with or -1\n    WAKETIME       : Ada.Calendar.Time;     --  end of delay period\n    Pcontrol       : PriCB;                 --  task priority parameter rec.\n    QUANTUM        : Duration;              --  time slice\n    LASTRUN        : Ada.Calendar.Time;     --  time last run end (fairness)\n    DISPLAY        : Co_Defs.Display_Type;  --  Stack base index per nesting level,\n                                            --      used for addressing variables.\n    STACKSIZE      : Defs.Index;            --  Stack overflow is raised if exceeded.\n    SUSPEND        : Integer;               --  id of object suspended on\n    R1, R2, R3     : General_Register;\n    R_Temp         : General_Register;\n    Exception_Info : Exception_Propagation_Data;\n  end record;\n\n  type Enode;\n  type Eptr is access Enode;  --  task entry rendzv pointer\n\n  type Enode is record    --  task entry structure\n    Task_Index : TRange;  --  index of task enqueued for rendzv\n    Next       : Eptr;    --  next entry in list\n  end record;\n\n  procedure Dispose is new Ada.Unchecked_Deallocation (Enode, Eptr);\n\n  type EHeader is record\n    Task_Index : TRange;  --  index of task that contains entry\n    First : Eptr;  --  ptr to first node in rendzv queue\n    Last : Eptr;   --  ptr to last  node in rendzv queue\n  end record;\n\n  type Entry_Queue is array (1 .. Defs.entry_table_max) of EHeader;\n\n  package File_Vectors is new Ada.Containers.Vectors (Positive, File_Ptr);\n\n  type Task_Control_Blocks is array (TRange) of Task_Control_Block;\n\n  Single_Task : constant := -1;\n\n  subtype Scheduler_Type is Integer range Single_Task .. 6;\n\n  type Tick_Type is mod 128;\n\n  --  Objects of type Interpreter_Data contains data that may be useful\n  --  to be kept post-mortem, or in a snapshot toward the \"outside\", or\n  --  passed to the scheduler.\n\n  type Interpreter_Data is record\n    S                         : Stack_Type_Access;\n    PS                        : Processor_State;             --  Processor status register\n    IR                        : Order;                       --  Instruction register\n    CurTask                   : Integer;                     --  Index of currently executing task\n    TCB                       : Task_Control_Blocks;\n    Files                     : File_Vectors.Vector;\n    Snap                      : Boolean;            --  Snapshot flag to display scheduler status\n    Nb_Callers                : Integer;            --  AVL  TERMINATE\n    Nb_Complete               : Integer;            --  AVL  TERMINATE\n    EList                     : Entry_Queue;\n    TActive                   : TRange;             --  no. of active tasks\n    Start_Time                : Ada.Calendar.Time;\n    SWITCH                    : Boolean;            --  invoke scheduler on next cycle flag\n    SYSCLOCK                  : Ada.Calendar.Time;  --  (ms after 00:00:00 Jan 1, current year)\n    TIMER                     : Ada.Calendar.Time;  --  set to end of current task's time slice\n    Gen                       : Ada.Numerics.Float_Random.Generator;\n    Scheduler                 : Scheduler_Type := Single_Task;\n    Single_Task_Delay_Pending : Boolean        := False;\n    feedback_tick             : Tick_Type;\n  end record;\n\n  procedure Allocate_Text_File (\n    ND : in out Interpreter_Data;\n    R  : in out General_Register\n  );\n\n  procedure Free_Allocated_Contents (\n    ND         : in out Interpreter_Data;\n    Open_Files :    out Open_Files_Vectors.Vector\n  );\n\n  --  We have an \"array of Character\" (cf Is_Char_Array) on the stack\n  function Get_String_from_Stack (ND : Interpreter_Data; Idx, Size : Integer) return String;\n\n  procedure Pop (ND : in out Interpreter_Data; Amount : Positive := 1);\n  pragma Inline (Pop);\n  procedure Push (ND : in out Interpreter_Data; Amount : Positive := 1);\n  pragma Inline (Push);\n\n  --  Post Mortem Dump of the task stack causing the exception\n  --\n  procedure Post_Mortem_Dump (CD : Co_Defs.Compiler_Data; ND : In_Defs.Interpreter_Data);\n\n  procedure Check_Discriminant_Type (X : General_Register; Y : Defs.Typen);\n  pragma Inline (Check_Discriminant_Type);\n\nend HAC_Sys.PCode.Interpreter.In_Defs;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-multi_statement.adb",
    "content": "with HAC_Sys.PCode.Interpreter.Exceptions;\n\npackage body HAC_Sys.PCode.Interpreter.Multi_Statement is\n\n  procedure Do_Multi_Statement_Operation (CD : Compiler_Data; ND : in out Interpreter_Data) is\n    Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n    IR : Order renames ND.IR;\n    use type Defs.HAC_Integer;\n\n    procedure Do_CASE_Switch_1 is\n      Value : constant Defs.HAC_Integer := ND.S (Curr_TCB.T).I;\n      H2 : Integer;\n      jump : Boolean;\n    begin\n      Pop (ND);\n      H2 := Integer (IR.Y);\n      --\n      --  Now we loop over a bunch of (k_CASE_Choice_Data, k_CASE_Match_Jump) pairs\n      --  that should covers all cases.\n      --\n      loop\n        if CD.ObjCode (H2).F not in CASE_Any_Choice then\n          --  We hit the end of (k_CASE_Choice_Data, k_CASE_Match_Jump) pairs.\n          --  This means that Value, or OTHERS, were not found so far.\n          --  This situation should not happen; it should be caught at compile-time.\n          raise Exceptions.VM_Case_Check_Error;\n        end if;\n        case CASE_Any_Choice (CD.ObjCode (H2).F) is\n          when k_CASE_Choice_Value => jump := Value = CD.ObjCode (H2).Y;\n          when k_CASE_Choice_Range => jump := Value in CD.ObjCode (H2).X .. CD.ObjCode (H2).Y;\n          when k_CASE_Choice_Others => jump := True;\n        end case;\n        if jump then\n          --  The interpreter will execute instructions following \"=>\".\n          --  The address is stored with a k_CASE_Match_Jump instruction just after\n          --  the CASE_Any_Choice instruction.\n          Curr_TCB.PC := Defs.Index (CD.ObjCode (H2 + 1).Y);\n          exit;\n        end if;\n        --  Check the next (CASE_Any_Choice, k_CASE_Match_Jump) instruction pair:\n        H2 := H2 + 2;\n      end loop;\n    end Do_CASE_Switch_1;\n\n    stack_elements_used_by_FOR_loop : constant := 3;\n\n    procedure Do_FOR_Forward_Begin is  --  Start of a FOR loop, forward direction\n      FOR_Param_Addr : constant Defs.Index       := Defs.Index (ND.S (Curr_TCB.T - 2).I);\n      Lower_Bound    : constant Defs.HAC_Integer := ND.S (Curr_TCB.T - 1).I;\n      Upper_Bound    : constant Defs.HAC_Integer := ND.S (Curr_TCB.T).I;\n    begin\n      if Lower_Bound <= Upper_Bound then\n        --  The range is not empty -> we can start the loop with the first value.\n        ND.S (FOR_Param_Addr).I := Lower_Bound;\n      else\n        --  Empty range -> we don't enter the loop at all -> Jump after loop's end.\n        Curr_TCB.PC := Defs.Index (IR.Y);\n        Pop (ND, stack_elements_used_by_FOR_loop);\n      end if;\n    end Do_FOR_Forward_Begin;\n\n    procedure Do_FOR_Forward_End is  --  End of a FOR loop, forward direction\n      FOR_Param_Addr : constant Defs.Index       := Defs.Index (ND.S (Curr_TCB.T - 2).I);\n      Upper_Bound    : constant Defs.HAC_Integer := ND.S (Curr_TCB.T).I;\n      Next_Value     :          Defs.HAC_Integer;\n    begin\n      Next_Value := ND.S (FOR_Param_Addr).I + 1;  --  !! Overflow check before here\n      if Next_Value <= Upper_Bound then\n        ND.S (FOR_Param_Addr).I := Next_Value;\n        Curr_TCB.PC := Defs.Index (IR.Y);  --  Jump back to loop's begin\n      else\n        Pop (ND, stack_elements_used_by_FOR_loop);  --  Leave loop (just go to next instruction)\n      end if;\n    end Do_FOR_Forward_End;\n\n    procedure Do_FOR_Reverse_Begin is  --  Start of a FOR loop, reverse direction\n      FOR_Param_Addr : constant Defs.Index       := Defs.Index (ND.S (Curr_TCB.T - 2).I);\n      Lower_Bound    : constant Defs.HAC_Integer := ND.S (Curr_TCB.T - 1).I;\n      Upper_Bound    : constant Defs.HAC_Integer := ND.S (Curr_TCB.T).I;\n    begin\n      if Lower_Bound <= Upper_Bound then\n        --  The range is not empty -> we can start the loop with the first value.\n        ND.S (FOR_Param_Addr).I := Upper_Bound;\n      else\n        --  Empty range -> we don't enter the loop at all -> Jump after loop's end.\n        Curr_TCB.PC := Defs.Index (IR.Y);\n        Pop (ND, stack_elements_used_by_FOR_loop);\n      end if;\n    end Do_FOR_Reverse_Begin;\n\n    procedure Do_FOR_Reverse_End is  --  End of a FOR loop, reverse direction\n      FOR_Param_Addr : constant Defs.Index       := Defs.Index (ND.S (Curr_TCB.T - 2).I);\n      Lower_Bound    : constant Defs.HAC_Integer := ND.S (Curr_TCB.T - 1).I;\n      Next_Value     :          Defs.HAC_Integer;\n    begin\n      Next_Value := ND.S (FOR_Param_Addr).I - 1;  --  !! Overflow check before here\n      if Next_Value >= Lower_Bound then\n        ND.S (FOR_Param_Addr).I := Next_Value;\n        Curr_TCB.PC := Defs.Index (IR.Y);  --  Jump back to loop's begin\n      else\n        Pop (ND, stack_elements_used_by_FOR_loop);  --  Leave loop (just go to next instruction)\n      end if;\n    end Do_FOR_Reverse_End;\n\n  begin\n    case Multi_Statement_Opcode (ND.IR.F) is\n      when k_CASE_Switch        => Do_CASE_Switch_1;\n      when CASE_Data_Opcode     => null;  --  Only via k_CASE_Switch.\n      when k_FOR_Forward_Begin  => Do_FOR_Forward_Begin;\n      when k_FOR_Forward_End    => Do_FOR_Forward_End;\n      when k_FOR_Reverse_Begin  => Do_FOR_Reverse_Begin;\n      when k_FOR_Reverse_End    => Do_FOR_Reverse_End;\n      when k_FOR_Release_Stack  => Pop (ND, stack_elements_used_by_FOR_loop * Natural (ND.IR.Y));\n    end case;\n  end Do_Multi_Statement_Operation;\n\nend HAC_Sys.PCode.Interpreter.Multi_Statement;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-multi_statement.ads",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\nprivate package HAC_Sys.PCode.Interpreter.Multi_Statement is\n  use Co_Defs, In_Defs;\n\n  -----------------------\n  --  VM Instructions  --\n  -----------------------\n\n  --  Execute instruction stored as Opcode in ND.IR.F.\n  --  ND.IR.F is in the Multi_Statement_Opcode subtype range.\n  procedure Do_Multi_Statement_Operation (CD : Compiler_Data; ND : in out Interpreter_Data);\n\nend HAC_Sys.PCode.Interpreter.Multi_Statement;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-operators.adb",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.Interfacing,\n     HAC_Sys.PCode.Interpreter.Exceptions;\n\nwith HAT;\n\nwith Ada.Calendar,\n     Ada.Exceptions,\n     Ada.Numerics,\n     Ada.Strings.Fixed;\n\npackage body HAC_Sys.PCode.Interpreter.Operators is\n\n  procedure Do_Unary_Operator (ND : in out In_Defs.Interpreter_Data) is\n    use In_Defs;\n    Curr_TCB_Top : Integer renames ND.TCB (ND.CurTask).T;\n    X : General_Register renames ND.S (Curr_TCB_Top);\n    H1 : Defs.Index;\n    use type Defs.HAC_Float, Defs.HAC_Integer;\n    I_to_F : Defs.HAC_Float;\n  begin\n    case Unary_Operator_Opcode (ND.IR.F) is\n      when k_Dereference          => X   := ND.S (Defs.Index (X.I));  --  \"[T] := ([T].I).all\"\n      when k_Dereference_Discrete => X.I := ND.S (Defs.Index (X.I)).I;\n      when k_NOT_Boolean          => X.I := Boolean'Pos (not Boolean'Val (X.I));\n      when k_Unary_MINUS_Float    => X.R := -X.R;\n      when k_Unary_MINUS_Integer =>\n        if X.I = Defs.HAC_Integer'First then\n          raise Exceptions.VM_Overflow_Error;\n        end if;\n        X.I := -X.I;\n      when k_Integer_to_Float =>\n        H1 := Curr_TCB_Top - Defs.Index (ND.IR.Y);\n        I_to_F := Defs.HAC_Float (ND.S (H1).I);\n        ND.S (H1) := GR_Real (I_to_F);\n    end case;\n  end Do_Unary_Operator;\n\n  procedure Do_Binary_Operator (ND : in out In_Defs.Interpreter_Data) is\n    use In_Defs;\n    Curr_TCB_Top : Integer renames ND.TCB (ND.CurTask).T;\n    X : General_Register renames ND.S (Curr_TCB_Top - 1);  --  X = [T-1]\n    Y : General_Register renames ND.S (Curr_TCB_Top);      --  Y = [T]\n    use type Defs.HAC_Float, Defs.HAC_Integer, Defs.Typen;\n    --\n    procedure Check_X_Float is\n    pragma Inline (Check_X_Float);\n    begin\n      if X.Special /= Defs.Floats then\n        raise Exceptions.VM_Invalid_Data;\n      end if;\n    end Check_X_Float;\n    --\n    procedure Check_X_Y_Float is\n    pragma Inline (Check_X_Y_Float);\n    begin\n      if X.Special /= Defs.Floats or else Y.Special /= Defs.Floats then\n        raise Exceptions.VM_Invalid_Data;\n      end if;\n    end Check_X_Y_Float;\n    use HAT.VStr_Pkg;\n  begin\n    --  We do  [T-1] <- ([T-1] operator [T])  and pop later.\n    case Binary_Operator_Opcode (ND.IR.F) is\n      when k_EQL_Float => Check_X_Y_Float; X.I := Boolean'Pos (X.R =  Y.R);\n      when k_NEQ_Float => Check_X_Y_Float; X.I := Boolean'Pos (X.R /= Y.R);\n      when k_LSS_Float => Check_X_Y_Float; X.I := Boolean'Pos (X.R <  Y.R);\n      when k_LEQ_Float => Check_X_Y_Float; X.I := Boolean'Pos (X.R <= Y.R);\n      when k_GTR_Float => Check_X_Y_Float; X.I := Boolean'Pos (X.R >  Y.R);\n      when k_GEQ_Float => Check_X_Y_Float; X.I := Boolean'Pos (X.R >= Y.R);\n      --\n      when k_EQL_Integer => X.I := Boolean'Pos (X.I =  Y.I);\n      when k_NEQ_Integer => X.I := Boolean'Pos (X.I /= Y.I);\n      when k_LSS_Integer => X.I := Boolean'Pos (X.I <  Y.I);\n      when k_LEQ_Integer => X.I := Boolean'Pos (X.I <= Y.I);\n      when k_GTR_Integer => X.I := Boolean'Pos (X.I >  Y.I);\n      when k_GEQ_Integer => X.I := Boolean'Pos (X.I >= Y.I);\n      --\n      when k_EQL_VString => X.I := Boolean'Pos (X.V =  Y.V);\n      when k_NEQ_VString => X.I := Boolean'Pos (X.V /= Y.V);\n      when k_LSS_VString => X.I := Boolean'Pos (X.V <  Y.V);\n      when k_LEQ_VString => X.I := Boolean'Pos (X.V <= Y.V);\n      when k_GTR_VString => X.I := Boolean'Pos (X.V >  Y.V);\n      when k_GEQ_VString => X.I := Boolean'Pos (X.V >= Y.V);\n      --\n      when k_AND_Boolean => X.I := Boolean'Pos (Boolean'Val (X.I) and Boolean'Val (Y.I));\n      when k_OR_Boolean  => X.I := Boolean'Pos (Boolean'Val (X.I) or  Boolean'Val (Y.I));\n      when k_XOR_Boolean => X.I := Boolean'Pos (Boolean'Val (X.I) xor Boolean'Val (Y.I));\n      --\n      when k_ADD_Integer      => X.I := X.I + Y.I;\n      when k_SUBTRACT_Integer => X.I := X.I - Y.I;\n      when k_MULT_Integer     => X.I := X.I * Y.I;\n      when k_DIV_Integer      =>\n        if Y.I = 0 then raise Exceptions.VM_Division_by_0 with \"/\"; end if;\n        X.I := X.I / Y.I;\n      when k_MOD_Integer      =>\n        if Y.I = 0 then raise Exceptions.VM_Division_by_0 with \"mod\"; end if;\n        X.I := X.I mod Y.I;\n      when k_REM_Integer      =>\n        if Y.I = 0 then raise Exceptions.VM_Division_by_0 with \"rem\"; end if;\n        X.I := X.I rem Y.I;\n      when k_Power_Integer    => X.I := X.I ** Natural (Y.I);\n      --\n      when k_ADD_Float           => Check_X_Y_Float; X.R := X.R + Y.R;\n      when k_SUBTRACT_Float      => Check_X_Y_Float; X.R := X.R - Y.R;\n      when k_MULT_Float          => Check_X_Y_Float; X.R := X.R * Y.R;\n      when k_DIV_Float           => Check_X_Y_Float; X.R := X.R / Y.R;\n      when k_Power_Float         => Check_X_Y_Float; X.R := X.R ** Y.R;\n      when k_Power_Float_Integer => Check_X_Float;   X.R := X.R ** Natural (Y.I);\n    end case;\n    Pop (ND);\n  exception\n    when E : Constraint_Error | Ada.Numerics.Argument_Error =>\n      Exceptions.Raise_VM_Exception_from_Constraint_Error\n        (Ada.Exceptions.Exception_Message (E));\n  end Do_Binary_Operator;\n\n  procedure Do_Multiple_Operator (ND : in out In_Defs.Interpreter_Data) is\n    use In_Defs;\n    Top : Integer renames ND.TCB (ND.CurTask).T;\n    result_pos, terms : Integer;\n    use type Defs.HAC_Float, Defs.HAC_Integer, Defs.Typen;\n  begin\n    --  [T-(terms-1)] := [T-(terms-1)] + [T-(terms-1)+1] + ... + [T-(terms-1)+(terms-1)]\n    terms := Integer (ND.IR.Y);\n    result_pos := Top - (terms - 1);\n    case Multiple_Operator_Opcode (ND.IR.F) is\n      when k_ADD_Integer_Multiple =>\n        for term in 2 .. terms loop\n          ND.S (result_pos).I := ND.S (result_pos).I + ND.S (result_pos + term - 1).I;\n        end loop;\n      when k_ADD_Float_Multiple =>\n        for cell in 0 .. terms - 1 loop\n          if ND.S (result_pos + cell).Special /= Defs.Floats then\n            raise Exceptions.VM_Invalid_Data;\n          end if;\n        end loop;\n        for term in 2 .. terms loop\n          ND.S (result_pos).R := ND.S (result_pos).R + ND.S (result_pos + term - 1).R;\n        end loop;\n    end case;\n    Pop (ND, terms - 1);\n  exception\n    when E : Constraint_Error =>\n      Exceptions.Raise_VM_Exception_from_Constraint_Error\n        (Ada.Exceptions.Exception_Message (E));\n  end Do_Multiple_Operator;\n\n  procedure Do_Special_Operator (ND : in out In_Defs.Interpreter_Data) is\n    use In_Defs;\n    Top : Integer renames ND.TCB (ND.CurTask).T;\n    X : General_Register renames ND.S (Top - 2);  --  X = [T-2]\n    Y : General_Register renames ND.S (Top - 1);  --  Y = [T-1]\n    Z : General_Register renames ND.S (Top);      --  Z = [T]\n    use type Defs.HAC_Float, Defs.HAC_Integer, Defs.Typen;\n    --\n    procedure Check_Y_Z_Float is\n    pragma Inline (Check_Y_Z_Float);\n    begin\n      if Y.Special /= Defs.Floats or else Z.Special /= Defs.Floats then\n        raise Exceptions.VM_Invalid_Data;\n      end if;\n    end Check_Y_Z_Float;\n  begin\n    case Special_Operator_Opcode (ND.IR.F) is\n      when k_MULT_then_ADD_Integer =>\n        X.I := X.I + Y.I * Z.I;\n        Pop (ND, 2);\n      when k_MULT_then_ADD_Float =>\n        for cell in 0 .. 2 loop\n          if ND.S (Top - cell).Special /= Defs.Floats then\n            raise Exceptions.VM_Invalid_Data;\n          end if;\n        end loop;\n        X.R := X.R + Y.R * Z.R;\n        Pop (ND, 2);\n      when Op_then_Store_Opcode =>\n        case Op_then_Store_Opcode (ND.IR.F) is\n          when k_ADD_Integer_then_Store      => ND.S (Defs.Index (X.I)).I := Y.I + Z.I;\n          when k_SUBTRACT_Integer_then_Store => ND.S (Defs.Index (X.I)).I := Y.I - Z.I;\n          when k_MULT_Integer_then_Store     => ND.S (Defs.Index (X.I)).I := Y.I * Z.I;\n          when Op_Float_then_Store_Opcode =>\n            Check_Y_Z_Float;\n            case Op_Float_then_Store_Opcode (ND.IR.F) is\n              when k_ADD_Float_then_Store =>      ND.S (Defs.Index (X.I)) := GR_Real (Y.R + Z.R);\n              when k_SUBTRACT_Float_then_Store => ND.S (Defs.Index (X.I)) := GR_Real (Y.R - Z.R);\n              when k_MULT_Float_then_Store =>     ND.S (Defs.Index (X.I)) := GR_Real (Y.R * Z.R);\n            end case;\n        end case;\n        Pop (ND, 3);\n      when Op_Integer_Literal_Opcode =>\n        --  No push / pop !\n        case Op_Integer_Literal_Opcode (ND.IR.F) is\n          when k_ADD_Integer_Literal      => Z.I := Z.I + ND.IR.Y;\n          when k_SUBTRACT_Integer_Literal => Z.I := Z.I - ND.IR.Y;\n          when k_MULT_Integer_Literal     => Z.I := Z.I * ND.IR.Y;\n          when k_DIV_Integer_Literal      =>\n            if ND.IR.Y = 0 then raise Exceptions.VM_Division_by_0 with \"/\"; end if;\n            Z.I := Z.I / ND.IR.Y;\n          when Compare_Integer_Literal_Opcode =>\n            case Compare_Integer_Literal_Opcode (ND.IR.F) is\n              when k_EQL_Integer_Literal => Z.I := Boolean'Pos (Z.I =  ND.IR.Y);\n              when k_NEQ_Integer_Literal => Z.I := Boolean'Pos (Z.I /= ND.IR.Y);\n              when k_LSS_Integer_Literal => Z.I := Boolean'Pos (Z.I <  ND.IR.Y);\n              when k_LEQ_Integer_Literal => Z.I := Boolean'Pos (Z.I <= ND.IR.Y);\n              when k_GTR_Integer_Literal => Z.I := Boolean'Pos (Z.I >  ND.IR.Y);\n              when k_GEQ_Integer_Literal => Z.I := Boolean'Pos (Z.I >= ND.IR.Y);\n            end case;\n        end case;\n      when k_NAND_Boolean =>\n        Y.I := Boolean'Pos (not (Boolean'Val (Y.I) and Boolean'Val (Z.I)));\n        Pop (ND);\n      when k_NOR_Boolean =>\n        Y.I := Boolean'Pos (not (Boolean'Val (Y.I) or Boolean'Val (Z.I)));\n        Pop (ND);\n    end case;\n  exception\n    when E : Constraint_Error =>\n      Exceptions.Raise_VM_Exception_from_Constraint_Error\n        (Ada.Exceptions.Exception_Message (E));\n  end Do_Special_Operator;\n\n  procedure Do_SF_Operator (BD : Builder.Build_Data; ND : in out In_Defs.Interpreter_Data) is\n    use Defs, In_Defs;\n    CD : Co_Defs.Compiler_Data renames BD.CD.all;\n    Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n    Top_Item : General_Register renames ND.S (Curr_TCB.T);\n    idx, len, from, to : Integer;\n    c : Character;\n    code : constant SF_Code := SF_Code'Val (ND.IR.Y);\n    use Exceptions;\n    use Ada.Strings;\n    use type HAC_Integer, HAC_Float, HAT.Time, HAT.VString;\n    Going : Direction;\n    --\n  begin\n    case code is\n      when SF_Abs_Int   => Top_Item.I := abs (Top_Item.I);\n      when SF_Abs_Float => Top_Item.R := abs (Top_Item.R);\n      when SF_T_Val =>   --  Ord = Character'Val : RM 3.5.5 (5,7)\n        if Top_Item.I not in Defs.OrdMinChar .. Defs.OrdMaxChar then\n          raise VM_Out_of_Range with \": not in Character's range\";\n        end if;\n      when SF_T_Pos =>   --  S'Pos : RM 3.5.5 (2)\n        null;\n      when SF_T_Succ => Top_Item.I := Top_Item.I + 1;  --  S'Succ : RM 3.5 (22)\n      when SF_T_Pred => Top_Item.I := Top_Item.I - 1;  --  S'Pred : RM 3.5 (25)\n      when SF_in_discrete_Interval =>\n        --  SF_in_discrete_Interval (x, a, b) is equivalent to: `x in a .. b`\n        Pop (ND, 2);\n        --  [T] := [T] in [T+1] .. [T+2]\n        ND.S (Curr_TCB.T).I :=\n          Boolean'Pos (\n            ND.S (Curr_TCB.T).I in ND.S (Curr_TCB.T + 1).I .. ND.S (Curr_TCB.T + 2).I\n          );\n      when SF_not_in_discrete_Interval =>\n        --  SF_not_in_discrete_Interval (x, a, b) is equivalent to: `x not in a .. b`\n        Pop (ND, 2);\n        --  [T] := [T] not in [T+1] .. [T+2]\n        ND.S (Curr_TCB.T).I :=\n          Boolean'Pos (\n            ND.S (Curr_TCB.T).I not in ND.S (Curr_TCB.T + 1).I .. ND.S (Curr_TCB.T + 2).I\n          );\n      when SF_Round_Float_to_Int =>\n        Top_Item.I := HAC_Integer (Top_Item.R);\n      when SF_Trunc_Float_to_Int =>\n        Top_Item.I := HAC_Integer (Defs.HAC_Float'Floor (Top_Item.R));\n      when SF_Float_to_Duration =>\n        Top_Item := GR_Duration (Duration (Top_Item.R));\n      when SF_Duration_to_Float =>\n        Top_Item := GR_Real (Defs.HAC_Float (Top_Item.Dur));\n      when SF_Int_to_Duration =>\n        Top_Item := GR_Duration (Duration (Top_Item.I));\n      when SF_Duration_to_Int =>\n        Top_Item.I := HAC_Integer (Top_Item.Dur);\n      when SF_Sin        => Top_Item.R := HAT.Sin (Top_Item.R);\n      when SF_Cos        => Top_Item.R := HAT.Cos (Top_Item.R);\n      when SF_Exp        => Top_Item.R := HAT.Exp (Top_Item.R);\n      when SF_Log        => Top_Item.R := HAT.Log (Top_Item.R);\n      when SF_Sqrt       => Top_Item.R := HAT.Sqrt (Top_Item.R);\n      when SF_Arctan     => Top_Item.R := HAT.Arctan (Top_Item.R);\n      when SF_Sgn_Int    => Top_Item.I := (if Top_Item.I > 0 then 1 elsif Top_Item.I < 0 then -1 else 0);\n      when SF_Sgn_Float  => Top_Item.R := (if Top_Item.R > 0.0 then 1.0 elsif Top_Item.R < 0.0 then -1.0 else 0.0);\n      when SF_Random_Int => Top_Item.I := HAC_Integer (HAT.Rand (Integer (Top_Item.I)));\n      when SF_Min_Int =>\n        Pop (ND);\n        --  [T] := Min ([T], [T+1]) :\n        ND.S (Curr_TCB.T).I := HAC_Integer'Min (ND.S (Curr_TCB.T).I, ND.S (Curr_TCB.T + 1).I);\n      when SF_Max_Int =>\n        Pop (ND);\n        --  [T] := Max ([T], [T+1]) :\n        ND.S (Curr_TCB.T).I := HAC_Integer'Max (ND.S (Curr_TCB.T).I, ND.S (Curr_TCB.T + 1).I);\n      when SF_Min_Float =>\n        Pop (ND);\n        --  [T] := Min ([T], [T+1]) :\n        ND.S (Curr_TCB.T).R := HAC_Float'Min (ND.S (Curr_TCB.T).R, ND.S (Curr_TCB.T + 1).R);\n      when SF_Max_Float =>\n        Pop (ND);\n        --  [T] := Max ([T], [T+1]) :\n        ND.S (Curr_TCB.T).R := HAC_Float'Max (ND.S (Curr_TCB.T).R, ND.S (Curr_TCB.T + 1).R);\n      when SF_String_to_VString =>   --  Unary \"+\", equivalent to the call To_VString (S)\n        idx := Integer (ND.S (Curr_TCB.T).I);      --  Index in the stack (the string's address)\n        len := Integer (ND.IR.X);                  --  Length of string\n        ND.S (Curr_TCB.T) := GR_VString (Get_String_from_Stack (ND, idx, len));\n      when SF_String_Literal_to_VString =>  --  Unary \"+\", equivalent to the call To_VString (\"abc\")\n        Pop (ND);\n        len := Integer (ND.S (Curr_TCB.T).I);      --  Length of string\n        idx := Integer (ND.S (Curr_TCB.T + 1).I);  --  Index to string table\n        ND.S (Curr_TCB.T) := GR_VString (CD.Strings_Constants_Table (idx .. idx + len - 1));\n      when SF_VString_to_String =>\n        --  The type has just changed to Strings_as_VStrings at parser level.\n        --  For the VM, it's a VString one way or the other.\n        null;\n      when SF_Char_to_VString =>\n        --  We create a 1-character temporary String: (1 => Character'Val (...)) and\n        --  convert it to a VString.\n        ND.S (Curr_TCB.T) := GR_VString (HAT.To_VString ((1 => Character'Val (ND.S (Curr_TCB.T).I))));\n      when SF_Two_VStrings_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T), Defs.VStrings);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 1), Defs.VStrings);\n        --  [T] := [T] & [T+1] :\n        ND.S (Curr_TCB.T).V := ND.S (Curr_TCB.T).V & ND.S (Curr_TCB.T + 1).V;\n      when SF_VString_Char_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T), Defs.VStrings);\n        ND.S (Curr_TCB.T).V := ND.S (Curr_TCB.T).V & Character'Val (ND.S (Curr_TCB.T + 1).I);\n      when SF_Char_VString_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 1), Defs.VStrings);\n        ND.S (Curr_TCB.T) :=\n          GR_VString (Character'Val (ND.S (Curr_TCB.T).I) & ND.S (Curr_TCB.T + 1).V);\n      when SF_LStr_VString_Concat =>\n        --  Literal: 2 items, VString: 1 item. Total, 3 items folded into 1 item.\n        Pop (ND, 2);\n        len := Integer (ND.S (Curr_TCB.T).I);      --  Length of string\n        idx := Integer (ND.S (Curr_TCB.T + 1).I);  --  Index to string table\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 2), Defs.VStrings);\n        ND.S (Curr_TCB.T) :=\n          GR_VString (CD.Strings_Constants_Table (idx .. idx + len - 1) & ND.S (Curr_TCB.T + 2).V);\n      when SF_VString_Int_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T), Defs.VStrings);\n        HAT.VStr_Pkg.Append (ND.S (Curr_TCB.T).V, HAC_Image (ND.S (Curr_TCB.T + 1).I));\n      when SF_Int_VString_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 1), Defs.VStrings);\n        ND.S (Curr_TCB.T) := GR_VString ((HAC_Image (ND.S (Curr_TCB.T).I)) & ND.S (Curr_TCB.T + 1).V);\n      when SF_VString_Float_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T), Defs.VStrings);\n        HAT.VStr_Pkg.Append (ND.S (Curr_TCB.T).V, HAT.HAC_Image (ND.S (Curr_TCB.T + 1).R));\n      when SF_Float_VString_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 1), Defs.VStrings);\n        ND.S (Curr_TCB.T) :=\n          GR_VString (HAT.\"&\" (ND.S (Curr_TCB.T).R, ND.S (Curr_TCB.T + 1).V));\n      when SF_VString_Duration_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T), Defs.VStrings);\n        HAT.VStr_Pkg.Append (ND.S (Curr_TCB.T).V, HAT.Image (ND.S (Curr_TCB.T + 1).Dur));\n      when SF_Duration_VString_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 1), Defs.VStrings);\n        ND.S (Curr_TCB.T) := GR_VString (HAT.\"&\" (ND.S (Curr_TCB.T).Dur, ND.S (Curr_TCB.T + 1).V));\n      when SF_VString_Boolean_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T), Defs.VStrings);\n        ND.S (Curr_TCB.T).V := HAT.\"&\" (ND.S (Curr_TCB.T).V, Boolean'Val (ND.S (Curr_TCB.T + 1).I));\n      when SF_Boolean_VString_Concat =>\n        Pop (ND);\n        Check_Discriminant_Type (ND.S (Curr_TCB.T + 1), Defs.VStrings);\n        ND.S (Curr_TCB.T) := GR_VString (HAT.\"&\" (Boolean'Val (ND.S (Curr_TCB.T).I), ND.S (Curr_TCB.T + 1).V));\n      when SF_Element =>\n        Pop (ND);\n        --  [T] := Element ([T], [T+1]) :\n        idx := Integer (ND.S (Curr_TCB.T + 1).I);\n        len := HAT.Length (ND.S (Curr_TCB.T).V);\n        if idx < 1 then\n          Raise_Standard (ND, VME_Index_Error, \"Element: Index not positive\", True);\n        elsif idx > len then\n          Raise_Standard\n            (ND, VME_Index_Error,\n             \"Element: Index,\" & idx'Image &\n             \", is larger than Length (Source),\" & len'Image, True);\n        end if;\n        c := HAT.Element (ND.S (Curr_TCB.T).V, idx);\n        ND.S (Curr_TCB.T).I := Character'Pos (c);\n      when SF_Length =>\n        --  [T] := Length ([T]) :\n        len := HAT.Length (Top_Item.V);\n        Top_Item.I := HAC_Integer (len);\n      when SF_Slice =>\n        Pop (ND, 2);\n        from := Integer (ND.S (Curr_TCB.T + 1).I);\n        to   := Integer (ND.S (Curr_TCB.T + 2).I);\n        if from < 1 then\n          Raise_Standard (ND, VME_Constraint_Error, \"Slice: Low is not positive:\" &\n            Integer'Image (from), True);\n        elsif to < 0 then\n          Raise_Standard (ND, VME_Constraint_Error, \"Slice: High is negative: \" &\n            Integer'Image (to), True);\n        end if;\n        len := HAT.Length (ND.S (Curr_TCB.T).V);\n        if from > len + 1 then\n          Raise_Standard (ND, VME_Index_Error,\n            \"Slice: Low is larger than Length (Source) + 1. See RM A.4.4 (101)\", True);\n        elsif to > len then\n          Raise_Standard (ND, VME_Index_Error,\n            \"Slice: High is larger than Length (Source). See RM A.4.4 (101)\", True);\n        end if;\n        --  [T] := Slice ([T], [T+1], [T+2]) :\n        HAT.VStr_Pkg.Set_Unbounded_String\n          (ND.S (Curr_TCB.T).V, HAT.VStr_Pkg.Slice (ND.S (Curr_TCB.T).V, from, to));\n      when SF_To_Lower_Char =>\n        Top_Item.I := Character'Pos (HAT.To_Lower (Character'Val (Top_Item.I)));\n      when SF_To_Upper_Char =>\n        Top_Item.I := Character'Pos (HAT.To_Upper (Character'Val (Top_Item.I)));\n      when SF_To_Lower_VStr =>\n        HAT.VStr_Pkg.Set_Unbounded_String (Top_Item.V, HAT.ACH.To_Lower (HAT.VStr_Pkg.To_String (Top_Item.V)));\n      when SF_To_Upper_VStr =>\n        HAT.VStr_Pkg.Set_Unbounded_String (Top_Item.V, HAT.ACH.To_Upper (HAT.VStr_Pkg.To_String (Top_Item.V)));\n      when SF_Index | SF_Index_Backward =>\n        Going := (if code = SF_Index then Forward else Backward);\n        Pop (ND, 2);\n        from := Integer (ND.S (Curr_TCB.T + 2).I);\n        ND.S (Curr_TCB.T).I :=\n          HAC_Integer\n           (if from >= 1 then\n              --  [T] := Index (Source: [T], Pattern: [T+1], From: [T+2], Going) :\n              HAT.VStr_Pkg.Index\n                (ND.S (Curr_TCB.T).V,\n                 HAT.VStr_Pkg.To_String (ND.S (Curr_TCB.T + 1).V),\n                 from,\n                 Going)\n            else\n              --  [T] := Index (Source: [T], Pattern: [T+1], Going) :\n              HAT.VStr_Pkg.Index\n                (ND.S (Curr_TCB.T).V,\n                 HAT.VStr_Pkg.To_String (ND.S (Curr_TCB.T + 1).V),\n                 Going));\n      when SF_Head =>\n        Pop (ND);\n        --  [T] := Head ([T], [T+1]) :\n        ND.S (Curr_TCB.T).V :=\n          HAT.VStr_Pkg.Head (ND.S (Curr_TCB.T).V, Natural (ND.S (Curr_TCB.T + 1).I));\n      when SF_Tail =>\n        Pop (ND);\n        --  [T] := Tail ([T], [T+1]) :\n        ND.S (Curr_TCB.T).V :=\n          HAT.VStr_Pkg.Tail (ND.S (Curr_TCB.T).V, Natural (ND.S (Curr_TCB.T + 1).I));\n      when SF_Head_Before_Match =>\n        Pop (ND);\n        --  [T] := Head_Before_Match ([T], [T+1]) :\n        ND.S (Curr_TCB.T).V :=\n          HAT.Head_Before_Match (ND.S (Curr_TCB.T).V, ND.S (Curr_TCB.T + 1).V);\n      when SF_Tail_After_Match =>\n        Pop (ND);\n        --  [T] := Tail_After_Match ([T], [T+1]) :\n        ND.S (Curr_TCB.T).V :=\n          HAT.Tail_After_Match (ND.S (Curr_TCB.T).V, ND.S (Curr_TCB.T + 1).V);\n      when SF_Starts_With =>\n        Pop (ND);\n        --  [T] := Starts_With ([T], [T+1]) :\n        ND.S (Curr_TCB.T).I :=\n          Boolean'Pos (HAT.Starts_With (ND.S (Curr_TCB.T).V, ND.S (Curr_TCB.T + 1).V));\n      when SF_Ends_With =>\n        Pop (ND);\n        --  [T] := Ends_With ([T], [T+1]) :\n        ND.S (Curr_TCB.T).I :=\n          Boolean'Pos (HAT.Ends_With (ND.S (Curr_TCB.T).V, ND.S (Curr_TCB.T + 1).V));\n      when SF_Year =>\n        ND.S (Curr_TCB.T).I := HAC_Integer (Ada.Calendar.Year (ND.S (Curr_TCB.T).Tim));\n      when SF_Month =>\n        ND.S (Curr_TCB.T).I := HAC_Integer (Ada.Calendar.Month (ND.S (Curr_TCB.T).Tim));\n      when SF_Day =>\n        ND.S (Curr_TCB.T).I := HAC_Integer (Ada.Calendar.Day (ND.S (Curr_TCB.T).Tim));\n      when SF_Seconds =>\n        ND.S (Curr_TCB.T) := GR_Duration (Ada.Calendar.Seconds (ND.S (Curr_TCB.T).Tim));\n      when SF_Int_Times_Char =>\n        Pop (ND);\n        if ND.S (Curr_TCB.T).I < 0 then raise VM_Out_of_Range with \": negative value\"; end if;\n        --  [T] := [T] * [T+1] :\n        ND.S (Curr_TCB.T) :=\n          GR_VString (Natural (ND.S (Curr_TCB.T).I) * Character'Val (ND.S (Curr_TCB.T + 1).I));\n      when SF_Int_Times_VStr =>\n        Pop (ND);\n        if ND.S (Curr_TCB.T).I < 0 then raise VM_Out_of_Range with \": negative value\"; end if;\n        --  [T] := [T] * [T+1] :\n        ND.S (Curr_TCB.T) :=\n          GR_VString (Natural (ND.S (Curr_TCB.T).I) * ND.S (Curr_TCB.T + 1).V);\n      when SF_Trim_Left  => Top_Item.V := HAT.VStr_Pkg.Trim (Top_Item.V, Left);\n      when SF_Trim_Right => Top_Item.V := HAT.VStr_Pkg.Trim (Top_Item.V, Right);\n      when SF_Trim_Both  => Top_Item.V := HAT.VStr_Pkg.Trim (Top_Item.V, Both);\n      --\n      when SF_Time_Subtract =>\n        Pop (ND);\n        ND.S (Curr_TCB.T) := GR_Duration (ND.S (Curr_TCB.T).Tim - ND.S (Curr_TCB.T + 1).Tim);\n      when SF_Duration_Subtract =>\n        Pop (ND);\n        ND.S (Curr_TCB.T).Dur := ND.S (Curr_TCB.T).Dur - ND.S (Curr_TCB.T + 1).Dur;\n      when SF_Duration_Add =>\n        Pop (ND);\n        ND.S (Curr_TCB.T).Dur := ND.S (Curr_TCB.T).Dur + ND.S (Curr_TCB.T + 1).Dur;\n      --\n      when SF_Image_Ints      => Top_Item := GR_VString (HAC_Image (Top_Item.I));\n      when SF_Image_Floats    => Top_Item := GR_VString (HAT.HAC_Image (Top_Item.R));\n      when SF_Image_Times     => Top_Item := GR_VString (HAT.HAC_Image (Top_Item.Tim));\n      when SF_Image_Durations => Top_Item := GR_VString (HAT.Image (Top_Item.Dur));\n      --\n      when SF_Integer_Value | SF_Value_Attribute_Ints =>\n        begin\n          Top_Item.I := HAC_Integer'Value (HAT.To_String (Top_Item.V));\n        exception\n          when E : Constraint_Error =>\n            Raise_Standard (ND, VME_Constraint_Error, Ada.Exceptions.Exception_Message (E), True);\n        end;\n      when SF_Float_Value | SF_Value_Attribute_Floats =>\n        begin\n          Top_Item := GR_Real (HAC_Float'Value (HAT.To_String (Top_Item.V)));\n        exception\n          when E : Constraint_Error =>\n            Raise_Standard (ND, VME_Constraint_Error, Ada.Exceptions.Exception_Message (E), True);\n        end;\n      --\n      when SF_Image_Attribute_Ints   => Top_Item := GR_VString (HAC_Integer'Image (Top_Item.I));\n      when SF_Image_Attribute_Floats => Top_Item := GR_VString (HAC_Float'Image (Top_Item.R));\n      when SF_Image_Attribute_Bools  => Top_Item := GR_VString (Boolean'Image (Boolean'Val (Top_Item.I)));\n      when SF_Image_Attribute_Chars  => Top_Item := GR_VString (Character'Image (Character'Val (Top_Item.I)));\n      when SF_Image_Attribute_Durs   => Top_Item := GR_VString (Duration'Image (Top_Item.Dur));\n      when SF_Image_Attribute_Enums  =>\n        --  .Name contains the upper case representation as required by RM 3.5 (32).\n        declare\n          full_name : constant String := A2S (CD.id_table (Natural (ND.IR.X) + Natural (Top_Item.I)).name);\n          dot : constant Natural := Ada.Strings.Fixed.Index (full_name, \".\", Going => Backward);\n        begin\n          Top_Item :=\n            (if dot = 0 then\n               GR_VString (full_name)\n             else\n               GR_VString (full_name (dot + 1 .. full_name'Last)));\n        end;\n      --\n      when SF_Value_Attribute_Bools  =>\n        begin\n          Top_Item.I := Boolean'Pos (Boolean'Value (HAT.To_String (Top_Item.V)));\n        exception\n          when E : Constraint_Error =>\n            Raise_Standard (ND, VME_Constraint_Error, Ada.Exceptions.Exception_Message (E), True);\n        end;\n      when SF_Value_Attribute_Chars  =>\n        begin\n          Top_Item.I := Character'Pos (Character'Value (HAT.To_String (Top_Item.V)));\n        exception\n          when E : Constraint_Error =>\n            Raise_Standard (ND, VME_Constraint_Error, Ada.Exceptions.Exception_Message (E), True);\n        end;\n      when SF_Value_Attribute_Durs   =>\n        begin\n          Top_Item := GR_Duration (Duration'Value (HAT.To_String (Top_Item.V)));\n        exception\n          when E : Constraint_Error =>\n            Raise_Standard (ND, VME_Constraint_Error, Ada.Exceptions.Exception_Message (E), True);\n        end;\n      when SF_Value_Attribute_Enums  =>\n        --  If there is a performance issue here, we could replace\n        --  this linear search with something using Hashed_Maps.\n        declare\n          to_match_any_case : constant String := HAT.To_String (Top_Item.V);\n          to_match : constant String := HAT.ACH.To_Upper (to_match_any_case);\n          j : HAC_Integer := -1;\n        begin\n          for i in 0 .. CD.id_table (Natural (ND.IR.X)).xtyp.Discrete_Last loop\n            if CD.id_table (Natural (ND.IR.X) + Natural (i + 1)).name = to_match then\n              j := i;\n              exit;\n            end if;\n          end loop;\n          if j >= 0 then\n            Top_Item.I := j;\n          else\n            Raise_Standard (ND, VME_Constraint_Error,\n              '\"' & to_match_any_case &\n              \"\"\" is not a literal of enumeration type \"\"\" &\n              A2S (CD.id_table (Natural (ND.IR.X)).name_with_case) & '\"',\n              True);\n          end if;\n        end;\n      --\n      when SF_Exists           => Top_Item.I := Boolean'Pos (HAT.Exists (Top_Item.V));\n      when SF_Directory_Exists => Top_Item.I := Boolean'Pos (HAT.Directory_Exists (Top_Item.V));\n      when SF_File_Exists      => Top_Item.I := Boolean'Pos (HAT.File_Exists (Top_Item.V));\n      when SF_Get_Env          => Top_Item.V := HAT.Get_Env (Top_Item.V);\n      when SF_Get_VM_Variable  =>\n        HAT.VStr_Pkg.Set_Unbounded_String\n          (Top_Item.V, Interfacing.Get_VM_Variable (BD, HAT.To_String (Top_Item.V)));\n      --\n      when SF_Niladic =>\n        --  NILADIC functions need to push a new item (their own result).\n        Push (ND);\n        case SF_Niladic (code) is\n          when SF_Clock =>\n            ND.S (Curr_TCB.T) := GR_Time (Ada.Calendar.Clock);\n          when SF_Random_Float =>\n            ND.S (Curr_TCB.T) := GR_Real (Defs.HAC_Float (HAT.Rnd));\n          when SF_Null_VString =>\n            ND.S (Curr_TCB.T) := GR_VString (HAT.Null_VString);\n          when SF_Argument_Count | SF_Directory_Separator |\n               SF_Current_Directory | SF_Get_Needs_Skip_Line |\n               SF_Command_Name =>\n            --  Those functions have been already processed at an\n            --  upper calling level by Do_Standard_Function.\n            null;\n        end case;\n      when SF_File_or_Console_Information | SF_Argument =>\n        --  Those functions have been already processed at an\n        --  upper calling level by Do_Standard_Function.\n        null;\n      when SF_Is_Open =>\n        ND.S (Curr_TCB.T).I := Boolean'Pos (HAT.Is_Open (ND.S (Curr_TCB.T).Txt.all));\n    end case;\n  exception\n    when E : Ada.Numerics.Argument_Error =>\n      Exceptions.Raise_VM_Exception_from_Constraint_Error\n        (Ada.Exceptions.Exception_Message (E));\n  end Do_SF_Operator;\n\nend HAC_Sys.PCode.Interpreter.Operators;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-operators.ads",
    "content": "with HAC_Sys.Builder,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\nprivate package HAC_Sys.PCode.Interpreter.Operators is\n\n  -----------------------\n  --  VM Instructions  --\n  -----------------------\n\n  --  Execute operator stored as Opcode in ND.IR.F.\n  procedure Do_Unary_Operator (ND : in out In_Defs.Interpreter_Data);\n  procedure Do_Binary_Operator (ND : in out In_Defs.Interpreter_Data);\n  procedure Do_Multiple_Operator (ND : in out In_Defs.Interpreter_Data);\n  procedure Do_Special_Operator (ND : in out In_Defs.Interpreter_Data);\n\n  --  Execute operator through the Opcode k_Standard_Functions.\n  procedure Do_SF_Operator (BD : Builder.Build_Data; ND : in out In_Defs.Interpreter_Data);\n\nend HAC_Sys.PCode.Interpreter.Operators;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-tasking-scheduler.adb",
    "content": "--  Translated from newsched.pas on 28-Jun-2022 by (New) P2Ada v. 28-Oct-2009\n\nseparate (HAC_Sys.PCode.Interpreter.Tasking)\nprocedure Scheduler (CD : Compiler_Data; ND : in out Interpreter_Data) is\n\n  TCount : constant Natural := CD.Tasks_Definitions_Count;\n\n  --  =======================================================================\n  --   Calc_Priority:  Returns dynamic priority of task t.\n  --\n  --     Dynamic priority is a function of:\n  --       User specified task priority which can be dynamically set via\n  --         SMALL_SP.PRIORITY.\n  --\n  --  9X   Priority inheritance - if a task is inheriting priorities then\n  --         its dynamic priority is the maximum of the dynamic priorities\n  --         of ALL tasks enqueued to rendezvous with it.  Inheritance is\n  --         activated for a task by calling SMALL_SP.INHERITP(TRUE).\n  --       Rendezvous status - if a task X is not inheriting priorities but\n  --         is in rendezvous with another task Y then X's dynamic priority\n  --         is the larger of X's priority and Y's dynamic priority.\n  --\n  --  =======================================================================\n  --  Translated from interdef.pas on 28-Jun-2022 by (New) P2Ada v. 28-Oct-2009\n  --\n  function Calc_Priority (t : TRange) return Float is\n    Result_Calc_Priority, p1, p2 : Float;\n                              et : Eptr;\n    --  Convert integer user priority to real range [0.0, 1.0]\n    function  CVTR (upri : Integer) return Float is\n    begin  --  upri is in range [0, PriMax]\n      return Float (upri) / Float (Defs.PriMax);\n    end CVTR;\n\n    --  Scheduling fairness adjustment to be added to static priority\n    function Fairness (t : TRange) return Float is\n      use Ada.Calendar;\n    begin  --  Adjustment is directly prop. to elapsed time since last run\n      return\n        Float (Clock - ND.TCB (t).LASTRUN) / 20000.0;  --  20000.0 for tuning\n    end Fairness;\n\n  begin\n    if ND.TCB (t).Pcontrol.INHERIT then  --  Consider ALL tasks waiting on task t\n      p1 := CVTR (ND.TCB (t).Pcontrol.UPRI) + Fairness (t);\n      for e in 1 .. CD.Entries_Count loop  --  For each entry\n        if ND.EList (e).Task_Index = t then\n          --  If an entry queue for task t\n          --  then check priority of every task on queue\n          et := ND.EList (e).First;\n          while et /= null loop\n            --  Calc Priority, RECURSIVE\n            p2 := Calc_Priority (et.all.Task_Index);\n            if p2 > p1 then\n              p1 := p2;  --  Keep maximum priority\n            end if;\n            et := et.all.Next;  --  Next task in queue\n          end loop;\n        end if;\n      end loop;\n      Result_Calc_Priority := p1;\n    elsif ND.TCB (t).InRendzv /= NilTask then  --  In Rendezvous with some task\n      --  Compare task t pri. with task in rendezvous with, use max.\n      p1 := CVTR (ND.TCB (t).Pcontrol.UPRI) + Fairness (t);  --  task t\n      p2 := Calc_Priority (ND.TCB (t).InRendzv);             --  task t's caller\n      Result_Calc_Priority := Float'Max (p1, p2);\n    else\n      --  Not inheriting and not in rendezvous, simplest case.\n      Result_Calc_Priority := CVTR (ND.TCB (t).Pcontrol.UPRI) + Fairness (t);\n    end if;\n    return Result_Calc_Priority;\n  end Calc_Priority;\n\n  --                        The George Washington University\n  --         Department of Electrical Engineering and Computer Science\n  --                             Small Ada Schedulers\n  --                            Amr El-Kadi  Fall 1990\n\n  procedure  Scheduler_0 (NexTask : in out Integer;  PS : in out  Processor_State) is\n     maxpriority, p : Float;\n         nready : Integer;\n    allcomplete : Boolean := True;  --  check if all tasks are completed\n          dummy : Boolean;\n  begin\n    for t in  0 .. TCount loop\n      if ND.TCB (t).TS /= Completed then\n        allcomplete := False;\n        exit;\n      end if;\n    end loop;\n    if  allcomplete then\n      PS := FIN;  --  Stop the SmallAda processor\n    else\n      nready := 0;\n      maxpriority := -1.0;\n      for t in 0 .. TCount loop\n        --  Of ready tasks, find one w/ max priority\n        if ND.TCB (t).TS = Ready then\n          p := Calc_Priority (t);\n          if  p > maxpriority then\n            maxpriority := p;\n            NexTask := t;\n          end if;\n          nready := nready + 1;\n        end if;\n      end loop;\n      if nready = 0 then\n        --  No ready tasks ; any delayed ? ; if yes then WAIT\n        if Any_Task_Delayed (CD, ND) then\n          --  Update SYSCLOCK and do loop again\n          Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n          PS := WAIT;  --  there are delayed tasks, put processor\n                       --  in a wait state\n        else  --  no ready tasks, no delayed tasks, DEADLOCK\n          PS := DEADLOCK;\n        end if;\n      else  --  There was at least one ready task ; continue to process\n        PS := Running;\n        --         if (tcb [0].ts = completed) then\n        --         begin\n        --           PS := FIN ;\n        --           for t := 1 to tcount do\n        --           begin\n        --             if ((tcb[t].ts = ready) and (not (tcb [t].term))) then\n        --             begin\n        --               PS := DEADLOCK ;   {Check for deadlock} {Oguz Tumer}\n        --             end ;\n        --           end ;\n        --         end ;\n      end if;\n    end if;\n  end Scheduler_0;\n\n  --  This Scheduler implements the Run Until Blocked strategy\n  --              Amr El-Kadi    Fall 1990\n\n  procedure  Scheduler_1 (NextTask : in out Integer;  PS : in out Processor_State) is\n    nready             : Integer;\n    allcomplete, dummy : Boolean;\n  begin\n    if ND.TCB (NextTask).TS /= Ready then\n      --  If the task was running, it becomes ready now\n      if ND.TCB (NextTask).TS = Running then ND.TCB (NextTask).TS := Ready; end if;\n      if Any_Task_Delayed (CD, ND) then  --  Check if any is delayed\n        Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n        PS := WAIT; --  Processor's state is waiting\n      end if;\n      nready := 0;\n      allcomplete := True;\n      for t in 0 .. TCount loop  --  Check if all have completed\n        if ND.TCB (t).TS /= Completed then\n          allcomplete := False;\n          if ND.TCB (t).TS = Ready then nready := nready + 1; end if;  --  Count ready tasks\n        end if;\n      end loop;\n      if allcomplete then\n        PS := FIN;  --  Stop the Processor\n      else\n        if nready = 0 and PS /= WAIT then\n          PS := DEADLOCK;  --  No ready or delayed tasks\n        else\n          if  nready /= 0 then  --  There is at least one ready task\n            PS := Running;\n            --  Search Starting from the current for a ready task\n            NextTask := NextTask + 1;\n            if NextTask > TCount then NextTask := 0; end if;\n            while ND.TCB (NextTask).TS /= Ready loop\n              NextTask := NextTask + 1;\n              if NextTask > TCount then NextTask := 0; end if;\n            end loop;\n          end if;\n        end if;\n      end if;\n    else\n      PS := Running;\n    end if;\n  end Scheduler_1;\n\n  --  This Scheduler implements the Round Robin strategy  (using time slices)\n  --                      Amr El-Kadi    Fall 1990\n\n  procedure  Scheduler_2 (NextTask : in out Integer; PS : in out Processor_State) is\n    nready             : Integer;\n    allcomplete, dummy : Boolean;\n  begin\n    ND.TCB (NextTask).QUANTUM := ND.TCB (NextTask).QUANTUM - 1.0;  --  decrement time given\n    if ND.TCB (NextTask).QUANTUM < 0.0 or ND.TCB (NextTask).TS /= Ready then  --  Time slice was exhausted\n      --  If the task was running, it becomes ready now\n      if ND.TCB (NextTask).TS = Running then ND.TCB (NextTask).TS := Ready; end if;\n      if Any_Task_Delayed (CD, ND) then  --  Check if any is delayed\n        Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n        PS := WAIT; --  Processor's state is waiting\n      end if;\n      nready := 0;\n      allcomplete := True;\n      for t in 0 .. TCount loop  --  Check if all have completed\n        if ND.TCB (t).TS /= Completed then\n          allcomplete := False;\n          if ND.TCB (t).TS = Ready then nready := nready + 1; end if;  --  Count ready tasks\n        end if;\n      end loop;\n      if  allcomplete then\n        PS := FIN;  --  Stop the Processor\n      else\n        if nready = 0  and PS /= WAIT then\n          PS := DEADLOCK;  --  No ready or delayed tasks\n        else\n          if nready /= 0 then\n            --  There is at least one ready task\n            PS := Running;\n            --  Search Starting from the current for a ready task\n            NextTask := NextTask + 1;\n            if NextTask > TCount then NextTask := 0; end if;\n            while ND.TCB (NextTask).TS /= Ready loop\n              NextTask := NextTask + 1;\n              if NextTask > TCount then NextTask := 0; end if;\n            end loop;\n            ND.TCB (NextTask).QUANTUM := TSlice;  --  give it a time slice\n          end if;\n        end if;\n      end if;\n    else\n      PS := Running;\n    end if;  --  Time slice was not exhausted\n  end Scheduler_2;\n\n  --  This procedure searches the list of READY tasks and returns the\n  --  index of the Ready Task with the highest priority\n  --                      Amr El-Kadi\n\n  procedure highest (t : in out Integer) is\n  begin\n    t := 0;\n    for i in 0 .. TCount loop\n      if ND.TCB (i).TS = Ready and then ND.TCB (i).Pcontrol.UPRI > ND.TCB (t).Pcontrol.UPRI then\n        t := i;\n      end if;\n    end loop;\n  end highest;\n\n  --  This Scheduler implements the Static Priority strategy  (using lexical order)\n  --          This does not use time slicing, but it is preemptive\n  --                      Amr El-Kadi    Fall 1990\n\n  procedure  Scheduler_3 (NextTask : in out Integer;  PS : in out Processor_State) is\n                     nready : Integer;\n                allcomplete : Boolean;\n                      dummy : Boolean;\n  begin\n    --  If the task was running, it becomes ready now\n    if ND.TCB (NextTask).TS = Running then ND.TCB (NextTask).TS := Ready; end if;\n    if Any_Task_Delayed (CD, ND) then  --  Check if any is delayed\n      Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n      PS := WAIT;  --  Processor's state is waiting\n    end if;\n    nready := 0;\n    allcomplete := True;\n    for t in 0 .. TCount loop  --  Check if all have completed\n      if ND.TCB (t).TS /= Completed then\n        allcomplete := False;\n        if ND.TCB (t).TS = Ready then nready := nready + 1; end if; --  Count ready tasks\n      end if;\n    end loop;\n    if  allcomplete then\n      PS := FIN;  --  Stop the Processor\n    else\n      if nready = 0 and PS /= WAIT then\n        PS := DEADLOCK;  --  No ready or delayed tasks\n      else\n        if nready /= 0 then\n          --  There is at least one ready task\n          PS := Running;\n          --  Search for the highest priority task\n          highest (NextTask);\n        end if;\n      end if;\n    end if;\n  end Scheduler_3;\n\n  --  This Scheduler implements the Static Priority strategy  (using lexical order)\n  --            This does use time slicing, and it is not preemptive\n  --                      Amr El-Kadi    Fall 1990\n\n  procedure  Scheduler_4 (NextTask : in out  Integer;  PS : in out  Processor_State) is\n    nready             : Integer;\n    allcomplete, dummy : Boolean;\n  begin\n    ND.TCB (NextTask).QUANTUM := ND.TCB (NextTask).QUANTUM - 1.0;  --  decrement time given\n    if ND.TCB (NextTask).QUANTUM < 0.0 or ND.TCB (NextTask).TS /= Ready then  --  Time slice was exhausted\n      --  If the task was running, it becomes ready now\n      if ND.TCB (NextTask).TS = Running then ND.TCB (NextTask).TS := Ready; end if;\n      if Any_Task_Delayed (CD, ND) then  --  Check if any is delayed\n        Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n        PS := WAIT; --  Processor's state is waiting\n      end if;\n      nready := 0;\n      allcomplete := True;\n      for t in 0 .. TCount loop  --  Check if all have completed\n        if ND.TCB (t).TS /= Completed then\n          allcomplete := False;\n          if ND.TCB (t).TS = Ready then nready := nready + 1; end if; --  Count ready tasks\n        end if;\n      end loop;\n      if  allcomplete then\n        PS := FIN;  --  Stop the Processor\n      else\n        if nready = 0 and PS /= WAIT then\n          PS := DEADLOCK;  --  No ready or delayed tasks\n        else\n          if nready /= 0 then\n            --  There is at least one ready task\n            PS := Running;\n              --  Search for the highest priority task\n              highest (NextTask);\n              ND.TCB (NextTask).QUANTUM := TSlice; --  give it a time slice\n          end if;\n        end if;\n      end if;\n    else\n      PS := Running;\n    end if; --  Time slice was not exhausted\n  end Scheduler_4;\n\n  --  This Scheduler implements the Static Priority strategy  (using lexical order)\n  --            This does use time slicing, and it is preemptive\n  --                      Amr El-Kadi    Fall 1990\n\n  procedure  Scheduler_5 (NextTask : in out Integer;  PS : in out  Processor_State) is\n    tt, nready         : Integer;\n    allcomplete, dummy : Boolean;\n  begin\n    ND.TCB (NextTask).QUANTUM := ND.TCB (NextTask).QUANTUM - 1.0;  --  decrement time given\n    --  If the task was running, it becomes ready now\n    if ND.TCB (NextTask).TS = Running then ND.TCB (NextTask).TS := Ready; end if;\n    if Any_Task_Delayed (CD, ND) then  --  Check if any is delayed\n      Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n      PS := WAIT; --  Processor's state is waiting\n    end if;\n\n    nready := 0;\n    allcomplete := True;\n    for t in 0 .. TCount loop  --  Check if all have completed\n      if ND.TCB (t).TS /= Completed then\n        allcomplete := False;\n        if ND.TCB (t).TS = Ready then nready := nready + 1; end if;  --  Count ready tasks\n      end if;\n    end loop;\n    if  allcomplete then\n      PS := FIN;  --  Stop the Processor\n    else\n      if nready = 0 and PS /= WAIT then\n        PS := DEADLOCK;  --  No ready or delayed tasks\n      else\n        if nready /= 0 then\n           --  There is at least one ready task\n          PS := Running;\n          if ND.TCB (NextTask).QUANTUM < 0.0 or ND.TCB (NextTask).TS /= Ready  then  --  Time slice was exhausted\n            --  Search for the highest priority task\n            highest (NextTask);\n            ND.TCB (NextTask).QUANTUM := TSlice; --  give it a time slice\n          else\n            tt := NextTask;\n            --  Search for the highest priority task\n            highest (tt);\n            if tt /= NextTask then --  one with higher priority was found\n              ND.TCB (NextTask).QUANTUM := 0.0;  --  reset the time slice for the old one\n              NextTask := tt;\n              ND.TCB (NextTask).QUANTUM := TSlice; --  give it a time slice\n            end if;\n          end if;\n        end if;\n      end if;\n    end if;\n  end Scheduler_5;\n\n  --  This Scheduler implements the Static Priority strategy  (using lexical order)\n  --            This does not use time slicing, and it is not preemptive\n  --                      Amr El-Kadi    Fall 1990\n\n  procedure  Scheduler_6 (NextTask : in out Integer; PS : in out Processor_State) is\n    nready             : Integer;\n    allcomplete, dummy : Boolean;\n  begin\n    ND.TCB (NextTask).QUANTUM := ND.TCB (NextTask).QUANTUM - 1.0; --  decrement time given\n    if ND.TCB (NextTask).TS /= Ready then\n      --  If the task was running, it becomes ready now\n      if ND.TCB (NextTask).TS = Running then ND.TCB (NextTask).TS := Ready; end if;\n      if Any_Task_Delayed (CD, ND) then  --  Check if any is delayed\n        Wake_Tasks (CD, ND, dummy);  --  wakes tasks\n        PS := WAIT; --  Processor's state is waiting\n      end if;\n      nready := 0;\n      allcomplete := True;\n      for t in 0 .. TCount loop  --  Check if all have completed\n        if ND.TCB (t).TS /= Completed then\n          allcomplete := False;\n          if ND.TCB (t).TS = Ready then nready := nready + 1; end if; --  Count ready tasks\n        end if;\n      end loop;\n      if  allcomplete then\n        PS := FIN;  --  Stop the Processor\n      else\n        if nready = 0 and PS /= WAIT then\n          PS := DEADLOCK;  --  No ready or delayed tasks\n        else\n          if nready /= 0 then\n            --  There is at least one ready task\n            PS := Running;\n            --  Search for the highest priority task\n            highest (NextTask);\n          end if;\n        end if;\n      end if;\n    else\n      PS := Running;  --  Task did not block yet\n    end if;\n  end Scheduler_6;\n\nbegin\n  case ND.Scheduler is\n    when 0 => Scheduler_0 (ND.CurTask, ND.PS);\n    when 1 => Scheduler_1 (ND.CurTask, ND.PS);\n    when 2 => Scheduler_2 (ND.CurTask, ND.PS);\n    when 3 => Scheduler_3 (ND.CurTask, ND.PS);\n    when 4 => Scheduler_4 (ND.CurTask, ND.PS);\n    when 5 => Scheduler_5 (ND.CurTask, ND.PS);\n    when 6 => Scheduler_6 (ND.CurTask, ND.PS);\n    when Single_Task => null;\n  end case;\nend Scheduler;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-tasking.adb",
    "content": "with Ada.Calendar;\nwith Ada.Numerics.Float_Random;\n\npackage body HAC_Sys.PCode.Interpreter.Tasking is\n\n  function Any_Task_Delayed (CD : Compiler_Data; ND : Interpreter_Data) return Boolean is\n    task_delayed : Boolean := False;\n  begin\n    for t in TRange'First .. CD.Tasks_Definitions_Count loop\n      task_delayed := ND.TCB (t).TS = Delayed or\n                     ND.TCB (t).TS = TimedRendz or\n                     ND.TCB (t).TS = TimedWait;\n      exit when task_delayed;\n    end loop;\n    return task_delayed;\n  end Any_Task_Delayed;\n\n  function EIndex (CD : Compiler_Data; Entry_Index : Integer) return Integer is\n    i, e : Integer;\n  begin\n    e := -1;\n    i := 1;\n    while i <= CD.Entries_Count and e = -1 loop\n      if Entry_Index = CD.Entries_Table (i) then\n        e := i;\n      end if;\n      i := i + 1;\n    end loop;\n    return e;\n  end EIndex;\n\n  function First_Caller (CD : Compiler_Data; ND : in out Interpreter_Data; Entry_Index : Integer) return Integer is\n    ix, val : Integer;\n  begin\n    ix := EIndex (CD, Entry_Index);\n    if ND.EList (ix).First = null then\n      val := -1;\n    else\n      val := ND.EList (ix).First.Task_Index;\n    end if;\n    return val;\n  end First_Caller;\n\n  procedure Queue (\n    CD           :        Compiler_Data;\n    ND           : in out Interpreter_Data;\n    Entry_Index  :        Integer;\n    Calling_Task :        TRange\n  )\n  is\n    ix         : constant Integer := EIndex (CD, Entry_Index);\n    enode_var  : constant Eptr := new Enode'(Task_Index => Calling_Task, Next => null);\n    E_Q_Header : EHeader renames ND.EList (ix);\n  begin\n    --  Queue an entry call by Calling_Task for entry 'Entry'.\n    if E_Q_Header.First = null then\n      E_Q_Header.First := enode_var;\n    else\n      E_Q_Header.Last.Next := enode_var;\n    end if;\n    E_Q_Header.Last := enode_var;\n  end Queue;\n\n  procedure Do_Tasking_Operation (CD : Compiler_Data; ND : in out Interpreter_Data) is\n    Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n    IR : Order renames ND.IR;\n\n   procedure Do_Accept_Rendezvous is\n      --  Hathorn, Cramer\n      H1, H2, H3 : Integer;\n    begin\n      H1 := Integer (IR.Y);                         --  entry pointer\n      H2 := First_Caller (CD, ND, H1);     --  first waiting task\n      H3 := Integer (CD.id_table (H1).lev);  --  level of accepting entry\n      if H2 >= 0 then\n        --  start rendzv if call is waiting\n        Curr_TCB.DISPLAY (Defs.Nesting_Level (H3 + 1)) := ND.TCB (H2).B; --  address callers\n        --  parms\n        Curr_TCB.InRendzv := H2;  --  indicate that task is in Rendzv\n        if ND.TCB (H2).TS = TimedRendz then\n          ND.TCB (H2).TS := WaitRendzv;\n        end if;\n      else\n        --  or put self to sleep\n        Curr_TCB.SUSPEND := H1;\n        Curr_TCB.TS      := WaitRendzv;      --  status is waiting for\n        --  rendezvous\n        Curr_TCB.PC      := Curr_TCB.PC - 1;          --  do this\n        --  step again when awakened\n\n      end if;\n      ND.SWITCH := True;\n    end Do_Accept_Rendezvous;\n\n    procedure Do_End_Rendezvous is\n      --  Hathorn\n      function Remove_First (Entry_Index : Integer) return TRange is\n        ix, val : Integer;\n        dmy     : Eptr;\n      begin\n        ix := EIndex (CD, Entry_Index);\n        declare\n          E_Q_Header : EHeader renames ND.EList (ix);\n        begin\n          val := E_Q_Header.First.Task_Index;\n          if E_Q_Header.First = E_Q_Header.Last then\n            E_Q_Header.First := null;\n            E_Q_Header.Last  := null;\n          else\n            dmy              := E_Q_Header.First;\n            E_Q_Header.First := E_Q_Header.First.Next;\n            Dispose (dmy);\n          end if;\n        end;\n        return val;\n      end Remove_First;\n      --\n      H1, H2 : Integer;\n    begin\n      Curr_TCB.InRendzv := NilTask;  --  indicate rendezvous has ended\n      H1 := Integer (ND.IR.Y);       --  entry pointer\n      H2 := Remove_First (H1);       --  waiting task pointer\n      if H2 >= 0 then\n        --  wake up waiting task\n        ND.TCB (H2).SUSPEND := 0;\n        ND.TCB (H2).TS      := Ready;\n        ND.SWITCH              := True;\n      end if;\n    end Do_End_Rendezvous;\n\n    procedure Do_Selective_Wait is\n      use type Defs.HAC_Float, Defs.Nesting_Level, Ada.Calendar.Time;\n      H1, H2, H3 : Integer;\n    begin\n      case IR.X is\n        when 1 => --  Start Selective Wait seq.\n          Curr_TCB.R1.I := 0;               --  next instruction if delay expires\n          Curr_TCB.R2   := GR_Real (-1.0);  --  delay time\n\n        when 2 => --  Retain entry ID\n          Curr_TCB.R3.I := IR.Y;\n\n        when 3 => --  Accept if its still on queue\n          H1 := Integer (Curr_TCB.R3.I);\n          H2 := First_Caller (CD, ND, H1);    --  first waiting task\n          H3 := Integer (CD.id_table (H1).lev);     --  level of accepting entry\n          if H2 >= 0 then\n            Curr_TCB.DISPLAY (Defs.Nesting_Level (H3 + 1)) := ND.TCB (H2).B;\n              --  address callers parms\n            Curr_TCB.InRendzv := H2;             --  indicate task InRendz\n            if ND.TCB (H2).TS = TimedRendz then  --  turn off entry timeout\n              ND.TCB (H2).TS := WaitRendzv;      --  if it was on\n            end if;\n          else\n            Curr_TCB.PC := Defs.Index (IR.Y);  --  Jump to patched in address\n          end if;\n          ND.SWITCH := True;\n\n        when 4 => --  Update minimum delay time\n          if ND.S (Curr_TCB.T).R > 0.0 then\n            if Curr_TCB.R2.R = -1.0 then\n              Curr_TCB.R2.R := ND.S (Curr_TCB.T).R;\n              Curr_TCB.R1.I := IR.Y;   --  ins after JMP\n            else\n              if ND.S (Curr_TCB.T).R < Curr_TCB.R2.R then\n                Curr_TCB.R2.R := ND.S (Curr_TCB.T).R;\n                Curr_TCB.R1.I := IR.Y;   --  ins after JMP\n              end if;\n            end if;\n          end if;\n          Pop (ND);\n\n        when 5 | 6 => --  end of SELECT\n\n          if Curr_TCB.R2.R > 0.0 then\n            --  Timed Wait\n            Curr_TCB.TS       := TimedWait;\n            ND.SYSCLOCK       := Ada.Calendar.Clock;\n            Curr_TCB.WAKETIME := ND.SYSCLOCK + Duration (Curr_TCB.R2.R);\n            Curr_TCB.PC       := Defs.Index (IR.Y);  --  Do SELECT again when awakened by caller\n            ND.SWITCH := True;  --  give up control\n          end if;\n          --  AVL -- TERMINATE\n          --  IS THE PARENT TASK COMPLETED?\n          if ND.TCB (0).TS = Completed and then ND.CurTask /= 0 and then IR.X /= 6 then\n            ND.Nb_Callers := 0; --  LET'S SEE IF THERE ARE CALLERS\n            for ITERM in 1 .. CD.Entries_Count loop\n              if ND.EList (ITERM).First /= null then\n                ND.Nb_Callers := ND.Nb_Callers + 1;\n              end if;\n            end loop;\n            --  YES, NO CALLERS\n            if ND.Nb_Callers = 0 then  --  YES, NO CALLERS\n              --  ARE THE SIBLING TASKS EITHER COMPLETED OR\n              --  IN THE SAME STATE AS CURTASK?\n              ND.Nb_Complete := 0;\n              for ITERM in 1 .. CD.Tasks_Definitions_Count loop\n                if ND.TCB (ITERM).TS = Completed then\n                  ND.Nb_Complete := ND.Nb_Complete + 1;\n                else\n                  if ND.TCB (ITERM).TS = Curr_TCB.TS then\n                    ND.Nb_Complete := ND.Nb_Complete + 1;\n                  else\n                    if ND.TCB (ITERM).TS = Ready and then\n                      Curr_TCB.TS = Running\n                    then\n                      ND.Nb_Complete := ND.Nb_Complete + 1;\n                    end if;\n                  end if;\n                end if;\n              end loop;\n              if CD.Tasks_Definitions_Count = ND.Nb_Complete then\n                --  YES, THEN ALL TASKS ARE NOW TERMINATING\n                for ITERM in 1 .. CD.Tasks_Definitions_Count loop\n                  ND.TCB (ITERM).TS := Terminated;\n                end loop;\n                ND.PS := FIN;\n              end if;\n            end if;\n          end if;\n        --               if ir.x = 6 then\n        --               begin\n        --                 term := false ;    {Task doesn't have a terminate}\n        --               end ;                {alternative}\n        --\n\n        when others =>\n          null;  -- [P2Ada]: no otherwise / else in Pascal\n      end case;\n    end Do_Selective_Wait;\n\n    procedure Do_Signal_Semaphore is\n      H1 : constant Integer := Integer (ND.S (Curr_TCB.T).I);\n      H2, H3 : Integer;\n      use Ada.Numerics.Float_Random;\n      use type Defs.HAC_Integer;\n    begin\n      Pop (ND);\n      H2 := CD.Tasks_Definitions_Count + 1;\n      H3 := Integer (Random (ND.Gen) * Float (H2));\n      while H2 >= 0 and then ND.TCB (H3).TS /= WaitSem and then ND.TCB (H3).SUSPEND /= H1\n      loop\n        H3 := (H3 + 1) mod (Defs.TaskMax + 1);\n        H2 := H2 - 1;\n      end loop;\n      if H2 < 0 or else ND.S (H1).I < 0 then\n        ND.S (H1).I := ND.S (H1).I + 1;\n      else\n        ND.TCB (H3).SUSPEND := 0;\n        ND.TCB (H3).TS      := Ready;\n      end if;\n      Curr_TCB.TS := Ready; --  end critical section\n      ND.SWITCH := True;\n    end Do_Signal_Semaphore;\n\n    procedure Do_Wait_Semaphore is\n      H1 : constant Integer := Integer (ND.S (Curr_TCB.T).I);\n      use type Defs.HAC_Integer;\n    begin\n      Pop (ND);\n      if ND.S (H1).I > 0 then\n        ND.S (H1).I := ND.S (H1).I - 1;\n        Curr_TCB.TS := Critical;   --  In a critical section, task gets\n        --  exclusive access to the virtual\n      else\n        --  processor until section ends.\n        Curr_TCB.SUSPEND := H1;\n        Curr_TCB.TS      := WaitSem;\n        ND.SWITCH        := True;\n      end if;\n    end Do_Wait_Semaphore;\n\n    procedure Do_Set_Quantum_Task is\n      use type Defs.HAC_Float;\n    begin\n      --  Cramer\n      if ND.S (Curr_TCB.T).R <= 0.0 then\n        ND.S (Curr_TCB.T).R := Defs.HAC_Float (TSlice);\n      end if;\n      Curr_TCB.QUANTUM := Duration (ND.S (Curr_TCB.T).R);\n      Pop (ND);\n    end Do_Set_Quantum_Task;\n\n    procedure Do_Set_Task_Priority is\n      use type Defs.HAC_Integer;\n    begin\n      --  Cramer\n      if ND.S (Curr_TCB.T).I > Defs.PriMax then\n        ND.S (Curr_TCB.T).I := Defs.PriMax;\n      end if;\n      if ND.S (Curr_TCB.T).I < 0 then\n        ND.S (Curr_TCB.T).I := 0;\n      end if;\n      Curr_TCB.Pcontrol.UPRI := Integer (ND.S (Curr_TCB.T).I);\n      Pop (ND);\n    end Do_Set_Task_Priority;\n\n    procedure Do_Set_Task_Priority_Inheritance is\n      use type Defs.HAC_Integer;\n    begin\n      --  Cramer\n      Curr_TCB.Pcontrol.INHERIT := ND.S (Curr_TCB.T).I /= 0;\n      --  Set priority inherit indicator\n      Pop (ND);\n    end Do_Set_Task_Priority_Inheritance;\n\n    procedure Do_Delay is\n      use type Ada.Calendar.Time;\n    begin\n      if ND.S (Curr_TCB.T).Dur > 0.0 then\n        if ND.Scheduler = Single_Task then\n          ND.Single_Task_Delay_Pending := True;\n        end if;\n        Curr_TCB.TS := Delayed;  --  set task state to delayed\n        ND.SYSCLOCK := Ada.Calendar.Clock;    --  update System Clock\n        Curr_TCB.WAKETIME := ND.SYSCLOCK + ND.S (Curr_TCB.T).Dur;  --  set wakeup time\n        ND.SWITCH := True;          --  give up control\n      end if;\n      Pop (ND);\n    end Do_Delay;\n\n    procedure Do_Halt_Interpreter is\n    begin\n      if ND.TActive = 0 then\n        ND.PS := FIN;\n        --  OK even when PS = Exception_Raised.\n        --  At this point the exception is clearly unhandled.\n      else\n        ND.TCB (0).TS := Completed;\n        ND.SWITCH := True;\n        Curr_TCB.PC := Curr_TCB.PC - 1;\n      end if;\n    end Do_Halt_Interpreter;\n\n  begin\n    case Tasking_Opcode (ND.IR.F) is\n      when k_Accept_Rendezvous             => Do_Accept_Rendezvous;\n      when k_End_Rendezvous                => Do_End_Rendezvous;\n      when k_Wait_Semaphore                => Do_Wait_Semaphore;\n      when k_Signal_Semaphore              => Do_Signal_Semaphore;\n      when k_Set_Quantum_Task              => Do_Set_Quantum_Task;\n      when k_Set_Task_Priority             => Do_Set_Task_Priority;\n      when k_Set_Task_Priority_Inheritance => Do_Set_Task_Priority_Inheritance;\n      when k_Selective_Wait                => Do_Selective_Wait;\n      when k_Delay                         => Do_Delay;\n      when k_Halt_Interpreter              => Do_Halt_Interpreter;\n    end case;\n  end Do_Tasking_Operation;\n\n  procedure Init_main_task (CD : Compiler_Data; ND : in out Interpreter_Data) is\n    use Ada.Numerics.Float_Random;\n    use type Defs.HAC_Integer;\n  begin\n    Reset (ND.Gen);  --  initialize pseudo-random number generator\n    --  After compiled, just begin exec\n    --  Initialize run-time stack\n    ND.S (1).I := 0;\n    ND.S (2).I := 0;\n    ND.S (3).I := -1;\n    ND.S (4).I := Defs.HAC_Integer (CD.main_proc_id_index);\n    declare\n      Main_TCB : Task_Control_Block renames ND.TCB (0);\n    begin\n      Main_TCB.PC := Defs.Index (CD.id_table (CD.main_proc_id_index).adr_or_sz);  --  first pcode instruction\n      Main_TCB.T := CD.Blocks_Table (CD.id_table (CD.main_proc_id_index).block_or_pkg_ref).VSize - 1;\n      Main_TCB.B := 0;\n      Main_TCB.TS := Ready;\n      Main_TCB.InRendzv := NilTask;\n      Main_TCB.DISPLAY (0) := 0;  --  Added for modularity (library-level calls), in 2021\n      Main_TCB.DISPLAY (1) := 0;  --  In Pascal-S.\n      Main_TCB.STACKSIZE := Defs.StMax - (CD.Tasks_Definitions_Count * Defs.STKINCR);\n      Main_TCB.SUSPEND := 0;\n      Main_TCB.QUANTUM := TSlice;\n      Main_TCB.Pcontrol.UPRI := 0;\n      Main_TCB.Pcontrol.INHERIT := False;\n      Main_TCB.LASTRUN := ND.Start_Time;\n      Main_TCB.Exception_Info.Currently_Raised := (No_Exception, 0);\n      Main_TCB.WAKETIME := ND.Start_Time;  --  Added 2020-06-23 for Single_Task\n    end;\n  end Init_main_task;\n\n  procedure Init_other_tasks (CD : Compiler_Data; ND : in out Interpreter_Data) is\n    H1 : Integer;\n    use type Defs.HAC_Integer;\n  begin\n    for Task_To_Init in 1 .. CD.Tasks_Definitions_Count loop\n      declare\n        Curr_TCB : Task_Control_Block renames ND.TCB (Task_To_Init);\n      begin\n        H1 := CD.Tasks_Definitions_Table (Task_To_Init);\n        Curr_TCB.PC := Defs.Index (CD.id_table (H1).adr_or_sz);\n        Curr_TCB.B := ND.TCB (Task_To_Init - 1).STACKSIZE + 1;\n        Curr_TCB.T := Curr_TCB.B + CD.Blocks_Table (CD.id_table (H1).block_or_pkg_ref).VSize - 1;\n        ND.S (Curr_TCB.B + 1).I := 0;\n        ND.S (Curr_TCB.B + 2).I := 0;\n        ND.S (Curr_TCB.B + 3).I := -1;\n        ND.S (Curr_TCB.B + 4).I := Defs.HAC_Integer (H1);\n        Curr_TCB.DISPLAY (1) := 0;\n        Curr_TCB.DISPLAY (2) := Curr_TCB.B;\n        Curr_TCB.STACKSIZE := Curr_TCB.B + Defs.STKINCR - 1;\n        Curr_TCB.SUSPEND := 0;\n        Curr_TCB.TS := Ready;\n        Curr_TCB.InRendzv := NilTask;\n        Curr_TCB.QUANTUM := TSlice;\n        Curr_TCB.Pcontrol.UPRI := 0;\n        Curr_TCB.Pcontrol.INHERIT := False;\n        Curr_TCB.LASTRUN := ND.Start_Time;\n        Curr_TCB.Exception_Info.Currently_Raised := (No_Exception, 0);\n      end;\n    end loop;\n    --  Initially no queued entry calls\n    for E_Idx in 1 .. CD.Entries_Count loop\n      ND.EList (E_Idx).Task_Index := TRange (CD.id_table (CD.Entries_Table (E_Idx)).adr_or_sz);  --  Task index\n      ND.EList (E_Idx).First := null;\n      ND.EList (E_Idx).Last  := null;\n    end loop;\n    ND.TActive   := CD.Tasks_Definitions_Count;  --  All tasks are active initially\n    ND.Scheduler := (if ND.TActive = 0 then Single_Task else 1);\n    ND.CurTask   := 0;  --  IT WAS -1 ?\n    ND.SWITCH    := True;\n    ND.TIMER     := ND.Start_Time;  --  was 0.0\n    ND.PS        := Running;\n  end Init_other_tasks;\n\n  procedure ShowQ (\n    CD          : Compiler_Data;\n    ND          : in out Interpreter_Data;\n    Entry_Index : Integer\n  )\n  is\n    ix : constant Integer := EIndex (CD, Entry_Index);\n    p  : Eptr := ND.EList (ix).First;\n    use Defs, Ada.Text_IO;\n  begin\n    Put (\"Dumping q for entry \" & A2S (CD.id_table (Entry_Index).name) & \" entry index=\");\n    IIO.Put (HAC_Integer (ix));\n    New_Line;\n    if p = null then\n      Put (\"*** EMPTY ***\");\n      New_Line;\n    else\n      loop\n        Put (\"Task \");\n        Put (A2S (CD.id_table (CD.Tasks_Definitions_Table (p.Task_Index)).name));\n        New_Line;\n        p := p.Next;\n        exit when p = null;\n      end loop;\n    end if;\n  end ShowQ;\n\n  procedure Wake_Tasks (\n    CD     :        Compiler_Data;\n    ND     : in out Interpreter_Data;\n    Result :    out Boolean\n  )\n  is\n    procedure Purge (Entry_Index : Integer; t : TRange) is\n      p, q : Eptr;     --  has timed out, the entry\n      ix : Integer;     --  is purged from the q.\n    begin\n      ix := EIndex (CD, Entry_Index);\n      q  := null;\n      p  := ND.EList (ix).First;\n      while p /= null loop\n        if p.Task_Index = t then\n          if ND.EList (ix).First = ND. EList (ix).Last then\n            ND.EList (ix).First := null;\n            ND.EList (ix).Last  := null;\n          else\n            if p = ND.EList (ix).First then\n              ND.EList (ix).First := p.Next;\n            else\n              if p = ND.EList (ix).Last then\n                ND.EList (ix).Last := q;\n                q.Next      := null;\n              else\n                q.Next := p.Next;\n              end if;\n            end if;\n          end if;\n          Dispose (p);\n          p := null;  --  to exit loop\n        else\n          --  try next entry in list\n          q := p;\n          p := p.Next;\n        end if;\n      end loop;\n    end Purge;\n    --\n    count : Integer := 0;\n    use type Ada.Calendar.Time;\n  begin\n    for t in 0 .. CD.Tasks_Definitions_Count loop\n      if (ND.TCB (t).TS = Delayed or else\n          ND.TCB (t).TS = TimedRendz or else\n          ND.TCB (t).TS = TimedWait)\n        and then\n          ND.SYSCLOCK >= ND.TCB (t).WAKETIME\n      then\n        if ND.TCB (t).TS = TimedRendz then\n          ND.TCB (t).R1.I := 0;  --  timeout on rendezvous\n          Purge (Integer (ND.TCB (t).R2.I), t);  --  remove from callee's q\n        end if;\n        if ND.TCB (t).TS = TimedWait then\n          ND.TCB (t).PC := Defs.Index (ND.TCB (t).R1.I);  --  t.out on accept\n        end if;\n        ND.TCB (t).TS := Ready;\n        count := count + 1;\n      end if;\n    end loop;\n    Result := count > 0;\n  end Wake_Tasks;\n\n  procedure ShowTime is null;\n  procedure SnapShot is null;\n\n  procedure Scheduler (CD : Compiler_Data; ND : in out Interpreter_Data) is separate;\n\n  procedure Manage_Scheduling (CD : Compiler_Data; ND : in out Interpreter_Data) is\n    were_tasks_awakened : Boolean;\n    use Ada.Calendar;\n  begin\n    ND.SYSCLOCK := Clock;\n    if ND.Snap then\n      ShowTime;\n    end if;\n    if ND.TCB (ND.CurTask).TS = Critical then  --  SmallAda inter.pas line 456\n      if ND.Snap then\n        SnapShot;\n      end if;\n    else\n      Wake_Tasks (CD, ND, were_tasks_awakened);\n      if ND.SWITCH or else       --  ------------> Voluntary release of control\n         ND.SYSCLOCK >= ND.TIMER or else   --  ---> Time slice exceeded\n         were_tasks_awakened           --  ------> Awakened task causes switch\n      then\n        if ND.CurTask >= 0 then\n          ND.TCB (ND.CurTask).LASTRUN := ND.SYSCLOCK;\n          if ND.TCB (ND.CurTask).TS = Running then\n            ND.TCB (ND.CurTask).TS := Ready;\n            --  SWITCH PROCCESS\n          end if;\n        end if;\n        loop  --  Call Main Scheduler (SmallAda inter.pas line 479):\n          Scheduler (CD, ND);\n          ND.SYSCLOCK := Clock;\n          if ND.Snap then\n            ShowTime;\n          end if;\n          if ND.Snap then\n            SnapShot;\n          end if;\n          exit when ND.PS /= WAIT;\n        end loop;\n        --\n        if ND.PS = DEADLOCK or ND.PS = FIN then\n          return;\n        end if;\n        --\n        ND.TIMER := ND.SYSCLOCK + ND.TCB (ND.CurTask).QUANTUM;\n        ND.TCB (ND.CurTask).TS := Running;\n        ND.SWITCH := False;\n        if ND.Snap then\n          SnapShot;\n        end if;\n      end if;\n    end if;\n  end Manage_Scheduling;\n\nend HAC_Sys.PCode.Interpreter.Tasking;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter-tasking.ads",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\nprivate package HAC_Sys.PCode.Interpreter.Tasking is\n  use Co_Defs, In_Defs;\n\n  -----------------------\n  --  VM Instructions  --\n  -----------------------\n\n  --  Execute tasking instruction stored as Opcode in ND.IR.F.\n  --  ND.IR.F is in the Tasking_Opcode subtype range.\n  procedure Do_Tasking_Operation (CD : Compiler_Data; ND : in out Interpreter_Data);\n\n  -------------\n  --  Misc.  --\n  -------------\n\n  function Any_Task_Delayed (CD : Compiler_Data; ND : Interpreter_Data) return Boolean;\n\n  function EIndex (CD : Compiler_Data; Entry_Index : Integer) return Integer;\n\n  procedure Init_main_task (CD : Compiler_Data; ND : in out Interpreter_Data);\n  procedure Init_other_tasks (CD : Compiler_Data; ND : in out Interpreter_Data);\n\n  procedure Queue (\n    CD           :        Compiler_Data;\n    ND           : in out Interpreter_Data;\n    Entry_Index  :        Integer;\n    Calling_Task :        TRange\n  );\n\n  procedure ShowQ (\n    CD          : Compiler_Data;\n    ND          : in out Interpreter_Data;\n    Entry_Index : Integer\n  );\n\n  procedure Wake_Tasks (\n    CD     :        Compiler_Data;\n    ND     : in out Interpreter_Data;\n    Result :    out Boolean\n  );\n\n  --  Default Task time-slice in seconds\n  --  Feldman: 60ths of a sec on Mac\n  TSlice : constant Duration := 0.016666666;\n\n  procedure Manage_Scheduling (CD : Compiler_Data; ND : in out Interpreter_Data);\n\nend HAC_Sys.PCode.Interpreter.Tasking;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter.adb",
    "content": "with HAC_Sys.Co_Defs,\n     HAC_Sys.Interfacing,\n     HAC_Sys.PCode.Interpreter.Calls,\n     HAC_Sys.PCode.Interpreter.Composite_Data,\n     HAC_Sys.PCode.Interpreter.Exceptions,\n     HAC_Sys.PCode.Interpreter.In_Defs,\n     HAC_Sys.PCode.Interpreter.Multi_Statement,\n     HAC_Sys.PCode.Interpreter.Operators,\n     HAC_Sys.PCode.Interpreter.Tasking;\n\nwith HAT;\n\nwith Ada.Characters.Handling,\n     Ada.Command_Line,\n     Ada.Exceptions,\n     Ada.IO_Exceptions;\n\npackage body HAC_Sys.PCode.Interpreter is\n\n  procedure Interpret (\n    BD          : in out Builder.Build_Data;  --  Everything is compiled and ready to run\n    Post_Mortem :    out Post_Mortem_Data\n  )\n  is\n    ND : In_Defs.Interpreter_Data;\n    CD : Co_Defs.Compiler_Data renames BD.CD.all;\n\n    use Co_Defs, Defs, In_Defs, Exceptions;\n\n    procedure Pop (Amount : Positive := 1) is  begin Pop (ND, Amount); end Pop;\n    procedure Push (Amount : Positive := 1) is begin Push (ND, Amount); end Push;\n\n    procedure Start_Interpreter is\n    begin\n      ND.S             := new Stack_Type;\n      ND.PS            := Running;\n      ND.Start_Time    := Ada.Calendar.Clock;\n      ND.Snap          := False;\n      ND.SWITCH        := False;           --  invoke scheduler on next cycle flag\n      ND.SYSCLOCK      := ND.Start_Time;\n      ND.TIMER         := ND.SYSCLOCK;     --  set to end of current task's time slice\n      ND.feedback_tick := 1;\n      Tasking.Init_main_task (BD.CD.all, ND);\n      Tasking.Init_other_tasks (BD.CD.all, ND);\n      Post_Mortem.Max_Stack_Usage := 0;\n    end Start_Interpreter;\n\n    procedure Do_HAT_Function is\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      Top_Item : General_Register renames ND.S (Curr_TCB.T);\n      Code : constant SF_Code := SF_Code'Val (ND.IR.Y);\n      use type Operand_1_Type;\n    begin\n      case Code is\n        when SF_File_or_Console_Information =>\n          if ND.IR.X = 0 then  --  Niladic File info function -> abstract console\n            Push;\n            case SF_File_or_Console_Information (Code) is\n              when SF_EOF  => ND.S (Curr_TCB.T).I := Boolean'Pos (Console.End_Of_File);\n              when SF_EOLN => ND.S (Curr_TCB.T).I := Boolean'Pos (Console.End_Of_Line);\n            end case;\n          else\n            case SF_File_or_Console_Information (Code) is\n              when SF_EOF =>\n                ND.S (Curr_TCB.T).I := Boolean'Pos (HAT.End_Of_File (ND.S (Curr_TCB.T).Txt.all));\n              when SF_EOLN =>\n                ND.S (Curr_TCB.T).I := Boolean'Pos (HAT.End_Of_Line (ND.S (Curr_TCB.T).Txt.all));\n            end case;\n          end if;\n        when SF_Argument =>\n          --  The stack top item may change its type here.\n          declare\n            arg_i : constant Integer := Integer (Top_Item.I);\n          begin\n            if arg_i not in 1 .. System_Calls.Argument_Count then\n              Raise_Standard (ND, VME_Constraint_Error,\n                \"Argument number not in 1 .. Argument_Count\", True);\n            end if;\n            Top_Item := GR_VString (System_Calls.Argument (arg_i));\n          end;\n        when SF_Argument_Count =>\n          Push;  --  Niladic function, needs to push a new item (their own result).\n          ND.S (Curr_TCB.T).I := HAC_Integer (System_Calls.Argument_Count);\n        when SF_Command_Name =>\n          Push;  --  Niladic function, needs to push a new item (their own result).\n          ND.S (Curr_TCB.T) := GR_VString (System_Calls.Command_Name);\n        when SF_Directory_Separator =>\n          Push;  --  Niladic function, needs to push a new item (their own result).\n          ND.S (Curr_TCB.T).I := Character'Pos (System_Calls.Directory_Separator);\n        when SF_Current_Directory =>\n          Push;  --  Niladic function, needs to push a new item (their own result).\n          ND.S (Curr_TCB.T) := GR_VString (HAT.Current_Directory);\n        when SF_Get_Needs_Skip_Line =>\n          Push;  --  Niladic function, needs to push a new item (their own result).\n          ND.S (Curr_TCB.T).I := Boolean'Pos (Console.Get_Needs_Skip_Line);\n        when others =>\n          Operators.Do_SF_Operator (BD, ND);  --  Doesn't need generic stuff.\n      end case;\n    end Do_HAT_Function;\n\n    procedure Do_Text_Read (Code : SP_Code) is\n      CH : Character;\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      Out_Param : constant Index := Index (ND.S (Curr_TCB.T).I);\n      Typ : Typen;\n      Immediate : constant Boolean := Code = SP_Get_Immediate;\n      FP : File_Ptr;\n      String_Length_Decoding : Operand_2_Type;\n      use type Operand_2_Type;\n    begin\n      Typ := Typen'Val (ND.IR.Y mod (2 ** Typen'Size));\n      if Code in SP_Get .. SP_Get_Line then\n        --  The End_Of_File_Console check is skipped here (disturbs GNAT's run-time).\n        case Typ is\n          when Ints     => Console.Get (ND.S (Out_Param).I);\n          when Floats   =>\n            ND.S (Out_Param) := GR_Real (0.0);  --  First, switch type to Floats.\n            Console.Get (ND.S (Out_Param).R);\n          when VStrings => ND.S (Out_Param) := GR_VString (Console.Get_Line);\n          when Chars    =>\n            if Immediate then\n              Console.Get_Immediate (CH);\n            else\n              Console.Get (CH);\n            end if;\n            ND.S (Out_Param).I := Character'Pos (CH);\n          when Arrays =>\n            --  We have a String, with a given length.\n            String_Length_Decoding := ND.IR.Y / (2 ** Typen'Size);\n            for i in 1 .. Index (String_Length_Decoding) loop\n              Console.Get (CH);\n              ND.S (Out_Param + i - 1).I := Character'Pos (CH);\n            end loop;\n          when others =>\n            null;\n        end case;\n        if Code = SP_Get_Line and Typ /= VStrings then\n          Console.Skip_Line;\n        end if;\n        Pop;\n      else\n        FP := ND.S (Curr_TCB.T - 1).Txt;\n        if Ada.Text_IO.End_Of_File (FP.all) then\n          raise VM_End_Error;\n        end if;\n        case Typ is\n          when Ints =>\n            Defs.IIO.Get (FP.all, ND.S (Out_Param).I);\n          when Floats =>\n            declare\n              the_value : Defs.HAC_Float;\n            begin\n              Defs.RIO.Get (FP.all, the_value);\n              ND.S (Out_Param) := GR_Real (the_value);\n            end;\n          when Chars =>\n            Ada.Text_IO.Get (FP.all, CH);\n            ND.S (Out_Param).I := Character'Pos (CH);\n          when VStrings =>\n            ND.S (Out_Param) := GR_VString (Ada.Text_IO.Get_Line (FP.all));\n          when Arrays =>\n            --  We have a String, with a given length.\n            String_Length_Decoding := ND.IR.Y / (2 ** Typen'Size);\n            for i in 1 .. Index (String_Length_Decoding) loop\n              --  A.10.7 (15): \"Determines the length of the given string and\n              --  attempts that number of Get operations for successive\n              --  characters of the string (in particular, no operation\n              --  is performed if the string is null).\"\n              if Ada.Text_IO.End_Of_File (FP.all) then\n                raise VM_End_Error;\n              end if;\n              Ada.Text_IO.Get (FP.all, CH);\n              ND.S (Out_Param + i - 1).I := Character'Pos (CH);\n            end loop;\n          when others =>\n            null;\n        end case;\n        if Code = SP_Get_Line_File and Typ /= VStrings then\n          Ada.Text_IO.Skip_Line (FP.all);\n        end if;\n        Pop (2);\n      end if;\n      ND.SWITCH := True;  --  give up control when doing I/O\n    exception\n      when E : Constraint_Error =>\n        Raise_Standard (ND, VME_Constraint_Error, Ada.Exceptions.Exception_Message (E), True);\n      when E : Ada.IO_Exceptions.Data_Error =>\n        Raise_Standard (ND, VME_Data_Error, Ada.Exceptions.Exception_Message (E), True);\n    end Do_Text_Read;\n\n    procedure Do_Write_Formatted (Code : SP_Code) is\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      FP       : File_Ptr;\n      item_typ : constant Typen := Typen'Val (ND.IR.Y);\n      --  Parameters used: see default_extra_put_param in HAC.Parser.Standard_Procedures.\n      all_params : Positive;\n      pos : Positive := 1;\n      len : Natural  := 0;\n      use Ada.Text_IO;\n    begin\n      case item_typ is\n        when Ints            => all_params := 3;\n        when Floats          => all_params := 4;\n        when Bools           => all_params := 2;\n        when String_Literals => all_params := 2;  --  Position and length\n                                pos := Integer (ND.S (Curr_TCB.T).I);\n                                len := Integer (ND.S (Curr_TCB.T - 1).I);\n        when Arrays          => all_params := 2;  --  Address and size\n        when others          => all_params := 1;  --  Chars, VStrings, ...\n      end case;\n      if Code in SP_Put .. SP_Put_Line then\n        case item_typ is\n          when Ints =>\n            Console.Put\n              (I     =>              ND.S (Curr_TCB.T - 2).I,\n               Width => Field       (ND.S (Curr_TCB.T - 1).I),\n               Base  => Number_Base (ND.S (Curr_TCB.T).I));\n          when Floats =>\n            Console.Put\n              (F    =>        ND.S (Curr_TCB.T - 3).R,\n               Fore => Field (ND.S (Curr_TCB.T - 2).I),\n               Aft  => Field (ND.S (Curr_TCB.T - 1).I),\n               Exp  => Field (ND.S (Curr_TCB.T).I));\n          when Bools =>\n            Console.Put\n              (B     => Boolean'Val (ND.S (Curr_TCB.T - 1).I),\n               Width => Field       (ND.S (Curr_TCB.T).I));\n               --  !! But there is also a \"Set\" parameter.\n          when Chars =>\n            Console.Put (Character'Val (ND.S (Curr_TCB.T).I));\n          when VStrings |\n               Strings_as_VStrings =>\n            Console.Put (HAT.VStr_Pkg.To_String (ND.S (Curr_TCB.T).V));\n          when String_Literals =>\n            Console.Put (CD.Strings_Constants_Table (pos .. pos + len - 1));\n          when Arrays =>\n            Console.Put\n              (Get_String_from_Stack\n                (ND,\n                 Integer (ND.S (Curr_TCB.T - 1).I),\n                 Integer (ND.S (Curr_TCB.T).I)));\n          when others =>\n            null;\n        end case;\n        if Code = SP_Put_Line then\n          Console.New_Line;\n        end if;\n      else\n        FP := ND.S (Curr_TCB.T - all_params).Txt;\n        case item_typ is\n          when Ints =>\n            IIO.Put\n              (FP.all,\n               Item  =>              ND.S (Curr_TCB.T - 2).I,\n               Width => Field       (ND.S (Curr_TCB.T - 1).I),\n               Base  => Number_Base (ND.S (Curr_TCB.T).I));\n          when Floats =>\n            RIO.Put\n              (FP.all,\n               Item =>        ND.S (Curr_TCB.T - 3).R,\n               Fore => Field (ND.S (Curr_TCB.T - 2).I),\n               Aft  => Field (ND.S (Curr_TCB.T - 1).I),\n               Exp  => Field (ND.S (Curr_TCB.T).I));\n          when Bools =>\n            BIO.Put\n              (FP.all,\n               Item  => Boolean'Val (ND.S (Curr_TCB.T - 1).I),\n               Width => Field       (ND.S (Curr_TCB.T).I));\n               --  !! But there is also a \"Set\" parameter.\n          when Chars =>\n            HAT.Put (FP.all, Character'Val (ND.S (Curr_TCB.T).I));\n          when VStrings |\n               Strings_as_VStrings =>\n            HAT.Put (FP.all, HAT.VStr_Pkg.To_String (ND.S (Curr_TCB.T).V));\n          when String_Literals     =>\n            HAT.Put (FP.all, CD.Strings_Constants_Table (pos .. pos + len - 1));\n          when Arrays =>\n            HAT.Put\n              (FP.all,\n               Get_String_from_Stack\n                 (ND,\n                  Integer (ND.S (Curr_TCB.T - 1).I),\n                  Integer (ND.S (Curr_TCB.T).I)));\n          when others =>\n            null;\n        end case;\n        if Code = SP_Put_Line_File then\n          Ada.Text_IO.New_Line (FP.all);\n        end if;\n        all_params := all_params + 1;  --  Count the file parameter for popping.\n      end if;\n      Pop (all_params);\n      ND.SWITCH := True;  --  give up control when doing I/O\n    end Do_Write_Formatted;\n\n    procedure Do_Code_for_Automatic_Initialization is\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      Var_Addr : constant Index := Index (ND.S (Curr_TCB.T).I);\n    begin\n      case Typen'Val (ND.IR.Y) is\n        when VStrings   => ND.S (Var_Addr) := GR_VString (HAT.Null_VString);\n        when Text_Files => Allocate_Text_File (ND, ND.S (Var_Addr));\n        when others     => null;\n      end case;\n      Pop;\n    end Do_Code_for_Automatic_Initialization;\n\n    procedure Do_HAT_Procedure is\n      Code : constant SP_Code := SP_Code'Val (ND.IR.X);\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      Top_Item       : General_Register renames ND.S (Curr_TCB.T);\n      Below_Top_Item : General_Register renames ND.S (Curr_TCB.T - 1);\n      use HAT.VStr_Pkg;\n      use type Defs.HAC_Integer;\n      Lines : Ada.Text_IO.Positive_Count;\n      Shell_Exec_Result : Integer;\n      --\n      --  !!  Workaround for the non-initialization of files in records\n      --      and arrays (bug #2). We can remove this late initialization\n      --      when general implicit initialization (including for composite\n      --      types: arrays, records) is implemented.\n      --      When the memory cell already contains a Text_Files,\n      --      if the previous owner forgot to close the file, we get\n      --      a Status_Error instead of a Use_Error.\n      --\n      procedure Switch_to_Text_Files (M : in out General_Register) is\n      begin\n        if M.Special /= Defs.Text_Files then\n          Allocate_Text_File (ND, M);\n        end if;\n      end Switch_to_Text_Files;\n\n      through : Integer;\n\n    begin\n      case Code is\n        when SP_Copy_File        => HAT.Copy_File (Below_Top_Item.V, Top_Item.V);\n        when SP_Create_Directory => HAT.Create_Directory (Top_Item.V);\n        when SP_Create_Path      => HAT.Create_Path (Top_Item.V);\n        when SP_Delete_Directory => HAT.Delete_Directory (Top_Item.V);\n        when SP_Delete_File      => HAT.Delete_File (Top_Item.V);\n        when SP_Rename           => HAT.Rename (Below_Top_Item.V, Top_Item.V);\n        when SP_Set_Directory    => HAT.Set_Directory (Top_Item.V);\n        when SP_Set_Env          => HAT.Set_Env (Below_Top_Item.V, Top_Item.V);\n        when SP_Set_Exit_Status  => HAT.Set_Exit_Status (Integer (Top_Item.I));\n        --\n        when SP_Set_VM_Variable  =>\n          Interfacing.Set_VM_Variable\n            (BD, To_String (Below_Top_Item.V), To_String (Top_Item.V));\n        when SP_Delete =>\n          through := Integer (Top_Item.I);\n          if through > HAT.Length (ND.S (Defs.Index (ND.S (Curr_TCB.T - 2).I)).V) then\n            Raise_Standard\n              (ND, VME_Index_Error,\n               \"Delete: Through, \" & through'Image &\n               \", is larger than Length (Source)\", True);\n          end if;\n          HAT.Delete\n            (Source  => ND.S (Defs.Index (ND.S (Curr_TCB.T - 2).I)).V,\n             From    => Integer (Below_Top_Item.I),\n             Through => through);\n        --\n        when SP_Create =>\n          Switch_to_Text_Files (ND.S (Defs.Index (Below_Top_Item.I)));\n          HAT.Create (ND.S (Defs.Index (Below_Top_Item.I)).Txt.all, Top_Item.V);\n        when SP_Open =>\n          Switch_to_Text_Files (ND.S (Defs.Index (Below_Top_Item.I)));\n          HAT.Open (ND.S (Defs.Index (Below_Top_Item.I)).Txt.all, Top_Item.V);\n        when SP_Append =>\n          Switch_to_Text_Files (ND.S (Defs.Index (Below_Top_Item.I)));\n          HAT.Append (ND.S (Defs.Index (Below_Top_Item.I)).Txt.all, Top_Item.V);\n        when SP_Close =>\n          Check_Discriminant_Type (ND.S (Defs.Index (Top_Item.I)), Defs.Text_Files);\n          HAT.Close (ND.S (Defs.Index (Top_Item.I)).Txt.all);\n        when SP_Push_Abstract_Console =>\n          Push;\n          ND.S (Curr_TCB.T) := GR_Abstract_Console;\n        when SP_Get | SP_Get_Immediate | SP_Get_Line | SP_Get_File | SP_Get_Line_File =>\n          Do_Text_Read (Code);\n        when SP_Put .. SP_Put_Line_File =>\n          Do_Write_Formatted (Code);\n        when SP_New_Line =>\n          Lines := Ada.Text_IO.Positive_Count (Top_Item.I);\n          if Below_Top_Item.Txt = Abstract_Console then\n            Console.New_Line (Lines);\n          else\n            HAT.New_Line (Below_Top_Item.Txt.all, Lines);\n          end if;\n        when SP_Skip_Line =>\n          Lines := Ada.Text_IO.Positive_Count (Top_Item.I);\n          if Below_Top_Item.Txt = Abstract_Console then\n            --  The End_Of_File_Console check is skipped here (disturbs GNAT's run-time).\n            Console.Skip_Line (Lines);\n          elsif HAT.End_Of_File (Below_Top_Item.Txt.all) then\n            raise VM_End_Error;\n          else\n            HAT.Skip_Line (Below_Top_Item.Txt.all, Lines);\n          end if;\n          ND.feedback_tick := 0;  --  Force feedback before next instruction.\n        when SP_Shell_Execute_without_Result =>\n          declare\n            Command : constant String := To_String (Top_Item.V);\n          begin\n            System_Calls.Shell_Execute (Command, Shell_Exec_Result);\n          end;\n        when SP_Shell_Execute_with_Result =>\n          declare\n            Command        : constant String     := To_String (Below_Top_Item.V);\n            Result_Address : constant Defs.Index := Defs.Index (Top_Item.I);\n          begin\n            System_Calls.Shell_Execute (Command, Shell_Exec_Result);\n            ND.S (Result_Address).I := Defs.HAC_Integer (Shell_Exec_Result);\n          end;\n        when SP_Shell_Execute_Output =>\n          declare\n            Command           : constant String     := To_String (Below_Top_Item.V);\n            Output_Address    : constant Defs.Index := Defs.Index (Top_Item.I);\n            Shell_Exec_Output : HAT.VString;\n          begin\n            System_Calls.Shell_Execute_Output (Command, Shell_Exec_Result, Shell_Exec_Output);\n            ND.S (Output_Address) := GR_VString (Shell_Exec_Output);\n          end;\n        when SP_Shell_Execute_Result_Output =>\n          declare\n            Command           : constant String     := To_String (ND.S (Curr_TCB.T - 2).V);\n            Result_Address    : constant Defs.Index := Defs.Index (Below_Top_Item.I);\n            Output_Address    : constant Defs.Index := Defs.Index (Top_Item.I);\n            Shell_Exec_Output : HAT.VString;\n          begin\n            System_Calls.Shell_Execute_Output (Command, Shell_Exec_Result, Shell_Exec_Output);\n            ND.S (Result_Address).I := Defs.HAC_Integer (Shell_Exec_Result);\n            ND.S (Output_Address)   := GR_VString (Shell_Exec_Output);\n          end;\n        when SP_Randomize =>\n          HAT.Randomize;\n        when SP_Random_Seed =>\n          HAT.Random_Seed (Integer (Top_Item.I mod (2 ** (Integer'Size - 1))));\n        when SP_Wait | SP_Signal | SP_Priority | SP_InheritP | SP_Quantum =>\n          null;\n      end case;\n      --  Release the stack:\n      case Code is\n        when SP_Close | SP_Delete_File | SP_Set_Directory | SP_Set_Exit_Status |\n             SP_Shell_Execute_without_Result |\n             SP_Random_Seed\n        =>\n          Pop;\n        when SP_Open | SP_Append | SP_Create | SP_Set_Env | SP_Copy_File |\n             SP_Rename | SP_New_Line | SP_Skip_Line |\n             SP_Shell_Execute_with_Result | SP_Shell_Execute_Output\n        =>\n          Pop (2);\n        when SP_Shell_Execute_Result_Output | SP_Delete =>\n          Pop (3);\n        when others =>\n          null;\n      end case;\n      ND.SWITCH := True;  --  give up control when doing I/O\n    exception\n      when Ada.Text_IO.Name_Error =>\n        case Code is\n          when SP_Open | SP_Create | SP_Append =>\n            Raise_Standard (ND, VME_Name_Error,\n              \"File not found, or invalid name: \" & To_String (Top_Item.V), True);\n          when others =>\n            Raise_Standard (ND, VME_Name_Error, Stop_Current_Instruction => True);\n        end case;\n      when E : Ada.Text_IO.Mode_Error =>\n        Raise_Standard (ND, VME_Mode_Error, Ada.Exceptions.Exception_Message (E));\n      when E : Ada.Text_IO.Status_Error =>\n        case Code is\n          when SP_Open | SP_Create | SP_Append =>\n            Raise_Standard (ND, VME_Status_Error, \"File already open\", True);\n          when SP_Close =>\n            Raise_Standard (ND, VME_Status_Error, \"File not open\", True);\n          when others =>\n            Raise_Standard (ND, VME_Status_Error, \"File not open? [\" &\n              Ada.Exceptions.Exception_Message (E) & ']', True);\n        end case;\n      when Ada.Text_IO.Use_Error =>\n        case Code is\n          when SP_Open | SP_Create | SP_Append =>\n            Raise_Standard (ND, VME_Use_Error,\n              \"Cannot access file: \" & To_String (Top_Item.V), True);\n          when others =>\n            Raise_Standard (ND, VME_Use_Error, Stop_Current_Instruction => True);\n        end case;\n    end Do_HAT_Procedure;\n\n    procedure Add_Stack_Trace_Line (Offset : Natural) is\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      D : Debug_Info renames CD.ObjCode (Curr_TCB.PC - Offset).D;\n      use HAT.VStr_Pkg, Ada.Containers;\n      --  Limit huge trace-backs (likely, recursive calls):\n      max_trace_back_length : constant := 500;\n    begin\n      if D.Full_Block_Id /= Universe\n        and then Curr_TCB.Exception_Info.ST_Message.Length < max_trace_back_length\n      then\n        Curr_TCB.Exception_Info.ST_Message.Append (D);\n      end if;\n    end Add_Stack_Trace_Line;\n\n    procedure Fetch_Instruction with Inline is\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n    begin\n      if ND.PS = Exception_Raised then\n        --  \"Raised\" flag is up, we just skip everything\n        --  except a final return and the start of the\n        --  optional exception handler.\n        --  !! To do: add an exception handler NOP instruction.\n        --  !! To do: skip the intermediate return's, otherwise\n        --     the exception handler won't be reached.\n        while not OK_for_Exception (CD.ObjCode (Curr_TCB.PC).F) loop\n          Curr_TCB.PC := Curr_TCB.PC + 1;\n        end loop;\n      end if;\n      ND.IR := CD.ObjCode (Curr_TCB.PC);\n      Curr_TCB.PC := Curr_TCB.PC + 1;\n    end Fetch_Instruction;\n\n    procedure Execute_Current_Instruction is\n      Curr_TCB : Task_Control_Block renames ND.TCB (ND.CurTask);\n      IR : Order renames ND.IR;\n      use type HAC_Integer;\n      --\n      procedure Do_Atomic_Data_Push_Operation with Inline is\n        Base                : constant Index := Curr_TCB.DISPLAY (Nesting_Level (IR.X));\n        Address_of_Variable : constant Index := Base + Index (IR.Y);\n      begin\n        Push;\n        case Atomic_Data_Push_Opcode (ND.IR.F) is\n          when k_Push_Address =>\n            --  Push \"v'Access\" of variable v\n            ND.S (Curr_TCB.T).I := HAC_Integer (Address_of_Variable);\n          when k_Push_Value =>\n            --  Push variable v's value.\n            ND.S (Curr_TCB.T) := ND.S (Address_of_Variable);\n          when k_Push_Discrete_Value =>\n            --  Push variable v's discrete value.\n            ND.S (Curr_TCB.T).I := ND.S (Address_of_Variable).I;\n          when k_Push_Indirect_Value =>\n            --  Push \"v.all\" (variable v contains an access).\n            ND.S (Curr_TCB.T) := ND.S (Index (ND.S (Address_of_Variable).I));\n          when k_Push_Indirect_Discrete_Value =>\n            --  Discrete variant of k_Push_Indirect_Value.\n            ND.S (Curr_TCB.T).I := ND.S (Index (ND.S (Address_of_Variable).I)).I;\n        end case;\n      end Do_Atomic_Data_Push_Operation;\n      --\n      procedure Do_Literal_Push_Operation with Inline is\n      begin\n        Push;\n        case Literal_Push_Opcode (ND.IR.F) is\n          when k_Push_Discrete_Literal =>\n            --  Literal: discrete value (Integer, Character, Boolean, Enum)\n            ND.S (Curr_TCB.T).I := IR.Y;\n          when k_Push_Float_Literal =>\n            ND.S (Curr_TCB.T) := GR_Real (CD.Float_Constants_Table (Integer (IR.Y)));\n          when k_Push_Float_First =>\n            ND.S (Curr_TCB.T) := GR_Real (HAC_Float'First);\n          when k_Push_Float_Last =>\n            ND.S (Curr_TCB.T) := GR_Real (HAC_Float'Last);\n        end case;\n      end Do_Literal_Push_Operation;\n      --\n      procedure Do_Swap is\n        temp : constant General_Register := ND.S (Curr_TCB.T);\n      begin\n        ND.S (Curr_TCB.T)     := ND.S (Curr_TCB.T - 1);\n        ND.S (Curr_TCB.T - 1) := temp;\n      end Do_Swap;\n      --\n      procedure Check_Lower (bound : HAC_Integer; TYP : Typen; Ref : Index) is\n      pragma Inline (Check_Lower);\n      begin\n        if ND.S (Curr_TCB.T).I < bound then\n          raise VM_Out_of_Range\n            with\n              \": value \" &\n              Discrete_Image (CD, ND.S (Curr_TCB.T).I, TYP, Ref) &\n              \" is below destination (sub)type's lower bound, \" &\n              Discrete_Image (CD, bound, TYP, Ref);\n        end if;\n      end Check_Lower;\n      --\n      procedure Check_Upper (bound : HAC_Integer; TYP : Typen; Ref : Index) is\n      pragma Inline (Check_Upper);\n      begin\n        if ND.S (Curr_TCB.T).I > bound then\n          raise VM_Out_of_Range\n            with\n              \": value \" &\n              Discrete_Image (CD, ND.S (Curr_TCB.T).I, TYP, Ref) &\n              \" is above destination (sub)type's upper bound, \" &\n              Discrete_Image (CD, bound, TYP, Ref);\n        end if;\n      end Check_Upper;\n      --\n      procedure Do_Jump with Inline is\n      begin\n        if IR.Y < 0 then\n          raise Abnormal_Termination with \"Unpatched jump address\";\n        end if;\n        Curr_TCB.PC := Index (IR.Y);\n      end Do_Jump;\n      --\n    begin\n      case ND.IR.F is\n        when k_Store =>  --  [T-1].all := [T], then pop 2x.\n          if Typ_with_Variant_Part (Typen'Val (IR.Y))\n            and then Typen'Val (IR.Y) /= ND.S (Curr_TCB.T).Special\n          then\n            raise VM_Invalid_Data;  --  Source contains uninitialized data.\n          end if;\n          --  NB: we don't check the destination discriminant\n          --  which may be wrong for the right reason, i.e. on first\n          --  assignment to a variable, which has contained garbage\n          --  before the assignment.\n          ND.S (Index (ND.S (Curr_TCB.T - 1).I)) := ND.S (Curr_TCB.T);\n          Pop (2);\n        when k_Store_Discrete =>  --  [T-1].all := [T], then pop 2x.\n          ND.S (Index (ND.S (Curr_TCB.T - 1).I)).I := ND.S (Curr_TCB.T).I;\n          Pop (2);\n        when k_Store_Discrete_Literal =>  --  [T].all := IR.Y, then pop.\n          --  Equivalent to: Push_Discrete_Literal, then Store_Discrete.\n          --  No validity check: the value is discrete.\n          --  Range-checked at compile-time (in current version of HAC\n          --  where all ranges & subtypes are static).\n          --  Future versions: possible range checks would be between\n          --  k_Push_Discrete_Literal and k_Store; then, no folding\n          --  into k_Store_Discrete_Literal.\n          ND.S (Index (ND.S (Curr_TCB.T).I)).I := IR.Y;\n          Pop;\n        when k_Store_Float_Literal =>  --  [T].all := float_table (IR.Y), then pop.\n          ND.S (Index (ND.S (Curr_TCB.T).I)) :=\n            GR_Real (CD.Float_Constants_Table (Integer (IR.Y)));\n          Pop;\n        --\n        when Atomic_Data_Push_Opcode  => Do_Atomic_Data_Push_Operation;\n        when Literal_Push_Opcode      => Do_Literal_Push_Operation;\n        when Composite_Data_Opcode    => Composite_Data.Do_Composite_Data_Operation (CD, ND);\n        when Unary_Operator_Opcode    => Operators.Do_Unary_Operator (ND);\n        when Binary_Operator_Opcode   => Operators.Do_Binary_Operator (ND);\n        when Multiple_Operator_Opcode => Operators.Do_Multiple_Operator (ND);\n        when Special_Operator_Opcode  => Operators.Do_Special_Operator (ND);\n        when Multi_Statement_Opcode   => Multi_Statement.Do_Multi_Statement_Operation (CD, ND);\n        when Calling_Opcode           => Calls.Do_Calling_Operation (CD, ND);\n        when Tasking_Opcode           => Tasking.Do_Tasking_Operation (CD, ND);\n        --\n        when k_Jump =>\n          Do_Jump;\n        when k_Jump_If_Zero_With_Pop =>\n          --  NB: this is the original conditional jump in Pascal-S.\n          if ND.S (Curr_TCB.T).I = 0 then\n            Do_Jump;\n          end if;\n          Pop;  --  NB: the popping happens regardless of the branch.\n        when k_Jump_If_Zero_No_Pop =>\n          if ND.S (Curr_TCB.T).I = 0 then\n            Do_Jump;\n          end if;\n        when k_Jump_If_Non_Zero_No_Pop =>\n          if ND.S (Curr_TCB.T).I /= 0 then\n            Do_Jump;\n          end if;\n        --\n        when k_Check_Lower_Bound => Check_Lower (IR.X, Typen'Val (IR.Y), Index (IR.Z));\n        when k_Check_Upper_Bound => Check_Upper (IR.X, Typen'Val (IR.Y), Index (IR.Z));\n        --\n        when k_Variable_Initialization => Do_Code_for_Automatic_Initialization;\n        when k_HAT_Procedure           => Do_HAT_Procedure;\n        when k_HAT_Function            => Do_HAT_Function;\n        --\n        when k_Pop =>\n          Pop;\n        when k_Swap =>\n          Do_Swap;\n        when k_Pop_to_Temp =>\n          Curr_TCB.R_Temp := ND.S (Curr_TCB.T);\n          Pop;\n        when k_Push_Temp =>\n          Push;\n          ND.S (Curr_TCB.T) := Curr_TCB.R_Temp;\n        when k_Push_Two_Discrete_Literals =>\n          Push (2);\n          ND.S (Curr_TCB.T - 1).I := IR.X;\n          ND.S (Curr_TCB.T).I     := IR.Y;\n        when k_Push_Two_Float_Literals =>\n          Push (2);\n          ND.S (Curr_TCB.T - 1) := GR_Real (CD.Float_Constants_Table (Integer (IR.X)));\n          ND.S (Curr_TCB.T)     := GR_Real (CD.Float_Constants_Table (Integer (IR.Y)));\n      end case;\n    exception\n      when others =>\n        Add_Stack_Trace_Line (Offset => 0);\n        ND.PS := Exception_Raised;\n        raise;\n    end Execute_Current_Instruction;\n\n    procedure Execute_Current_Instruction_with_Exception with Inline is\n      use Ada.Exceptions;\n    begin\n      Execute_Current_Instruction;\n      if ND.PS = Exception_Raised then\n        --  We have just executed a Return, so the last instruction\n        --  (with the program counter back to the caller side), was a Call.\n        Add_Stack_Trace_Line (Offset => 1);\n      end if;\n    exception\n      when VM_Case_Check_Error =>\n        Raise_Standard (ND, VME_Program_Error, \"CASE Statement doesn't cover all cases\");\n      when VM_Constraint_Error =>\n        Raise_Standard (ND, VME_Constraint_Error);\n      when VM_Subprogram_Spec =>\n        Raise_Standard (ND, VME_Program_Error, \"(HAC bug) Unlinked subprogram specification\");\n      when E : VM_Division_by_0 =>\n        Raise_Standard (ND, VME_Constraint_Error, \"Division by 0 (operator: \" & Exception_Message (E) & ')');\n      when VM_End_Error =>\n        Raise_Standard (ND, VME_End_Error, \"\");\n      when VM_Function_End_without_Return =>\n        Raise_Standard (ND, VME_Program_Error, \"Function's end reached without \"\"return\"\" statement\");\n      when VM_Invalid_Data =>\n        Raise_Standard (ND, VME_Constraint_Error, \"Invalid data (maybe due to an uninitialized variable)\");\n      when E : VM_Out_of_Range  =>\n        Raise_Standard (ND, VME_Constraint_Error, \"Out of range\" & Exception_Message (E));\n      when VM_Overflow_Error =>\n        Raise_Standard (ND, VME_Constraint_Error, \"Overflow check failed\");\n      when VM_Stack_Overflow  =>\n        Raise_Standard (ND, VME_Storage_Error, \"Stack overflow\");\n      when VM_Stack_Underflow =>\n        Raise_Standard (ND, VME_Storage_Error, \"Stack underflow\");\n      when VM_Raised_Exception =>\n        null;  --  HAC exception has been already raised (see Name_Error for an example).\n    end Execute_Current_Instruction_with_Exception;\n\n    procedure Single_Task_Delays is\n      User_Aborted : Boolean;\n      use Ada.Calendar, Tasking;\n      wake : constant Time := ND.TCB (ND.CurTask).WAKETIME;\n    begin\n      ND.SYSCLOCK := Clock;\n      if wake > ND.SYSCLOCK then\n        while wake - ND.SYSCLOCK > TSlice loop\n          Feedback\n            (Stack_Current => ND.TCB (ND.CurTask).T,\n             Stack_Total   => ND.S'Last,\n             Wall_Clock    => ND.SYSCLOCK,\n             User_Abort    => User_Aborted);\n          --\n          if User_Aborted then\n            Raise_Standard (ND, VME_User_Abort, \"\");\n          end if;\n          delay TSlice;\n          ND.SYSCLOCK := Clock;\n        end loop;\n        delay Duration'Max (0.0, wake - ND.SYSCLOCK);\n      end if;\n      ND.SWITCH := False;\n      ND.Single_Task_Delay_Pending := False;\n    end Single_Task_Delays;\n\n    User_Aborted : Boolean;\n\n  begin  --  Interpret\n    Start_Interpreter;\n    --\n    Running_State :\n    loop  --  ... until Processor state is not Running or Exception_Raised\n      if ND.Scheduler = Single_Task then\n        if ND.Single_Task_Delay_Pending then\n          Single_Task_Delays;\n        end if;\n      else\n        Tasking.Manage_Scheduling (CD, ND);\n      end if;\n      if ND.feedback_tick = 0 then\n        ND.SYSCLOCK := Ada.Calendar.Clock;\n        Feedback\n          (Stack_Current => ND.TCB (ND.CurTask).T,\n           Stack_Total   => ND.S'Last,\n           Wall_Clock    => ND.SYSCLOCK,\n           User_Abort    => User_Aborted);\n        --\n        if User_Aborted then\n          Raise_Standard (ND, VME_User_Abort, \"\");\n        end if;\n      end if;\n      ND.feedback_tick := ND.feedback_tick + 1;\n      exit Running_State when ND.PS = DEADLOCK or ND.PS = FIN;  --  SmallAda inter.pas line 490\n      --\n      Fetch_Instruction;\n      --  HERE IS THE POINT WHERE THE TASK MONITORING IS CALLED (removed)\n      Execute_Current_Instruction_with_Exception;\n      Post_Mortem.Max_Stack_Usage := Integer'Max (Post_Mortem.Max_Stack_Usage, ND.TCB (ND.CurTask).T);\n      --\n      exit Running_State when ND.PS not in Running_or_in_Exception;\n    end loop Running_State;\n    --\n    if ND.PS not in Exception_Raised .. FIN then\n      Post_Mortem_Dump (CD, ND);\n    end if;\n    --\n    Free_Allocated_Contents (ND, Post_Mortem.Open_Files);\n    --\n    Post_Mortem.Unhandled  := ND.TCB (ND.CurTask).Exception_Info;\n    Post_Mortem.Stack_Size := In_Defs.Stack_Type'Last;\n    --  Use Is_Exception_Raised to check whether an exception was\n    --  unhandled when leaving the interpreter.\n    case ND.PS is\n      when FIN              => null;  --  All good, end reached (can have an unhandled exception).\n      when Running          => null;  --  Should not happen here.\n      when Exception_Raised => null;  --  Unhandled exception information stored in Unhandled.\n      when DEADLOCK         => raise Abnormal_Termination with \"Tasking: Deadlock\";\n      when WAIT             => raise Abnormal_Termination with \"Tasking: Wait\";\n    end case;\n  end Interpret;\n\n  function Current_IO_Get_Needs_Skip_Line return Boolean is\n  begin\n    return True;  --  The input is buffered with Ada.Text_IO.Get (not Get_Immediate).\n  end Current_IO_Get_Needs_Skip_Line;\n\n  procedure Interpret_on_Current_IO (\n    BD_CIO           : in out Builder.Build_Data;  --  Everything is compiled and ready to run\n    Argument_Shift   : in     Natural := 0;   --  Number of arguments to be skipped\n    Full_Script_Name : in     String;         --  This is for Command_Name\n    Post_Mortem      :    out Post_Mortem_Data\n  )\n  is\n\n    procedure No_Feedback (\n      Stack_Current, Stack_Total : in     Natural;\n      Wall_Clock                 : in     Ada.Calendar.Time;\n      User_Abort                 :    out Boolean\n    )\n    is\n    pragma Unreferenced (Stack_Total, Wall_Clock, Stack_Current);\n    begin\n      User_Abort := False;  --  Ctrl-C will make it - in a less polite way...\n    end No_Feedback;\n\n    function Shifted_Argument_Count return Natural is\n    begin\n      return Ada.Command_Line.Argument_Count - Argument_Shift;\n    end Shifted_Argument_Count;\n\n    function Shifted_Argument (Number : Positive) return String is\n    begin\n      return Ada.Command_Line.Argument (Number + Argument_Shift);\n    end Shifted_Argument;\n\n    function Custom_Command_Name return String is\n    begin\n      return Full_Script_Name;\n    end Custom_Command_Name;\n\n    package Current_IO_Console is new\n      Console_Traits\n         (Ada.Text_IO.End_Of_File,\n          Ada.Text_IO.End_Of_Line,\n          Current_IO_Get_Needs_Skip_Line,\n          Defs.IIO.Get,\n          Defs.RIO.Get,\n          Ada.Text_IO.Get,\n          Ada.Text_IO.Get_Immediate,\n          Ada.Text_IO.Get_Line,\n          Ada.Text_IO.Skip_Line,\n          Defs.IIO.Put,\n          Defs.RIO.Put,\n          Defs.BIO.Put,\n          HAT.Put,\n          HAT.Put,\n          Ada.Text_IO.New_Line\n         );\n\n    package Custom_System_Calls is new\n      System_Calls_Traits\n         (Shifted_Argument_Count,\n          Shifted_Argument,\n          Custom_Command_Name,\n          HAT.Shell_Execute,\n          HAT.Shell_Execute,  --  This profile has an Output parameter.\n          HAT.Directory_Separator\n         );\n\n    procedure Interpret_on_Current_IO_Instance is new\n      Interpret\n         (No_Feedback,\n          Current_IO_Console,\n          Custom_System_Calls\n         );\n\n  begin\n    Interpret_on_Current_IO_Instance (BD_CIO, Post_Mortem);\n  end Interpret_on_Current_IO;\n\n  function Image (E : Exception_Propagation_Data) return String is\n    Img : constant String := Exception_Type'Image (E.Currently_Raised.Ex_Typ);\n  begin\n    case E.Currently_Raised.Ex_Typ is\n      when No_Exception =>\n        return \"\";\n      when VME_User_Abort =>\n        return \"User_Abort\";\n      when VME_Custom =>\n        return \"(custom)\";  --  needs to use details\n      when Ada_Error_Exception_Type =>\n        --  Turn the enumerated item identifier, e.g. VME_MODE_ERROR, to \"Mode_Error\":\n        return Img (Img'First + 4) &\n          Ada.Characters.Handling.To_Lower (Img (Img'First + 5 .. Img'Last - 6)) &\n          \"_Error\";\n    end case;\n  end Image;\n\n  function Message (E : Exception_Propagation_Data) return String is\n  begin\n    return HAT.To_String (E.Exception_Message);\n  end Message;\n\n  function Is_Exception_Raised (E : Exception_Propagation_Data) return Boolean is\n  begin\n    return E.Currently_Raised.Ex_Typ /= No_Exception;\n  end Is_Exception_Raised;\n\n  function Is_User_Abort (E : Exception_Propagation_Data) return Boolean is\n  begin\n    return E.Currently_Raised.Ex_Typ = VME_User_Abort;\n  end Is_User_Abort;\n\n  procedure Show_Trace_Back (E : Exception_Propagation_Data) is\n  begin\n    for STL of E.ST_Message loop\n      Show_Line_Information (\n        HAT.To_String (STL.File_Name),\n        HAT.To_String (STL.Full_Block_Id),\n        STL.Line_Number\n      );\n    end loop;\n  end Show_Trace_Back;\n\nend HAC_Sys.PCode.Interpreter;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode-interpreter.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Builder,\n     HAC_Sys.Defs;\n\nwith Ada.Calendar, Ada.Containers.Vectors, Ada.Text_IO;\n\npackage HAC_Sys.PCode.Interpreter is\n\n  ------------------\n  --  Exceptions  --\n  ------------------\n\n  type Exception_Propagation_Data is private;\n\n  function Is_Exception_Raised (E : Exception_Propagation_Data) return Boolean;\n  function Is_User_Abort (E : Exception_Propagation_Data) return Boolean;\n\n  function Image (E : Exception_Propagation_Data) return String;\n  function Message (E : Exception_Propagation_Data) return String;\n\n  generic\n    with procedure Show_Line_Information (\n      File_Name   : String;   --  Example: hac-pcode-interpreter.adb\n      Block_Name  : String;   --  Example: HAC.PCode.Interpreter.Do_Write_Formatted\n      Line_Number : Positive\n    );\n  procedure Show_Trace_Back (E : Exception_Propagation_Data);\n\n  ------------------------\n  --  Post Mortem Data  --\n  ------------------------\n\n  type Open_File_Data is record\n    Name : HAT.VString;\n    Mode : Ada.Text_IO.File_Mode;\n  end record;\n\n  package Open_Files_Vectors is new Ada.Containers.Vectors (Positive, Open_File_Data);\n\n  type Post_Mortem_Data is record\n    Unhandled       : Exception_Propagation_Data;\n    Max_Stack_Usage : Natural;\n    Stack_Size      : Positive;\n    Open_Files      : Open_Files_Vectors.Vector;\n  end record;\n\n  ------------------------------------------------------------------------------\n  --  Here, we provide a ready-to-use, \"standard\" instantiation of the        --\n  --  interpreter, with Ada.Text_IO, Ada.Command_Line, ..., for the console.  --\n  --  See hac.adb for an example where the console interface is used.         --\n  --  See the LEA project for an example where it is *not* used, and a more   --\n  --  sophisticated interface is used instead.                                --\n  ------------------------------------------------------------------------------\n\n  procedure Interpret_on_Current_IO (\n    BD_CIO           : in out Builder.Build_Data;  --  Everything is compiled and ready to run\n    Argument_Shift   : in     Natural := 0;        --  Number of arguments to be skipped\n    Full_Script_Name : in     String;              --  This is for Command_Name\n    Post_Mortem      :    out Post_Mortem_Data\n  );\n\n  --  Part of the subprograms useed for the Interpret_on_Current_IO\n  --  instanciation.\n  --\n  function Current_IO_Get_Needs_Skip_Line return Boolean;\n\n  ---------------------------------------------------------------------------------\n  --  The following version of the interpreter abstracts ALL console Text I/O,   --\n  --  in case we use something else than a standard terminal / console.          --\n  --  Similarily we abstract Argument_Count and a few others.                    --\n  --  See the LEA project for a specific non-trivial (windowed) implementation.  --\n  ---------------------------------------------------------------------------------\n\n  --  Due to the large amount of abstracted subprograms, we wrap\n  --  some groups into \"traits\". The idea is explained here:\n  --  https://blog.adacore.com/traits-based-containers\n  --\n  generic\n    with function End_Of_File return Boolean;\n    with function End_Of_Line return Boolean;\n    with function Get_Needs_Skip_Line return Boolean;\n    --  ^ True  for a real console with Ada.Text_IO (line buffer);\n    --    False for input boxes (like in LEA) or other kind of immediate input.\n    with procedure Get (I : out HAC_Sys.Defs.HAC_Integer; Width : Ada.Text_IO.Field := 0);\n    with procedure Get (F : out HAC_Sys.Defs.HAC_Float;   Width : Ada.Text_IO.Field := 0);\n    with procedure Get (C : out Character);\n    with procedure Get_Immediate (C : out Character);\n    with function Get_Line return String;\n    with procedure Skip_Line (Spacing : Ada.Text_IO.Positive_Count := 1);\n    --\n    with procedure Put (\n      I     : HAC_Sys.Defs.HAC_Integer;\n      Width : Ada.Text_IO.Field       := HAC_Sys.Defs.IIO.Default_Width;\n      Base  : Ada.Text_IO.Number_Base := HAC_Sys.Defs.IIO.Default_Base);\n    with procedure Put (\n      F    : HAC_Sys.Defs.HAC_Float;\n      Fore : Integer := HAC_Sys.Defs.RIO.Default_Fore;\n      Aft  : Integer := HAC_Sys.Defs.RIO.Default_Aft;\n      Exp  : Integer := HAC_Sys.Defs.RIO.Default_Exp\n    );\n    with procedure Put (\n      B     : in Boolean;\n      Width : Ada.Text_IO.Field    := HAC_Sys.Defs.BIO.Default_Width;\n      Set   : Ada.Text_IO.Type_Set := HAC_Sys.Defs.BIO.Default_Setting);\n    with procedure Put (C : in Character);\n    with procedure Put (S : in String);\n    with procedure New_Line (Spacing : Ada.Text_IO.Positive_Count := 1);\n  package Console_Traits is\n  end Console_Traits;\n\n  generic\n    --  Function profiles for Argument* are from Ada.Command_Line (RM A.15).\n    with function Argument_Count return Natural;\n    with function Argument (Number : in Positive) return String;\n    with function Command_Name return String;\n    --  Shell execution, Directory_Separator, ... are also abstracted.\n    with procedure Shell_Execute (Command : String; Result : out Integer);\n    with procedure Shell_Execute_Output (Command : String; Result : out Integer; Output : out HAT.VString);\n    with function Directory_Separator return Character;\n  package System_Calls_Traits is\n  end System_Calls_Traits;\n\n  generic\n    with procedure Feedback\n      (Stack_Current, Stack_Total : in     Natural;\n       Wall_Clock                 : in     Ada.Calendar.Time;\n       User_Abort                 :    out Boolean);\n    with package Console is new Console_Traits (<>);\n    with package System_Calls is new System_Calls_Traits (<>);\n    --\n  procedure Interpret (\n    BD          : in out Builder.Build_Data;  --  Everything is compiled and ready to run\n    Post_Mortem :    out Post_Mortem_Data\n  );\n\n  Abnormal_Termination : exception;\n\n  type Exception_Type is\n    (No_Exception,\n     --  Ada classics:\n     VME_Constraint_Error,\n     VME_Data_Error,\n     VME_End_Error,\n     VME_Index_Error,\n     VME_Mode_Error,\n     VME_Name_Error,\n     VME_Program_Error,\n     VME_Status_Error,\n     VME_Storage_Error,\n     VME_Use_Error,\n     --\n     VME_User_Abort,\n     VME_Custom\n    );\n\n  subtype Ada_Error_Exception_Type is Exception_Type range VME_Constraint_Error .. VME_Use_Error;\n\nprivate\n\n  subtype Exception_Detail is Integer;\n  --  Currently a placeholder (this is for the VME_Custom choice)\n\n  type Exception_Identity is record\n    Ex_Typ : Exception_Type;\n    Detail : Integer;  --  For the VME_Custom choice\n  end record;\n\n  package Stack_Trace_Messages is new Ada.Containers.Vectors (Positive, Debug_Info);\n  subtype Stack_Trace_Message is Stack_Trace_Messages.Vector;\n\n  type Exception_Propagation_Data is record\n    Currently_Raised  : Exception_Identity;\n    ST_Message        : Stack_Trace_Message;\n    Exception_Message : HAT.VString;\n  end record;\n\nend HAC_Sys.PCode.Interpreter;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode.adb",
    "content": "with HAC_Sys.Errors;\n\nwith Ada.Strings.Fixed;\n\npackage body HAC_Sys.PCode is\n\n  --    type ObjData is (\n  --     TabT,\n  --     ATabt,\n  --     BTabt,\n  --     CodeT,\n  --     ECountT,\n  --     EntryTABt,\n  --     FatT,\n  --     FcTabt,\n  --     STabT,\n  --     TCountT,\n  --     TaskTabT);\n  --\n  --    type TArraysTab is array (1 .. AMax) of ATabEntry;\n  --    type TBlockTab is array (1 .. BMax) of BTabEntry;\n  --    type TObjCode is array (0 .. CDMax) of Order;\n  --    type TEntryTAB is array (0 .. EntryMax) of Index;\n  --    type TTskDefTab is array (0 .. TaskMax) of Index;\n  --    type TIdTab is array (0 .. TMax) of TabEntry;\n  --    type TStringTab is array (0 .. SMax) of Character;\n  --    type TFloatPtTab is array (1 .. C2Max) of Float;\n\n  --    type SMAObject (O : ObjData) is record\n  --      case O is\n  --        when ATabt =>      ArraysTab : TArraysTab;\n  --        when BTabt =>      BlockTab : TBlockTab;\n  --        when CodeT =>      ObjCode : TObjCode;\n  --        when ECountT =>    ECount : Integer;\n  --        when EntryTABt =>  EntryTAB : TEntryTAB;\n  --        when FatT =>       FileIOTab : FilDescr;\n  --        when FcTabt =>     FloatPtTab : TFloatPtTab;\n  --        when STabT =>      StringTab : TStringTab;\n  --        when TabT =>       IdTab : TIdTab;\n  --        when TaskTabT =>   TskDefTab : TTskDefTab;\n  --        when TCountT =>    TCount : Integer;\n  --      end case;\n  --    end record;\n\n  --    package OAIO is new Sequential_IO(SMAObject);\n  --    use OAIO;\n\n  --  ** The next three functions are almost identical.\n  --\n  --  * Emit   store an object code for an instruction with no\n  --  *      arguments,\n  --  * Emit1  store an object code for an instruction with one\n  --  *      argument (Y), and\n  --  * Emit2  store an object code for an instruction with two\n  --  *      arguments.\n  --  *\n  --  * Originally it was implemented as three procedures.\n  --  *\n  --  * Emit and Emit1 call Emit2 with 0 for unused arguments\n  --  *\n  --  * Manuel *\n\n  procedure Emit_Instruction (\n    OC          : in out Object_Code_Table;\n    LC          : in out Integer;\n    D           :        Debug_Info;\n    FCT         :        Opcode;\n    a           :        Operand_1_Type;\n    B           :        Operand_2_Type;\n    c           :        Operand_3_Type;\n    folded      :    out Boolean;\n    specialized :    out Boolean\n  )\n  is\n    use type Defs.HAC_Integer;\n    FCT_corr : Opcode := FCT;\n    --\n    --  Replace an instruction by a more specialized instruction.\n    --\n    procedure Try_Specialization is\n      procedure Specialize (new_value : Opcode) with Inline is\n      begin\n        FCT_corr := new_value;\n        specialized := True;\n      end Specialize;\n    begin\n      case FCT_corr is\n        when k_Store =>\n          if Defs.Discrete_Typ (Defs.Typen'Val (B)) then\n            Specialize (k_Store_Discrete);\n          end if;\n        when k_Dereference =>\n          if Defs.Discrete_Typ (Defs.Typen'Val (B)) then\n            Specialize (k_Dereference_Discrete);\n          end if;\n        when others => null;\n      end case;\n    end Try_Specialization;\n    --\n    --  Try folding two instruction into one.\n    --  This technique is only doable within Ada statements,\n    --  otherwise the jumps will be wrong...\n    --\n    procedure Try_Folding is\n      old : Order renames OC (LC - 1);\n      procedure Simple_Substitution\n        (prev_old_value, prev_new_value : Opcode) is\n      pragma Inline (Simple_Substitution);\n      begin\n        if (not folded) and then old.F = prev_old_value then\n          old.F := prev_new_value;\n          folded := True;\n        end if;\n      end Simple_Substitution;\n    begin\n      case FCT_corr is\n        when k_SUBTRACT_Integer => Simple_Substitution (k_Push_Discrete_Literal, k_SUBTRACT_Integer_Literal);\n        when k_MULT_Integer     => Simple_Substitution (k_Push_Discrete_Literal, k_MULT_Integer_Literal);\n        when k_DIV_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_DIV_Integer_Literal);\n        when k_EQL_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_EQL_Integer_Literal);\n        when k_NEQ_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_NEQ_Integer_Literal);\n        when k_LSS_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_LSS_Integer_Literal);\n        when k_LEQ_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_LEQ_Integer_Literal);\n        when k_GTR_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_GTR_Integer_Literal);\n        when k_GEQ_Integer      => Simple_Substitution (k_Push_Discrete_Literal, k_GEQ_Integer_Literal);\n        when k_ADD_Integer =>\n          case old.F is\n            when k_ADD_Integer =>\n              old.F := k_ADD_Integer_Multiple;\n              old.Y := 3;\n              folded := True;\n            when k_ADD_Integer_Multiple =>\n              old.Y := old.Y + 1;\n              folded := True;\n            when others => null;\n          end case;\n          Simple_Substitution (k_MULT_Integer, k_MULT_then_ADD_Integer);\n          Simple_Substitution (k_Push_Discrete_Literal, k_ADD_Integer_Literal);\n        when k_ADD_Float =>\n          case old.F is\n            when k_ADD_Float =>\n              old.F := k_ADD_Float_Multiple;\n              old.Y := 3;\n              folded := True;\n            when k_ADD_Float_Multiple =>\n              old.Y := old.Y + 1;\n              folded := True;\n            when others => null;\n          end case;\n          Simple_Substitution (k_MULT_Float, k_MULT_then_ADD_Float);\n        when k_Unary_MINUS_Integer =>\n          if old.F = k_Push_Discrete_Literal\n            and then old.Y > Defs.HAC_Integer'First\n          then\n            old.Y := -old.Y;\n            folded := True;\n          end if;\n        when k_Push_Discrete_Literal =>\n          if old.F = k_Push_Discrete_Literal then\n            old.F := k_Push_Two_Discrete_Literals;\n            old.X := old.Y;\n            old.Y := B;\n            folded := True;\n          end if;\n        when k_Push_Float_Literal =>\n          if old.F = k_Push_Float_Literal then\n            old.F := k_Push_Two_Float_Literals;\n            old.X := old.Y;\n            old.Y := B;\n            folded := True;\n          end if;\n        when k_Store =>\n          Simple_Substitution (k_Push_Float_Literal, k_Store_Float_Literal);\n          --  ^ Operand B (for this opcode, special type info) is discarded\n          --  since the TYP is Floats.\n          --\n          Simple_Substitution (k_ADD_Float,      k_ADD_Float_then_Store);\n          Simple_Substitution (k_SUBTRACT_Float, k_SUBTRACT_Float_then_Store);\n          Simple_Substitution (k_MULT_Float,     k_MULT_Float_then_Store);\n        when k_Store_Discrete =>\n          Simple_Substitution (k_Push_Discrete_Literal, k_Store_Discrete_Literal);\n          --  ^ Operand B (for this opcode, special type info) is discarded\n          --  since we have a (subtype-checked) discrete value.\n          Simple_Substitution (k_ADD_Integer,      k_ADD_Integer_then_Store);\n          Simple_Substitution (k_SUBTRACT_Integer, k_SUBTRACT_Integer_then_Store);\n          Simple_Substitution (k_MULT_Integer,     k_MULT_Integer_then_Store);\n        when k_NOT_Boolean =>\n          Simple_Substitution (k_AND_Boolean, k_NAND_Boolean);\n          Simple_Substitution (k_OR_Boolean,  k_NOR_Boolean);\n        when others =>\n          null;\n      end case;\n    end Try_Folding;\n    --\n  begin\n    folded      := False;\n    specialized := False;\n    if LC = OC'Last then\n      Errors.Fatal (Errors.Object_Code);\n    end if;\n    Try_Specialization;\n    if LC > OC'First then\n      Try_Folding;\n    end if;\n    if not folded then\n      OC (LC).F := FCT_corr;\n      OC (LC).X := a;\n      OC (LC).Y := B;\n      OC (LC).Z := c;\n      OC (LC).D := D;\n      LC        := LC + 1;\n    end if;\n  end Emit_Instruction;\n\n  procedure Patch_Addresses (\n    OC            : in out Object_Code_Table;\n    dummy_address :        Operand_2_Type\n  )\n  is\n    use Defs;\n    use type HAC_Integer;\n  begin\n    for Op of OC (OC'First .. OC'Last - 1) loop\n      if Op.F in Jump_Opcode and then Op.Y = dummy_address then\n        Op.Y := HAC_Integer (OC'Last);\n      end if;\n    end loop;\n  end Patch_Addresses;\n\n  procedure Patch_Addresses (\n    OC  : in out Object_Code_Table;\n    PT  :        Patch_Table;\n    Top : in out Natural\n  )\n  is\n  begin\n    for Instruction_Address of PT (PT'First .. Top) loop\n      OC (Integer (Instruction_Address)).Y := Operand_2_Type (OC'Last);\n    end loop;\n    Top := 0;\n  end Patch_Addresses;\n\n  procedure Feed_Patch_Table (\n    PT  : in out Patch_Table;\n    Top : in out Natural;\n    LC  :        Integer\n  )\n  is\n  begin\n    if Top < PT'Last then\n      Top := Top + 1;\n    else\n      Errors.Fatal (Errors.PATCHING);\n    end if;\n    PT (Top) := Operand_2_Type (LC);\n  end Feed_Patch_Table;\n\n  procedure Dump (\n    OC        : Object_Code_Table;\n    Str_Const : String;\n    Flt_Const : Defs.Float_Constants_Table_Type;\n    Text      : Ada.Text_IO.File_Type\n  )\n  is\n    use Ada.Strings.Fixed, Ada.Text_IO, Defs;\n    package Opcode_IO   is new Enumeration_IO (Opcode);\n    package Code_Pos_IO is new Integer_IO (Natural);\n    package Operand1_IO is new Integer_IO (Operand_1_Type);\n    package Operand2_IO is new Integer_IO (Operand_2_Type);\n    function HAC_Image is new HAT.HAC_Generic_Image (Defs.HAC_Integer);\n    SF_C : SF_Code;\n    SP_C : SP_Code;\n    Old_X1 : Operand_1_Type := 0;\n    Old_Y1 : Operand_2_Type := 0;\n    --\n    function Padded_Opcode (o : Opcode) return String is\n      s : String (1 .. Opcode'Width);\n    begin\n      Opcode_IO.Put (s, o);\n      return s;\n    end Padded_Opcode;\n    use type Operand_2_Type;\n  begin\n    Put_Line\n      (Text, \"Position   : Opcode \" & (Opcode'Width - 7) * ' ' &\n             \"Level/X        \" &\n             \"Addr/Val/Y\" &\n             \";      Approx source location; Extra information\");\n    Put_Line (Text, 120 * '-');\n    for i in OC'Range loop\n      Code_Pos_IO.Put (Text, i);\n      Put (Text, \": \" & Padded_Opcode (OC (i).F));\n      case OC (i).F is  --  Omit showing X for some 1-operand instructions\n        when k_Return_Call | k_Return_Function |\n          k_Mark_Stack | k_Push_Discrete_Literal |\n          k_Push_Float_Literal .. k_Push_Float_Last |\n          k_Store |\n          k_Pop |\n          Unary_Operator_Opcode |\n          Binary_Operator_Opcode |\n          Special_Operator_Opcode |\n          Jump_Opcode\n        =>\n          Put (Text, \"     \");\n        when others =>\n          Operand1_IO.Put (Text, OC (i).X, 5);\n      end case;\n      case OC (i).F is  --  Omit showing Y for some 0-operand instructions\n        when k_Pop |\n          k_Push_Float_First .. k_Push_Float_Last |\n          Binary_Operator_Opcode |\n          k_ADD_Integer_Multiple .. k_MULT_Float_then_Store |\n          k_NAND_Boolean | k_NOR_Boolean\n        =>\n          Put (Text, \"                    \");\n        when others =>\n          Operand2_IO.Put (Text, OC (i).Y);\n      end case;\n      Put (Text, \"; \");\n      Code_Pos_IO.Put (Text, OC (i).D.Line_Number);\n      Put (Text, \"  \" & HAT.VStr_Pkg.To_String (OC (i).D.Full_Block_Id));\n      case OC (i).F is  --  Show extra information\n        when k_Push_Float_Literal =>\n          Put (Text, \"; \" & HAT.HAC_Image (Flt_Const (Integer (OC (i).Y))));\n        when k_Push_Float_First =>\n          Put (Text, \"; HAT.Real'First: \" & HAC_Float'Image (HAT.Real'First));\n        when k_Push_Float_Last =>\n          Put (Text, \"; HAT.Real'Last: \" & HAC_Float'Image (HAT.Real'Last));\n        when k_Variable_Initialization =>\n          Put (Text, \"; \" & Defs.Typen'Image (Defs.Typen'Val (OC (i).Y)));\n        when k_HAT_Function =>\n          SF_C := SF_Code'Val (OC (i).Y);\n          Put (Text, \"; \" & SF_Code'Image (SF_C));\n        when k_HAT_Procedure =>\n          SP_C := SP_Code'Val (OC (i).X);\n          Put (Text, \"; \" & SP_Code'Image (SP_C));\n          case SP_C is\n            when SP_Get .. SP_Get_Line =>\n              Put (Text, \"; \" & Defs.Typen'Image (Defs.Typen'Val (OC (i).Y)));\n            when SP_Put .. SP_Put_Line =>\n              if Defs.Typen'Val (OC (i).Y) = Defs.String_Literals then\n                --  We know that a string literal was pushed just before,\n                --  as a pair of discrete literals (CD.target.Emit_Push_Discrete_Literals).\n                Put\n                  (Text,\n                   \"; \"\"\" &\n                   Str_Const\n                     (Integer (Old_Y1) .. Integer (Old_Y1 +  Old_X1 - 1)) &\n                   '\"');\n              end if;\n            when others =>\n              null;\n          end case;\n        when k_FOR_Release_Stack =>\n          Put (Text, \"; Release stack used by FOR loop(s)\");\n        when k_CASE_Switch =>\n          Put (Text, \"; (CASE) Jump to the switch block\");\n        when k_CASE_Choice_Value =>\n          Put (Text, \"; (CASE) WHEN \" & HAC_Image (OC (i).Y) & \" =>\");\n        when k_CASE_Choice_Range =>\n          Put (Text, \"; (CASE) WHEN \" &\n            HAC_Image (OC (i).X) & \" ..\" &\n            HAC_Image (OC (i).Y) & \" =>\");\n        when k_CASE_Choice_Others =>\n          Put (Text, \"; (CASE) WHEN OTHERS =>\");\n        when k_Mark_Stack =>\n          Put (Text, \"; Mark stack for calling subprogram with ID #\" & HAC_Image (OC (i).Y));\n        when k_Call =>\n          Put (Text, \"; Call with PSize = \" & HAC_Image (OC (i).Y + 1));\n        when k_Update_Display_Vector =>\n          Put (Text, \"; Update: low level (called) = \" & HAC_Image (OC (i).X) &\n                     \", high level (caller) = \" & HAC_Image (OC (i).Y));\n        when others =>\n          null;\n      end case;\n      New_Line (Text);\n      --\n      Old_X1 := OC (i).X;\n      Old_Y1 := OC (i).Y;\n    end loop;\n  end Dump;\n\n  -------------------------------------------------------------SaveOBJ----\n\n  procedure SaveOBJ (FileName : String) is\n  --   ObjFile:  OAIO.File_Type;\n  --   Buffer: SMAObject;\n  begin\n    --   Create( ObjFile, name => FileName & \".Obj\");\n    --\n    --   FOR  I  IN   1.. AMax  LOOP\n    --     Buffer.ArraysTab(I) := ArraysTab(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   FOR  I  IN   1.. BMax  LOOP\n    --     Buffer.BlockTab(I) := BlockTab(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   FOR  I  IN   0.. CDMax  LOOP\n    --     Buffer.ObjCode(I) := ObjCode(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   Buffer.ECount := ECount;\n    --   Write(ObjFile, Buffer);\n    --\n    --   FOR  I  IN   0.. EntryMax  LOOP\n    --     Buffer.EntryTAB(I) := EntryTAB(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   --{Buffer.FileIOTab := FileIOTab;} --{ Error assigning file }\n    --\n    --   FOR  I  IN   1.. C2Max  LOOP\n    --     Buffer.FloatPtTab(I) := FloatPtTab(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   FOR  I  IN   0.. SMax  LOOP\n    --     Buffer.StringTab(I) := StringTab(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   FOR  I  IN   0.. TMax  LOOP\n    --     Buffer.IdTab(I) := IdTab(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   FOR  I  IN   0.. TaskMax  LOOP\n    --     Buffer.TskDefTab(I) := TskDefTab(I);\n    --   END LOOP;\n    --   Write(ObjFile, Buffer);\n    --\n    --   Buffer.TCount := TCount;\n    --   Write(ObjFile, Buffer);\n    --\n    --   Close(ObjFile);\n\n    null; -- will be streamed...\n\n  end SaveOBJ;\n\n  ----------------------------------------------------------RestoreOBJ----}\n\n  procedure RestoreOBJ (FileName : String) is\n  --   ObjFile:  OAIO.File_Type;\n  --   Buffer: SMAObject;\n  begin\n    --   BEGIN\n    --     Open(ObjFile, in_file, FileName & \".Obj\");\n    --   EXCEPTION\n    --     when others=>\n    --       IF qDebug THEN\n    --         Text_IO.Put_Line(\"Cannot find file : \" & FileName & \".Obj\");\n    --       END IF;\n    --       raise Failure_1_0;\n    --   END;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   1.. AMax  LOOP\n    --     ArraysTab(I) := Buffer.ArraysTab(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   1.. BMax  LOOP\n    --     BlockTab(I) := Buffer.BlockTab(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   0.. CDMax  LOOP\n    --     ObjCode(I) := Buffer.ObjCode(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   ECount := Buffer.ECount;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   0.. EntryMax  LOOP\n    --     EntryTAB(I) := Buffer.EntryTAB(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   --{FileIOTab := Buffer.FileIOTab;} --{ Error assigning file }\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   1.. C2Max  LOOP\n    --     FloatPtTab(I) := Buffer.FloatPtTab(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   0.. SMax  LOOP\n    --     StringTab(I) := Buffer.StringTab(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   0.. TMax  LOOP\n    --     IdTab(I) := Buffer.IdTab(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   FOR  I  IN   0.. TaskMax  LOOP\n    --     TskDefTab(I) := Buffer.TskDefTab(I);\n    --   END LOOP;\n    --\n    --   Read(ObjFile, Buffer);\n    --   TCount := Buffer.TCount;\n    --\n    --   Close(ObjFile);\n\n    null; -- will be streamed...\n\n  end RestoreOBJ;\n\nend HAC_Sys.PCode;\n"
  },
  {
    "path": "src/execute/hac_sys-pcode.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  This package defines the PCode Virtual Machine.\n\nwith HAC_Sys.Defs;\n\nwith HAT;\n\nwith Ada.Text_IO;  --  Only used for file descriptors\n\npackage HAC_Sys.PCode is\n\n  -----------------------------------------------------PCode Opcodes----\n\n  type Opcode is\n  (\n    k_Push_Address,\n    k_Push_Value,\n    k_Push_Discrete_Value,\n    k_Push_Indirect_Value,\n    k_Push_Indirect_Discrete_Value,\n    --\n    k_Push_Discrete_Literal,\n    k_Push_Float_Literal,\n    k_Push_Float_First,\n    k_Push_Float_Last,\n    --\n    k_Push_Two_Discrete_Literals,\n    k_Push_Two_Float_Literals,\n    --\n    k_Pop,\n    --\n    k_Variable_Initialization,\n    k_Store,\n    k_Store_Discrete,           --  Like Store, but copies only the discrete field.\n    k_Store_Discrete_Literal,   --  Equivalent to: Push_Discrete_Literal, then Store_Discrete.\n    k_Store_Float_Literal,      --  Equivalent to: Push_Float_Literal, then Store.\n    k_Swap,                     --  Swap the two items at the top of the stack.\n    k_Pop_to_Temp,              --  Pop top item to a temp register.\n    k_Push_Temp,                --  Push temp register on the stack.\n    k_Check_Lower_Bound,\n    k_Check_Upper_Bound,\n    --\n    k_Jump,\n    k_Jump_If_Zero_With_Pop,            --  Jump if [T].I = 0, always pop  -> general use\n    k_Jump_If_Zero_No_Pop,              --  Jump if [T].I = 0, no pop      -> for \"and then\"\n    k_Jump_If_Non_Zero_No_Pop,          --  Jump if [T].I /= 0, no pop     -> for \"or else\"\n    --\n    k_CASE_Switch,\n    k_CASE_Choice_Value,\n    k_CASE_Choice_Range,\n    k_CASE_Choice_Others,\n    k_CASE_Match_Jump,\n    k_CASE_No_Choice_Found,\n    --\n    k_FOR_Forward_Begin,\n    k_FOR_Reverse_Begin,\n    k_FOR_Forward_End,\n    k_FOR_Reverse_End,\n    k_FOR_Release_Stack,\n    --\n    k_Array_Index_Element_Size_1,\n    k_Array_Index,\n    k_Array_Index_No_Check_Element_Size_1,\n    k_Array_Index_No_Check,\n    --\n    k_Record_Field_Offset,\n    k_Load_Block,                       --  Push a composite type's data on the stack.\n    k_Load_String_Literal,              --  Push a string literal's contents on the stack.\n    k_Copy_Block,\n    k_String_Literal_Assignment,\n    --\n    k_Mark_Stack,                       --  First instruction for a Call\n    k_Call,                             --  Procedure and task entry Call\n    k_Exchange_with_External,\n    k_Return_Call,\n    k_Return_Function,\n    k_Update_Display_Vector,\n    --\n    --  Unary operators\n    --\n    k_Integer_to_Float,                 --  The reverse conversion is done by a k_Standard_Functions\n    k_Dereference,\n    k_Dereference_Discrete,\n    k_Unary_MINUS_Float,                --  2020-04-04\n    k_Unary_MINUS_Integer,\n    k_NOT_Boolean,\n    --\n    --  Binary operators\n    --\n    k_EQL_Integer,\n    k_NEQ_Integer,\n    k_LSS_Integer,\n    k_LEQ_Integer,\n    k_GTR_Integer,\n    k_GEQ_Integer,\n    --\n    k_EQL_VString,\n    k_NEQ_VString,\n    k_LSS_VString,\n    k_LEQ_VString,\n    k_GTR_VString,\n    k_GEQ_VString,\n    --\n    k_EQL_Float,\n    k_NEQ_Float,\n    k_LSS_Float,\n    k_LEQ_Float,\n    k_GTR_Float,\n    k_GEQ_Float,\n    --\n    k_ADD_Integer,\n    k_SUBTRACT_Integer,\n    k_MULT_Integer,\n    k_DIV_Integer,\n    k_MOD_Integer,\n    k_REM_Integer,\n    k_Power_Integer,                    --  2018-03-18 : 3 ** 6\n    --\n    k_ADD_Float,\n    k_SUBTRACT_Float,\n    k_MULT_Float,\n    k_DIV_Float,\n    k_Power_Float,                      --  2018-03-22 : 3.14 ** 6.28\n    k_Power_Float_Integer,              --  2018-03-22 : 3.14 ** 6\n    --\n    k_AND_Boolean,\n    k_OR_Boolean,\n    k_XOR_Boolean,\n    --\n    --  Special operators, resulting of folding of two or more instructions\n    --\n    k_ADD_Integer_Multiple,             --  2022-05-21 : add 3 or more terms\n    k_ADD_Float_Multiple,               --  2022-05-21 : add 3 or more terms\n    k_MULT_then_ADD_Integer,            --  2022-05-21 : i + j * k\n    k_MULT_then_ADD_Float,              --  2022-05-21 : i + j * k\n    --\n    k_ADD_Integer_then_Store,\n    k_SUBTRACT_Integer_then_Store,\n    k_MULT_Integer_then_Store,\n    --\n    k_ADD_Float_then_Store,\n    k_SUBTRACT_Float_then_Store,\n    k_MULT_Float_then_Store,\n    --\n    k_ADD_Integer_Literal,\n    k_SUBTRACT_Integer_Literal,\n    k_MULT_Integer_Literal,\n    k_DIV_Integer_Literal,\n    k_EQL_Integer_Literal,\n    k_NEQ_Integer_Literal,\n    k_LSS_Integer_Literal,\n    k_LEQ_Integer_Literal,\n    k_GTR_Integer_Literal,\n    k_GEQ_Integer_Literal,\n    --\n    k_NAND_Boolean,\n    k_NOR_Boolean,\n    --\n    k_HAT_Procedure,\n    k_HAT_Function,\n    --\n    --\n    k_Halt_Interpreter,                 --  Switch off the processor's running loop\n    --\n    --  Tasking stuff\n    --\n    k_Accept_Rendezvous,\n    k_End_Rendezvous,\n    k_Wait_Semaphore,\n    k_Signal_Semaphore,\n    k_Delay,\n    k_Set_Quantum_Task,\n    k_Set_Task_Priority,\n    k_Set_Task_Priority_Inheritance,\n    k_Selective_Wait\n  );\n\n  subtype Unary_Operator_Opcode    is Opcode range k_Integer_to_Float .. k_NOT_Boolean;\n  subtype Binary_Operator_Opcode   is Opcode range k_EQL_Integer .. k_XOR_Boolean;\n  subtype Multiple_Operator_Opcode is Opcode range k_ADD_Integer_Multiple .. k_ADD_Float_Multiple;\n  subtype Special_Operator_Opcode  is Opcode range k_MULT_then_ADD_Integer .. k_NOR_Boolean;\n  subtype Op_then_Store_Opcode is Special_Operator_Opcode\n     range k_ADD_Integer_then_Store .. k_MULT_Float_then_Store;\n  subtype Op_Float_then_Store_Opcode is Op_then_Store_Opcode\n     range k_ADD_Float_then_Store .. k_MULT_Float_then_Store;\n  subtype Op_Integer_Literal_Opcode is Special_Operator_Opcode\n     range k_ADD_Integer_Literal .. k_GEQ_Integer_Literal;\n  subtype Compare_Integer_Literal_Opcode is Op_Integer_Literal_Opcode\n     range k_EQL_Integer_Literal .. k_GEQ_Integer_Literal;\n  --\n  subtype Atomic_Data_Push_Opcode is Opcode range k_Push_Address .. k_Push_Indirect_Discrete_Value;\n  subtype Literal_Push_Opcode     is Opcode range k_Push_Discrete_Literal .. k_Push_Float_Last;\n  subtype Calling_Opcode          is Opcode range k_Mark_Stack .. k_Update_Display_Vector;\n  subtype CASE_Any_Choice         is Opcode range k_CASE_Choice_Value .. k_CASE_Choice_Others;\n  subtype CASE_Data_Opcode        is Opcode range k_CASE_Choice_Value .. k_CASE_No_Choice_Found;\n  subtype Composite_Data_Opcode   is Opcode range k_Array_Index_Element_Size_1 .. k_String_Literal_Assignment;\n  subtype Jump_Opcode             is Opcode range k_Jump .. k_Jump_If_Non_Zero_No_Pop;\n  subtype Multi_Statement_Opcode  is Opcode range k_CASE_Switch .. k_FOR_Release_Stack;\n  subtype Tasking_Opcode          is Opcode range k_Halt_Interpreter .. k_Selective_Wait;\n\n  For_END_Instruction : constant array (k_FOR_Forward_Begin .. k_FOR_Reverse_Begin) of Opcode :=\n    (k_FOR_Forward_Begin => k_FOR_Forward_End,\n     k_FOR_Reverse_Begin => k_FOR_Reverse_End);\n\n  type Opcode_Set is array (Opcode) of Boolean;\n  OK_for_Exception : constant Opcode_Set :=\n    (k_Return_Call .. k_Return_Function | k_Halt_Interpreter => True, others => False);\n\n  --  Type for operand 2 (Y) is large enough for containing\n  --  addresses, plus signed integer values *in* HAC programs.\n  --\n  subtype Operand_1_Type is Defs.HAC_Integer;\n  subtype Operand_2_Type is Defs.HAC_Integer;\n  subtype Operand_3_Type is Defs.HAC_Integer;\n\n  type Debug_Info is record\n    --  Line number in the source code.\n    Line_Number   : Positive;\n    --  Current block's path (if any). Example: hac-pcode-interpreter.adb.\n    Full_Block_Id : HAT.VString;\n    --  Source code file name.         Example: HAC.PCode.Interpreter.Do_Write_Formatted.\n    File_Name     : HAT.VString;\n  end record;\n\n  --  PCode instruction record (stores a compiled PCode instruction)\n  type Order is record\n    F : Opcode;          --  Opcode (or instruction field)\n    X : Operand_1_Type;  --  Operand 1 is mostly used to point to the static level\n    Y : Operand_2_Type;  --  Operand 2 is used to pass addresses and sizes to the\n                         --    instructions, or to pass immediate discrete values (k_Literal).\n    Z : Operand_3_Type;\n    D : Debug_Info;\n  end record;\n\n  type Object_Code_Table is array (Natural range <>) of Order;\n\n  --  For jumps forward in the code towards an ELSE, ELSIF, END IF, END LOOP, ...\n  --  When the code is emited, the address is still unknown.\n  --  When the address is known, jump addresses are patched.\n\n  --  Patching using dummy addresses.\n  --  For loops, this technique can be used only for exiting\n  --  the current loop.\n\n  dummy_address_if   : constant := -1;\n  dummy_address_loop : constant := -2;\n\n  --  Patch to OC'Last all addresses of Jump_Opcode's which are equal to dummy_address.\n  procedure Patch_Addresses (\n    OC            : in out Object_Code_Table;\n    dummy_address :        Operand_2_Type\n  );\n\n  --  Mechanism for patching instructions at selected addresses.\n  type Patch_Table is array (Positive range <>) of Operand_2_Type;\n  subtype Fixed_Size_Patch_Table is Patch_Table (1 .. HAC_Sys.Defs.Patch_Max);\n\n  --  Patch to OC'Last all addresses for Jump instructions whose\n  --  addresses are contained in the Patch_Table, up to index Top.\n  --  Reset Top to 0.\n  procedure Patch_Addresses (\n    OC  : in out Object_Code_Table;\n    PT  :        Patch_Table;\n    Top : in out Natural\n  );\n\n  --  Add new instruction address to a Patch_Table.\n  procedure Feed_Patch_Table (\n    PT  : in out Patch_Table;\n    Top : in out Natural;\n    LC  :        Integer\n  );\n\n  procedure Dump (\n    OC        : Object_Code_Table;\n    Str_Const : String;\n    Flt_Const : Defs.Float_Constants_Table_Type;\n    Text      : Ada.Text_IO.File_Type\n  );\n\n  --  Store PCode instruction in the object code table OC at position LC and increments LC.\n\n  procedure Emit_Instruction (\n    OC          : in out Object_Code_Table;\n    LC          : in out Integer;\n    D           :        Debug_Info;\n    FCT         :        Opcode;\n    a           :        Operand_1_Type;\n    B           :        Operand_2_Type;\n    c           :        Operand_3_Type;\n    folded      :    out Boolean;\n    specialized :    out Boolean\n  );\n\n  --  Save and restore an object file\n  procedure SaveOBJ (FileName : String);\n  procedure RestoreOBJ (FileName : String);\n\nend HAC_Sys.PCode;\n"
  },
  {
    "path": "src/hac_sys-interfacing.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  This package defines the interfacing mechanism between HAC and a \"full Ada\" app.\n--  Demo in: demo/data_exchange/exchange_native_side.adb\n\nwith HAC_Sys.Builder,\n     HAC_Sys.PCode.Interpreter.In_Defs;\n\npackage HAC_Sys.Interfacing is\n\n  type HAC_Element is private;\n\n  ------------------------------------\n  --  Native  ->  HAC  conversions  --\n  ------------------------------------\n\n  function To_HAC (Data : Integer)    return HAC_Element;\n  function To_HAC (Data : Long_Float) return HAC_Element;\n  function To_HAC (Data : String)     return HAC_Element;\n\n  generic\n    type Any_Integer is range <>;\n  function To_HAC_Any_Integer (Data : Any_Integer) return HAC_Element;\n\n  generic\n    type Any_Enum is (<>);\n  function To_HAC_Any_Enum (Data : Any_Enum) return HAC_Element;\n\n  generic\n    type Any_Float is digits <>;\n  function To_HAC_Any_Float (Data : Any_Float) return HAC_Element;\n\n  ------------------------------------\n  --  HAC  ->  Native  conversions  --\n  ------------------------------------\n\n  function To_Native (Data : HAC_Element) return Integer;\n  function To_Native (Data : HAC_Element) return Long_Float;\n  function To_Native (Data : HAC_Element) return String;\n\n  generic\n    type Any_Integer is range <>;\n  function To_Native_Any_Integer (Data : HAC_Element) return Any_Integer;\n\n  generic\n    type Any_Enum is (<>);\n  function To_Native_Any_Enum (Data : HAC_Element) return Any_Enum;\n\n  generic\n    type Any_Float is digits <>;\n  function To_Native_Any_Float (Data : HAC_Element) return Any_Float;\n\n  HAC_Type_Error : exception;\n\n  type HAC_Element_Array is array (Positive range <>) of HAC_Element;\n\n  ----------------------\n  --  Call-back type  --\n  ----------------------\n\n  type Exported_Procedure is access procedure (Data : in out HAC_Element_Array);\n\n  --  Registration. You can register call-backs any time: before compilation,\n  --  after compilation, or even during HAC's run-time if you can control,\n  --  from the Native program, when a call-back is called. For instance,\n  --  the registration of a call-back to some Native procedure or another one\n  --  might be done during another call-back.\n  --\n  procedure Register\n    (BD       : Builder.Build_Data;\n     Callback : Exported_Procedure;\n     Name     : String);\n\n  procedure Deregister\n    (BD       : Builder.Build_Data;\n     Name     : String);\n\n  ---------------------------------\n  --  Virtual Machine Variables  --\n  ---------------------------------\n\n  --  The strings set as Virtual Machine Variables can be read and written\n  --  from a HAC program via the HAT.Get_VM_Variable and HAT.Set_VM_Variable\n  --  subprograms. This way, data can be exchanged, before and after running\n  --  a program through the HAC VM interpreter, between that program and the\n  --  program that runs HAC. The strings are as persistent as an object\n  --  of type Builder.Build_Data is.\n  --  See demo/data_exchange/exchange_native_side_pkg.adb for an example.\n\n  function Get_VM_Variable (BD : Builder.Build_Data; Name : String) return String;\n  procedure Set_VM_Variable (BD : in out Builder.Build_Data; Name : String; Value : String);\n\nprivate\n\n  type HAC_Element is new HAC_Sys.PCode.Interpreter.In_Defs.Data_Type;\n\nend HAC_Sys.Interfacing;\n"
  },
  {
    "path": "src/hac_sys.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Version / date / download info: see the version, reference, web strings\n--    defined at the end of the public part of this package.\n--\n--  Legal licensing note:\n--\n--  Copyright (c) 2013 .. 2026 Gautier de Montmollin\n--\n--      History and authors list of works HAC was originally\n--      derived from can be found in hac.txt.\n--\n--  Permission is hereby granted, free of charge, to any person obtaining a copy\n--  of this software and associated documentation files (the \"Software\"), to deal\n--  in the Software without restriction, including without limitation the rights\n--  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n--  copies of the Software, and to permit persons to whom the Software is\n--  furnished to do so, subject to the following conditions:\n--\n--  The above copyright notice and this permission notice shall be included in\n--  all copies or substantial portions of the Software.\n--\n--  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n--  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n--  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n--  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n--  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n--  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n--  THE SOFTWARE.\n--\n--  NB: this is the MIT License, as found 12-Sep-2013 on the site\n--  http://www.opensource.org/licenses/mit-license.php\n--\n-------------------------------------------------------------------------------------\n--\n\npackage HAC_Sys is\n\n  --------------------------------------------------------------\n  -- Information about this package - e.g. for an \"about\" box --\n  --------------------------------------------------------------\n\n  version   : constant String := \"0.42\";\n  reference : constant String := \"31-Jan-2026\";\n  --  Hopefully the latest version is reachable at one of those URLs:\n  web       : constant String := \"https://hacadacompiler.sourceforge.io/\";\n  web2      : constant String := \"https://sourceforge.net/projects/hacadacompiler/\";\n  web3      : constant String := \"https://github.com/zertovitch/hac\";\n  web4      : constant String := \"https://alire.ada.dev/crates/hac\";\n\nend HAC_Sys;\n"
  },
  {
    "path": "src/hat-non_standard.adb",
    "content": "--  GNAT version.\n\nwith Interfaces.C;\n\nseparate (HAT) package body Non_Standard is\n\n  function GNAT_Sys (Arg : Interfaces.C.char_array) return Interfaces.C.int;\n  pragma Import (C, GNAT_Sys, \"system\");\n\n  procedure Sys (Command : String; Result : out Integer) is\n  --  https://rosettacode.org/wiki/Execute_a_system_command#Ada\n  begin\n    Result := Integer (GNAT_Sys (Interfaces.C.To_C (Command)));\n  end Sys;\n\n  GNAT_Directory_Separator : constant Character;\n  pragma Import (C, GNAT_Directory_Separator, \"__gnat_dir_separator\");\n\n  function Directory_Separator return Character is\n  begin\n    return GNAT_Directory_Separator;\n  end Directory_Separator;\n\nend Non_Standard;\n"
  },
  {
    "path": "src/hat-non_standard_oawin64.adb",
    "content": "--  ObjectAda64 for Windows version.\n\n--  with Ada.Unchecked_Conversion;\n--  with Win32.Crt.Process;\n\nwith Interfaces.C;\n\nseparate (HAT) package body Non_Standard is\n\n  function MS_Sys (Arg : Interfaces.C.char_array) return Interfaces.C.int;\n  pragma Import (C, MS_Sys, \"system\");\n\n  --  You may (or not) need to add the following search path to the OA .prj project:\n  --    C:\\Program Files (x86)\\PTC\\ObjectAda64\\win32ada\\binding\\lib\\\n  --\n  --  In ADA.LIB (in, e.g., the hac_objectada-Win32(Intel)-Debug directory):\n  --\n  --         PATH\n  --           PATHNAME: ..\\..\\..\\program files (x86)\\ptc\\objectada64\\lib\\rts\n  --  --->     PATHNAME: ..\\..\\..\\program files (x86)\\ptc\\objectada64\\win32ada\\binding\\lib\n  --         ENDPATH\n\n  procedure Sys (Command : String; Result : out Integer) is\n    --  cmd_nul : aliased Interfaces.C.char_array := Interfaces.C.To_C (Command);\n    --  type p_Char is access all Interfaces.C.char_array;\n    --  p_cmd_nul : p_Char := cmd_nul'Access;\n    --  function Convert is new Ada.Unchecked_Conversion (p_Char, Win32.PCSTR);\n  begin\n    Result := Integer (MS_Sys (Interfaces.C.To_C (Command)));\n    --  Result := Integer (Win32.Crt.Process.System (Convert (p_cmd_nul)));\n  end Sys;\n  \n  function Directory_Separator return Character is\n  begin\n    return '\\';\n  end Directory_Separator;\n\nend Non_Standard;\n"
  },
  {
    "path": "src/hat.adb",
    "content": "with Ada.Containers.Hashed_Maps,\n     Ada.Numerics.Float_Random,\n     Ada.Numerics.Generic_Elementary_Functions,\n     Ada.Streams.Stream_IO,\n     Ada.Strings.Fixed,\n     Ada.Strings.Unbounded.Hash,\n     Ada.Text_IO.Text_Streams;\n\npackage body HAT is\n\n  package REF is new Ada.Numerics.Generic_Elementary_Functions (Real);\n\n  function \"**\" (F1, F2 : Real) return Real is\n  begin\n    return REF.\"**\" (F1, F2);\n  end \"**\";\n\n  function Sqrt (I : Integer) return Real is\n  begin\n    return REF.Sqrt (Real (I));\n  end Sqrt;\n\n  function Sqrt (F : Real) return Real is\n  begin\n    return REF.Sqrt (F);\n  end Sqrt;\n\n  function Chr (I : Integer) return Character is\n  begin\n    return Character'Val (I);\n  end Chr;\n\n  function Ord (C : Character) return Integer is\n  begin\n    return Character'Pos (C);\n  end Ord;\n\n  function Succ (C : Character) return Character is\n  begin\n    return Character'Succ (C);\n  end Succ;\n\n  function Pred (C : Character) return Character is\n  begin\n    return Character'Pred (C);\n  end Pred;\n\n  function Round (F : Real) return Integer is\n  begin\n    return Integer (F);\n  end Round;\n\n  function Trunc (F : Real) return Integer is\n  begin\n    return Integer (Real'Floor (F));\n  end Trunc;\n\n  function Sin (F : Real) return Real is\n  begin\n    return REF.Sin (F);\n  end Sin;\n\n  function Cos (F : Real) return Real is\n  begin\n    return REF.Cos (F);\n  end Cos;\n\n  function Arctan (F : Real) return Real is\n  begin\n    return REF.Arctan (F);\n  end Arctan;\n\n  function Log (F : Real) return Real is\n  begin\n    return REF.Log (F);\n  end Log;\n\n  function Exp (F : Real) return Real is\n  begin\n    return REF.Exp (F);\n  end Exp;\n\n  function Sgn (I : Integer) return Integer is\n  begin\n    return (if I > 0 then 1 elsif I < 0 then -1 else 0);\n  end Sgn;\n\n  function Sgn (F : Real) return Real is\n  begin\n    return (if F > 0.0 then 1.0 elsif F < 0.0 then -1.0 else 0.0);\n  end Sgn;\n\n  function Rand (I : Integer) return Integer is\n    res : Integer;\n  begin\n    loop\n      res := Trunc (Rnd * Real (I + 1));\n      exit when res < I + 1;  --  In extremely rare cases we have res = I + 1.\n    end loop;\n    return res;\n  end Rand;\n\n  gen : Ada.Numerics.Float_Random.Generator;\n\n  function Rnd return Real is\n  begin\n    return Real (Ada.Numerics.Float_Random.Random (gen));\n  end Rnd;\n\n  procedure Randomize is\n  begin\n    Ada.Numerics.Float_Random.Reset (gen);\n  end Randomize;\n\n  procedure Random_Seed (New_Seed : Positive) is\n  begin\n    Ada.Numerics.Float_Random.Reset (gen, New_Seed);\n  end Random_Seed;\n\n  function HAC_Image (I : Integer) return String is\n    Im : constant String := Integer'Image (I);\n  begin\n    --  Return image without leading ' ' on non-negative values.\n    return (if I < 0 then Im else Im (Im'First + 1 .. Im'Last));\n  end HAC_Image;\n\n  function HAC_Image (T : Ada.Calendar.Time) return String is\n    use Ada;\n    --  Time_display returns date & time, current or given.\n    --  E.g.: \"2013/08/01  05:49:51\"\n    --  Useful for a log file or a display of a lengthy operation.\n    --  This is Ada 83 compatible. Format accepted by SQL queries.\n    --\n    --    32- or 64-bit: DEC/Compaq/HP Ada (83), GNAT (95/2005), ObjectAda (95)\n    --    16-bit:        Meridian (83) -> Long_Integer is 32-bit\n    --    16-bit:        Janus 2.x (83): KO: no Long_Integer\n    --\n    --  Test program in following comment:\n    --\n    --   with Text_IO,Time_display;procedure Test is begin Text_IO.Put(Time_display);end;\n    --\n    function Time_display (\n      T        : Calendar.Time := Calendar.Clock;\n      Seconds  : Boolean       := True;\n      Intra_day : Boolean      := True\n    )\n      return String\n    is\n      subtype Sec_int is Long_Integer; -- must contain 86_400\n      s : constant Sec_int := Sec_int (Calendar.Seconds (T));\n      m : constant Sec_int := s / 60;\n      --  + 100: trick for obtaining 0x\n      sY : constant String := Integer'Image (Year (T));\n      sM : constant String := Integer'Image (Month (T) + 100);\n      sD : constant String := Integer'Image (Day (T)  + 100);\n      shr : constant String := Sec_int'Image (m  /  60 + 100);\n      smn : constant String := Sec_int'Image (m mod 60 + 100);\n      ssc : constant String := Sec_int'Image (s mod 60 + 100);\n      --\n      function Optional_seconds return String is\n      begin\n        return (if Seconds then ':' & ssc (ssc'Last - 1 .. ssc'Last) else \"\");\n      end Optional_seconds;\n      --\n      --  The \"if expression\" version of that function\n      --  confuses ObjectAda 10.4.\n      --\n      --  function Optional_intra_day return String is\n      --  begin\n      --    return\n      --     (if Intra_day then\n      --        \"  \" & shr (shr'Last - 1 .. shr'Last) & ':' &\n      --        smn (smn'Last - 1 .. smn'Last) & Optional_seconds\n      --      else\n      --        \"\");\n      --  end Optional_intra_day;\n\n      function Optional_intra_day return String is\n      begin\n        if Intra_day then\n          return\n            \"  \" &\n            shr (shr'Last - 1 .. shr'Last) & ':' &\n            smn (smn'Last - 1 .. smn'Last) & Optional_seconds;\n        else\n          return \"\";\n        end if;\n      end Optional_intra_day;\n\n    begin\n      return\n        sY (sY'Last - 3 .. sY'Last) & '/' &  -- not Year 10'000 compliant.\n        sM (sM'Last - 1 .. sM'Last) & '/' &\n        sD (sD'Last - 1 .. sD'Last) &\n        Optional_intra_day;\n    end Time_display;\n  begin\n    return Time_display (T);\n  end HAC_Image;\n\n  function To_VString (C : Character) return VString is\n  begin\n    return To_VString ((1 => C));\n  end To_VString;\n\n  function Slice (Source : VString; Low : Positive; High : Natural) return VString\n  is\n  begin\n    return +VStr_Pkg.Slice (Source, Low, High);\n  end Slice;\n\n  function \"&\" (I : Integer; V : VString) return VString is\n  begin\n    return HAC_Image (I) & V;\n  end \"&\";\n\n  function \"&\" (V : VString; I : Integer) return VString is\n  begin\n    return V & HAC_Image (I);\n  end \"&\";\n\n  function \"&\" (R : Real; V : VString) return VString is\n  begin\n    return HAC_Image (R) & V;\n  end \"&\";\n\n  function \"&\" (V : VString; R : Real) return VString is\n  begin\n    return V & HAC_Image (R);\n  end \"&\";\n\n  function \"&\" (D : Duration; V : VString) return VString is\n  begin\n    return Image (D) & V;\n  end \"&\";\n\n  function \"&\" (V : VString; D : Duration) return VString is\n  begin\n    return V & Image (D);\n  end \"&\";\n\n  function Nice_Image (B : Boolean) return VString is\n    img : constant String := Boolean'Image (B);\n  begin\n    return +(img (img'First) & ACH.To_Lower (img (img'First + 1 .. img'Last)));\n  end Nice_Image;\n\n  function \"&\" (B : Boolean; V : VString) return VString is\n  begin\n    return Nice_Image (B) & V;\n  end \"&\";\n\n  function \"&\" (V : VString; B : Boolean) return VString is\n  begin\n    return V & Nice_Image (B);\n  end \"&\";\n\n  function To_Lower (Item : VString) return VString is\n  begin\n    return +Ada.Characters.Handling.To_Lower (VStr_Pkg.To_String (Item));\n  end To_Lower;\n\n  function To_Upper (Item : VString) return VString is\n  begin\n    return +Ada.Characters.Handling.To_Upper (VStr_Pkg.To_String (Item));\n  end To_Upper;\n\n  function Head (Source : VString; Count : Natural) return VString is\n  begin\n    return VStr_Pkg.Head (Source, Count);  --  We use the default padding: ' '.\n  end Head;\n\n  function Tail (Source : VString; Count : Natural) return VString is\n  begin\n    return VStr_Pkg.Tail (Source, Count);  --  We use the default padding: ' '.\n  end Tail;\n\n  function Head_Before_Match (Source : VString; Pattern : Character) return VString is\n  begin\n    return Head_Before_Match (Source, (1 => Pattern));\n  end Head_Before_Match;\n\n  function Head_Before_Match (Source : VString; Pattern : String) return VString is\n  begin\n    return Head_Before_Match (Source, +Pattern);\n  end Head_Before_Match;\n\n  function Head_Before_Match (Source : VString; Pattern : VString) return VString is\n    i : constant Natural := Index (Source, Pattern);\n  begin\n    return (if i = 0 then Null_VString else Slice (Source, 1, i - 1));\n  end Head_Before_Match;\n\n  function Tail_After_Match (Source : VString; Pattern : Character) return VString is\n  begin\n    return Tail_After_Match (Source, (1 => Pattern));\n  end Tail_After_Match;\n\n  function Tail_After_Match (Source : VString; Pattern : String) return VString is\n  begin\n    return Tail_After_Match (Source, +Pattern);\n  end Tail_After_Match;\n\n  function Tail_After_Match (Source : VString; Pattern : VString) return VString is\n    ------------------------------------------------------------------------------\n    --  Description : Extract a substring from Source starting after the Pattern,\n    --                to the end\n    --  Arguments   : String to scan and Search pattern\n    --  Return      : A substring from the character after the first Pattern\n    --                found backward to the String's end\n    --  Author      : Stephane Riviere, 2021\n    --\n    --  Examples :\n    --\n    --  Tail_After_Match (+\"/etc/genesix/gnx-startup\",\n    --    +\"/\")) returns \"gnx-startup\"\n    --    +\"ix\")) returns \"/gnx-startup\"\n    --    +\"gene\")) returns \"six/gnx-startup\"\n    --    +\"etc/genesix/gnx-startu\")) returns \"p\"\n    --    +\"/etc/genesix/gnx-startu\")) returns \"p\"\n    --    +\"/etc/genesix/gnx-startup\")) returns empty string\n    --    +\"/etc/genesix/gnx-startupp\")) returns empty string\n    ------------------------------------------------------------------------------\n    Result : VString := +\"\";\n    Source_Length : constant Natural := Length (Source);\n    Pattern_Length : constant Natural := Length (Pattern);\n  begin\n    for I in reverse 1 .. Source_Length - Pattern_Length loop\n      if Slice (Source, I, I + Pattern_Length - 1) = Pattern then\n        Result := Slice (Source, I + Pattern_Length, Source_Length);\n        exit;\n      end if;\n    end loop;\n    return Result;\n  end Tail_After_Match;\n\n  function Starts_With (Item : VString; Pattern : Character) return Boolean is\n  begin\n    return 1 <= Length (Item) and then Element (Item, 1) = Pattern;\n  end Starts_With;\n\n  function Starts_With (Item : VString; Pattern : String) return Boolean is\n  begin\n    return Pattern'Length <= Length (Item)\n             and then VStr_Pkg.To_String (VStr_Pkg.Head (Item, Pattern'Length)) = Pattern;\n  end Starts_With;\n\n  function Starts_With (Item : VString; Pattern : VString) return Boolean is\n  begin\n    return Length (Pattern) <= Length (Item)\n             and then VStr_Pkg.Head (Item, Length (Pattern)) = Pattern;\n  end Starts_With;\n\n  function Ends_With (Item : VString; Pattern : Character) return Boolean is\n  begin\n    return 1 <= Length (Item) and then Element (Item, Length (Item)) = Pattern;\n  end Ends_With;\n\n  function Ends_With (Item : VString; Pattern : String) return Boolean is\n  begin\n    return Pattern'Length <= Length (Item)\n             and then VStr_Pkg.To_String (VStr_Pkg.Tail (Item, Pattern'Length)) = Pattern;\n  end Ends_With;\n\n  function Ends_With (Item : VString; Pattern : VString) return Boolean is\n  begin\n    return Length (Pattern) <= Length (Item)\n             and then VStr_Pkg.Tail (Item, Length (Pattern)) = Pattern;\n  end Ends_With;\n\n  -------------\n  --  Index  --\n  -------------\n\n  function Index (Source : VString; Pattern : Character) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, (1 => Pattern));\n  end Index;\n\n  function Index (Source : VString; Pattern : String) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, Pattern);\n  end Index;\n\n  function Index (Source : VString; Pattern : VString) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, VStr_Pkg.To_String (Pattern));\n  end Index;\n\n  function Index (Source : VString; Pattern : Character; From : Positive) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, (1 => Pattern), From);\n  end Index;\n\n  function Index (Source : VString; Pattern : String; From : Positive) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, Pattern, From);\n  end Index;\n\n  function Index (Source : VString; Pattern : VString; From : Positive) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, VStr_Pkg.To_String (Pattern), From);\n  end Index;\n\n  ----------------------\n  --  Index_Backward  --\n  ----------------------\n\n  function Index_Backward (Source : VString; Pattern : Character) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, (1 => Pattern), Ada.Strings.Backward);\n  end Index_Backward;\n\n  function Index_Backward (Source : VString; Pattern : String) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, Pattern, Ada.Strings.Backward);\n  end Index_Backward;\n\n  function Index_Backward (Source : VString; Pattern : VString) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, VStr_Pkg.To_String (Pattern), Ada.Strings.Backward);\n  end Index_Backward;\n\n  function Index_Backward (Source : VString; Pattern : Character; From : Positive) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, (1 => Pattern), From, Ada.Strings.Backward);\n  end Index_Backward;\n\n  function Index_Backward (Source : VString; Pattern : String; From : Positive) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, Pattern, From, Ada.Strings.Backward);\n  end Index_Backward;\n\n  function Index_Backward (Source : VString; Pattern : VString; From : Positive) return Natural is\n  begin\n    return VStr_Pkg.Index (Source, VStr_Pkg.To_String (Pattern), From, Ada.Strings.Backward);\n  end Index_Backward;\n\n  function \"*\" (Num : Natural; Pattern : String) return VString is\n  begin\n    return +Ada.Strings.Fixed.\"*\" (Num, Pattern);\n  end \"*\";\n\n  function Trim_Left  (Source : VString) return VString is\n  begin\n    return VStr_Pkg.Trim (Source, Ada.Strings.Left);\n  end Trim_Left;\n\n  function Trim_Right (Source : VString) return VString is\n  begin\n    return VStr_Pkg.Trim (Source, Ada.Strings.Right);\n  end Trim_Right;\n\n  function Trim_Both  (Source : VString) return VString is\n  begin\n    return VStr_Pkg.Trim (Source, Ada.Strings.Both);\n  end Trim_Both;\n\n  function Image (I : Integer) return VString is\n    function HAC_Image_for_Integer is\n      new HAT.HAC_Generic_Image (Abstract_Integer => Integer);\n  begin\n    return +HAC_Image_for_Integer (I);\n  end Image;\n\n  function Image (F : Real) return VString is\n  begin\n    return +HAC_Image (F);\n  end Image;\n\n  function Image (T : Ada.Calendar.Time) return VString is\n  begin\n    return +HAC_Image (T);\n  end Image;\n\n  function Image (D : Duration) return VString is\n    Im : constant String := Duration'Image (D);\n  begin\n    --  Return image without leading ' ' on non-negative values.\n    return (if D < 0.0 then +Im else +Im (Im'First + 1 .. Im'Last));\n  end Image;\n\n  function Integer_Value (V : VString) return Integer is\n  begin\n    return Integer'Value (VStr_Pkg.To_String (V));\n  end Integer_Value;\n\n  function Float_Value (V : VString) return Real is\n  begin\n    return Real'Value (VStr_Pkg.To_String (V));\n  end Float_Value;\n\n  procedure Open (File : in out File_Type; Name : String) is\n    use Ada.Text_IO;\n  begin\n    Open (File, In_File, Name);\n  end Open;\n\n  procedure Open (File : in out File_Type; Name : VString) is\n  begin Open (File, VStr_Pkg.To_String (Name)); end Open;\n\n  procedure Create (File : in out File_Type; Name : String) is\n    use Ada.Text_IO;\n  begin\n    Create (File, Out_File, Name);\n  end Create;\n\n  procedure Create (File : in out File_Type; Name : VString) is\n  begin Create (File, VStr_Pkg.To_String (Name)); end Create;\n\n  procedure Append (File : in out File_Type; Name : String) is\n    use Ada.Text_IO;\n  begin\n    Open (File, Append_File, Name);\n  end Append;\n\n  procedure Append (File : in out File_Type; Name : VString) is\n  begin\n    Append (File, VStr_Pkg.To_String (Name));\n  end Append;\n\n   ---------\n   -- GET --\n   ---------\n\n  procedure Get (I : out Integer) is begin IIO.Get (I); end Get;\n  procedure Get (I : out Interfaces.Integer_64) is begin IIO_64.Get (I); end Get;\n  procedure Get (File : File_Type; I : out Integer) is begin IIO.Get (File, I); end Get;\n  procedure Get (File : File_Type; I : out Interfaces.Integer_64) is\n  begin IIO_64.Get (File, I); end Get;\n\n  procedure Get (F : out Real) is begin RIO.Get (F); end Get;\n  procedure Get (File : File_Type; F : out Real) is begin RIO.Get (File, F); end Get;\n\n   --------------\n   -- GET_LINE --\n   --------------\n\n  procedure Get_Line (C : out Character) is begin Get (C); Skip_Line; end Get_Line;\n  procedure Get_Line (File : File_Type; C : out Character) is\n    begin Get (File, C); Skip_Line (File); end Get_Line;\n\n  procedure Get_Line (I : out Integer) is begin Get (I); Skip_Line; end Get_Line;\n  procedure Get_Line (I : out Interfaces.Integer_64) is begin Get (I); Skip_Line; end Get_Line;\n  procedure Get_Line (File : File_Type; I : out Integer) is\n    begin Get (File, I); Skip_Line (File); end Get_Line;\n  procedure Get_Line (File : File_Type; I : out Interfaces.Integer_64) is\n    begin Get (File, I); Skip_Line (File); end Get_Line;\n\n  procedure Get_Line (F : out Real) is begin Get (F); Skip_Line; end Get_Line;\n  procedure Get_Line (File : File_Type; F : out Real) is\n    begin Get (File, F); Skip_Line (File); end Get_Line;\n\n  procedure Get_Line (V : out VString) is begin V := +Ada.Text_IO.Get_Line; end Get_Line;\n  procedure Get_Line (File : File_Type; V : out VString) is\n    begin V := +Ada.Text_IO.Get_Line (File); end Get_Line;\n\n  ---------\n  -- PUT --\n  ---------\n\n  procedure Put (C     : Character) is\n  begin\n    Character'Write (Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Current_Output), C);\n  end Put;\n\n  procedure Put (File  : File_Type; C : Character) is\n  begin\n    Character'Write (Ada.Text_IO.Text_Streams.Stream (File), C);\n  end Put;\n\n  procedure Put (B     : Boolean;\n                 Width : Ada.Text_IO.Field := BIO.Default_Width)\n  is\n  begin\n    BIO.Put (B, Width);\n  end Put;\n\n  procedure  Put (File  : File_Type;\n                  B     : Boolean;\n                  Width : Ada.Text_IO.Field       := BIO.Default_Width)\n  is\n  begin\n    BIO.Put (File, B, Width);\n  end Put;\n\n  procedure Put (S : in String) is\n  begin\n    String'Write (Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Current_Output), S);\n  end Put;\n\n  procedure Put (File : File_Type; S : in String) is\n  begin\n    String'Write (Ada.Text_IO.Text_Streams.Stream (File), S);\n  end Put;\n\n  procedure Put (V : in VString) is begin Put (VStr_Pkg.To_String (V)); end Put;\n  procedure Put (File : File_Type; V : in VString) is begin Put (File, VStr_Pkg.To_String (V)); end Put;\n\n   --------------\n   -- PUT_LINE --\n   --------------\n\n  procedure Put_Line (C : Character) is begin Put (C); New_Line; end Put_Line;\n  procedure  Put_Line (File : File_Type; C : in Character) is\n    begin Put (File, C); New_Line (File); end Put_Line;\n\n  procedure Put_Line (I     : Integer;\n                      Width : Ada.Text_IO.Field       := IIO.Default_Width;\n                      Base  : Ada.Text_IO.Number_Base := IIO.Default_Base)\n  is\n  begin\n    Put (I, Width, Base);\n    New_Line;\n  end Put_Line;\n\n  procedure  Put_Line (File  : File_Type;\n                       I     : Integer;\n                       Width : Ada.Text_IO.Field       := IIO.Default_Width;\n                       Base  : Ada.Text_IO.Number_Base := IIO.Default_Base)\n  is\n  begin\n    Put (File, I, Width, Base);\n    New_Line (File);\n  end Put_Line;\n\n  procedure Put_Line (F    : Real;\n                      Fore : Integer := RIO.Default_Fore;\n                      Aft  : Integer := RIO.Default_Aft;\n                      Expo : Integer := RIO.Default_Exp)\n  is\n  begin\n    Put (F, Fore, Aft, Expo);\n    New_Line;\n  end Put_Line;\n\n  procedure Put_Line (File : File_Type;\n                      F    : Real;\n                      Fore : Integer := RIO.Default_Fore;\n                      Aft  : Integer := RIO.Default_Aft;\n                      Expo : Integer := RIO.Default_Exp)\n  is\n  begin\n    Put (File, F, Fore, Aft, Expo);\n    New_Line (File);\n  end Put_Line;\n\n  procedure Put_Line (B     : Boolean;\n                      Width : Ada.Text_IO.Field := BIO.Default_Width)\n  is\n  begin\n    Put (B, Width);\n    New_Line;\n  end Put_Line;\n\n  procedure Put_Line (File  : File_Type;\n                      B     : Boolean;\n                      Width : Ada.Text_IO.Field := BIO.Default_Width)\n  is\n  begin\n    Put (File, B, Width);\n    New_Line (File);\n  end Put_Line;\n\n  procedure Put_Line (V : VString) is begin Put_Line (VStr_Pkg.To_String (V)); end Put_Line;\n  procedure Put_Line (File : File_Type; V : VString) is begin Put_Line (File, VStr_Pkg.To_String (V)); end Put_Line;\n\n  ----------\n  -- WAIT --\n  ----------\n\n  procedure Wait (S : Semaphore) is\n  begin\n    raise Program_Error with \"WAIT unimplemented\";\n  end Wait;\n\n  ------------\n  -- SIGNAL --\n  ------------\n\n  procedure Signal (S : Semaphore) is\n  begin\n    raise Program_Error with \"SIGNAL unimplemented\";\n  end Signal;\n\n  function Argument (Number : Positive) return VString is\n  begin\n    return +Ada.Command_Line.Argument (Number);\n  end Argument;\n\n  function Command_Name return VString is\n  begin\n    return +Ada.Command_Line.Command_Name;\n  end Command_Name;\n\n  procedure Set_Exit_Status (Code : in Integer) is\n  begin\n    Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Exit_Status (Code));\n  end Set_Exit_Status;\n\n  function Get_Env (Name : String) return VString is\n    use Ada.Environment_Variables;\n  begin\n    return\n      (if Ada.Environment_Variables.Exists (Name) then +Value (Name)\n       else Null_VString);\n  end Get_Env;\n\n  function Get_Env (Name : VString) return VString is\n  begin\n    return Get_Env (VStr_Pkg.To_String (Name));\n  end Get_Env;\n\n  procedure Set_Env (Name : VString; Value : String) is\n  begin\n    Set_Env (VStr_Pkg.To_String (Name), Value);\n  end Set_Env;\n\n  procedure Set_Env (Name : String; Value : VString) is\n  begin\n    Set_Env (Name, VStr_Pkg.To_String (Value));\n  end Set_Env;\n\n  procedure Set_Env (Name : VString; Value : VString) is\n  begin\n    Set_Env (VStr_Pkg.To_String (Name), VStr_Pkg.To_String (Value));\n  end Set_Env;\n\n  package String_Maps is new Ada.Containers.Hashed_Maps\n    (Key_Type        => VString,\n     Element_Type    => VString,\n     Hash            => Ada.Strings.Unbounded.Hash,\n     Equivalent_Keys => HAT.\"=\",\n     \"=\"             => HAT.\"=\");\n\n  --  We emulate here the pool of VM variables attached to the HAC VM.\n  global_VM_variables : String_Maps.Map;\n\n  function Get_VM_Variable (Name : String)  return VString is\n  begin\n    return Get_VM_Variable (+Name);\n  end Get_VM_Variable;\n\n  function Get_VM_Variable (Name : VString) return VString is\n    cur : constant String_Maps.Cursor := global_VM_variables.Find (Name);\n    use String_Maps;\n  begin\n    return\n      (if cur = String_Maps.No_Element then Null_VString\n       else String_Maps.Element (cur));\n  end Get_VM_Variable;\n\n  procedure Set_VM_Variable (Name : String;  Value : String) is\n  begin\n    Set_VM_Variable (+Name, +Value);\n  end Set_VM_Variable;\n\n  procedure Set_VM_Variable (Name : VString; Value : String) is\n  begin\n    Set_VM_Variable (Name, +Value);\n  end Set_VM_Variable;\n\n  procedure Set_VM_Variable (Name : String;  Value : VString) is\n  begin\n    Set_VM_Variable (+Name, Value);\n  end Set_VM_Variable;\n\n  procedure Set_VM_Variable (Name : VString; Value : VString) is\n  begin\n    global_VM_variables.Include (Name, Value);\n  end Set_VM_Variable;\n\n  function Current_Directory return VString is\n  begin\n    return +Ada.Directories.Current_Directory;\n  end Current_Directory;\n\n  procedure Set_Directory (Directory : VString) is\n  begin\n    Set_Directory (VStr_Pkg.To_String (Directory));\n  end Set_Directory;\n\n  procedure Copy_File (Source_Name : String; Target_Name : String) is\n  begin\n    Ada.Directories.Copy_File (Source_Name, Target_Name);  --  Form: default value \"\".\n  end Copy_File;\n\n  procedure Copy_File (Source_Name : VString; Target_Name : String) is\n  begin\n    Copy_File (VStr_Pkg.To_String (Source_Name), Target_Name);\n  end Copy_File;\n\n  procedure Copy_File (Source_Name : String; Target_Name : VString) is\n  begin\n    Copy_File (Source_Name, VStr_Pkg.To_String (Target_Name));\n  end Copy_File;\n\n  procedure Copy_File (Source_Name : VString; Target_Name : VString) is\n  begin\n    Copy_File (VStr_Pkg.To_String (Source_Name), VStr_Pkg.To_String (Target_Name));\n  end Copy_File;\n\n  procedure Create_Directory (New_Directory : String) is\n  begin\n    Ada.Directories.Create_Directory (New_Directory);  --  Form is left as default.\n  end Create_Directory;\n\n  procedure Create_Directory (New_Directory : VString) is\n  begin\n    Create_Directory (VStr_Pkg.To_String (New_Directory));\n  end Create_Directory;\n\n  procedure Create_Path (New_Path : String) is\n  begin\n    Ada.Directories.Create_Path (New_Path);  --  Form is left as default.\n  end Create_Path;\n\n  procedure Create_Path (New_Path : VString) is\n  begin\n    Create_Path (VStr_Pkg.To_String (New_Path));\n  end Create_Path;\n\n  procedure Delete_Directory (Directory : VString) is\n  begin\n    Delete_Directory (VStr_Pkg.To_String (Directory));\n  end Delete_Directory;\n\n  procedure Delete_File (Name : VString) is\n  begin\n    Delete_File (VStr_Pkg.To_String (Name));\n  end Delete_File;\n\n  function Exists (Name : VString) return Boolean is\n  begin\n    return Exists (VStr_Pkg.To_String (Name));\n  end Exists;\n\n  function Directory_Exists (Name : String) return Boolean is\n    use Ada.Directories;\n  begin\n    return Exists (Name) and then Kind (Name) = Directory;\n  end Directory_Exists;\n\n  function Directory_Exists (Name : VString) return Boolean is\n  begin\n    return Directory_Exists (VStr_Pkg.To_String (Name));\n  end Directory_Exists;\n\n  function File_Exists (Name : String) return Boolean is\n    use Ada.Directories;\n  begin\n    return Exists (Name) and then Kind (Name) = Ordinary_File;\n  end File_Exists;\n\n  function File_Exists (Name : VString) return Boolean is\n  begin\n    return File_Exists (VStr_Pkg.To_String (Name));\n  end File_Exists;\n\n  procedure Rename (Old_Name : VString; New_Name : String) is\n  begin\n    Rename (VStr_Pkg.To_String (Old_Name), New_Name);\n  end Rename;\n\n  procedure Rename (Old_Name : String; New_Name : VString) is\n  begin\n    Rename (Old_Name, VStr_Pkg.To_String (New_Name));\n  end Rename;\n\n  procedure Rename (Old_Name : VString; New_Name : VString) is\n  begin\n    Rename (VStr_Pkg.To_String (Old_Name), VStr_Pkg.To_String (New_Name));\n  end Rename;\n\n  function HAC_Generic_Image (I : Abstract_Integer) return String is\n    Im : constant String := Abstract_Integer'Image (I);\n  begin\n    --  Return image without leading ' ' on non-negative values.\n    return (if I < 0 then Im else Im (Im'First + 1 .. Im'Last));\n  end HAC_Generic_Image;\n\n  largest_without_exponent : constant := 10.0 ** (Real'Digits - 1);\n\n  function HAC_Image (F : Real) return String is\n    --  Code from TeXCAD (tc.adb, TeX_Number),\n    --  less a few simplifications.\n    s : String (1 .. Real'Digits + 15);\n    na, nb, np, ne : Natural;\n    function Image_with_exponent return String is\n    begin\n      RIO.Put (s, F);\n      na := s'First;\n      for i in s'Range loop\n        case s (i) is\n          when ' ' => na := i + 1;  --  * Trim spaces on the left\n          when others => null;\n        end case;\n      end loop;\n      ne := Ada.Strings.Fixed.Index (s, \"0E\");\n      if ne > 0 then\n        --  Simplify \"4.56000000000000E+68\" into \"4.56E+68\".\n        --  * Remove extra '0's...\n        nb := ne - 1;\n        while s (nb) = '0' loop\n          nb := nb - 1;\n        end loop;\n        if s (nb) = '.' then\n          --  \"4.E+68\" from \"4.00000000000000E+68\" would be too much trimming...\n          nb := nb + 1;  --  We keep one '0' -> \"4.0E+68\".\n        end if;\n        return s (na .. nb) & s (ne + 1 .. s'Last);\n      end if;\n      return s (na .. s'Last);\n    end Image_with_exponent;\n    --\n    function Count_Nonzero_Digits (any : String) return Natural is\n      n : Natural := 0;\n    begin\n      for c of any loop\n        exit when c = 'E';  --  Ignore exponent part.\n        if c in '1' .. '9' then\n          n := n + 1;\n        end if;\n      end loop;\n      return n;\n    end Count_Nonzero_Digits;\n  begin\n    if abs F >= largest_without_exponent then\n      return Image_with_exponent;\n    end if;\n    --  Image without exponent (E).\n    --  If the number is too large for this layout, the Layout_Error\n    --  exception is raised and we call Image_with_exponent.\n    RIO.Put (s, F, Exp => 0);\n    declare\n      F_image   : constant String := Real'Image (F);\n      tolerance : constant := 1;\n    begin\n      if Count_Nonzero_Digits (s) + tolerance < Count_Nonzero_Digits (F_image) then\n        return Image_with_exponent;\n        --  Significant loss of significant digits.\n        --  Typically 6.62607015e-34 is displayed as 0.0[0] unless the\n        --  type Real has a 34 digits precision (unlikely...). See Strings test.\n        --  The tolerance is due to the case where s is, e.g., \"123.4567890\"\n        --  and F_image is \"1.234567891E+02\". Spot the last significant\n        --  digit: '0' vs. '1'. Such an accuracy error is normal.\n      end if;\n    end;\n    --  We don't want to lose any digit in the decimal representation without exponent.\n    na := s'First;\n    nb := s'Last;\n    np := 0;\n    for i in s'Range loop\n      case s (i) is\n        when '.' => np := i; exit;    --  Find a decimal point\n        when ' ' => na := i + 1;      --  * Trim spaces on the left\n        when others => null;\n      end case;\n    end loop;\n    if np > 0 then\n      --  In case of a decimal point.\n      while nb > np + 1 and then s (nb) = '0' loop\n        nb := nb - 1;                 --  * Remove extra '0's except for \"x.0\"\n      end loop;\n    end if;\n    return s (na .. nb);\n  exception\n    when Ada.Text_IO.Layout_Error =>\n      --  Number too large, we fall back to show the version with exponent.\n      return Image_with_exponent;\n  end HAC_Image;\n\n  package Non_Standard is\n\n    procedure Sys (Command : String; Result : out Integer);\n\n    function Directory_Separator return Character;\n\n  end Non_Standard;\n\n  package body Non_Standard is separate;\n\n  procedure Shell_Execute (Command : String; Result : out Integer) is\n    --  https://rosettacode.org/wiki/Execute_a_system_command#Ada\n  begin\n    Non_Standard.Sys (Command, Result);\n  end Shell_Execute;\n\n  procedure Shell_Execute (Command : VString; Result : out Integer) is\n  begin\n    Shell_Execute (VStr_Pkg.To_String (Command), Result);\n  end Shell_Execute;\n\n  procedure Shell_Execute (Command : String) is\n    Dummy : Integer;\n  begin\n    Shell_Execute (Command, Dummy);\n  end Shell_Execute;\n\n  procedure Shell_Execute (Command : VString) is\n  begin\n    Shell_Execute (VStr_Pkg.To_String (Command));\n  end Shell_Execute;\n\n  --  Versions with outward piping:\n\n  procedure Shell_Execute (Command : String; Result : out Integer; Output : out VString) is\n    package SIO renames Ada.Streams.Stream_IO;\n    temp_1, temp_2 : SIO.File_Type;\n  begin\n    SIO.Create (temp_1, SIO.Out_File, \"\");\n    declare\n      temp_name_2 : constant String := SIO.Name (temp_1) & \"_shell_exec.tmp\";\n    begin\n      Non_Standard.Sys (Command & '>' & temp_name_2, Result);\n      if Exists (temp_name_2) then\n        SIO.Open (temp_2, SIO.In_File, temp_name_2);\n        declare\n          size : constant SIO.Count := SIO.Size (temp_2);\n          buffer : String (1 .. Natural (size));\n        begin\n          if SIO.\">\" (size, 0) then\n            String'Read (SIO.Stream (temp_2), buffer);\n            Output := To_VString (buffer);\n          else\n            Output := Null_VString;\n          end if;\n        end;\n        SIO.Delete (temp_2);\n      else\n        Output := Null_VString;\n      end if;\n    end;\n    SIO.Close (temp_1);\n  end Shell_Execute;\n\n  procedure Shell_Execute (Command : VString; Result : out Integer; Output : out VString) is\n  begin\n    Shell_Execute (VStr_Pkg.To_String (Command), Result, Output);\n  end Shell_Execute;\n\n  procedure Shell_Execute (Command : String; Output : out VString) is\n    Dummy : Integer;\n  begin\n    Shell_Execute (Command, Dummy, Output);\n  end Shell_Execute;\n\n  procedure Shell_Execute (Command : VString; Output : out VString) is\n  begin\n    Shell_Execute (VStr_Pkg.To_String (Command), Output);\n  end Shell_Execute;\n\n  function Directory_Separator return Character is\n  begin\n    return Non_Standard.Directory_Separator;\n  end Directory_Separator;\n\n  function Search_File (simple_file_name, path : String) return String is\n    sep_pos : Natural := path'First - 1;\n    new_sep_pos : Natural;\n  begin\n    for i in path'Range loop\n      new_sep_pos := sep_pos;\n      if path (i) in ',' | ';' then\n        new_sep_pos := i;\n      elsif i = path'Last then\n        new_sep_pos := i + 1;\n      end if;\n      if new_sep_pos > sep_pos then\n        declare\n          full_file_name : constant String :=\n            path (sep_pos + 1 .. new_sep_pos - 1) & HAT.Directory_Separator & simple_file_name;\n        begin\n          if HAT.Exists (full_file_name) then\n            return full_file_name;\n          end if;\n        end;\n      end if;\n      sep_pos := new_sep_pos;\n    end loop;\n    return \"\";\n  end Search_File;\n\nbegin\n  pragma Assert\n    (Real'Digits >= Interfaces.IEEE_Float_64'Digits,\n     \"HAT.Real must have at least the precision of IEEE Double Precision\");\n  Ada.Numerics.Float_Random.Reset (gen);  --  Randomize.\nend HAT;\n"
  },
  {
    "path": "src/hat.ads",
    "content": "--  HAT - HAC Ada Toolbox\n-------------------------\n--\n--  The HAT package and possible children contains definitions\n--  that are useful for HAC in its minimal operating mode.\n--\n--  HAT is compilable by a \"full Ada\" compiler like GNAT or ObjectAda,\n--  so the HAC programs can be run on both HAC and a full Ada system.\n--\n--  Another purpose of this specification is to have a document,\n--  automatically verified by \"full Ada\" systems, of the standard types\n--  and subprograms available in HAC.\n--\n--  Furthermore, some items of HAT are used in the HAC virtual machine.\n--  See occurrences of \"HAT\" in HAC.PCode.Interpreter's body.\n------------------------\n--\n--  Legal licensing note:\n--\n--  Copyright (c) 2020 .. 2024 Gautier de Montmollin\n--\n--  Permission is hereby granted, free of charge, to any person obtaining a copy\n--  of this software and associated documentation files (the \"Software\"), to deal\n--  in the Software without restriction, including without limitation the rights\n--  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n--  copies of the Software, and to permit persons to whom the Software is\n--  furnished to do so, subject to the following conditions:\n--\n--  The above copyright notice and this permission notice shall be included in\n--  all copies or substantial portions of the Software.\n--\n--  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n--  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n--  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n--  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n--  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n--  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n--  THE SOFTWARE.\n--\n--  NB: this is the MIT License, as found 12-Sep-2013 on the site\n--  http://www.opensource.org/licenses/mit-license.php\n--\n-------------------------------------------------------------------------------------\n--\nwith Ada.Calendar,\n     Ada.Characters.Handling,\n     Ada.Command_Line,\n     Ada.Directories,\n     Ada.Environment_Variables,\n     Ada.Numerics,\n     Ada.Strings.Unbounded,\n     Ada.Text_IO;\n\nwith Interfaces;\n\nwith System;\n\n--  Disable GNAT warning: declaration of \"=\" hides predefined operator.\npragma Warnings (\"H\");\n\npackage HAT is\n\n  -----------------------------------------\n  --  Floating-point numeric type: Real  --\n  -----------------------------------------\n\n  type Real is digits System.Max_Digits;\n  package RIO is new Ada.Text_IO.Float_IO (Real);\n\n  function \"**\" (F1, F2 : Real) return Real with Inline;\n\n  --  Square Root\n  function Sqrt (I : Integer) return Real with Inline;\n  function Sqrt (F : Real)    return Real with Inline;\n\n  --  Integer to Character (equivalent to Character'Val (I))\n  function Chr (I : Integer)   return Character with Inline;\n\n  --  Character to Integer (equivalent to Character'Pos (C))\n  function Ord (C : Character) return Integer with Inline;\n\n  --  Next Character (equivalent to Character'Succ (C))\n  function Succ (C : Character) return Character with Inline;\n\n  --  Previous Character (equivalent to Character'Pred (C))\n  function Pred (C : Character) return Character with Inline;\n\n  --  Round to an Integer (equivalent to Integer (F))\n  function Round (F : Real) return Integer with Inline;\n\n  --  Truncate\n  function Trunc (F : Real) return Integer with Inline;\n\n  --  Min & Max\n  function Min (I, J : Integer) return Integer renames Integer'Min;\n  function Max (I, J : Integer) return Integer renames Integer'Max;\n  function Min (I, J : Interfaces.Integer_64) return Interfaces.Integer_64\n    renames Interfaces.Integer_64'Min;\n  function Max (I, J : Interfaces.Integer_64) return Interfaces.Integer_64\n    renames Interfaces.Integer_64'Max;\n  function Min (F, G : Real)    return Real renames Real'Min;\n  function Max (F, G : Real)    return Real renames Real'Max;\n\n  Pi : constant := Ada.Numerics.Pi;\n\n  --  Trigonometric functions w/ arguments in radians\n  function Sin    (F : Real) return Real with Inline;\n  function Cos    (F : Real) return Real with Inline;\n  function Arctan (F : Real) return Real with Inline;\n\n  --  Logarithmic / Exponential functions\n  function Log (F : Real) return Real with Inline;\n  function Exp (F : Real) return Real with Inline;\n\n  --  Sign function\n  function Sgn (I : Integer) return Integer with Inline;\n  function Sgn (F : Real)    return Real with Inline;\n\n  -----------------------------\n  --  Pseudo-random numbers  --\n  -----------------------------\n\n  --  Pseudo-random number in the real range [0, I+1[ , truncated to lowest\n  --  integer. For example, Rand (10) returns equiprobable integer values\n  --  from 0 to 10 (so, there are 11 possible values).\n  function Rand (I : Integer) return Integer;\n\n  --  Pseudo-random number from 0 to 1, uniform.\n  function Rnd return Real;\n\n  procedure Randomize;\n  procedure Random_Seed (New_Seed : Positive);\n\n  --\n\n  package IIO    is new Ada.Text_IO.Integer_IO (Integer);\n  package IIO_64 is new Ada.Text_IO.Integer_IO (Interfaces.Integer_64);\n  package BIO    is new Ada.Text_IO.Enumeration_IO (Boolean);\n\n  ------------------------------------------\n  --  Variable-size string type: VString  --\n  ------------------------------------------\n\n  package VStr_Pkg renames Ada.Strings.Unbounded;  --  Could use XStrings instead.\n  subtype VString is VStr_Pkg.Unbounded_String;\n  Null_VString : VString renames VStr_Pkg.Null_Unbounded_String;\n  function To_VString (S : String) return VString renames VStr_Pkg.To_Unbounded_String;\n  function To_VString (C : Character) return VString;\n  function To_String (V : VString) return String renames VStr_Pkg.To_String;\n  package ACH renames Ada.Characters.Handling;\n  --\n  procedure Delete (Source : in out VString; From : Positive; Through : Natural) renames VStr_Pkg.Delete;\n  function Element (Source : VString; Index : Positive) return Character renames VStr_Pkg.Element;\n  function Ends_With (Item : VString; Pattern : Character) return Boolean;\n  function Ends_With (Item : VString; Pattern : String) return Boolean;\n  function Ends_With (Item : VString; Pattern : VString) return Boolean;\n  function Head (Source : VString; Count : Natural) return VString;\n  --\n  function Index (Source : VString; Pattern : Character) return Natural;\n  function Index (Source : VString; Pattern : String) return Natural;\n  function Index (Source : VString; Pattern : VString) return Natural;\n  function Index (Source : VString; Pattern : Character; From : Positive) return Natural;\n  function Index (Source : VString; Pattern : String; From : Positive) return Natural;\n  function Index (Source : VString; Pattern : VString; From : Positive) return Natural;\n  --\n  function Index_Backward (Source : VString; Pattern : Character) return Natural;\n  function Index_Backward (Source : VString; Pattern : String) return Natural;\n  function Index_Backward (Source : VString; Pattern : VString) return Natural;\n  function Index_Backward (Source : VString; Pattern : Character; From : Positive) return Natural;\n  function Index_Backward (Source : VString; Pattern : String; From : Positive) return Natural;\n  function Index_Backward (Source : VString; Pattern : VString; From : Positive) return Natural;\n  --\n  function Length (Source : VString) return Natural renames VStr_Pkg.Length;\n  function Slice (Source : VString; Low : Positive; High : Natural) return VString;\n  function Starts_With (Item : VString; Pattern : Character) return Boolean;\n  function Starts_With (Item : VString; Pattern : String) return Boolean;\n  function Starts_With (Item : VString; Pattern : VString) return Boolean;\n  function Tail (Source : VString; Count : Natural) return VString;\n\n  --  Head_Before_Match returns the head of Source preceding first occurrence of Pattern.\n  --  The result is empty if Pattern is not found.\n  function Head_Before_Match (Source : VString; Pattern : Character) return VString;\n  function Head_Before_Match (Source : VString; Pattern : String) return VString;\n  function Head_Before_Match (Source : VString; Pattern : VString) return VString;\n\n  --  Tail_After_Match returns the tail of Source following last occurrence of Pattern.\n  --  The result is empty if Pattern is not found.\n  function Tail_After_Match (Source : VString; Pattern : Character) return VString;\n  function Tail_After_Match (Source : VString; Pattern : String) return VString;\n  function Tail_After_Match (Source : VString; Pattern : VString) return VString;\n\n  function To_Lower (Item : Character) return Character renames ACH.To_Lower;  --  RM A.3.2 (6)\n  function To_Upper (Item : Character) return Character renames ACH.To_Upper;  --  RM A.3.2 (6)\n  function To_Lower (Item : VString) return VString;\n  function To_Upper (Item : VString) return VString;\n\n  function Trim_Left  (Source : VString) return VString;\n  function Trim_Right (Source : VString) return VString;\n  function Trim_Both  (Source : VString) return VString;\n  --\n  function \"+\" (S : String) return VString renames To_VString;\n  function \"+\" (C : Character) return VString renames To_VString;\n  function \"-\" (V : VString) return String renames To_String;\n  --\n  function \"*\" (Num : Natural; Pattern : Character) return VString renames VStr_Pkg.\"*\";\n  function \"*\" (Num : Natural; Pattern : String) return VString;\n  function \"*\" (Num : Natural; Pattern : VString) return VString renames VStr_Pkg.\"*\";\n  --\n  function \"&\" (V1, V2 : VString) return VString renames VStr_Pkg.\"&\";\n  --\n  function \"&\" (V : VString; S : String) return VString renames VStr_Pkg.\"&\";\n  function \"&\" (S : String; V : VString) return VString renames VStr_Pkg.\"&\";\n  --\n  function \"&\" (V : VString; C : Character) return VString renames VStr_Pkg.\"&\";\n  function \"&\" (C : Character; V : VString) return VString renames VStr_Pkg.\"&\";\n  --\n  function \"&\" (I : Integer; V : VString) return VString;\n  function \"&\" (V : VString; I : Integer) return VString;\n  --\n  function \"&\" (R : Real; V : VString) return VString;\n  function \"&\" (V : VString; R : Real) return VString;\n  --\n  function \"&\" (D : Duration; V : VString) return VString;\n  function \"&\" (V : VString; D : Duration) return VString;\n  --\n  function \"&\" (B : Boolean; V : VString) return VString;\n  function \"&\" (V : VString; B : Boolean) return VString;\n  --\n  function \"=\"  (Left, Right : VString) return Boolean renames VStr_Pkg.\"=\";\n  function \"<\"  (Left, Right : VString) return Boolean renames VStr_Pkg.\"<\";\n  function \"<=\" (Left, Right : VString) return Boolean renames VStr_Pkg.\"<=\";\n  function \">\"  (Left, Right : VString) return Boolean renames VStr_Pkg.\">\";\n  function \">=\" (Left, Right : VString) return Boolean renames VStr_Pkg.\">=\";\n  --\n  function \"=\"  (Left : VString;  Right : String) return Boolean renames VStr_Pkg.\"=\";\n  function \"<\"  (Left : VString;  Right : String) return Boolean renames VStr_Pkg.\"<\";\n  function \"<=\" (Left : VString;  Right : String) return Boolean renames VStr_Pkg.\"<=\";\n  function \">\"  (Left : VString;  Right : String) return Boolean renames VStr_Pkg.\">\";\n  function \">=\" (Left : VString;  Right : String) return Boolean renames VStr_Pkg.\">=\";\n\n  function Image (I : Integer) return VString;\n  function Image (F : Real) return VString;            --  \"nice\" image of F\n  function Image (T : Ada.Calendar.Time) return VString;\n  function Image (D : Duration) return VString;\n\n  function Integer_Value (V : VString) return Integer;\n  function Float_Value (V : VString) return Real;\n\n  -------------------------\n  --  Text Input/Output  --\n  --  1) Console I/O     --\n  -------------------------\n\n  --  We have a real console/terminal input where several\n  --  inputs can be made on the same line, followed by a\n  --  \"Return\". It behaves like for a file. Actually it\n  --  *could* be a file, if run like this: prog <input.txt .\n  --\n  function Get_Needs_Skip_Line return Boolean is (True);\n\n  --  Get\n  procedure Get (C : out Character) renames Ada.Text_IO.Get;\n  procedure Get (S : out String)    renames Ada.Text_IO.Get;\n  procedure Get (I : out Integer);\n  procedure Get (I : out Interfaces.Integer_64);\n  procedure Get (F : out Real);\n\n  procedure Get_Immediate (C : out Character) renames Ada.Text_IO.Get_Immediate;\n\n  --  Get and then move file pointer to next line (Skip_Line)\n  procedure Get_Line (C : out Character);\n  procedure Get_Line (I : out Integer);\n  procedure Get_Line (I : out Interfaces.Integer_64);\n  procedure Get_Line (F : out Real);\n  procedure Get_Line (V : out VString);  --  Gets the line till its end.\n\n  procedure Skip_Line (Spacing : Ada.Text_IO.Positive_Count := 1)\n    renames Ada.Text_IO.Skip_Line;\n\n  --  Put\n  procedure Put (C     : Character);\n  procedure Put (I     : Integer;\n                 Width : Ada.Text_IO.Field       := IIO.Default_Width;\n                 Base  : Ada.Text_IO.Number_Base := IIO.Default_Base) renames IIO.Put;\n  procedure Put (F     : Real;\n                 Fore  : Integer := RIO.Default_Fore;\n                 Aft   : Integer := RIO.Default_Aft;\n                 Expo  : Integer := RIO.Default_Exp) renames RIO.Put;\n  procedure Put (B     : Boolean;\n                 Width : Ada.Text_IO.Field       := BIO.Default_Width);\n  procedure Put (S     : String);\n  procedure Put (V     : VString);\n\n  --  Put and then New_Line (for S: it is the same as Ada.Text_IO.Put_Line)\n  procedure Put_Line (C     : Character);\n  procedure Put_Line (I     : Integer;\n                      Width : Ada.Text_IO.Field       := IIO.Default_Width;\n                      Base  : Ada.Text_IO.Number_Base := IIO.Default_Base);\n  procedure Put_Line (F     : Real;\n                      Fore  : Integer := RIO.Default_Fore;\n                      Aft   : Integer := RIO.Default_Aft;\n                      Expo  : Integer := RIO.Default_Exp);\n  procedure Put_Line (B     : Boolean;\n                      Width : Ada.Text_IO.Field := BIO.Default_Width);\n  procedure Put_Line (S     : String) renames Ada.Text_IO.Put_Line;\n  procedure Put_Line (V     : VString);\n\n  procedure New_Line (Spacing : Ada.Text_IO.Positive_Count := 1)\n    renames Ada.Text_IO.New_Line;\n\n  function End_Of_Line return Boolean renames Ada.Text_IO.End_Of_Line;\n  function End_Of_File return Boolean renames Ada.Text_IO.End_Of_File;\n\n  -------------------------\n  --  Text Input/Output  --\n  --  2) File I/O        --\n  -------------------------\n\n  subtype File_Type is Ada.Text_IO.File_Type;\n\n  --  Open file as input\n  procedure Open (File : in out File_Type; Name : String);\n  procedure Open (File : in out File_Type; Name : VString);\n\n  --  Create file as output. If Name = \"\", it creates a temporary file.\n  procedure Create (File : in out File_Type; Name : String);\n  procedure Create (File : in out File_Type; Name : VString);\n\n  --  Append to existing file (output).\n  procedure Append (File : in out File_Type; Name : String);\n  procedure Append (File : in out File_Type; Name : VString);\n\n  procedure Close (File : in out File_Type) renames Ada.Text_IO.Close;\n\n  --  Get\n  procedure Get (File : File_Type; C : out Character) renames Ada.Text_IO.Get;\n  procedure Get (File : File_Type; S : out String)    renames Ada.Text_IO.Get;\n  procedure Get (File : File_Type; I : out Integer);\n  procedure Get (File : File_Type; I : out Interfaces.Integer_64);\n  procedure Get (File : File_Type; F : out Real);\n\n  --  Get and then move file pointer to next line (Skip_Line)\n  procedure Get_Line (File : File_Type; C : out Character);\n  procedure Get_Line (File : File_Type; I : out Integer);\n  procedure Get_Line (File : File_Type; I : out Interfaces.Integer_64);\n  procedure Get_Line (File : File_Type; F : out Real);\n  procedure Get_Line (File : File_Type; V : out VString);     --  Gets the line till its end.\n\n  procedure Skip_Line (File : File_Type; Spacing : Ada.Text_IO.Positive_Count := 1)\n    renames Ada.Text_IO.Skip_Line;\n\n  --  Put\n  procedure Put (File  : File_Type; C : Character);\n  procedure Put (File  : File_Type;\n                 I     : Integer;\n                 Width : Ada.Text_IO.Field       := IIO.Default_Width;\n                 Base  : Ada.Text_IO.Number_Base := IIO.Default_Base) renames IIO.Put;\n  procedure Put (File  : File_Type;\n                 F     : Real;\n                 Fore  : Integer := RIO.Default_Fore;\n                 Aft   : Integer := RIO.Default_Aft;\n                 Expo  : Integer := RIO.Default_Exp) renames RIO.Put;\n  procedure Put (File  : File_Type;\n                 B     : Boolean;\n                 Width : Ada.Text_IO.Field       := BIO.Default_Width);\n  procedure Put (File  : File_Type;\n                 S     : String);\n  procedure Put (File  : File_Type;\n                 V     : VString);\n\n  --  Put and then New_Line (for S: it is the same as Ada.Text_IO.Put_Line)\n  procedure Put_Line (File  : File_Type;\n                      C     : Character);\n  procedure Put_Line (File  : File_Type;\n                      I     : Integer;\n                      Width : Ada.Text_IO.Field       := IIO.Default_Width;\n                      Base  : Ada.Text_IO.Number_Base := IIO.Default_Base);\n  procedure Put_Line (File  : File_Type;\n                      F     : Real;\n                      Fore  : Integer := RIO.Default_Fore;\n                      Aft   : Integer := RIO.Default_Aft;\n                      Expo  : Integer := RIO.Default_Exp);\n  procedure Put_Line (File  : File_Type;\n                      B     : Boolean;\n                      Width : Ada.Text_IO.Field := BIO.Default_Width);\n  procedure Put_Line (File  : File_Type;\n                      S     : String) renames Ada.Text_IO.Put_Line;\n  procedure Put_Line (File  : File_Type;\n                      V     : VString);\n\n  procedure New_Line (File : File_Type; Spacing : Ada.Text_IO.Positive_Count := 1)\n    renames Ada.Text_IO.New_Line;\n\n  function End_Of_Line (File : File_Type) return Boolean renames Ada.Text_IO.End_Of_Line;\n  function End_Of_File (File : File_Type) return Boolean renames Ada.Text_IO.End_Of_File;\n  function Is_Open     (File : File_Type) return Boolean renames Ada.Text_IO.Is_Open;\n\n  ------------\n  --  Time  --\n  ------------\n\n  subtype Time is Ada.Calendar.Time;\n\n  function Clock return Time renames Ada.Calendar.Clock;\n  function \"-\" (Left : Time; Right : Time) return Duration renames Ada.Calendar.\"-\";\n  --  The following functions are slightly different (no subtypes) from\n  --  Ada.Calendar's but GNAT accepts the renaming. Is it correct?\n  function Year    (Date : Time) return Integer renames Ada.Calendar.Year;\n  function Month   (Date : Time) return Integer renames Ada.Calendar.Month;\n  function Day     (Date : Time) return Integer renames Ada.Calendar.Day;\n  function Seconds (Date : Time) return Duration renames Ada.Calendar.Seconds;\n\n  -------------------------------------------------------------------------------------\n  --  System (items similar to items in Ada.Directories, Ada.Environment_Variables)  --\n  -------------------------------------------------------------------------------------\n\n  function Argument_Count return Natural renames Ada.Command_Line.Argument_Count;\n  function Argument (Number : Positive) return VString;\n  function Command_Name return VString;\n  procedure Set_Exit_Status (Code : in Integer);\n\n  --  Get_Env: returns the value of environment variable Name.\n  --  If Name is not set, returns an empty string.\n  function Get_Env (Name : String)  return VString;\n  function Get_Env (Name : VString) return VString;\n\n  --  Set_Env: sets the value of environment variable Name.\n  procedure Set_Env (Name : String;  Value : String) renames Ada.Environment_Variables.Set;\n  procedure Set_Env (Name : VString; Value : String);\n  procedure Set_Env (Name : String;  Value : VString);\n  procedure Set_Env (Name : VString; Value : VString);\n\n  --  Virtual Machine Variables work in a similar way as environment variables.\n  --  The difference: they are visible only to an instance of the Virtual Machine,\n  --  that is, to an object of type Builder.Build_Data.\n  --  There are two ways of accessing them:\n  --    1) from the HAC program via Get_VM_Variable, Set_VM_Variable below.\n  --    2) from the \"full Ada\" application hosting HAC,\n  --       via HAC_Sys.Interfacing.Get_VM_Variable, Set_VM_Variable.\n\n  function Get_VM_Variable (Name : String)  return VString;\n  function Get_VM_Variable (Name : VString) return VString;\n\n  procedure Set_VM_Variable (Name : String;  Value : String);\n  procedure Set_VM_Variable (Name : VString; Value : String);\n  procedure Set_VM_Variable (Name : String;  Value : VString);\n  procedure Set_VM_Variable (Name : VString; Value : VString);\n\n  function Current_Directory return VString;\n\n  procedure Set_Directory (Directory : String) renames Ada.Directories.Set_Directory;\n  procedure Set_Directory (Directory : VString);\n\n  procedure Copy_File (Source_Name : String;  Target_Name : String);\n  procedure Copy_File (Source_Name : VString; Target_Name : String);\n  procedure Copy_File (Source_Name : String;  Target_Name : VString);\n  procedure Copy_File (Source_Name : VString; Target_Name : VString);\n\n  procedure Create_Directory (New_Directory : String);\n  procedure Create_Directory (New_Directory : VString);\n\n  procedure Create_Path (New_Path : String);\n  procedure Create_Path (New_Path : VString);\n\n  procedure Delete_Directory (Directory : String) renames Ada.Directories.Delete_Directory;\n  procedure Delete_Directory (Directory : VString);\n\n  procedure Delete_File (Name : String) renames Ada.Directories.Delete_File;\n  procedure Delete_File (Name : VString);\n\n  function Exists (Name : String) return Boolean renames Ada.Directories.Exists;\n  function Exists (Name : VString) return Boolean;\n  function Directory_Exists (Name : String) return Boolean;\n  function Directory_Exists (Name : VString) return Boolean;\n  function File_Exists (Name : String) return Boolean;\n  function File_Exists (Name : VString) return Boolean;\n\n  procedure Rename (Old_Name : String;  New_Name : String) renames Ada.Directories.Rename;\n  procedure Rename (Old_Name : VString; New_Name : String);\n  procedure Rename (Old_Name : String;  New_Name : VString);\n  procedure Rename (Old_Name : VString; New_Name : VString);\n\n  ---------------------\n  --  Shell_Execute  --\n  ---------------------\n\n  procedure Shell_Execute (Command : String; Result : out Integer);\n  procedure Shell_Execute (Command : VString; Result : out Integer);\n\n  --  In this version, the result value is discarded:\n  procedure Shell_Execute (Command : String);\n  procedure Shell_Execute (Command : VString);\n\n  --  The four above, but with piping of standard output into a VString:\n  procedure Shell_Execute (Command : String; Result : out Integer; Output : out VString);\n  procedure Shell_Execute (Command : VString; Result : out Integer; Output : out VString);\n  procedure Shell_Execute (Command : String; Output : out VString);\n  procedure Shell_Execute (Command : VString; Output : out VString);\n\n  function Directory_Separator return Character;\n\n  --  Semaphore stuff from SmallAda.\n  --  It pre-dates Ada tasks and stems from CoPascal.\n  type Semaphore is new Integer; -- private;\n  procedure  Wait   (S : Semaphore);\n  procedure  Signal (S : Semaphore);\n\n  ---------------------------------\n  --  End of compatibility part  --\n  ---------------------------------\n  --\n  --  The following part is formally public, but can only be directly\n  --  used by the HAC system itself (HAC_Sys) or other \"full Ada\"\n  --  programs using HAT (HAC programs cannot, so far, return String's\n  --  or use generics).\n  --  Some of those \"private\" items avoid code duplication or incompatibilities\n  --  between HAT (as compatibility package) and the HAC run-time system\n  --  itself.\n\n  generic\n    type Abstract_Integer is range <>;\n  function HAC_Generic_Image (I : Abstract_Integer) return String;\n\n  function HAC_Image (F : Real) return String;\n\n  function HAC_Image (T : Ada.Calendar.Time) return String;\n\n  function Search_File (simple_file_name, path : String) return String;\n\nprivate\n\n  --  type       SEMAPHORE is new INTEGER;\n\nend HAT;\n"
  },
  {
    "path": "src/manage/hac_sys-files-default.adb",
    "content": "with Ada.Directories,\n     Ada.Text_IO.Text_Streams,\n     Ada.Unchecked_Deallocation;\n\npackage body HAC_Sys.Files.Default is\n\n  overriding function Exists (cat : File_Catalogue; name : String) return Boolean\n  is\n  begin\n    return Ada.Directories.Exists (name);\n  exception\n    when others => return False;\n  end Exists;\n\n  overriding function Full_Source_Name (cat : File_Catalogue; name : String) return String\n  is\n  begin\n    return Ada.Directories.Full_Name (name);\n  end Full_Source_Name;\n\n  overriding function Full_Spec_Source_Name (cat : File_Catalogue; name : String) return String\n  is\n    other_name : String := name;\n  begin\n    if name'Length > 0 then\n      other_name (other_name'Last) := 's';  --  GNAT convention: .ads for spec.\n    end if;\n    return other_name;\n  end Full_Spec_Source_Name;\n\n  overriding function Full_Body_Source_Name (cat : File_Catalogue; name : String) return String\n  is\n    other_name : String := name;\n  begin\n    if name'Length > 0 then\n      other_name (other_name'Last) := 'b';  --  GNAT convention: .adb for body.\n    end if;\n    return other_name;\n  end Full_Body_Source_Name;\n\n  overriding function Is_Open (cat : File_Catalogue; name : String) return Boolean\n  is\n   file : Text_File_Access;\n  begin\n    if cat.read_open_map.Contains (name) then\n      file := cat.read_open_map.Element (name);\n      if file /= null then\n        return Ada.Text_IO.Is_Open (file.all);\n      end if;\n    end if;\n    return False;\n  end Is_Open;\n\n  overriding procedure Source_Open\n    (cat    : in out File_Catalogue;\n     name   : in     String;\n     stream :    out Root_Stream_Class_Access)\n  is\n    new_file : Text_File_Access;\n  begin\n    if cat.read_open_map.Contains (name) then\n      raise Constraint_Error with \"Attempt to re-open file named \"\"\" & name & '\"';\n    end if;\n    new_file := new Ada.Text_IO.File_Type;\n    cat.read_open_map.Insert (name, new_file);\n    Ada.Text_IO.Open (new_file.all, Ada.Text_IO.In_File, name);\n    stream := Root_Stream_Class_Access (Ada.Text_IO.Text_Streams.Stream (new_file.all));\n  end Source_Open;\n\n  overriding procedure Skip_Shebang\n    (cat            : in out File_Catalogue;\n     name           : in     String;\n     shebang_offset :    out Natural)\n  is\n    file : Text_File_Access;\n  begin\n    shebang_offset := 0;\n    if cat.read_open_map.Contains (name) then\n      file := cat.read_open_map.Element (name);\n      if file /= null\n        and then Ada.Text_IO.Is_Open (file.all)\n        and then not Ada.Text_IO.End_Of_File (file.all)\n      then\n        declare\n          possible_shebang : constant String := Ada.Text_IO.Get_Line (file.all);\n        begin\n          if possible_shebang'Length >= 2\n            and then\n              possible_shebang\n                (possible_shebang'First .. possible_shebang'First + 1) = \"#!\"\n          then\n            --  Ignore the first line, but count it.\n            shebang_offset := 1;\n          else\n            --  Uh-oh: not a shebang. Then we need to reset the file.\n            Ada.Text_IO.Reset (file.all);\n          end if;\n        end;\n      end if;\n    end if;\n  end Skip_Shebang;\n\n  overriding procedure Close (cat : in out File_Catalogue; name : String) is\n    procedure Free is new Ada.Unchecked_Deallocation (Ada.Text_IO.File_Type, Text_File_Access);\n    file : Text_File_Access;\n  begin\n    --  Permissive implementation:\n    --  OK if file is unknown to catalogue or not open.\n    if cat.read_open_map.Contains (name) then\n      file := cat.read_open_map.Element (name);\n      if file /= null then\n        if Ada.Text_IO.Is_Open (file.all) then\n          Ada.Text_IO.Close (file.all);\n        end if;\n        Free (file);\n      end if;\n      cat.read_open_map.Delete (name);\n    end if;\n  end Close;\n\nend HAC_Sys.Files.Default;\n"
  },
  {
    "path": "src/manage/hac_sys-files-default.ads",
    "content": "with Ada.Containers.Indefinite_Hashed_Maps,\n     Ada.Strings.Hash,\n     Ada.Text_IO;\n\npackage HAC_Sys.Files.Default is\n\n  --  This implementation deals with \"physical\" text files, without a search path.\n\n  type File_Catalogue is limited new Files.Abstract_File_Catalogue with private;\n\n  overriding function Exists (cat : File_Catalogue; name : String) return Boolean;\n\n  overriding function Full_Source_Name (cat : File_Catalogue; name : String) return String;\n\n  overriding function Full_Spec_Source_Name (cat : File_Catalogue; name : String) return String;\n\n  overriding function Full_Body_Source_Name (cat : File_Catalogue; name : String) return String;\n\n  overriding function Is_Open (cat : File_Catalogue; name : String) return Boolean;\n\n  overriding procedure Source_Open\n    (cat    : in out File_Catalogue;\n     name   : in     String;\n     stream :    out Root_Stream_Class_Access);\n\n  overriding procedure Skip_Shebang\n    (cat            : in out File_Catalogue;\n     name           : in     String;\n     shebang_offset :    out Natural);\n\n  overriding procedure Close (cat : in out File_Catalogue; name : String);\n\n  overriding procedure Add_to_Source_Path (cat : in out File_Catalogue; new_dir : String)\n  is null;  --  No search path by default.\n\nprivate\n\n  type Text_File_Access is access Ada.Text_IO.File_Type;\n\n  package Default_File_Name_Mapping is new Ada.Containers.Indefinite_Hashed_Maps\n    (Key_Type        => String,\n     Element_Type    => Text_File_Access,\n     Hash            => Ada.Strings.Hash,\n     Equivalent_Keys => \"=\");\n\n  type File_Catalogue is limited new Files.Abstract_File_Catalogue with record\n    read_open_map : Default_File_Name_Mapping.Map;\n  end record;\n\nend HAC_Sys.Files.Default;\n"
  },
  {
    "path": "src/manage/hac_sys-files.ads",
    "content": "with Ada.Streams.Stream_IO;\n\npackage HAC_Sys.Files is\n\n  --  This package deals with files in a broad sense.\n  --\n  --  A file can be, for instance:\n  --    - in the operating system's file system, in current directory\n  --    - in one of a set of directories (a search path)\n  --    - a remote file accessed through the Internet\n  --    - in one or more Zip archives (.har)\n  --    - in a database\n  --    - in a set of open editor windows, with or without\n  --        a \"physical\" file (see the LEA project as an example).\n  --\n  --  In the last four examples, it could be that the \"physical\" file\n  --  cannot be accessed via Ada.*_IO, or doesn't even exists.\n\n  subtype Root_Stream_Class_Access is Ada.Streams.Stream_IO.Stream_Access;\n\n  type Abstract_File_Catalogue is limited interface;\n\n  type Abstract_File_Catalogue_Reference is access all Abstract_File_Catalogue'Class;\n\n  function Exists (cat : Abstract_File_Catalogue; name : String) return Boolean\n  is abstract;\n\n  function Full_Source_Name (cat : Abstract_File_Catalogue; name : String) return String\n  is abstract;\n\n  function Full_Spec_Source_Name (cat : Abstract_File_Catalogue; name : String) return String\n  is abstract;\n\n  function Full_Body_Source_Name (cat : Abstract_File_Catalogue; name : String) return String\n  is abstract;\n\n  function Is_Open (cat : Abstract_File_Catalogue; name : String) return Boolean\n  is abstract;\n\n  --  A source file is a text and its search path\n  --  may be specific to source files.\n  --\n  procedure Source_Open\n    (cat    : in out Abstract_File_Catalogue;\n     name   : in     String;\n     stream :    out Root_Stream_Class_Access)\n  is abstract;\n\n  --  Skip a possible shebang line (such as \"#!/usr/bin/env hac\") that may\n  --  exist as first line of a main unit's source file.\n  --\n  --    shebang_offset = 0 if no shebang was found,\n  --    shebang_offset = 1 if a shebang was found.\n  --\n  procedure Skip_Shebang\n    (cat            : in out Abstract_File_Catalogue;\n     name           : in     String;\n     shebang_offset :    out Natural)\n  is abstract;\n\n  procedure Close (cat : in out Abstract_File_Catalogue; name : String)\n  is abstract;\n\n  --  Inform the File Catalogue that it may have to search a supplemental\n  --  directory.\n  --  It happens for instance on the \"--!hac_add_to_path <dir>\" special comment\n  --  within a HAC program.\n  --\n  procedure Add_to_Source_Path (cat : in out Abstract_File_Catalogue; new_dir : String)\n  is abstract;\n\nend HAC_Sys.Files;\n"
  },
  {
    "path": "src/manage/hac_sys-librarian-built_in_packages.adb",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Defs,\n     HAC_Sys.Compiler.PCode_Emit,\n     HAC_Sys.Parser.Packages;\n\nwith HAT;\nwith Interfaces;\n\npackage body HAC_Sys.Librarian.Built_In_Packages is\n\n  procedure Enter_and_Register_Built_In_Package (\n    CD   : in out Co_Defs.Compiler_Data;\n    LD   : in out Library_Data;\n    name : in     String\n  )\n  is\n    use Co_Defs, Defs;\n    unit : Library_Unit :=\n        (full_name     => HAT.To_VString (name),\n         kind          => Package_Declaration,\n         status        => Done,\n         id_index      => No_Id,\n         id_body_index => No_Id,\n         spec_context  => Co_Defs.Id_Maps.Empty_Map);\n  begin\n    Enter_Library_Level_Def (CD, name, paquetage, NOTYP, 0, is_built_in => True);\n    Parser.Packages.Feed_Packages_Table (CD);\n    --  Feed library:\n    unit.id_index := CD.Id_Count;\n    Register_Unit (LD, unit);\n  end Enter_and_Register_Built_In_Package;\n\n  procedure Define_and_Register_Standard (\n    CD : in out Co_Defs.Compiler_Data;\n    LD : in out Library_Data\n  )\n  is\n    use Co_Defs, Defs;\n    procedure Enter_Std_Typ (Name : String; T : Typen; First, Last : HAC_Integer) is\n    begin\n      Enter_Library_Level_Def (CD, \"Standard.\" & Name, type_mark, T, 1, First, Last, True);\n    end Enter_Std_Typ;\n  begin\n    Enter_Library_Level_Def (CD, \"\", constant_object, NOTYP, 0);  --  Unreachable Id with invalid Link.\n    --\n    Enter_and_Register_Built_In_Package (CD, LD, \"Standard\");\n    --\n    Enter_Library_Level_Def (CD, \"Standard.False\", declared_number_or_enum_item, Bools, 0, is_built_in => True);\n    Enter_Library_Level_Def (CD, \"Standard.True\",  declared_number_or_enum_item, Bools, 1, is_built_in => True);\n    --\n    Enter_Std_Typ (\"Character\",      Chars, 0, 255);\n    Enter_Std_Typ (\"Boolean\",        Bools, 0, 1);\n    Enter_Std_Typ (HAC_Integer_Name, Ints, HAC_Integer'First, HAC_Integer'Last);\n    --\n    --  The \"String\" type identifier is treated separately in the Type_Definition parser\n    --  and returns a constrained array of Character.\n    --  Here we just reserve the \"String\" identifier at library level, with a bogus base,\n    --  type String_Literals, which is actually used only for string literals like \"abcd\".\n    Enter_Std_Typ (\"String\",         String_Literals, 0, 0);\n    CD.String_Id_Index := CD.Id_Count;\n    --\n    Enter_Std_Typ (\"Natural\",  Ints, 0, HAC_Integer'Last);\n    Enter_Std_Typ (\"Positive\", Ints, 1, HAC_Integer'Last);\n    Enter_Std_Typ (\"Duration\", Durations, 0, 0);\n    --\n    CD.Packages_Table (CD.Packages_Count).last_public_declaration := CD.Id_Count;\n  end Define_and_Register_Standard;\n\n  procedure Define_and_Register_Interfaces (\n    CD : in out Co_Defs.Compiler_Data;\n    LD : in out Library_Data\n  )\n  is\n    use Co_Defs, Defs, Interfaces;\n    procedure Enter_Interfaces_Typ (Name : String; T : Typen; First, Last : HAC_Integer) is\n    begin\n      Enter_Library_Level_Def (CD, \"Interfaces.\" & Name, type_mark, T, 1, First, Last, True);\n    end Enter_Interfaces_Typ;\n  begin\n    Enter_and_Register_Built_In_Package (CD, LD, \"Interfaces\");\n    --\n    Enter_Interfaces_Typ (\"Integer_64\", Ints, -2**63, 2**63 - 1);\n    Enter_Interfaces_Typ (\"Integer_32\", Ints, -2**31, 2**31 - 1);\n    Enter_Interfaces_Typ (\"Integer_16\", Ints, -2**15, 2**15 - 1);\n    Enter_Interfaces_Typ (\"Integer_8\",  Ints, -2**7,  2**7  - 1);\n    --\n    CD.Packages_Table (CD.Packages_Count).last_public_declaration := CD.Id_Count;\n  end Define_and_Register_Interfaces;\n\n  procedure Define_and_Register_HAT (\n    CD : in out Co_Defs.Compiler_Data;\n    LD : in out Library_Data\n  )\n  is\n    use Co_Defs, Defs;\n\n    procedure Enter_HAT_Const (Name : String; Value : HAC_Float) is\n      Float_Index : Integer;\n    begin\n      Compiler.PCode_Emit.Enter_or_find_Float (CD, Value, Float_Index);\n      Enter_Library_Level_Def\n        (CD, HAT_Name & '.' & Name,\n         declared_number_or_enum_item, Floats, Float_Index, is_built_in => True);\n    end Enter_HAT_Const;\n\n    procedure Enter_HAT_Typ (Name : String; T : Typen; First, Last : HAC_Integer) is\n    begin\n      Enter_Library_Level_Def (CD, HAT_Name & '.' & Name, type_mark, T, 1, First, Last, True);\n    end Enter_HAT_Typ;\n\n    procedure Enter_HAT_Funct (Name : String; T : Typen; Code : Defs.SF_Code) is\n    begin\n      Enter_Library_Level_Def\n        (CD,\n         HAT_Name & '.' & Name,\n         funktion_intrinsic,\n         T,\n         Defs.SF_Code'Pos (Code),\n         is_built_in => True);\n    end Enter_HAT_Funct;\n\n    procedure Enter_HAT_Proc (Name : String; Code : Defs.SP_Code) is\n    begin\n      Enter_Library_Level_Def\n        (CD,\n         HAT_Name & '.' & Name,\n         prozedure_intrinsic,\n         NOTYP,\n         Defs.SP_Code'Pos (Code),\n         is_built_in => True);\n    end Enter_HAT_Proc;\n\n  begin\n    Enter_and_Register_Built_In_Package (CD, LD, HAT_Name);\n    --\n    Enter_HAT_Typ (\"File_Type\",    Text_Files, 0, 0);  --  2020.05.17\n    Enter_HAT_Typ (HAC_Float_Name, Floats, 0, 0);      --  Moved from Std 2021.12.26\n    Enter_HAT_Typ (\"Semaphore\",    Ints, 0, 0);\n    Enter_HAT_Typ (\"Time\",         Times, 0, 0);\n    Enter_HAT_Typ (\"VString\",      VStrings, 0, 0);    --  2020.05.02\n    --\n    --  Standard functions\n    --\n    Enter_HAT_Funct (\"Chr\",                 Chars,  SF_T_Val);    --  S'Val : RM 3.5.5 (5)\n    Enter_HAT_Funct (\"Ord\",                 Ints,   SF_T_Pos);    --  S'Pos : RM 3.5.5 (2)\n    Enter_HAT_Funct (\"Succ\",                Chars,  SF_T_Succ);   --  S'Succ : RM 3.5 (22)\n    Enter_HAT_Funct (\"Pred\",                Chars,  SF_T_Pred);   --  S'Pred : RM 3.5 (25)\n    --\n    Enter_HAT_Funct (\"Round\",               Ints,   SF_Round_Float_to_Int);\n    Enter_HAT_Funct (\"Trunc\",               Ints,   SF_Trunc_Float_to_Int);\n    --\n    Enter_HAT_Funct (\"Min\",                 Ints,   SF_Min_Int);  --  Overloaded for floats\n    Enter_HAT_Funct (\"Max\",                 Ints,   SF_Max_Int);  --  Overloaded for floats\n    --\n    Enter_HAT_Const (\"Pi\",                  HAT.Pi);\n    Enter_HAT_Funct (\"Sin\",                 Floats, SF_Sin);\n    Enter_HAT_Funct (\"Cos\",                 Floats, SF_Cos);\n    Enter_HAT_Funct (\"Exp\",                 Floats, SF_Exp);\n    Enter_HAT_Funct (\"Log\",                 Floats, SF_Log);\n    Enter_HAT_Funct (\"Sqrt\",                Floats, SF_Sqrt);\n    Enter_HAT_Funct (\"Arctan\",              Floats, SF_Arctan);\n    Enter_HAT_Funct (\"Sgn\",                 Ints,   SF_Sgn_Int);  --  Overloaded for floats\n    --\n    Enter_HAT_Funct (\"Rand\",                Ints,   SF_Random_Int);\n    Enter_HAT_Funct (\"Rnd\",                 Floats, SF_Random_Float);\n    Enter_HAT_Proc  (\"Randomize\",           SP_Randomize);\n    Enter_HAT_Proc  (\"Random_Seed\",         SP_Random_Seed);\n    Enter_HAT_Funct (\"Clock\",               Times,  SF_Clock);\n    --\n    Enter_HAT_Funct (\"Null_VString\",        VStrings,            SF_Null_VString);\n    Enter_HAT_Funct (\"Element\",             Chars,               SF_Element);\n    Enter_HAT_Funct (\"Index\",               Ints,                SF_Index);\n    Enter_HAT_Funct (\"Index_Backward\",      Ints,                SF_Index_Backward);\n    Enter_HAT_Funct (\"Length\",              Ints,                SF_Length);\n    Enter_HAT_Funct (\"Slice\",               VStrings,            SF_Slice);\n    Enter_HAT_Funct (\"To_Lower\",            Chars,               SF_To_Lower_Char);\n    Enter_HAT_Funct (\"To_Upper\",            Chars,               SF_To_Upper_Char);\n    Enter_HAT_Funct (\"To_VString\",          VStrings,            SF_String_Literal_to_VString);\n    Enter_HAT_Funct (\"To_String\",           Strings_as_VStrings, SF_VString_to_String);\n    --\n    Enter_HAT_Funct (\"Trim_Left\",           VStrings, SF_Trim_Left);\n    Enter_HAT_Funct (\"Trim_Right\",          VStrings, SF_Trim_Right);\n    Enter_HAT_Funct (\"Trim_Both\",           VStrings, SF_Trim_Both);\n    --\n    Enter_HAT_Funct (\"Head\",                VStrings, SF_Head);\n    Enter_HAT_Funct (\"Head_Before_Match\",   VStrings, SF_Head_Before_Match);\n    Enter_HAT_Funct (\"Tail\",                VStrings, SF_Tail);\n    Enter_HAT_Funct (\"Tail_After_Match\",    VStrings, SF_Tail_After_Match);\n    Enter_HAT_Funct (\"Starts_With\",         Bools,    SF_Starts_With);\n    Enter_HAT_Funct (\"Ends_With\",           Bools,    SF_Ends_With);\n    --\n    --  Ada.Calendar-like functions\n    --\n    Enter_HAT_Funct (\"Year\",                Ints,      SF_Year);\n    Enter_HAT_Funct (\"Month\",               Ints,      SF_Month);\n    Enter_HAT_Funct (\"Day\",                 Ints,      SF_Day);\n    Enter_HAT_Funct (\"Seconds\",             Durations, SF_Seconds);\n    --\n    --  Attribute-like functions\n    --\n    Enter_HAT_Funct (\"Image\",               VStrings, SF_Image_Ints);\n    Enter_HAT_Funct (\"Integer_Value\",       Ints,     SF_Integer_Value);\n    Enter_HAT_Funct (\"Float_Value\",         Floats,   SF_Float_Value);\n    --\n    --  Ada.Command_Line & Ada.Environment_Variables - like functions\n    --\n    Enter_HAT_Funct (\"Argument_Count\",      Ints,     SF_Argument_Count);\n    Enter_HAT_Funct (\"Argument\",            VStrings, SF_Argument);\n    Enter_HAT_Funct (\"Command_Name\",        VStrings, SF_Command_Name);\n    Enter_HAT_Funct (\"Get_Env\",             VStrings, SF_Get_Env);\n    Enter_HAT_Funct (\"Get_VM_Variable\",     VStrings, SF_Get_VM_Variable);\n    --\n    --  Ada.Directories-like functions\n    --\n    Enter_HAT_Funct (\"Current_Directory\",   VStrings, SF_Current_Directory);\n    Enter_HAT_Funct (\"Directory_Exists\",    Bools,    SF_Directory_Exists);\n    Enter_HAT_Funct (\"Exists\",              Bools,    SF_Exists);\n    Enter_HAT_Funct (\"File_Exists\",         Bools,    SF_File_Exists);\n    --  This one is *not* in Ada.Directories:\n    Enter_HAT_Funct (\"Directory_Separator\", Chars,    SF_Directory_Separator);\n    --\n    Enter_HAT_Funct (\"Get_Needs_Skip_Line\", Bools, SF_Get_Needs_Skip_Line);\n    --\n    --  Ada.Text_IO-like subprograms\n    --\n    Enter_HAT_Proc (\"Create\",         SP_Create);\n    Enter_HAT_Proc (\"Open\",           SP_Open);\n    Enter_HAT_Proc (\"Append\",         SP_Append);\n    Enter_HAT_Proc (\"Close\",          SP_Close);\n    Enter_HAT_Proc (\"Get\",            SP_Get);\n    Enter_HAT_Proc (\"Get_Immediate\",  SP_Get_Immediate);\n    Enter_HAT_Proc (\"Get_Line\",       SP_Get_Line);\n    Enter_HAT_Proc (\"Skip_Line\",      SP_Skip_Line);\n    Enter_HAT_Proc (\"Put\",            SP_Put);\n    Enter_HAT_Proc (\"Put_Line\",       SP_Put_Line);\n    Enter_HAT_Proc (\"New_Line\",       SP_New_Line);\n    Enter_HAT_Funct (\"End_Of_File\",   Bools, SF_EOF);\n    Enter_HAT_Funct (\"End_Of_Line\",   Bools, SF_EOLN);\n    Enter_HAT_Funct (\"Is_Open\",       Bools, SF_Is_Open);\n    --\n    --  Ada.Environment_Variables-like procedures\n    --\n    Enter_HAT_Proc (\"Set_Env\",         SP_Set_Env);\n    Enter_HAT_Proc (\"Set_VM_Variable\", SP_Set_VM_Variable);\n    --\n    --  Ada.Directories-like procedures\n    --\n    Enter_HAT_Proc (\"Copy_File\",        SP_Copy_File);\n    Enter_HAT_Proc (\"Create_Directory\", SP_Create_Directory);\n    Enter_HAT_Proc (\"Create_Path\",      SP_Create_Path);\n    Enter_HAT_Proc (\"Delete_Directory\", SP_Delete_Directory);\n    Enter_HAT_Proc (\"Delete_File\",      SP_Delete_File);\n    Enter_HAT_Proc (\"Rename\",           SP_Rename);\n    Enter_HAT_Proc (\"Set_Directory\",    SP_Set_Directory);\n    --\n    Enter_HAT_Proc (\"Shell_Execute\",   SP_Shell_Execute_with_Result);\n    Enter_HAT_Proc (\"Set_Exit_Status\", SP_Set_Exit_Status);\n    --\n    --  Ada.Strings.Unbounded-like procedures\n    --\n    Enter_HAT_Proc (\"Delete\", SP_Delete);\n    --\n    --  Tasking related (from SmallAda)\n    --\n    Enter_HAT_Proc (\"Wait\",           SP_Wait);\n    Enter_HAT_Proc (\"Signal\",         SP_Signal);\n    Enter_HAT_Proc (\"Quantum\",        SP_Quantum);\n    Enter_HAT_Proc (\"Priority\",       SP_Priority);\n    Enter_HAT_Proc (\"InheritP\",       SP_InheritP);\n    --\n    CD.Packages_Table (CD.Packages_Count).last_public_declaration := CD.Id_Count;\n  end Define_and_Register_HAT;\n\nend HAC_Sys.Librarian.Built_In_Packages;\n"
  },
  {
    "path": "src/manage/hac_sys-librarian-built_in_packages.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n--  This package provides the insertion \"by hand\" of packages\n--  of HAC's run-time library into compiler and library data.\n\nwith HAC_Sys.Co_Defs;\n\nprivate package HAC_Sys.Librarian.Built_In_Packages is\n\n  ---------------------------------------------\n  --  Enter \"manually\" the Standard package  --\n  ---------------------------------------------\n\n  procedure Define_and_Register_Standard (\n    CD : in out Co_Defs.Compiler_Data;\n    LD : in out Library_Data\n  );\n\n  -----------------------------------------------\n  --  Enter \"manually\" the Interfaces package  --\n  -----------------------------------------------\n\n  procedure Define_and_Register_Interfaces (\n    CD : in out Co_Defs.Compiler_Data;\n    LD : in out Library_Data\n  );\n\n  ----------------------------------------\n  --  Enter \"manually\" the HAT package  --\n  ----------------------------------------\n\n  procedure Define_and_Register_HAT (\n    CD : in out Co_Defs.Compiler_Data;\n    LD : in out Library_Data\n  );\n\nend HAC_Sys.Librarian.Built_In_Packages;\n"
  },
  {
    "path": "src/manage/hac_sys-librarian.adb",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Compiler,\n     HAC_Sys.Librarian.Built_In_Packages,\n     HAC_Sys.Parser.Helpers,\n     HAC_Sys.Parser.Packages,\n     HAC_Sys.Errors;\n\nwith Ada.Characters.Handling,\n     Ada.Exceptions;\n\npackage body HAC_Sys.Librarian is\n\n  ---------------------------------------------\n  --  Introduce a new unit into the library  --\n  ---------------------------------------------\n\n  procedure Register_Unit\n    (LD         : in out Library_Data;\n     Descriptor : in     Library_Unit)\n  is\n    use Librarian.Library_Name_Mapping;\n    UVFN : constant HAT.VString := HAT.To_Upper (Descriptor.full_name);\n    is_new : Boolean;\n  begin\n    is_new := LD.map.Find (UVFN) = No_Element;\n    if not is_new then\n      raise Program_Error with\n        \"Duplicate registration for unit \" &\n        HAT.To_String (Descriptor.full_name) &\n        \". This case should be handled by Apply_WITH\";\n    end if;\n    LD.library.Append (Descriptor);\n    LD.map.Insert (UVFN, LD.library.Last_Index);\n    --  HAT.PUT_LINE (\"Registering: \" & Full_Name);\n  end Register_Unit;\n\n  procedure Change_Unit_Details\n    (LD         : in out Library_Data;\n     Descriptor : in     Library_Unit)\n  is\n    use Library_Name_Mapping;\n    UVFN : constant HAT.VString := HAT.To_Upper (Descriptor.full_name);\n    c : Cursor;\n    book_nr : Positive;\n  begin\n    c := LD.map.Find (UVFN);\n    if c = No_Element then\n      raise Program_Error with \"Change_Unit_Status called on non-registered unit\";\n    end if;\n    book_nr := Element (c);\n    LD.library.Replace_Element (book_nr, Descriptor);\n  end Change_Unit_Details;\n\n  procedure Enter_Library_Level_Def\n    (CD             : in out Co_Defs.Compiler_Data;\n     Full_Ident     : in     String;  --  \"Main\", \"Standard.False\", ...\n     New_Entity     : in     Co_Defs.Entity_Kind;\n     Base_Type      : in     Defs.Typen;\n     Size           : in     Integer;\n     Discrete_First : in     Defs.HAC_Integer := Defs.HAC_Integer'First;\n     Discrete_Last  : in     Defs.HAC_Integer := Defs.HAC_Integer'Last;\n     is_built_in    : in     Boolean := False)\n  is\n    use Ada.Characters.Handling, Co_Defs, Defs;\n    use type Nesting_Level;\n    Alfa_Ident       : constant Alfa := S2A (Full_Ident);\n    Alfa_Ident_Upper : constant Alfa := S2A (To_Upper (Full_Ident));\n    last : Index := CD.Id_Count;\n  begin\n    CD.Id_Count := CD.Id_Count + 1;\n    --  Find the last library-level definition:\n    while last > 0 and then CD.id_table (last).lev > 0 loop\n      last := last - 1;\n    end loop;\n    CD.id_table (CD.Id_Count) :=\n      (name                  => Alfa_Ident_Upper,\n       name_with_case        => Alfa_Ident,\n       link                  => last,\n       entity                => New_Entity,\n       decl_kind             => complete,\n       xtyp                  => (TYP            => Base_Type,\n                                 Ref            => 0,\n                                 Is_Range       => False,\n                                 Discrete_First => Discrete_First,\n                                 Discrete_Last  => Discrete_Last),\n       block_or_pkg_ref      => 0,\n       normal                => True,\n       lev                   => 0,\n       adr_or_sz             => HAC_Integer (Size),\n       is_referenced         => False,\n       is_read               => no,\n       is_written_after_init => no,\n       is_initialized        => none,\n       location              => (0, 0, 0));\n\n    CD.target.Mark_Declaration (is_built_in);\n    CD.Blocks_Table (0).Last_Id_Idx := CD.Id_Count;\n    CD.CUD.level_0_def.Include (Alfa_Ident_Upper, CD.Id_Count);\n  end Enter_Library_Level_Def;\n\n  procedure Set_File_Catalogue\n    (LD  : in out Library_Data;\n     cat : in     Files.Abstract_File_Catalogue_Reference)\n  is\n  begin\n    LD.cat := cat;\n  end Set_File_Catalogue;\n\n  function Find_Unit_File_Name\n    (LD        : Library_Data;\n     Unit_Name : String)\n  return String\n  is\n    GNAT_prefix : constant String := GNAT_File_Naming (Unit_Name);\n    spec_fn : constant String := GNAT_prefix & \".ads\";\n    body_fn : constant String := GNAT_prefix & \".adb\";\n  begin\n    if LD.cat.Exists (spec_fn) then\n      return spec_fn;\n    elsif LD.cat.Exists (body_fn) then\n      return body_fn;\n    else\n      return \"\";\n    end if;\n  end Find_Unit_File_Name;\n\n  procedure Activate_Unit (CD : in out Co_Defs.Compiler_Data; Upper_Name : in String) is\n    use Co_Defs, Defs;\n    unit_idx : Natural;\n    upper_name_alfa : constant Alfa := S2A (Upper_Name);\n    use type Nesting_Level;\n  begin\n    --  HAT.PUT_LINE (\"WITH: Activating \" & Upper_Name);\n    --  Activate the unit itself:\n    unit_idx := Parser.Helpers.Locate_Identifier\n      (CD, upper_name_alfa, Level => 0, Level_0_Filter => False);\n    CD.CUD.level_0_def.Include (upper_name_alfa, unit_idx);\n    --  Only packages specifications need to have their items made visible.\n    if CD.id_table (unit_idx).entity = paquetage then\n      declare\n        pkg_table_entry : Package_Table_Entry\n          renames CD.Packages_Table (CD.id_table (unit_idx).block_or_pkg_ref);\n      begin\n        for declaration_in_pkg_index in\n          pkg_table_entry.first_public_declaration ..\n          pkg_table_entry.last_public_declaration\n        loop\n          if CD.id_table (declaration_in_pkg_index).lev = 0 then\n            --  We check that the level is 0 because subprogram\n            --  parameters have level 1 and of course we don't\n            --  want *them* to be globally visible. An inclusion\n            --  of parameters would be especially nasty because\n            --  the identifiers don't have any prefix!\n            CD.CUD.level_0_def.Include\n              (CD.id_table (declaration_in_pkg_index).name,\n               declaration_in_pkg_index);\n          end if;\n        end loop;\n      end;\n    end if;\n  end Activate_Unit;\n\n  procedure Compile_WITHed_Unit\n    (CD         : in out Co_Defs.Compiler_Data;\n     LD         : in out Library_Data;\n     upper_name : in     String)\n  is\n    fn : constant String := Find_Unit_File_Name (LD, upper_name);\n    --  ^ NB: if there is a spec, priority is with the spec.\n    use Co_Defs, Defs, Errors;\n    as_specification, needs_body : Boolean;\n    --\n    unit : Library_Unit :=\n      (full_name     => HAT.To_VString (upper_name),\n       kind          => Package_Declaration,  --  Temporary value\n       status        => In_Progress,          --  Temporary value.\n       id_index      => No_Id,                --  Temporary value.\n       id_body_index => No_Id,                --  Temporary value.\n       spec_context  => Id_Maps.Empty_Map);\n  begin\n    --\n    --  Add new unit name to the library catalogue\n    --\n    --\n    Register_Unit (LD, unit);\n    --\n    if fn = \"\" then\n      Error\n        (CD,\n         err_library_error,\n         \"no file found matching the name \"\"\" &\n         GNAT_File_Naming (upper_name) & \".ad*\"\"\",\n         severity => major);\n    else\n      as_specification := fn (fn'Last) = 's';\n      --  \".ads\" extension ? Then it's a spec.\n      --\n      Compiler.Compile_Unit\n        (CD                     => CD,\n         LD                     => LD,\n         upper_name             => upper_name,\n         file_name              => fn,\n         as_specification       => as_specification,\n         as_main_unit           => False,\n         needs_opening_a_stream => True,\n         first_compilation      => False,\n         specification_id_index => Co_Defs.No_Id,\n         new_id_index           => unit.id_index,\n         unit_context           => unit.spec_context,\n         kind                   => unit.kind,\n         needs_body             => needs_body);\n      --\n      if as_specification then\n        case unit.kind is\n          when Subprogram_Unit =>\n            unit.status := Body_Postponed;\n          when Package_Declaration =>\n            unit.status := (if needs_body then Body_Postponed else Spec_Only);\n          when Package_Body =>\n            null;  --  Not relevant (spec.)\n        end case;\n      else\n        unit.status := Done;\n      end if;\n      Change_Unit_Details (LD, unit);\n      --\n      --  Activate unit library-level declaration for the first time.\n      --  It must be visible to the WITH-ing unit.\n      --\n      Activate_Unit (CD, upper_name);\n    end if;\n  end Compile_WITHed_Unit;\n\n  procedure Apply_WITH\n    (CD         : in out Co_Defs.Compiler_Data;\n     LD         : in out Library_Data;\n     Upper_Name : in     String)\n  is\n    use Ada.Exceptions, Defs, HAT, Errors;\n    UVN : constant VString := To_VString (Upper_Name);\n  begin\n    if LD.map.Contains (UVN) then\n      if LD.library.Element (LD.map.Element (UVN)).status = In_Progress then\n        --  Ouch, we are WITH-ing a unit which is being compiled.\n        raise Circular_Unit_Dependency with Upper_Name;\n      end if;\n      --  Definition is already somewhere in CD (from the compilation\n      --  of another unit), we just need to reactivate it.\n      --  This situation includes the duplicate WITH case (not nice but correct).\n      --  Packages Standard, Interfaces and HAT are also reactivated on\n      --  second WITH (implicitly for Standard).\n      Activate_Unit (CD, Upper_Name);\n    elsif Upper_Name = \"STANDARD\" then\n      Built_In_Packages.Define_and_Register_Standard (CD, LD);\n    elsif Upper_Name = \"INTERFACES\" then\n      Built_In_Packages.Define_and_Register_Interfaces (CD, LD);\n    elsif Upper_Name = \"ADA\"\n      or else (Upper_Name'Length > 3\n               and then Upper_Name (Upper_Name'First .. Upper_Name'First + 3) = \"ADA.\")\n    then\n      Error\n        (CD,\n         err_library_error,\n         \"Ada package (and children) are not yet part of\" &\n         \" HAC's predefined library. Consider the \" & HAT_Name & \" package.\",\n         severity => major);\n    elsif Upper_Name = HAT_Name then\n      Built_In_Packages.Define_and_Register_HAT (CD, LD);\n    elsif Upper_Name in \"HAC_PACK\" | \"HAL\" then\n      Error\n        (CD,\n         err_obsolete_hat_name,\n         HAT_Name,\n         Upper_Name,\n         severity => major);\n    else\n      begin\n        Compile_WITHed_Unit (CD, LD, Upper_Name);\n      exception\n        when E : Circular_Unit_Dependency =>\n          --  Re-raise the exception but add current unit to the\n          --  dependency chain.\n          raise Circular_Unit_Dependency\n            with Upper_Name & \" -> \" & Exception_Message (E);\n      end;\n    end if;\n  end Apply_WITH;\n\n  procedure Apply_WITH_USE_Standard\n    (CD : in out Co_Defs.Compiler_Data;\n     LD : in out Library_Data)\n  is\n  begin\n    Apply_WITH (CD, LD, \"STANDARD\");\n    Parser.Packages.Apply_USE_Clause\n      (CD,\n       Library_Level,\n       False,\n       Parser.Helpers.Locate_Identifier (CD, Defs.S2A (\"STANDARD\"), 0));\n  end Apply_WITH_USE_Standard;\n\n  function GNAT_File_Naming (Unit_Name : String) return String is\n    result : String := Ada.Characters.Handling.To_Lower (Unit_Name);\n  begin\n    for c of result loop\n      if c = '.' then\n        c := '-';\n      end if;\n    end loop;\n    return result;\n  end GNAT_File_Naming;\n\n  function Ada_RM_Casing (Identifier : String) return String is\n    use Ada.Characters.Handling;\n    copy : String := To_Lower (Identifier);\n    first_letter : Boolean := True;\n  begin\n    for i in copy'Range loop\n      if first_letter then\n        copy (i) := To_Upper (copy (i));\n      end if;\n      first_letter := copy (i) = '_';\n    end loop;\n    return copy;\n  end Ada_RM_Casing;\n\nend HAC_Sys.Librarian;\n"
  },
  {
    "path": "src/manage/hac_sys-librarian.ads",
    "content": "-------------------------------------------------------------------------------------\n--\n--  HAC - HAC Ada Compiler\n--\n--  A compiler in Ada for an Ada subset\n--\n--  Copyright, license, etc. : see top package.\n--\n-------------------------------------------------------------------------------------\n--\n\nwith HAC_Sys.Co_Defs,\n     HAC_Sys.Defs,\n     HAC_Sys.Files.Default;\n\nwith HAT;\n\nwith Ada.Containers.Hashed_Maps,\n     Ada.Containers.Vectors,\n     Ada.Strings.Unbounded.Hash;\n\npackage HAC_Sys.Librarian is\n\n  Library_Level : constant := 0;\n\n  type Build_Mode is\n    (Read_HCU_Files\n        --  ^ Full compilation around main unit is done in memory.\n        --    If available and { up-to-date or no source file present },\n        --    .hcu files are downloaded to the compilation tables.\n     --  Write_HCU_Files\n     --    --    If a .hcu file not yet available or out-of-date,\n     --    --    the source is compiled and the .hcu file is (re)written.\n    );\n\n  --  HAC Compiled Unit files have the .hcu extension. Some may be stored in .zip library files.\n\n  type Compilation_Status is\n    (In_Progress,     --  Specification or body-only is in progress.\n     Body_Postponed,  --  Specification done, body will be done later.\n     Spec_Only,       --  Specification-only is done, but we need to check absence of body.\n     Done);           --  Specification done; possible body is done or its absence is checked.\n\n  subtype Spec_Done is Compilation_Status range Body_Postponed .. Spec_Only;\n\n  --  RM 10.1.1\n\n  type Unit_Kind is\n    (Package_Declaration, Package_Body,\n     Procedure_Unit, Function_Unit);\n\n  subtype Subprogram_Unit is Unit_Kind range Procedure_Unit .. Function_Unit;\n\n  type Library_Unit is record\n    full_name     : HAT.VString;  --  Full unit name, like \"Ada.Strings.Fixed\"\n    kind          : Unit_Kind;\n    status        : Compilation_Status;\n    id_index      : Natural;\n    id_body_index : Natural;\n    spec_context  : Co_Defs.Id_Maps.Map;  --  WITH & USE's visible to the spec.\n  end record;\n\n  package Library_Unit_Vectors is new Ada.Containers.Vectors (Positive, Library_Unit);\n\n  package Library_Name_Mapping is new Ada.Containers.Hashed_Maps\n    (Key_Type        => HAT.VString,  --  Upper case of full unit name\n     Element_Type    => Positive,     --  Index in the library\n     Hash            => Ada.Strings.Unbounded.Hash,\n     Equivalent_Keys => Ada.Strings.Unbounded.\"=\");\n\n  --  Global object used as a default for library file management:\n  default_file_catalogue : aliased Files.Default.File_Catalogue;\n\n  type Library_Data is tagged record  --  !! details -> private\n    library      : Library_Unit_Vectors.Vector;  --  The library itself (= the \"books\")\n    map          : Library_Name_Mapping.Map;     --  Quick access by name to unit number\n    cat          : Files.Abstract_File_Catalogue_Reference :=\n                     default_file_catalogue'Access;\n  end record;\n\n  --  Method used internally by HAC.\n  --  Prefer using Build_Data's Set_File_Catalogue method.\n  --\n  procedure Set_File_Catalogue\n    (LD  : in out Library_Data;\n     cat : in     Files.Abstract_File_Catalogue_Reference);\n\n  --  Search for file (physical or not, depending on the\n  --  LD.cat.Exists function) corresponding to unit name.\n  --  First a spec, then a body.\n  --  If nothing found, return empty string.\n  --\n  function Find_Unit_File_Name\n    (LD        : Library_Data;\n     Unit_Name : String)\n  return String;\n\n  -----------------------------------------------------\n  --  Apply WITH clause for any unit, including the  --\n  --  Standard package and the special HAT package.  --\n  -----------------------------------------------------\n\n  procedure Apply_WITH\n    (CD         : in out Co_Defs.Compiler_Data;\n     LD         : in out Library_Data;\n     Upper_Name : in     String);\n\n  ----------------------------------------------------------\n  --  Apply the invisible \"with Standard; use Standard;\"  --\n  ----------------------------------------------------------\n\n  procedure Apply_WITH_USE_Standard\n    (CD : in out Co_Defs.Compiler_Data;\n     LD : in out Library_Data);\n\n  ----------------------------------------------------------------------\n  --  Add a new definition to the identifier table, at library level  --\n  ----------------------------------------------------------------------\n\n  procedure Enter_Library_Level_Def\n    (CD             : in out Co_Defs.Compiler_Data;\n     Full_Ident     : in     String;  --  \"Main\", \"Standard.False\", ...\n     New_Entity     : in     Co_Defs.Entity_Kind;\n     Base_Type      : in     Defs.Typen;\n     Size           : in     Integer;\n     Discrete_First : in     Defs.HAC_Integer := Defs.HAC_Integer'First;\n     Discrete_Last  : in     Defs.HAC_Integer := Defs.HAC_Integer'Last;\n     is_built_in    : in     Boolean := False);\n\n  Circular_Unit_Dependency : exception;\n\n  procedure Register_Unit\n    (LD         : in out Library_Data;\n     Descriptor : in     Library_Unit);\n\n  procedure Change_Unit_Details\n    (LD         : in out Library_Data;\n     Descriptor : in     Library_Unit);\n     --  ^ Changes in the library the details for\n     --    unit named Descriptor.Full_Name.\n\n  ----------------------------------------------------------------------\n  --  GNAT_File_Naming returns the file name that GNAT expects for    --\n  --  a unit with the name Unit_Name.                                 --\n  ----------------------------------------------------------------------\n\n  function GNAT_File_Naming (Unit_Name : String) return String;\n\n  function Ada_RM_Casing (Identifier : String) return String;\n\nprivate\n\nend HAC_Sys.Librarian;\n"
  },
  {
    "path": "test/all_noisy_tests.adb",
    "content": "--  We launch new instances of HAC (possibly from HAC itself, too).\n--  Usage:  hac all_noisy_tests.adb\n\nwith HAT;\n\nprocedure All_Noisy_Tests is\n\n  use HAT;\n\n  procedure Launch_Tests is\n\n    procedure Shell (command : VString; echo : Boolean) is\n    begin\n      if echo then\n        Put_Line (\"Executing: [\" & command & ']');\n      end if;\n      Shell_Execute (command);\n    end Shell;\n\n    procedure Launch_HAC (Ada_file_name : VString) is\n    begin\n      Put_Line (\"-------------------------------------------------------\");\n      Shell (\n        +\"..\" & Directory_Separator & \"hac -v1 \" & Ada_file_name,\n        False\n      );\n    end Launch_HAC;\n\n    procedure Build_HAC is\n    begin\n      if Get_Env (\"hacbuild\") = \"done\" then\n        return;\n      end if;\n      Put_Line (\"(Re-)building HAC, in case the present program isn't run from HAC...\");\n      Shell (+\"gprbuild -P ..\" & Directory_Separator & \"hac\", True);\n    end Build_HAC;\n\n    procedure Pause is\n      dummy : Character;\n    begin\n      Put (\"--- Press any key to continue in the HAC noisy test suite...\");\n      Get_Immediate (dummy);\n      New_Line;\n    end Pause;\n\n  begin\n    Put_Line (\"    ___________      _________________________________\");\n    Put_Line (\"   / *  HAC  * \\    /  \"\"Noisy tests\"\": a human is      \\\");\n    Put_Line (\"   \\__Testing__/    \\__required to check the output.__/\");\n    New_Line;\n    Build_HAC;  --  Redundant if this program is itself run through HAC.\n    --\n    Put_Line (\"----> Launching tests (one instance of HAC each)...\");\n    for e in 1 .. 4 loop\n      Launch_HAC (+\"exception_0\" & e & \".adb\");\n    end loop;\n    Pause;\n    Launch_HAC (+\"if_then_elsif_else.adb\");\n    Pause;\n    Launch_HAC (+\"digitz.adb\");\n    Put_Line (\"----> Done.\");\n  end Launch_Tests;\n\nbegin\n  Launch_Tests;\nend All_Noisy_Tests;\n"
  },
  {
    "path": "test/all_silent_tests.adb",
    "content": "--  This program runs a series of more than 115 regression tests to check\n--  the correct operation of the HAC compiler.\n--\n--  The failures and success are accounted and the sums are shown at the end.\n--\n--  NB: the individual tests, or this program itself, can actually be used\n--  for testing any Ada compiler. For that, all you have to do is to\n--  customize the procedure Launch_HAC below.\n--\n--  For each test we launch, possibly from HAC itself, a new instance of\n--  the HAC command-line tool (`hac` or `hac.exe`), which will build the\n--  test sources as a virtual machine executable and run it.\n--\n--  Usage (if run from `hac` or `hac.exe`):  hac all_silent_tests.adb\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure All_Silent_Tests is\n\n  use HAT;\n\n  procedure Launch_Tests is\n\n    procedure Shell (command : VString; echo : Boolean; success : out Boolean) is\n      r : Integer;\n    begin\n      if echo then\n        Put_Line (\"Executing: [\" & command & ']');\n      end if;\n      Shell_Execute (command, r);\n      success := r = Testing_Utilities.OK_Code;\n      if not success then\n        Put_Line (+\"*** Command: [\" & command & \"] FAILED ***. Return code: \" & r);\n      end if;\n    end Shell;\n\n    procedure Build_HAC (success : out Boolean) is\n    begin\n      if Get_Env (\"hacbuild\") = \"done\" then\n        success := True;\n        return;\n      end if;\n      Put_Line (\"(Re-)building HAC, in case the present program isn't run from HAC...\");\n      Shell (+\"gprbuild -P ..\" & Directory_Separator & \"hac\", True, success);\n    end Build_HAC;\n\n    successes, failures : Natural := 0;\n\n    procedure Launch_HAC (Ada_file_name, args : VString; ups : Positive) is\n      success : Boolean;\n    begin\n      Shell (\n        ups * (+\"..\" & Directory_Separator) & \"hac \" & Ada_file_name & ' ' & args,\n        False,\n        success\n      );\n      if success then\n        successes := successes + 1;\n      else\n        failures := failures + 1;\n      end if;\n    end Launch_HAC;\n\n    procedure Normal_Test (Ada_file_name : VString) is\n      short : VString;\n      sep : constant Natural := Index_Backward (Ada_file_name, Directory_Separator);\n      spc : constant Natural := Index_Backward (Ada_file_name, ' ');\n    begin\n      if spc > 0 then\n        short := Slice (Ada_file_name, sep + 1, spc - 1);\n      else\n        short := Slice (Ada_file_name, sep + 1, Length (Ada_file_name));\n      end if;\n      Put_Line (+\"      \" & short);\n      Launch_HAC (Ada_file_name, +\"\", 1);\n    end Normal_Test;\n\n    --  Advent of Code\n\n    procedure Launch_AoC (Year, Day, Solutions : VString) is\n    begin\n      if Index (Current_Directory, Year) = 0 then\n        New_Line;\n        Set_Directory (+\"..\" & Directory_Separator & Year);\n        Put_Line (\"    Advent of Code \" & Year & \" in \" & Current_Directory & ':');\n        Put (\"      \");\n      end if;\n      Put (Day & ' ');\n      Launch_HAC\n        (+\"aoc_\" & Year & '_' & Day & \".adb \",\n         Solutions,\n         --  ^ Solutions are validated by https://adventofcode.com/ .\n         --    It's the pair of answers, each appearing after\n         --   \"Your puzzle answer was \", separated by a space.\n         3);\n    end Launch_AoC;\n\n    hac_build_success : Boolean;\n\n    examples_dir : constant VString :=\n      +\"..\" & Directory_Separator &\n       \"exm\" & Directory_Separator;\n\n    generate : constant VString :=\n      +\"..\" & Directory_Separator &\n       \"hac \" & examples_dir & \"pkg_demo_gen.adb\";\n\n  begin\n    Put_Line (\"    ______________________      _____________________________________________\");\n    Put_Line (\"   /    *   H A C   *     \\    /  \"\"Silent tests\"\": when the failure count     \\\");\n    Put_Line (\"   |  Regression Testing  |    |  is zero, then the test suite is all fine.  |\");\n    Put_Line (\"   \\______________________/    \\_____________________________________________/\");\n    New_Line;\n    Build_HAC (hac_build_success);  --  Redundant if this program is itself run through HAC.\n    if not hac_build_success then\n      Put_Line (\"--- HAC build failed (called from all_silent_tests.adb) ---\");\n      return;\n    end if;\n    --\n    Put_Line (\"----> Launching tests.\");\n    Put_Line (\"  One instance of HAC is called each time, with compilation and execution...\");\n    New_Line;\n    Put_Line (+\"    Normal tests in \" & Current_Directory & ':');\n    Normal_Test (+\"attributes_test.adb\");\n    Normal_Test (examples_dir & \"barnes.adb 3816547290\");\n    Normal_Test (+\"case_statement.adb\");\n    Normal_Test (+\"constants.adb\");\n    Normal_Test (+\"declarations.adb\");\n    Normal_Test (+\"enumerations.adb\");\n    Normal_Test (+\"floats.adb\");\n    Normal_Test (+\"forward.adb\");\n    Normal_Test (+\"integers.adb\");\n    Normal_Test (+\"loops.adb\");\n    Normal_Test (+\"object_init.adb\");\n    --  Create the X_* packages, run pkg_demo and finally delete the X_* packages .\n    Shell_Execute (generate);\n    Normal_Test (+\"-I. ..\" & Directory_Separator & \"exm\" & Directory_Separator & \"pkg_demo.adb test_mode\");\n    Shell_Execute (generate & \" delete\");\n    --\n    Normal_Test (+\"recursion.adb\");\n    Normal_Test (+\"remarks_check.adb\");\n    Normal_Test (+\"sorting_tests.adb\");\n    Normal_Test (+\"strings.adb\");\n    Normal_Test (examples_dir & \"tasking\" & Directory_Separator & \"tasks_02.adb x\");\n    Normal_Test (+\"type_conversion.adb\");\n    --\n    Set_Directory (+\"..\" & Directory_Separator &\n                   \"exm\" & Directory_Separator &\n                   \"aoc\" & Directory_Separator &\n                   \"2021\");  --  <- We put on purpose the wrong starting year.\n    --\n    Launch_AoC (+\"2020\", +\"02\", +\"607 321\");                      --  Password Philosophy\n    Launch_AoC (+\"2020\", +\"03\", +\"218 3847183340\");               --  Toboggan Trajectory\n    Launch_AoC (+\"2020\", +\"04\", +\"228 175\");                      --  Passport Processing\n    Launch_AoC (+\"2020\", +\"05\", +\"835\");                          --  Binary Boarding\n    Launch_AoC (+\"2020\", +\"06\", +\"6532 3427\");                    --  Custom Customs\n    Launch_AoC (+\"2020\", +\"07\", +\"169 82372\");                    --  Handy Haversacks\n    Launch_AoC (+\"2020\", +\"08\", +\"1394 1626\");                    --  Handheld Halting\n    Launch_AoC (+\"2020\", +\"09\", +\"138879426 23761694\");           --  Encoding Error\n    Launch_AoC (+\"2020\", +\"10\", +\"2277 37024595836928\");          --  Adapter Array\n    Launch_AoC (+\"2020\", +\"11\", +\"37 26\");                        --  Seating System\n    Launch_AoC (+\"2020\", +\"12\", +\"1631 58606\");                   --  Rain Risk\n    Launch_AoC (+\"2020\", +\"13\", +\"222 408270049879073\");          --  Shuttle Search\n    Launch_AoC (+\"2020\", +\"15\", +\"436 1 10 27 78 438 1836 249\");  --  Rambunctious Recitation\n    Launch_AoC (+\"2020\", +\"16\", +\"23954 453459307723\");           --  Ticket Translation\n    Launch_AoC (+\"2020\", +\"17\", +\"207\");                          --  Conway Cubes\n    Launch_AoC (+\"2020\", +\"20\", +\"83775126454273\");               --  Jurassic Jigsaw\n    Launch_AoC (+\"2020\", +\"22\", +\"31957\");                        --  Crab Combat\n    Launch_AoC (+\"2020\", +\"23\", +\"67384529 49576328\");            --  Crab Cups\n    Launch_AoC (+\"2020\", +\"24\", +\"341 285\");                      --  Lobby Layout\n    --\n    Launch_AoC (+\"2021\", +\"01\", +\"1154 1127\");               --  Sonar Sweep\n    Launch_AoC (+\"2021\", +\"02\", +\"2187380 2086357770\");      --  Dive!\n    Launch_AoC (+\"2021\", +\"03\", +\"3549854 3765399\");         --  Binary Diagnostic\n    Launch_AoC (+\"2021\", +\"04\", +\"39984 8468\");              --  Giant Squid\n    Launch_AoC (+\"2021\", +\"05\", +\"6225 22116\");              --  Hydrothermal Venture\n    Launch_AoC (+\"2021\", +\"06\", +\"388419 1740449478328\");    --  Lanternfish\n    Launch_AoC (+\"2021\", +\"07\", +\"340052 92948968\");         --  The Treachery of Whales\n    Launch_AoC (+\"2021\", +\"08\", +\"440 1046281\");             --  Seven Segment Search\n    Launch_AoC (+\"2021\", +\"09\", +\"423 1198704\");             --  Smoke Basin\n    Launch_AoC (+\"2021\", +\"10\", +\"388713 3539961434\");       --  Syntax Scoring\n    Launch_AoC (+\"2021\", +\"11\", +\"1679 519\");                --  Dumbo Octopus\n    Launch_AoC (+\"2021\", +\"12\", +\"3497\");                    --  Passage Pathing\n    Launch_AoC (+\"2021\", +\"13\", +\"602\");                     --  Transparent Origami\n    Launch_AoC (+\"2021\", +\"14\", +\"2345 2432786807053\");      --  Extended Polymerization\n    Launch_AoC (+\"2021\", +\"15\", +\"656\");                     --  Chiton\n    Launch_AoC (+\"2021\", +\"16\", +\"927 1725277876501\");       --  Packet Decoder\n    Launch_AoC (+\"2021\", +\"21\", +\"684495 152587196649184\");  --  Dirac Dice\n    --\n    Launch_AoC (+\"2022\", +\"01\", +\"68442 204837\");                   --  Calorie Counting\n    Launch_AoC (+\"2022\", +\"02\", +\"14531 11258\");                    --  Rock Paper Scissors\n    Launch_AoC (+\"2022\", +\"03\", +\"8185 2817\");                      --  Rucksack Reorganization\n    Launch_AoC (+\"2022\", +\"04\", +\"657 938\");                        --  Camp Cleanup\n    Launch_AoC (+\"2022\", +\"05\", +\"VQZNJMWTR NLCDCLVMQ\");            --  Supply Stacks\n    Launch_AoC (+\"2022\", +\"06\", +\"1802 3551\");                      --  Tuning Trouble\n    Launch_AoC (+\"2022\", +\"07\", +\"1749646 1498966\");                --  No Space Left On Device\n    Launch_AoC (+\"2022\", +\"08\", +\"1843 180000\");                    --  Treetop Tree House\n    Launch_AoC (+\"2022\", +\"09\", +\"6314 2504\");                      --  Rope Bridge\n    Launch_AoC (+\"2022\", +\"10\", +\"12880\");                          --  Cathode-Ray Tube\n    Launch_AoC (+\"2022\", +\"11\", +\"102399 23641658401\");             --  Monkey in the Middle\n    Launch_AoC (+\"2022\", +\"12\", +\"440 439\");                        --  Hill Climbing Algorithm\n    Launch_AoC (+\"2022\", +\"13\", +\"6568 19493\");                     --  Distress Signal\n    Launch_AoC (+\"2022\", +\"14\", +\"964 32041\");                      --  Regolith Reservoir\n    Launch_AoC (+\"2022\", +\"17\", +\"3193 1577650429835\");             --  Pyroclastic Flow\n    Launch_AoC (+\"2022\", +\"18\", +\"3374 2010\");                      --  Boiling Boulders\n    Launch_AoC (+\"2022\", +\"21\", +\"286698846151845 3759566892642\");  --  Monkey Math\n    Launch_AoC (+\"2022\", +\"22\", +\"26558 110400\");                   --  Monkey Map\n    Launch_AoC (+\"2022\", +\"23\", +\"3689 965\");                       --  Unstable Diffusion\n    --\n    Launch_AoC (+\"2023\", +\"01\", +\"52974 53340\");                    --  Trebuchet?!\n    Launch_AoC (+\"2023\", +\"02\", +\"2176 63700\");                     --  Cube Conundrum\n    Launch_AoC (+\"2023\", +\"03\", +\"539590 80703636\");                --  Gear Ratios\n    Launch_AoC (+\"2023\", +\"04\", +\"23750 13261850\");                 --  Scratchcards\n    Launch_AoC (+\"2023\", +\"05\", +\"261668924 24261545\");             --  If You Give A Seed A Fertilizer\n    Launch_AoC (+\"2023\", +\"06\", +\"393120 36872656\");                --  Wait For It\n    Launch_AoC (+\"2023\", +\"07\", +\"252656917 253499763\");            --  Camel Cards\n    Launch_AoC (+\"2023\", +\"08\", +\"12737 9064949303801\");            --  Haunted Wasteland\n    Launch_AoC (+\"2023\", +\"09\", +\"1884768153 1031\");                --  Mirage Maintenance\n    Launch_AoC (+\"2023\", +\"10\", +\"6897 367\");                       --  Pipe Maze\n    Launch_AoC (+\"2023\", +\"11\", +\"10173804 634324905172\");          --  Cosmic Expansion\n    Launch_AoC (+\"2023\", +\"12\", +\"7007 3476169006222\");             --  Hot Springs\n    Launch_AoC (+\"2023\", +\"13\", +\"33728 28235\");                    --  Point of Incidence\n    Launch_AoC (+\"2023\", +\"14\", +\"113078 94255\");                   --  Parabolic Reflector Dish\n    Launch_AoC (+\"2023\", +\"15\", +\"513172 237806\");                  --  Lens Library\n    Launch_AoC (+\"2023\", +\"16\", +\"7996\");                           --  The Floor Will Be Lava\n    Launch_AoC (+\"2023\", +\"17\", +\"102 94\");                         --  Clumsy Crucible (example's data)\n    Launch_AoC (+\"2023\", +\"18\", +\"53300 64294334780659\");           --  Lavaduct Lagoon\n    Launch_AoC (+\"2023\", +\"19\", +\"19114 167409079868000\");          --  Aplenty\n    Launch_AoC (+\"2023\", +\"20\", +\"806332748 228060006554227\");      --  Pulse Propagation\n    Launch_AoC (+\"2023\", +\"21\", +\"3677\");                           --  Step Counter\n    Launch_AoC (+\"2023\", +\"22\", +\"5 7\");                            --  Sand Slabs (example's data)\n    Launch_AoC (+\"2023\", +\"23\", +\"94 154\");                         --  A Long Walk (example's data)\n    --  Launch_AoC (+\"2023\", +\"24\", +\"24192 664822352550558\");      --  Never Tell Me The Odds (depends on floating-point accuracy of HAT.Real)\n    Launch_AoC (+\"2023\", +\"25\", +\"54\");                             --  Snowverload (example's data)\n    --\n    Launch_AoC (+\"2024\", +\"01\", +\"2086478 24941624\");                             --  Historian Hysteria (sorting)\n    Launch_AoC (+\"2024\", +\"02\", +\"332 398\");                                      --  Red-Nosed Reports\n    Launch_AoC (+\"2024\", +\"03\", +\"173529487 99532691\");                           --  Mull It Over\n    Launch_AoC (+\"2024\", +\"04\", +\"2483 1925\");                                    --  Ceres Search\n    Launch_AoC (+\"2024\", +\"05\", +\"5166\");                                         --  Print Queue\n    Launch_AoC (+\"2024\", +\"06\", +\"5461\");                                         --  Guard Gallivant (part 2 takes 4 minutes on HAC!)\n    Launch_AoC (+\"2024\", +\"07\", +\"850435817339\");                                 --  Bridge Repair (part 2 takes 3 minutes on HAC!)\n    Launch_AoC (+\"2024\", +\"08\", +\"409 1308\");                                     --  Resonant Collinearity\n    Launch_AoC (+\"2024\", +\"09\", +\"6340197768906\");                                --  Disk Fragmenter (part 2 takes 34 seconds on HAC!)\n    Launch_AoC (+\"2024\", +\"10\", +\"737 1619\");                                     --  Hoof It\n    Launch_AoC (+\"2024\", +\"11\", +\"198089 236302670835517\");                       --  Plutonian Pebbles\n    Launch_AoC (+\"2024\", +\"12\", +\"1319878 784982\");                               --  Garden Groups\n    Launch_AoC (+\"2024\", +\"13\", +\"36954 79352015273424\");                         --  Claw Contraption\n    Launch_AoC (+\"2024\", +\"14\", +\"226236192\");                                    --  Restroom Redoubt (part 2 is visual)\n    Launch_AoC (+\"2024\", +\"15\", +\"1515788 1516544\");                              --  Warehouse Woes\n    Launch_AoC (+\"2024\", +\"16\", +\"74392\");                                        --  Reindeer Maze (part 2 takes long even on GNAT)\n    Launch_AoC (+\"2024\", +\"17\", +\"4635635210\");                                   --  Chronospatial Computer (example's data)\n    Launch_AoC (+\"2024\", +\"18\", +\"298 52,32\");                                    --  RAM Run\n    Launch_AoC (+\"2024\", +\"19\", +\"260 639963796864990\");                          --  Linen Layout\n    Launch_AoC (+\"2024\", +\"20\", +\"44 285\");                                       --  Race Condition (example's data)\n    Launch_AoC (+\"2024\", +\"21\", +\"222670 271397390297138\");                       --  Keypad Conundrum\n    Launch_AoC (+\"2024\", +\"22\", +\"37990510 23\");                                  --  Monkey Market (example's data)\n    Launch_AoC (+\"2024\", +\"23\", +\"1227 cl,df,ft,ir,iy,ny,qp,rb,sh,sl,sw,wm,wy\");  --  LAN Party\n    Launch_AoC (+\"2024\", +\"24\", +\"57270694330992\");                               --  Crossed Wires\n    Launch_AoC (+\"2024\", +\"25\", +\"3395\");                                         --  Code Chronicle\n    --\n    Launch_AoC (+\"2025\", +\"01\", +\"989 5941\");                     --  Secret Entrance\n    Launch_AoC (+\"2025\", +\"02\", +\"1227775554 4174379265\");        --  Gift Shop (example's data)\n    Launch_AoC (+\"2025\", +\"03\", +\"17613 175304218462560\");        --  Lobby\n    Launch_AoC (+\"2025\", +\"04\", +\"1320 8354\");                    --  Printing Department\n    Launch_AoC (+\"2025\", +\"05\", +\"798 366181852921027\");          --  Cafeteria\n    Launch_AoC (+\"2025\", +\"06\", +\"4449991244405 9348430857627\");  --  Trash Compactor\n    Launch_AoC (+\"2025\", +\"07\", +\"1562 24292631346665\");          --  Laboratories\n    Launch_AoC (+\"2025\", +\"08\", +\"40 25272\");                     --  Playground (example's data)\n    Launch_AoC (+\"2025\", +\"09\", +\"4749838800 1624057680\");        --  Movie Theater\n    Launch_AoC (+\"2025\", +\"10\", +\"7\");                            --  Factory\n    Launch_AoC (+\"2025\", +\"11\", +\"423 333657640517376\");          --  Reactor\n    --\n    New_Line (2);\n    New_Line;\n    Put_Line (\"----> Done.\");\n    New_Line;\n    if failures = 0 then\n      Put_Line (\"All tests passed successfully.\");\n    else\n      Put_Line (+\"*** There are FAILED tests ***\");\n    end if;\n    Put_Line (\"Summary:\");\n    Put_Line (+\"        \" & successes & \" successes\");\n    Put_Line (+\"          \" & failures & \" failures\");\n    New_Line;\n  end Launch_Tests;\n\nbegin\n  Launch_Tests;\nend All_Silent_Tests;\n"
  },
  {
    "path": "test/attributes_test.adb",
    "content": "with HAT;\r\nwith Testing_Utilities;\r\n\r\nprocedure Attributes_Test is\r\n  use HAT, Testing_Utilities;\r\n\r\n  type Enum is (aa, bb, cc, dd);\r\n  subtype Sub_Enum is Enum range bb .. cc;\r\n\r\n  dummy_e : Enum;\r\n  dummy_i, sum : Integer;\r\n\r\n  type A is array (Sub_Enum) of HAT.Real;\r\n  type M is array (-5 .. -2, bb .. dd) of Integer;\r\n  mm : M;\r\n\r\n  type R is record\r\n    x : Real;\r\n    y : M;\r\n  end record;\r\n\r\n  mmm : array (10 .. 20) of R;\r\n\r\nbegin\r\n  Assert (Enum'Image (bb) < Enum'Image (cc), +\"\"\"<\"\" on values Strings_as_VStrings, Image\");\r\n\r\n  Assert (Enum'First = aa,     +\"S'First\");\r\n  Assert (Enum'Last = dd,      +\"S'Last\");\r\n  Assert (Enum'Pred (dd) = cc, +\"S'Pred\");\r\n  Assert (Enum'Succ (bb) = cc, +\"S'Succ\");\r\n\r\n  Assert (bb = A'First, +\"A'First\");\r\n  Assert (cc = A'Last,  +\"A'Last\");\r\n  Assert (2 = A'Length, +\"A'Length\");\r\n\r\n  Assert (M'First (1) = -5, +\"M'First (1)\");\r\n  Assert (M'Last (1) = -2,  +\"M'Last (1)\");\r\n  Assert (bb = M'First (2), +\"M'First (2)\");\r\n  Assert (dd = M'Last (2),  +\"M'Last (2)\");\r\n\r\n  for i in M'Range (1) loop\r\n    for j in M'Range (2) loop\r\n      mm (i, j) := i * Enum'Pos (j);\r\n    end loop;\r\n  end loop;\r\n\r\n  sum := 0;\r\n  for j in M'Range (2) loop\r\n    for i in M'Range (1) loop\r\n      sum := sum + mm (i, j);\r\n    end loop;\r\n  end loop;\r\n  Assert (sum = -84, +\"M'Range (N)\");\r\n\r\n  --  Calm down the warning [-rv] about a variable read but never written:\r\n  mmm (10).x := 123.0;\r\n\r\n  Assert (-2 = mmm (10).y'Last (1),  +\"Obj.Last (1)\");\r\n  Assert (bb = mmm (15).y'First (2), +\"Obj.First (2)\");\r\n\r\nend Attributes_Test;\r\n"
  },
  {
    "path": "test/case_statement.adb",
    "content": "with HAT;\nwith Testing_Utilities;\n\nprocedure Case_Statement is\n  use HAT, Testing_Utilities;\n\n  after_int_case : Boolean := False;\n\n  procedure Test_Int (i : Integer) is\n  begin\n    case (2 * (i + 1)) / 2 - 1 is\n      when 1 | -1 =>\n        Assert (abs i = 1, +\"Compiler bug [CASE test, Int, A]\");\n      when -7 =>\n        Assert (i + 7 = 0, +\"Compiler bug [CASE test, Int, B]\");\n      when others => null;\n      --\n      --  when 9 | others => null;  --  the choice \"others\" must appear alone and last\n      --  when 2 => null;  --  the choice \"others\" must appear alone and last\n      --  when 2 .. 9223372036854775807   => null;\n      --  when -9223372036854775807 .. -8 => null;  --  Integer'First as literal not supported (overflow)\n    end case;\n    after_int_case := True;\n  end Test_Int;\n\n  some_vowels_occurrences : Integer := 0;\n  small_consonants_occurrences : Integer := 0;\n\n  procedure Test_Char (c : Character) is\n  begin\n    case c is\n      when 'a' | 'A' =>\n        if (c /= 'a') and (c /= 'A') then\n          Put (c); Put_Line (\"  Compiler bug [Char, A]\");\n          Set_Exit_Status (1);  --  Compiler test failed.\n        end if;\n        some_vowels_occurrences := some_vowels_occurrences + 1;\n      when '*' =>\n        null;\n      when 'e' =>\n        some_vowels_occurrences := some_vowels_occurrences + 1;\n      when 'b' .. 'd' | 'f' .. 'h' | 'j' .. 'n' | 'p' .. 't' | 'v' .. 'x' | 'z' =>\n        small_consonants_occurrences := small_consonants_occurrences + 1;\n      when others => null;\n    end case;\n  end Test_Char;\n\n  big_A : constant Character := 'A';  --  8-bit character\n\nbegin\n  for i in -10 .. 10 loop\n    Test_Int (i);\n  end loop;\n  Assert (after_int_case, +\"Compiler bug [CASE, Int, Z]\");\n  --\n  for c in big_A .. 'z' loop\n    Test_Char (c);\n  end loop;\n  Assert (some_vowels_occurrences = 3,       +\"Char, CASE 1\");\n  Assert (small_consonants_occurrences = 20, +\"Char, CASE 2\");\nend Case_Statement;\n"
  },
  {
    "path": "test/constants.adb",
    "content": "--  Output must be empty if the compiler is correct.\n--  The order of the declarations is a bit random, it is on purpose.\n--  Especially we want to detect eventual memory corruption (buggy compilers).\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Constants is\n  use HAT, Testing_Utilities;\n\n  n1, n2 : constant := 9.0;  --  Numeric constant (universal float)\n  n3 : constant := 1.0;\n\n  r1 : Real;\n  r2 : Real := 123.0;\n  r3 : constant Real := 456.0;\n\n  minus_pi : constant := -Pi;\n\n  i1 : constant Integer := 7;\n\n  type R is record a, b : Integer; end record;\n\n  s1 : R;\n\n  procedure Test_In (x : in R) is null;\n  procedure Test_Out (x : out R) is null;\n  procedure Test_In_Out (x : in out R) is null;\n\n  procedure Test_12_34 (x : R) is\n    y : constant R := x;\n  begin\n    Assert (y.a = 12 and y.b = 34, +\"Compiler bug [Constants, 12_34]\");\n    --  x.a := 666;  --  must be rejected (cannot modify \"in\" parameter)\n    --  y.a := 666;  --  must be rejected (cannot modify constant)\n    Test_In (x);\n    --  Test_Out (y);     --  must be rejected (cannot modify constant)\n    --  Test_In_Out (x);  --  must be rejected (cannot modify constant)\n  end Test_12_34;\n\n  type Animal is (ant, bat, cat, dog);\n\n  pet : constant Animal := dog;\n\nbegin\n  r1 := 123000.0;\n  Assert (Pi + minus_pi = 0.0,                  +\"Compiler bug [Constants, Pi - (Minus_Pi)]\");\n  Assert (r2 * 1000.0 = r1 and r3 - 333.0 = r2, +\"Compiler bug [Constants, 123]\");\n  Assert (n1 + n2 - 17.0 = n3,                  +\"Compiler bug [Constants, num const]\");\n  r2 := 7.0;\n  Assert (Integer (r2) = i1, +\"Compiler bug [Constants, i1 = 7]\");\n  --  s3.a := 4;  --  must be rejected (cannot modify constant)\n  --  i1 := 6;    --  must be rejected (cannot modify constant)\n  --  r3 := 6.0;  --  must be rejected (cannot modify constant)\n  s1.a := 12;\n  s1.b := 34;\n  Test_12_34 (s1);\n  for i in 1 .. 5 loop\n    null;\n    --  i := 1;  --  must be rejected (cannot modify constant)\n  end loop;\nend Constants;\n"
  },
  {
    "path": "test/declarations.adb",
    "content": "--  Declarations in Ada can be in any order.\n--  In Pascal it is: constants, types, variables, subprograms.\n--  SmallAda (and early versions of HAC) has some remnants of Pascal and funny other bugs...\n\nwith HAT; use HAT;\n\nprocedure Declarations is\n\n  Called_Mimi_Me : Boolean := False;\n  Called_Micro_Me : Boolean := False;\n\n  procedure Declarations is\n    procedure Declarations is\n    begin\n      Called_Micro_Me := True;\n      return;\n      Put (\"Noooo wayyyy (inner level 2)\");\n    end;\n  begin\n    Declarations;\n    Called_Mimi_Me := True;\n    return;  --  SmallAda & HAC < rev. 331: sees CD.Main_Program_ID and triggers \"ILLEGAL RETURN STATEMENT FROM MAIN\" !...\n    Put (\"Noooo wayyyy (inner level 1)\");\n    Set_Exit_Status (1);  --  Compiler test failed.\n  end\n  ;  --  SmallAda & HAC < rev. 332: sees CD.Main_Program_ID and triggers \"Incorrectly used symbol\" !...\n\n  type ee is (r, r2);\n\n  procedure Test (I : Integer) is\n  begin\n    null;\n  end Test;\n\n  procedure Not_Yet_Done (a : Integer) is null;  --  Ada 2005 null procedure.\n\n  --  HAC 0.01: a type right after a subprogram borked the parser!\n  type rec is record x, y : Integer; end record;\n  a, b : rec;\n\nbegin\n  a.x := 5;\n  a.y := 7;\n  b.x := 3;\n  b.y := 4;\n  if a.x + a.y - b.x * b.y /= 000 then\n    Put_Line (\"Compiler bug [A]\");\n    Set_Exit_Status (1);  --  Compiler test failed.\n  end if;\n  Not_Yet_Done (123);\n  Declarations;  --  Subprogram with the same name.\n  if not (Called_Mimi_Me and Called_Micro_Me) then\n    Set_Exit_Status (1);  --  Compiler test failed.\n    return;  --  HAC >= rev. 331: return from main emits a k_Halt_Interpreter\n  end if;\n  return;  --  HAC >= rev. 331: return from main emits a k_Halt_Interpreter\n  Put (\"Noooo wayyyy (inner level 0)\");\n  Set_Exit_Status (1);  --  Compiler test failed.\nend Declarations;\n"
  },
  {
    "path": "test/digitz.adb",
    "content": "with HAT;\n\nprocedure Digitz is\n  use HAT;\n\n  procedure Smalls is\n    --  Check accuracy of decimal image without exponent (\"E...\")\n    --  Was a problem till rev. 241.\n  begin\n    Put_Line (\"[00] \" & Image (Real (0.0)));\n    Put_Line (\"[01] \" & Image (Real (1.0E-10)));\n    Put_Line (\"[02] \" & Image (Real (0.0000000001)));\n    Put_Line (\"[03] \" & Image (Real (0.00000000012)));\n    Put_Line (\"[04] \" & Image (Real (0.000000000123)));\n    Put_Line (\"[05] \" & Image (Real (0.0000000001234)));\n    Put_Line (\"[06] \" & Image (Real (0.00000000012345)));\n    Put_Line (\"[07] \" & Image (Real (0.000000000123456)));\n    Put_Line (\"[08] \" & Image (Real (0.0000000001234567)));\n    Put_Line (\"[09] \" & Image (Real (0.00000000012345678)));\n    Put_Line (\"[10] \" & Image (Real (0.000000000123456789)));\n    Put_Line (\"[11] \" & Image (Real (0.00000000012345678901)));\n    Put_Line (\"[12] \" & Image (Real (0.00000000012345678901234)));\n    Put_Line (\"[13] \" & Image (Real (0.00000000012345678901234567)));\n    Put_Line (\"[14] \" & Image (Real (0.00000100012345678901234567)));\n    Put_Line (\"[15] \" & Image (Real (0.0000010001)));\n    Put_Line (\"[16] \" & Image (Real (0.00000100012345)));\n    Put_Line (\"[17] \" & Image (Real (0.000001000123456)));\n    --\n    Put_Line (\"[18] \" & Real'Image (7.77e-5));\n    Put_Line (\"[19] \" & Real'Image (7.77e-15));\n    Put_Line (\"[20] \" & Real'Image (7.77e-100));\n  end Smalls;\n\n  procedure Larges is\n    function RImage (r : Real) return VString is\n    --  Solve Real vs. Duration ambiguity with literals.\n    begin\n      return Image (r);\n    end RImage;\n  begin\n    Put_Line (\"[50] \" & RImage (1.0));\n    Put_Line (\"[51] \" & RImage (12.0));\n    Put_Line (\"[52] \" & RImage (123.0));\n    Put_Line (\"[53] \" & RImage (1234.0));\n    Put_Line (\"[54] \" & RImage (12345.0));\n    Put_Line (\"[55] \" & RImage (123456.0));\n    Put_Line (\"[56] \" & RImage (1234567.0));\n    Put_Line (\"[57] \" & RImage (12345678.0));\n    Put_Line (\"[58] \" & RImage (123456789.0));\n    Put_Line (\"[59] \" & RImage (1234567890.0));\n    Put_Line (\"[60] \" & RImage (12345678901.0));\n    Put_Line (\"[61] \" & RImage (123456789012.0));\n    Put_Line (\"[62] \" & RImage (1234567890123.0));\n    Put_Line (\"[63] \" & RImage (12345678901234.0));\n    Put_Line (\"[64] \" & RImage (123456789012345.0));\n    Put_Line (\"[65] \" & RImage (1234567890123456.0));\n    Put_Line (\"[66] \" & RImage (12345678901234567.0));\n    Put_Line (\"[67] \" & RImage (123456789012345678.0));\n    Put_Line (\"[68] \" & RImage (123456789012345678.0 * 10.0));\n    Put_Line (\"[69] \" & RImage (123456789012345678.0 * 100.0));\n    Put_Line (\"[70] \" & RImage (-12345678901.0));\n    Put_Line (\"[71] \" & RImage (-123456789012.0));\n    Put_Line (\"[72] \" & RImage (-1234567890123.0));\n    Put_Line (\"[73] \" & RImage (-12345678901234.0));\n    Put_Line (\"[74] \" & RImage (-123456789012345.0));\n    Put_Line (\"[75] \" & RImage (-1234567890123456.0));\n    Put_Line (\"[76] \" & RImage (-12345678901234567.0));\n    Put_Line (\"[77] \" & RImage (-123456789012345678.0));\n    Put_Line (\"[78] \" & RImage (-123456789012345678.0 * 10.0));\n    Put_Line (\"[79] \" & RImage (-123456789012345678.0 * 100.0));\n  end Larges;\n\nbegin\n  Smalls;\n  Larges;\nend Digitz;\n"
  },
  {
    "path": "test/enumerations.adb",
    "content": "--  Output should be empty if the compiler is correct.\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Enumerations is\n  use HAT, Testing_Utilities;\n\n  type E1 is (a);\n  type E2 is (b, c);\n  type E3 is (d, e, f);\n  type E4 is (g, h, i, j);\n\n  procedure Test_ARRAY is\n    aa : array (E3) of E4;\n  begin\n    aa (e) := g;\n  end Test_ARRAY;\n\n  x1 : E1;\n  x2 : E2;\n  x3 : E3;\n\n  type R is record\n    x1 : E1;\n    x2 : E2;\n    x3 : E3;\n    x4 : E4;\n  end record;\n\n  ww : array (1 .. 7) of R;\n\n  v : R;\n\n  zz : array (E3) of R;\n\n  type Animal is (ant, bat, cat, dog);\n\n  pet2 : Animal;\n\n  procedure Test_CASE is\n    a : Animal := dog;\n  begin\n    case a is\n      --  when d => null;  --  <-- wrong enum type\n      when dog =>\n        Assert (a = dog, +\"Compiler bug [Enumerations, CASE]\");\n      when others =>\n        null;\n    end case;\n  end Test_CASE;\n\n  subtype Beast is Animal;\n  subtype Insect is Animal range ant .. ant;\n  subtype Mammal is Animal range bat .. dog;\n\nbegin\n  v.x1 := a;\n  v.x2 := c;\n  x3 := e;\n  v.x3 := f;\n  Assert (x3 = e, +\"Compiler bug [Enumerations, A]\");\n  x1 := v.x1;\n  Assert (x1 = a, +\"Compiler bug [Enumerations, B]\");  --  Former HAC bug with selectors for enums\n  x3 := v.x3;\n  Assert (x3 = f, +\"Compiler bug [Enumerations, C]\");  --  Former HAC bug with selectors for enums\n  ww (1).x3 := e;\n  ww (5).x3 := ww (1).x3;\n  ww (1).x3 := f;\n  --\n  zz (d).x4 := j;\n  zz (e).x4 := i;\n  zz (f).x4 := h;\n  --\n  v.x3 := d;\n  v.x2 := b;\n  Assert (ww (5).x3 = e, +\"Compiler bug [Enumerations, D]\");\n  --\n  Assert (zz (d).x4 = j, +\"Compiler bug [Enumerations, E1]\");\n  Assert (zz (e).x4 = i, +\"Compiler bug [Enumerations, E2]\");\n  Assert (zz (f).x4 = h, +\"Compiler bug [Enumerations, E3]\");\n  --\n  for pet in Mammal loop\n    pet2 := pet;\n    Assert (not (pet2 in Insect),     +\"Compiler bug: Enumerations, membership 1 (IN)\");\n    Assert (not (pet2 not in Mammal), +\"Compiler bug: Enumerations, membership 2 (NOT IN)\");\n  end loop;\n  --\n  Test_CASE;\n  --\nend Enumerations;\n"
  },
  {
    "path": "test/exception_01.adb",
    "content": "procedure Exception_01 is\n  a : array (1 .. 3) of Integer;\n  i : Integer := 4;\nbegin\n  --  a (4) := 1234;  --  Compile-time error: \"error in range constraint:\n                      --  value of index (4) is out of the array's range, 1 .. 3\"\n  a (i) := 1234;  --  4 is out-of-range -> raises Constraint_Error.\nend Exception_01;\n"
  },
  {
    "path": "test/exception_02.adb",
    "content": "procedure Exception_02 is i : Integer := 3; begin i := i / 0; end;\n"
  },
  {
    "path": "test/exception_03.adb",
    "content": "procedure Exception_03 is\n  procedure P1 is\n    function F2 return Integer is\n      a : array (1 .. 3) of Integer;\n      i : Integer := 0;\n    begin\n      --  a (0) := 123;     --  Compile-time error: \"error in range constraint:\n                            --  value of index (0) is out of the array's range, 1 .. 3\"\n      a (i) := 123;     --  <-  *** Boom! *** : 0 is out-of-range\n      return 0;\n    end F2;\n    i : Integer := F2;  --  <-  Trace-back should show this line\n  begin\n    null;\n  end P1;\n  dummy : Integer;\nbegin\n  P1;                   --  <-  Trace-back should show this line\n  dummy := 1234;\n  dummy := 4321;\n  P1;                   --  <-  No executed due to previously raised exception.\nend Exception_03;\n"
  },
  {
    "path": "test/exception_04.adb",
    "content": "--  We demonstrate a trace-back occurring on a non-trivial call\n--  structure (recursion).\n\nprocedure Exception_04 is\n\n  procedure Nest is  --  Copy of some code from:  recursion.adb\n\n    Max_L : constant := 5;\n\n    procedure NTF is\n      --  Outer calls inner and vice-versa.\n      function Add_n_shift (N : Integer; Level : Integer) return Integer is\n        function Shift_n_add (N : Integer) return Integer is\n          a : array (1 .. 3) of Integer;\n          minus_4 : Integer := -4;\n        begin\n          if Level > 1 then\n            return Add_n_shift (N * 2, Level - 1);  --  <-  Trace-back should show this line\n          else\n            a (minus_4) := 5;                       --  <-  *** Boom! *** : -4 is out-of-range\n          end if;\n          return N;\n        end Shift_n_add;\n      begin\n        return Shift_n_add (N + 1);                 --  <-  Trace-back should show this line\n      end Add_n_shift;\n    begin\n      for L in reverse 1 .. Max_L loop\n        if Add_n_shift (0, L) /= 2 ** L - 1 then    --  <-  Trace-back should show this line\n          null;\n        end if;\n      end loop;\n    end NTF;\n\n  begin\n    NTF;                                     --  <-  Trace-back should show this line\n  end Nest;\n\n  procedure P1 is null;\n\n  dummy : Integer;\nbegin\n  dummy := 1234;\n  Nest;        --  <-  Trace-back should show this line\n  dummy := 4321;\n  P1;                   --  <-  No executed due to previously raised exception.\nend Exception_04;\n"
  },
  {
    "path": "test/floats.adb",
    "content": "--  Output should be empty if the compiler is correct.\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Floats is\n  use HAT, Testing_Utilities;\n\n  procedure Test_Exp_Log is\n    scale : constant := 500.0;\n    steps : constant := 100;\n    x1, x2 : Real;\n  begin\n    for i in 0 .. steps loop\n      x1 := Real (i) * scale * (1.0 / Real (steps));\n      x2 := Log (Exp (x1));\n      Assert (abs (x2 - x1) <= 1.0e-15, +\"Compiler bug [Floats, Exp_Log]\");\n    end loop;\n  end Test_Exp_Log;\n\n  procedure Test_Trigo is\n    scale : constant Real := Pi * 0.25;\n    steps : constant := 100;\n    x, s, c, t : Real;\n  begin\n    for i in 0 .. steps loop\n      x := Real (i) * scale * (1.0 / Real (steps));\n      s := Sin (x);\n      c := Cos (x);\n      if abs c > 0.0 then\n        t := s / c;\n        Assert (abs (Arctan (t) - x) <= 1.0e-15, +\"Compiler bug [Floats, Trigo]\");\n      end if;\n    end loop;\n  end Test_Trigo;\n\n  x1 : Real;\n  x2 : Real;\n  x3 : Real;\n\n  type R is record\n    x1 : Real;\n    x2 : Real;\n    x3 : Real;\n  end record;\n\n  ww : array (1 .. 7) of R;\n\n  v : R;\n\n  neg_float_value : constant := -5.07;\n\n  function Almost_Equal (x, y : Real) return Boolean is\n    eps : constant := 1.0e-14;  --  = 9.99999... * 10**(-Real'Digits).\n    --  2.22044604925031E-16 = Real'Base'Model_Epsilon\n    tol : Real := eps;\n    z, ax, ay, ma : Real;\n    eq : Boolean;\n  begin\n    z := abs (x - y);\n    ax := abs x;\n    ay := abs y;\n    ma := ax;\n    if ay < ma then ma := ay; end if;\n    --  ma is the minimum of absolute values of x and y.\n    tol := tol * ma;  --  Relative tolerance\n    eq := z <= tol;\n    Assert (eq,\n             +\"Issue on equality test: x=\" &\n             Real'Image (x) & \", y=\" &\n             Real'Image (y) & \", x-y=\" &\n             Real'Image (x - y) & \", tol=\" &\n             Real'Image (tol) & \"]  \");\n    return eq;\n  end Almost_Equal;\n\n  procedure Base_Test is\n  begin\n    --  Even with the same Real'Image, the difference in parsing (HAC for 10-base numbers,\n    --  GNAT otherwise) induces differences which are beyond Real's precision, but large\n    --  enough to have a non-zero z in computation.\n    if not Almost_Equal (10#920.4323#e-20, 9.20432300000000E-18) then Put_Line (\"[A]\"); end if;\n    if not Almost_Equal (10#8793.0#e-13, 8.79300000000000E-10)   then Put_Line (\"[B]\"); end if;\n    --\n    --  Here we have pasted from the output of floats.adb,\n    --  with:   Produce_Base_Test (True);\n    --\n    if not Almost_Equal (+13#62A.A#e+19,  1.53614085896374E+24) then Put_Line (\"[1]\"); end if;\n    if not Almost_Equal (+9#4458.4818#e17,  5.49270617585333E+19) then Put_Line (\"[2]\"); end if;\n    if not Almost_Equal (-13#19A.C7206#e7, -1.86341399270000E+10) then Put_Line (\"[3]\"); end if;\n    if not Almost_Equal (-6#3153.21#e-12, -3.29551144938688E-07) then Put_Line (\"[4]\"); end if;\n    if not Almost_Equal (-8#60.65#, -4.88281250000000E+01) then Put_Line (\"[5]\"); end if;\n    if not Almost_Equal (-16#62.17#, -9.80898437500000E+01) then Put_Line (\"[6]\"); end if;\n    if not Almost_Equal (+6#15.32111#e7,  3.23636400000000E+06) then Put_Line (\"[7]\"); end if;\n    if not Almost_Equal (-14#5.B7#e9, -1.20276808064000E+11) then Put_Line (\"[8]\"); end if;\n    if not Almost_Equal (-2#11.0#e-16, -4.57763671875000E-05) then Put_Line (\"[9]\"); end if;\n    if not Almost_Equal (+2#111.100#e+13,  6.14400000000000E+04) then Put_Line (\"[10]\"); end if;\n    if not Almost_Equal (-4#31331.311#e+16, -3.83896256512000E+12) then Put_Line (\"[11]\"); end if;\n    if not Almost_Equal (7#6353.1#e3,  7.69398000000000E+05) then Put_Line (\"[12]\"); end if;\n    if not Almost_Equal (9#54.74871#,  4.98392182763468E+01) then Put_Line (\"[13]\"); end if;\n    if not Almost_Equal (13#22548.A7#,  6.24218106508876E+04) then Put_Line (\"[14]\"); end if;\n    if not Almost_Equal (-2#1011.000#e9, -5.63200000000000E+03) then Put_Line (\"[15]\"); end if;\n    if not Almost_Equal (+12#48535.8A84#,  9.75297409336420E+04) then Put_Line (\"[16]\"); end if;\n    if not Almost_Equal (2#0.01#,  2.50000000000000E-01) then Put_Line (\"[17]\"); end if;\n    if not Almost_Equal (10#985.84#e-1,  9.85840000000000E+01) then Put_Line (\"[18]\"); end if;\n    if not Almost_Equal (-2#11.101#, -3.62500000000000E+00) then Put_Line (\"[19]\"); end if;\n    if not Almost_Equal (-2#10.1001#e19, -1.34348800000000E+06) then Put_Line (\"[20]\"); end if;\n    if not Almost_Equal (4#11.32000#,  5.87500000000000E+00) then Put_Line (\"[21]\"); end if;\n    if not Almost_Equal (+10#437.94309#,  4.37943090000000E+02) then Put_Line (\"[22]\"); end if;\n    if not Almost_Equal (16#70.461D#,  1.12273880004883E+02) then Put_Line (\"[23]\"); end if;\n    if not Almost_Equal (+13#A8.26877#,  1.38193254384004E+02) then Put_Line (\"[24]\"); end if;\n    if not Almost_Equal (-3#22120.1000#e7, -5.05926000000000E+05) then Put_Line (\"[25]\"); end if;\n    if not Almost_Equal (-2#10.10101#e+12, -1.08800000000000E+04) then Put_Line (\"[26]\"); end if;\n    if not Almost_Equal (+13#64C4.7869#e8,  1.14353935858760E+13) then Put_Line (\"[27]\"); end if;\n    if not Almost_Equal (-7#32465.145#e6, -9.56749794000000E+08) then Put_Line (\"[28]\"); end if;\n    if not Almost_Equal (+14#696C6.B05#,  2.56542787536443E+05) then Put_Line (\"[29]\"); end if;\n    if not Almost_Equal (-13#454B.90#e-8, -1.18871240938495E-05) then Put_Line (\"[30]\"); end if;\n    if not Almost_Equal (-3#0022.2101#, -8.79012345679012E+00) then Put_Line (\"[31]\"); end if;\n    if not Almost_Equal (-6#32012.22#e-18, -4.26190501736889E-11) then Put_Line (\"[32]\"); end if;\n    if not Almost_Equal (+10#19586.80#,  1.95868000000000E+04) then Put_Line (\"[33]\"); end if;\n    if not Almost_Equal (-7#355.052#, -1.87107871720117E+02) then Put_Line (\"[34]\"); end if;\n    if not Almost_Equal (-16#79D6.5339E#e+8, -1.33961426264064E+14) then Put_Line (\"[35]\"); end if;\n    if not Almost_Equal (+7#1.10#,  1.14285714285714E+00) then Put_Line (\"[36]\"); end if;\n    if not Almost_Equal (13#1.011#,  1.00637232589895E+00) then Put_Line (\"[37]\"); end if;\n    if not Almost_Equal (-11#50.2938#e6, -9.78946870000000E+07) then Put_Line (\"[38]\"); end if;\n    if not Almost_Equal (+5#220.020#,  6.00800000000000E+01) then Put_Line (\"[39]\"); end if;\n    if not Almost_Equal (2#0.1#,  5.00000000000000E-01) then Put_Line (\"[40]\"); end if;\n    if not Almost_Equal (-9#31351.26#, -2.07012962962963E+04) then Put_Line (\"[41]\"); end if;\n    if not Almost_Equal (-10#1.471#e-20, -1.47100000000000E-20) then Put_Line (\"[42]\"); end if;\n    if not Almost_Equal (-16#E5744.2#, -9.39844125000000E+05) then Put_Line (\"[43]\"); end if;\n    if not Almost_Equal (-12#439.7#e+11, -4.61841619746816E+14) then Put_Line (\"[44]\"); end if;\n    if not Almost_Equal (-16#535ED.6ACFC#, -3.41485417232513E+05) then Put_Line (\"[45]\"); end if;\n    if not Almost_Equal (+9#3.2347#,  3.26581313824112E+00) then Put_Line (\"[46]\"); end if;\n    if not Almost_Equal (13#31A3.189C5#,  6.89312879047006E+03) then Put_Line (\"[47]\"); end if;\n    if not Almost_Equal (-14#39C.513B#e18, -3.10069271780268E+23) then Put_Line (\"[48]\"); end if;\n    if not Almost_Equal (+3#2.0210#,  2.25925925925926E+00) then Put_Line (\"[49]\"); end if;\n    if not Almost_Equal (7#4513.415#e0,  1.62760641399417E+03) then Put_Line (\"[50]\"); end if;\n  end Base_Test;\n\n  procedure Produce_Base_Test (do_it : Boolean) is\n    digitz : constant String (1 .. 16) := \"0123456789ABCDEF\";\n    function Rand_Digits (base : Integer) return VString is\n      r : VString := +\"\";\n    begin\n      for d in 1 .. 1 + Rand (4) loop\n        r := r & digitz (1 + Rand (base - 1));\n      end loop;\n      return r;\n    end Rand_Digits;\n    b : Integer;\n    n, nn : VString;\n  begin\n    if not do_it then\n      return;  --  We stay silent\n    end if;\n    for it in 51 .. 100 loop\n      n := +\"\";\n      case Rand (2) is\n        when 0 => n := n & '+';\n        when 1 => n := n & '-';\n        when others => null;\n      end case;\n      b := 2 + Rand (14);\n      --  TBD: could it be that GNAT is less accurate for non-10 bases ?...\n      n := n & b & (+\"#\") & Rand_Digits (b) & '.' & Rand_Digits (b) & '#';\n      if Rnd > 0.5 then\n        n := n & 'e';\n        case Rand (2) is\n          when 0 => n := n & '+';\n          when 1 => n := n & '-';\n          when others => null;\n        end case;\n        n := n & Rand (20);\n      end if;\n      nn := +Real'Image (Float_Value (n));\n      Put_Line (\"    if not Almost_Equal (\" & n & (+\", \") & nn &\n                \") then Put_Line (\"\"[\" & it & \"]\"\"); end if;\");\n    end loop;\n  end Produce_Base_Test;\n\n  --  This is a copy of an example (see \"exm/three_lakes_s.adb\") of a\n  --  deterministic dynamic system (in this case, a differential equation).\n  --  Here, we check the end result of the calculation.\n  --\n  procedure Three_Lakes_S is\n    type Lake is (Morat, Neuchatel, Bienne);\n    type Lake_Vector is array (Lake) of Real;\n\n    procedure Times (l : Real; v : Lake_Vector; r : out Lake_Vector) is\n    begin\n      for i in Lake loop r (i) := v (i) * l; end loop;\n    end Times;\n\n    procedure Plus (a, b : Lake_Vector; r : out Lake_Vector) is\n    begin\n      for i in Lake loop r (i) := a (i) + b (i); end loop;\n    end Plus;\n\n    function Sign (i : Real) return Real is\n    begin\n      if    i < 0.0 then  return -1.0;\n      elsif i = 0.0 then  return  0.0;\n      else                return  1.0;\n      end if;\n    end Sign;\n\n    ivs : Lake_Vector;\n\n    procedure Init_Sensitivity is\n    begin\n      ivs (Morat)     := 1.0 / 2.2820e7;\n      ivs (Neuchatel) := 1.0 / 2.1581e8;\n      ivs (Bienne)    := 1.0 / 4.0870e7;\n    end Init_Sensitivity;\n\n    procedure Evolution (x : in out Lake_Vector; q_e : Lake_Vector; q_sb, h : Real) is\n\n      procedure f (x : Lake_Vector; r : out Lake_Vector) is\n        q_tr_mn, q_tr_nb : Real;\n        --\n        procedure Flux_tansfert is\n        begin\n          q_tr_mn :=\n            --  Canal de la Broye: Morat -> Neuchatel.\n            Sign (x (Morat) - x (Neuchatel)) *                       --  sens d'ecoulement\n            15.223 *                                                 --  facteur de debit\n            (((x (Morat) + x (Neuchatel)) * 0.5 - 426.0)**1.868) *   --  effet du niveau moyen\n            ((abs (x (Morat) - x (Neuchatel)))**0.483);      --  effet de la diff. de niveaux\n          --\n          q_tr_nb :=\n            --  Canal de la Thielle: Neuchatel -> Bienne.\n            Sign (x (Neuchatel) - x (Bienne)) *                      --  sens d'ecoulement\n            18.582 *                                                 --  facteur de debit\n            (((x (Neuchatel) + x (Bienne)) * 0.5 - 426.0)**2.511) *  --  effet du niveau moyen\n            ((abs (x (Neuchatel) - x (Bienne)))**0.482);     --  effet de la diff. de niveaux\n        end Flux_tansfert;\n      begin\n        Flux_tansfert;\n        r (Morat) := (q_e (Morat)     - q_tr_mn) * ivs (Morat);\n        r (Neuchatel) := (q_e (Neuchatel) + q_tr_mn - q_tr_nb) * ivs (Neuchatel);\n        r (Bienne) := (q_e (Bienne)              + q_tr_nb - q_sb) * ivs (Bienne);\n      end f;\n      k1, k2, k3, k4, tmp_a, tmp_b, dbk2, dbk3 : Lake_Vector;\n    begin\n      --  Runge-Kutta, Order 4\n      f (x, k1);\n      --\n      Times (h * 0.5, k1, tmp_a);\n      Plus (x, tmp_a, tmp_b);      --  tmp_b = x + h * 0.5 * k1\n      f (tmp_b, k2);\n      --\n      Times (h * 0.5, k2, tmp_a);\n      Plus (x, tmp_a, tmp_b);      --  tmp_b = x + h * 0.5 * k2\n      f (tmp_b, k3);\n      --\n      Times (h, k3, tmp_a);\n      Plus (x, tmp_a, tmp_b);      --  tmp_b = x + h * k3\n      f (tmp_b, k4);\n      --\n      Times (2.0, k2, dbk2);\n      Times (2.0, k3, dbk3);\n      Plus (k1, dbk2, tmp_a);\n      Plus (tmp_a, dbk3, tmp_b);\n      Plus (tmp_b, k4, tmp_a);     --  tmp_a = (k1 + 2.0 * k2 + 2.0 * k3 + k4)\n      Times (h * (1.0 / 6.0), tmp_a, tmp_b);\n      Plus (x, tmp_b, tmp_a);\n      x := tmp_a;\n    end Evolution;\n\n    procedure Simulation is\n      x, q_e : Lake_Vector;\n      q_sb, h : Real;\n      n_iter : Integer;\n\n    begin\n      h := 3600.0;\n      n_iter := 24 * 20;\n      x (Morat)     := 428.2;\n      x (Neuchatel) := 429.0;\n      x (Bienne)    := 429.4;\n      q_e (Morat)     := 40.0;\n      q_e (Neuchatel) := 70.0;\n      q_e (Bienne)    := 100.0;\n      q_sb := 200.0;\n      for i in 0 .. n_iter loop\n        Evolution (x, q_e, q_sb, h);\n      end loop;\n      Assert (abs (x (Neuchatel) - 429.06377) <= 0.0002, +\"Compiler bug [Floats, Three_Lakes_S]\");\n    end Simulation;\n\n  begin\n    Init_Sensitivity;\n    Simulation;\n  end Three_Lakes_S;\n\nbegin\n  v.x1 := 1.0;\n  v.x2 := 3.0;\n  x3 := 5.0;\n  v.x3 := 6.0;\n  Assert (x3 = 5.0, +\"Compiler bug [Floats, A]\");\n  x1 := v.x1;\n  Assert (x1 = 1.0, +\"Compiler bug [Floats, B]\");\n  x3 := v.x2;\n  Assert (x3 = 3.0, +\"Compiler bug [Floats, C]\");\n  ww (1).x3 := 3.4_5_6_7_8_9;\n  ww (5).x3 := ww (1).x3;\n  ww (1).x3 := 7.89;\n  v.x3 := 1.0;\n  v.x2 := 2.0;\n  Assert (abs (ww (5).x3 - (2.345_678 + 1.111111)) <= 0.000_000_1, +\"Compiler bug [Floats, D]\");\n  x2 := neg_float_value;\n  Assert (-x2 = 5.07, +\"Compiler bug [Floats, E]\");  --  Former HAC bug: unary minus was ineffective for floats\n  --\n  Test_Exp_Log;\n  Test_Trigo;\n  --\n  Produce_Base_Test (False);\n  Base_Test;\n  Three_Lakes_S;\n  --\n  Assert (Almost_Equal (HAT.Max (1.0, 2.0),  2.0), +\"HAT.Max [1]\");\n  Assert (Almost_Equal (HAT.Max (2.0, 1.0),  2.0), +\"HAT.Max [2]\");\n  --\n  Assert (Almost_Equal (HAT.Min (1.0, 2.0),  1.0), +\"HAT.Min [1]\");\n  Assert (Almost_Equal (HAT.Min (2.0, 1.0),  1.0), +\"HAT.Min [2]\");\n  --\n  Assert (Almost_Equal (HAT.Sgn (123.0),     1.0), +\"HAT.Sgn [1]\");\n  Assert (Almost_Equal (HAT.Sgn (0.0),       0.0), +\"HAT.Sgn [2]\");\n  Assert (Almost_Equal (HAT.Sgn (-123.0),   -1.0), +\"HAT.Sgn [3]\");\nend Floats;\n"
  },
  {
    "path": "test/forward.adb",
    "content": "--  Test forward subprogram declaration\n--  https://en.wikipedia.org/wiki/Forward_declaration\n\n--  Code taken from:\n--  http://rosettacode.org/wiki/Mutual_recursion#Ada\n--\n--  Hofstadter Female and Male sequences\n--\n--  F :  1 1 2 2 3 3 4 5 5 6 6 7 8 8 9 9 10 11 11 12 13 13 14 14\n--  M :  0 0 1 2 2 3 4 4 5 6 6 7 7 8 9 9 10 11 11 12 12 13 14 14\n--\n--  N :                      1 1 1\n--       0 1 2 3 4 5 6 7 8 9 0 1 2\n--\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Forward is\n  use HAT, Testing_Utilities;\n\n  function M (N : Integer) return Integer;  --  Forward declaration of M.\n\n  function F (N : Integer) return Integer is\n  begin\n    if N = 0 then\n      return 1;\n    else\n      return N - M (F (N - 1));\n    end if;\n  end F;\n\n  function M (N : Integer) return Integer is\n  begin\n    if N = 0 then\n      return 0;\n    else\n      return N - F (M (N - 1));\n    end if;\n  end M;\n\nbegin\n  Assert (4 = F (6),  +\"F (6)\");\n  Assert (4 = M (6),  +\"M (6)\");\n  Assert (8 = F (12), +\"F (12)\");\n  Assert (7 = M (12), +\"M (12)\");\nend Forward;\n"
  },
  {
    "path": "test/future/block_statements.adb",
    "content": "--  Testing Block Statements\n--   \n--  RM: 5.6 Block Statements\n--  https://www.adaic.org/resources/add_content/standards/05rm/html/RM-5-6.html\n--   \n--  [declare] begin [exception] end\n\nprocedure Block_Statements is\nbegin\n  L: for x in 1 .. 10 loop\n    M: for y in 1 .. 10 loop\n      declare\n        procedure P is\n        begin\n          null;  --  exit;  --  \"cannot exit from body or accept statement\n                            --   enclosed in loop (RM 5.7 (4))\"\n          L: for x in 1 .. 10 loop  --  Another L\n            exit L;\n          end loop L;\n        end;\n      begin\n        exit L;\n      end;\n    end loop M;\n  end loop L;\n  null;  --  exit;  --  \"no loop to exit from\"\nend Block_Statements;"
  },
  {
    "path": "test/hac_test.gpr",
    "content": "--  This is a GNAT, GCC or GNAT Studio project file\n--  for the examples of the HAC project\n--  ( http://hacadacompiler.sf.net/ or https://github.com/zertovitch/hac ).\n--\n--  These examples give (or should give...) the same output on a real\n--  Ada compiler as when compiled and run by HAC.\n--\n--  The official regression test for HAC is `all_silent_tests.adb`\n--  and runs most of the tests below.\n--\n--  Build me with \"gprbuild -P hac_test\", or open me with GNAT Studio.\n--  \n\nproject HAC_Test is\n\n   type HAC_Build_Mode_Type is (\"Debug\", \"Fast\");\n   HAC_Build_Mode : HAC_Build_Mode_Type := external (\"HAC_Build_Mode\", \"Debug\");\n\n   for Main use (\n     \"all_noisy_tests.adb\",\n     \"all_silent_tests.adb\",\n     \"silent_tests_single_build.adb\",\n     --\n     \"attributes_test.adb\",\n     \"case_statement.adb\",\n     \"constants.adb\",\n     \"declarations.adb\",\n     \"digitz.adb\",\n     \"enumerations.adb\",\n     \"exception_01.adb\",\n     \"exception_02.adb\",\n     \"exception_03.adb\",\n     \"exception_04.adb\",\n     \"floats.adb\",\n     \"forward.adb\",\n     \"if_then_elsif_else.adb\",\n     \"integers.adb\",\n     \"loops.adb\",\n     \"object_init.adb\",\n     \"recursion.adb\",\n     \"sorting_tests.adb\",\n     \"strings.adb\",\n     \"type_conversion.adb\",\n     \"test.adb\",\n     \"test1.adb\"\n   );\n\n   case HAC_Build_Mode is\n      when \"Debug\" =>\n         for Object_Dir use \"../obj/debug\";\n      when \"Fast\" =>\n         for Object_Dir use \"../obj/fast\";\n   end case;\n\n   for Source_Dirs use (\".\", \"../src\", \"../exm\");\n   for Exec_Dir use \".\";\n   for Create_Missing_Dirs use \"True\";  --  Flips by default the \"-p\" switch\n\n   package Pretty_Printer is\n      for Default_Switches (\"ada\") use (\"-i2\");\n   end Pretty_Printer;\n\n   Common_Compiler_Options := (\n     \"-gnatwa\",                        --  Warnings switches (a:turn on all info/warnings marked with +)\n     \"-gnatwcijkmopruvz.c.p.t.w.x\",    --  Warnings switches (run \"gnatmake\" for full list)\n     \"-gnatwCKMUV\",                    --  Warnings switches (turn OFF some that are irrelevant for the tests)\n     \"-gnatwh\",                        --  Warnings switches (h:turn on warnings for hiding declarations)\n     \"-gnatf\",  --  Full errors. Verbose details, all undefined references\n     \"-gnatq\",  --  Don't quit, try semantics, even if parse errors\n     \"-gnatQ\",  --  Don't quit, write ali/tree file even if compile errors\n     --\n     \"-gnatyaknpr\",   --  Style: check all casings: a:attribute, k:keywords, n:package Standard identifiers, p:pragma, r:identifier references\n     \"-gnatybfhiu\",   --  Style: check b:no blanks at end of lines, f:no ff/vtabs, h: no htabs, i:if-then layout, u:no unnecessary blank lines\n     \"-gnatyx\",       --  Style: check x:no extra parens\n     --  \"-gnatye\",       --  Style: check e:end/exit labels present\n     \"-gnatytc\"       --  Style: check t:token separation rules, c:comment format (two spaces)\n   );\n\n   Debug_Options := (\n     \"-gnata\",         --  Assertions enabled\n     \"-gnato\",         --  Enable overflow checking in STRICT mode\n     \"-gnatVa\",        --  Enable all validity checking options\n     \"-fstack-check\",\n     \"-fno-inline\",\n     --\n     \"-g\"              --  Generate debugging information\n   );\n\n   Fast_Options := (\n     \"-O2\",\n     \"-gnatpn\", \n     \"-fipa-cp-clone\", \"-fgcse-after-reload\", \n     \"-funroll-loops\", \"-fpeel-loops\", \"-funswitch-loops\", \n     \"-ftracer\", \"-fweb\", \"-ftree-vectorize\",\n     \"-frename-registers\", \"-ffunction-sections\",\n     \"-g\"     \n   );\n   \n   package Compiler is\n      case HAC_Build_Mode is\n         when \"Debug\" => for Default_Switches (\"ada\") use Common_Compiler_Options & Debug_Options;\n         when \"Fast\"  => for Default_Switches (\"ada\") use Common_Compiler_Options & Fast_Options;\n      end case;\n   end Compiler;\n\n   package Binder is\n      case HAC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-Es\");\n         when \"Fast\" =>\n      end case;\n   end Binder;\n\n   package Linker is\n      case HAC_Build_Mode is\n         when \"Debug\" =>\n            for Default_Switches (\"ada\") use (\"-g\");\n         when \"Fast\" =>\n            for Default_Switches (\"ada\") use (\"-s\", \"-Wl,--gc-sections\");\n      end case;\n   end Linker;\n\n   package Builder is\n      --   \"If -j0 is used, then the maximum number of simultaneous compilation\n      --    jobs is the number of core processors on the platform.\"\n      for Default_Switches (\"ada\") use (\"-g\", \"-j0\");\n   end Builder;\n\nend HAC_Test;\n"
  },
  {
    "path": "test/if_then_elsif_else.adb",
    "content": "with HAT; use HAT;\n\nprocedure If_Then_Elsif_Else is\n\n  procedure Test (I : Integer) is\n  begin\n    Put (I);\n    Put (\" compared to 10, 20 and 30 is : \");\n    if I < 10 then\n      Put_Line (\"the smallest\");\n    elsif I < 20 then\n      Put_Line (\"in [10, 19]\");\n    elsif I <= 30 then\n      Put_Line (\"in [20, 30]\");\n    else\n      Put_Line (\"the largest\");\n    end if;\n  end Test;\n\nbegin\n  for J in 8 .. 32 loop\n    Test (J);\n  end loop;\nend If_Then_Elsif_Else;\n"
  },
  {
    "path": "test/integers.adb",
    "content": "--  Output should be empty if the compiler is correct.\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Integers is\n  use HAT, Testing_Utilities;\n\n  x1 : Integer;\n  x2 : Integer;\n  x3 : Integer;\n\n  function Fibonacci (P : Integer) return Integer is\n  begin\n    if P <= 2 then\n      return 1;\n    else\n      return Fibonacci (P - 1) + Fibonacci (P - 2);\n    end if;\n  end Fibonacci;\n\n  type R is record\n    x1 : Integer;\n    x2 : Integer;\n    x3 : Integer;\n  end record;\n\n  v : R;\n\n  procedure Test_Patching is\n    --  -1 is the value of dummy_address for patching IF jumps...\n    patch_trap : constant := -1;\n    pt : Integer;\n  begin\n    for i in 1 .. 1 loop\n      --  SmallAda and early HAC versions patched all\n      --  instructions with an operand = -1 !...\n      pt := patch_trap;\n      if -pt /= 1 then\n        Put (pt);\n        Failure (+\"  Compiler bug [Integers, IF Patch]\");\n      end if;\n    end loop;\n  end Test_Patching;\n\nbegin\n  v.x1 := 1;\n  v.x2 := 3;\n  x3 := 5;\n  v.x3 := 6;\n  Assert (x3 = 5, +\"Compiler bug [Integers, A]\");\n  x1 := v.x1;\n  Assert (x1 = 1, +\"Compiler bug [Integers, B]\");\n  x3 := v.x3;\n  Assert (x3 = 6, +\"Compiler bug [Integers, C]\");\n  --\n  for i in 1 .. 10 loop\n    v.x1 := Fibonacci (i);\n    v.x2 := Fibonacci (i + 1);\n    v.x3 := Fibonacci (i + 2);\n    Assert (v.x1 - v.x3 + v.x2 = 0, +\"Compiler bug [Integers, D]\");\n  end loop;\n  --\n  Assert (12_000 = 12e003, +\"Compiler bug [Integers, E]\");\n  --\n  Test_Patching;\n  --\n  Assert (HAT.Max (1, 2) = 2, +\"HAT.Max [1]\");\n  Assert (HAT.Max (2, 1) = 2, +\"HAT.Max [2]\");\n  --\n  Assert (HAT.Min (1, 2) = 1, +\"HAT.Min [1]\");\n  Assert (HAT.Min (2, 1) = 1, +\"HAT.Min [2]\");\n  --\n  Assert (HAT.Sgn (123)  =  1, +\"HAT.Sgn [1]\");\n  Assert (HAT.Sgn (0)    =  0, +\"HAT.Sgn [2]\");\n  Assert (HAT.Sgn (-123) = -1, +\"HAT.Sgn [3]\");\nend Integers;\n"
  },
  {
    "path": "test/loops.adb",
    "content": "--  Output should be empty if the compiler is correct.\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Loops is\n  use HAT, Testing_Utilities;\nbegin\n  Ident_For :\n  for i in 1 .. 10 loop\n    exit when i = 5;\n    Assert (i < 5, +\"Compiler bug [A (missed exit]\");\n  end loop Ident_For;\n  --\n  for i in reverse 1 .. 10 loop\n    exit when i = 5;\n    Assert (i > 5, +\"Compiler bug [B (missed exit]\");\n  end loop;\n  --\n  L1_a :\n  for i in 10001 .. 10010 loop\n    L2_a :\n    for j in 20002 .. 20007 loop\n      exit L1_a when i = 10005;  --  exiting L2 would pass i = 10006, ...\n      Assert (i < 10005, +\"Compiler bug [C (missed exit]\" & i'Image);\n    end loop L2_a;\n  end loop L1_a;\n  --\n  L1_b :\n  for i in 30001 .. 30010 loop\n    L2_b :\n    loop\n      L3_b :\n      for j in 40002 .. 40007 loop\n        L4_b :\n        for k in 50004 .. 50008 loop\n          exit L1_b when i = 30005;  --  exiting L2, L3, L4 would pass i = 30006, ...\n          Assert (i < 30005, +\"Compiler bug [D (missed exit]\" & i'Image);\n        end loop L4_b;\n      end loop L3_b;\n      exit L2_b;\n    end loop L2_b;\n  end loop L1_b;\nend Loops;\n"
  },
  {
    "path": "test/object_init.adb",
    "content": "--  Test object initialization,\n--  implicit or explicit.\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Object_Init is\n  use HAT, Testing_Utilities;\n\n  procedure Test_Atomics is\n\n    --  Test \"atomic\" (<- in the PCode sense) variables, explicit\n    --  initialization.\n    procedure Atomic_Explicit is\n      a, b, c : Integer := 777;\n      d, e, f : constant Integer := 111;\n    begin\n      Assert (a - 666 = d and b / 7 = e and c + f = 888, +\"Compiler bug [Atomic_Explicit]\");\n      a := 3;\n      b := 4;\n      c := 5;\n    end Atomic_Explicit;\n\n    --  Test \"atomic\" (<- in the PCode sense) variables, implicit\n    --  initialization.\n    procedure Atomic_Implicit is\n      a, b, c : VString;  --  Initialized as empty VString's (= Unbounded_String's).\n    begin\n      a := a & b & \"abc\" & c;\n      Assert (a = \"abc\", +\"Compiler bug [Atomic_Implicit]\");\n      b := +\"gruik\";\n      c := +\"grrrr\";\n    end Atomic_Implicit;\n\n    tries : constant := 3;\n\n  begin\n    for trie in 1 .. tries loop\n      Atomic_Explicit;\n    end loop;\n    for trie in 1 .. tries loop\n      Atomic_Implicit;\n    end loop;\n    for trie in 1 .. tries loop\n      Atomic_Explicit;\n      Atomic_Implicit;\n    end loop;\n  end Test_Atomics;\n\n  procedure Old_Tests is\n    type Rec_1 is record\n      i : Integer;\n      r : Real;\n      j : Integer;\n    end record;\n\n    subtype Arr_Range is Integer range 7 .. 13;\n\n    type Arr_1 is array (Arr_Range, Arr_Range) of Rec_1;\n\n    type Rec_2 is record\n      n : Integer;\n      a : Arr_1;\n    end record;\n\n    type Arr_2 is array (Boolean) of Rec_2;\n\n    n1 : constant := 1234;\n    n2 : constant := 4567;\n\n    procedure Init_Nest_Arr (u : Arr_2; v : out Arr_2) is\n      w1, w2 : Arr_2 := u;  --  The actual test is here :-) .\n    begin\n      w1 (False).n := w2 (True).n;  --  Does nothing meaningful\n      w2 (False).n := w1 (True).n;  --  Does nothing meaningful\n      for r1 in Arr_Range loop\n        for r2 in Arr_Range loop\n          v (True).a (r1, r2).i := n1 * w1 (True).a (r1, r2).j;\n        end loop;\n      end loop;\n    end Init_Nest_Arr;\n\n    dummy_1 : Real := 101010.0;\n\n    procedure Init_Nest_Rec (u : Rec_2; v : out Rec_2) is\n      w1, w2 : constant Rec_2 := u;  --  The actual test is here :-) .\n    begin\n      v.n := w2.n;  --  Does nothing meaningful\n      for r1 in Arr_Range loop\n        for r2 in Arr_Range loop\n          v.a (r1, r2).i := n2 * w1.a (r1, r2).j;\n        end loop;\n      end loop;\n    end Init_Nest_Rec;\n\n    dummy_2 : Integer := 1000 * 200 * 30;\n\n    x, y, z : Arr_2;  --  Two complicated data\n\n    r : Rec_2;\n\n  begin\n    for b in Boolean loop\n      x (b).n := n1;\n      y (b).n := n2;\n      --\n      for r1 in Arr_Range loop\n        for r2 in Arr_Range loop\n          x (b).a (r1, r2).i :=  r1;\n          x (b).a (r1, r2).j :=  r1 * r2;\n        end loop;\n      end loop;\n      y (b).a := x (b).a;\n    end loop;\n    --\n    Init_Nest_Arr (y, z);\n    Assert (z (True).a (9, 11).i = 9 * 11 * n1, +\"Compiler bug [Arr]\");\n    Init_Nest_Rec (y (True), r);\n    Assert (r.a (7, 13).i = 7 * 13 * n2, +\"Compiler bug [Rec]\");\n  end Old_Tests;\n\nbegin\n  Test_Atomics;\n  Old_Tests;\nend Object_Init;\n"
  },
  {
    "path": "test/open_files.adb",
    "content": "--  Files f and g are left open (not closed) during the variables lifetime.\n--  `hac -v1 open_files.adb` will show their names.\n\nwith HAT;\n\nprocedure Open_Files is\n  use HAT;\n  procedure Sub is\n    g : File_Type;\n  begin\n    Open (g, \"floats.adb\");\n  end;\n  f : File_Type;\nbegin\n  Sub;\n  Open (f, \"open_files.adb\");\nend Open_Files;\n\n"
  },
  {
    "path": "test/optim.adb",
    "content": "--  This test is to be used with the \"-a\" option from the HAC command-line executable:\r\n--  hac -a optim.adb\r\n--\r\n--  We check here some optimizations, such as the removal of unnecessary range checks.\r\n\r\nwith HAT;\r\n\r\nprocedure Optim is\r\n\r\n  subtype Chiffre is Integer range 1 .. 9;\r\n\r\n  subtype Fuzzy is Integer range -100 .. 8;\r\n\r\n  type Animal is (ant, bat, cat, dog);\r\n  subtype Beast is Animal;\r\n  subtype Insect is Animal range ant .. ant;\r\n  subtype Mammal is Animal range bat .. dog;\r\n\r\n  procedure Assignment_No_Checks is\r\n    x : Chiffre;\r\n    a : Animal;\r\n    i : Insect;\r\n  begin\r\n    x := 1;  --  Low and high bound checks are optimized out.\r\n    for j in 2 .. 9 loop\r\n      x := j;  --  Low and high bound checks are optimized out.\r\n    end loop;\r\n    --  i := dog;  --  This issues (as it should) a compilation error.\r\n    i := ant;\r\n    a := i;\r\n  end;\r\n\r\n  procedure Assignment_Upper_Bound_Check_Only (y : Positive) is\r\n    x : Chiffre;\r\n    a : Animal;\r\n    i : Insect;\r\n  begin\r\n    x := y;  --  Low bound check is optimized out, high check remains.\r\n    HAT.Put_Line (Animal'Image (Animal'Last));\r\n    HAT.Put_Line (Animal'Image (Insect'Last));\r\n    a := cat;\r\n    i := a;  --  HAC: run-time error on upper bound check.\r\n             --  GNAT issues even a compile-time error!\r\n  end;\r\n\r\n  procedure Assignment_Lower_Bound_Check_Only (y : Fuzzy) is\r\n    x : Chiffre;\r\n  begin\r\n    x := y;  --  High bound check is optimized out, low check remains.\r\n  end;\r\n  \r\n  procedure Assignment_Both_Checks (y : Integer) is\r\n    x : Chiffre;\r\n  begin\r\n    x := y;  --  Low and high bound checks remain.\r\n  end;\r\n\r\n  procedure Array_With_Check (y : Integer) is\r\n    a : array (Chiffre) of Character;\r\n  begin\r\n    a (y) := 'x';\r\n  end;\r\n\r\n  procedure Array_No_Check (y : Chiffre) is\r\n    a : array (Chiffre) of Character;\r\n  begin\r\n    a (y) := 'x';\r\n    a (1) := 'a';\r\n    for idx in 2 .. 4 loop\r\n      a (idx) := 'a';\r\n    end loop;\r\n    for idx in Chiffre loop\r\n      a (idx) := 'a';\r\n    end loop;\r\n    for idx in a'Range loop\r\n      a (idx) := 'a';\r\n    end loop;\r\n  end;\r\n\r\n  i : Integer;\r\n  p : Positive;\r\n  m5 : constant := -5;\r\n\r\nbegin\r\n  HAT.Put_Line (1 + (2 + (3 + 4)));          --  Add_Multiple instruction\r\n  HAT.Put_Line (1.0 + (2.0 + (3.0 + 4.0)));  --  Add_Multiple instruction\r\n  HAT.Put_Line (1 + 2 * 3);          --  Mult_then_Add instruction\r\n  HAT.Put_Line (1.0 + 2.0 * 3.0);    --  Mult_then_Add instruction\r\n  p := -m5;\r\n  p := -(-5);\r\n  i := 0;\r\n  i := 5 + i * p;  --  Mult_then_Add instruction\r\n  --\r\n  --  i := -Integer'First;  --  This issues (as it should) a compilation error.\r\n  Assignment_No_Checks;\r\n  Assignment_Upper_Bound_Check_Only (Chiffre'Last);\r\n  i := -5;  --  Fold K_PUSH_DISCRETE_LITERAL & K_UNARY_MINUS_INTEGER into K_PUSH_DISCRETE_LITERAL.\r\nend Optim;\r\n"
  },
  {
    "path": "test/recursion.adb",
    "content": "--  We check numerical recursive functions (and also a bit the\n--  correctness of array operations, and nested subprograms too).\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Recursion is\n  use HAT, Testing_Utilities;\n\n  function Fibonacci (P : Natural) return Positive is\n  begin\n    if P <= 2 then\n      return 1;\n    else\n      return Fibonacci (P - 1) + Fibonacci (P - 2);\n    end if;\n  end Fibonacci;\n\n  function Ackermann (M, N : Natural) return Positive is\n  begin\n    if M = 0 then\n      return N + 1;\n    elsif N = 0 then\n      return Ackermann (M - 1, 1);\n    else\n      return Ackermann (M - 1, Ackermann (M, N - 1));\n    end if;\n  end Ackermann;\n\n  procedure Ackarray is\n    M_Max : constant := 3;\n    N_Max : constant := 4;\n    type Storage is array (0 .. M_Max, 0 .. N_Max) of Integer;\n    --\n    Noise_1 : constant Integer := 11111;\n    A : Storage;\n    Noise_2 : Integer;\n    B : Storage;\n    Noise_3 : Integer;\n  begin\n    for M in 0 .. M_Max loop\n      for N in reverse 0 .. N_Max loop\n        A (M, N) := Ackermann (M, N);\n      end loop;\n    end loop;\n    --\n    Noise_2 := 22222;\n    B := A;\n    Noise_3 := 33333;\n    --\n    for N in reverse 0 .. N_Max loop\n      for M in 0 .. M_Max loop\n        Assert (B (M, N) = Ackermann (M, N), +\"Compiler bug [Recursion, Ackermannm, Array]\");\n      end loop;\n    end loop;\n    --\n    Assert (Noise_1 + Noise_2 = Noise_3, +\"Compiler bug [Stack]\");\n  end Ackarray;\n\n  procedure Nesting_Tests is\n    --  We compute in an horribly complicated way the value: 2 ** Level - 1.\n    --  This is for testing recursion *and* nested subprograms together.\n\n    Max_L : constant := 20;\n\n    type Usine_a_Gaz is record\n      ant, bat : Real;\n      N        : Integer;\n      cat, dog : Boolean;\n    end record;\n\n    procedure Nesting_Test_P is\n      --  Outer calls inner and vice-versa.\n      procedure Add_1_and_shift (U : in out Usine_a_Gaz; Level : Integer) is\n        procedure Shift_and_add_1 (U : in out Usine_a_Gaz) is\n        begin\n          if Level > 1 then\n            U.N := U.N * 2;\n            Add_1_and_shift (U, Level - 1);\n          end if;\n        end Shift_and_add_1;\n      begin\n        U.N := U.N + 1;\n        Shift_and_add_1 (U);\n      end Add_1_and_shift;\n      R : Usine_a_Gaz;\n    begin\n      for L in 1 .. Max_L loop\n        R.N := 0;\n        Add_1_and_shift (R, L);\n        Assert (R.N = 2 ** L - 1, +\"Compiler bug [Recursion, Nesting_Test_P]\");\n      end loop;\n    end Nesting_Test_P;\n\n    procedure Nesting_Test_F is\n      --  Outer calls inner and vice-versa.\n      function Add_1_and_shift (N : Integer; Level : Integer) return Integer is\n        function Shift_and_add_1 (N : Integer) return Integer is\n        begin\n          if Level > 1 then\n            return Add_1_and_shift (N * 2, Level - 1);\n          end if;\n          return N;\n        end Shift_and_add_1;\n      begin\n        return Shift_and_add_1 (N + 1);\n      end Add_1_and_shift;\n    begin\n      for L in 1 .. Max_L loop\n        Assert (Add_1_and_shift (0, L) = 2 ** L - 1, +\"Compiler bug [Recursion, Nesting_Test_F]\");\n      end loop;\n    end Nesting_Test_F;\n\n  begin\n    Nesting_Test_P;\n    Nesting_Test_F;\n  end Nesting_Tests;\n\nbegin\n  Assert (Fibonacci (22) = 17_711, +\"Compiler bug [Recursion, Fibonacci]\");\n  Assert (Ackermann (3, 4) = 125,  +\"Compiler bug [Recursion, Ackermann]\");\n  Ackarray;\n  Nesting_Tests;\nend Recursion;\n"
  },
  {
    "path": "test/remarks_check.adb",
    "content": "--  Check for regression in HAC's production of remarks (warnings or notes).\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Remarks_Check is\n\n  use HAT;\n\n  --  Primitive file comparison for text files that should be identical.\n  procedure File_Comp (name_1, name_2 : VString; ok : out Boolean) is \n    f1, f2 : File_Type;\n    l1, l2 : VString;\n  begin\n    ok := True;\n    Open (f1, name_1);\n    Open (f2, name_2);\n    while not (End_Of_File (f1) or End_Of_File (f2)) loop\n      Get_Line (f1, l1);\n      Get_Line (f2, l2);\n      if l1 /= l2 then\n        Put_Line (\"*** Difference found:\");\n        Put_Line (name_1 & ':');\n        Put_Line (\"    \" & l1);\n        Put_Line (name_2 & ':');\n        Put_Line (\"    \" & l2);\n        ok := False;\n        exit;\n      end if;\n    end loop;\n    if ok then\n      if not End_Of_File (f1) then\n        Put_Line (\"*** Difference found: \" & name_1 & \" is longer.\");\n        ok := False;\n      elsif not End_Of_File (f2) then\n        Put_Line (\"*** Difference found: \" & name_2 & \" is longer.\");\n        ok := False;\n      end if;\n    end if;\n    Close (f1);\n    Close (f2);\n  end File_Comp;  \n\n  procedure Check (letter : Character) is \n    prefix   : constant VString := +\"remarks_\" & letter & '_';\n    name_ok  : constant VString := prefix & \"ok.txt\";\n    name_new : constant VString := prefix & \"new.txt\";\n    ok : Boolean;\n  begin\n    --  -r0 disables all remarks\n    Shell_Execute\n      (+\"..\" & Directory_Separator & \"hac -c -r0 -r\" & letter & \" ../exm/remarks.adb 2>\" & name_new);\n    File_Comp (name_ok, name_new, ok);\n    if not ok then\n      Testing_Utilities.Failure\n        (+\"Remarks_Check: possible regression in HAC's remarks (warnings or notes)\");\n    end if;\n  end Check;\n  \nbegin\n  Check ('k');\n  Check ('r');\n  Check ('u');\n  Check ('v');\nend Remarks_Check;\n"
  },
  {
    "path": "test/remarks_k_ok.txt",
    "content": "../exm/remarks.adb: 24:3-4: note: variable \"b0\" is not modified, could be declared constant [-rk]\n../exm/remarks.adb: 21:3-3: note: variable \"g\" is not modified, could be declared constant [-rk]\n../exm/remarks.adb: 17:3-3: note: variable \"d\" is not modified, could be declared constant [-rk]\n"
  },
  {
    "path": "test/remarks_r_ok.txt",
    "content": "../exm/remarks.adb: 13:7-16: note: \"use\" clause already applied, in same declarative part, for package \"Interfaces\" [-rr]\n../exm/remarks.adb: 110:5-7: note: \"when others\" is redundant here: all values are already explicitly covered [-rr]\n"
  },
  {
    "path": "test/remarks_u_ok.txt",
    "content": "../exm/remarks.adb: 30:6-7: note: parameter \"c1\" is not referenced [-ru]\n../exm/remarks.adb: 29:6-7: note: parameter \"b1\" is not referenced [-ru]\n../exm/remarks.adb: 28:6-7: note: parameter \"a1\" is not referenced [-ru]\n../exm/remarks.adb: 43:6-7: note: parameter \"b2\" is not referenced [-ru]\n../exm/remarks.adb: 93:13-15: note: procedure \"Tom\" is not referenced [-ru]\n../exm/remarks.adb: 71:12-22: note: function \"Max_Array_2\" is not referenced [-ru]\n../exm/remarks.adb: 60:12-20: note: function \"Max_Array\" is not referenced [-ru]\n../exm/remarks.adb: 50:12-18: note: function \"Useless\" is not referenced [-ru]\n../exm/remarks.adb: 41:13-26: note: procedure \"OK_Read_Writes\" is not referenced [-ru]\n../exm/remarks.adb: 27:13-31: note: procedure \"Missing_Read_Writes\" is not referenced [-ru]\n../exm/remarks.adb: 24:3-4: note: variable \"b0\" is not referenced [-ru]\n../exm/remarks.adb: 23:19-20: note: item \"y0\" is not referenced [-ru]\n../exm/remarks.adb: 20:3-3: note: variable \"f\" is never read [-ru]\n../exm/remarks.adb: 19:3-3: note: variable \"e\" is never read [-ru]\n../exm/remarks.adb: 17:3-3: note: variable \"d\" is not referenced [-ru]\n../exm/remarks.adb: 16:13-13: note: procedure \"C\" is not referenced [-ru]\n../exm/remarks.adb: 15:17-17: note: item \"y\" is not referenced [-ru]\n../exm/remarks.adb: 15:14-14: note: item \"x\" is not referenced [-ru]\n../exm/remarks.adb: 15:8-8: note: type \"B\" is not referenced [-ru]\n../exm/remarks.adb: 14:3-3: note: variable \"a\" is not referenced [-ru]\n"
  },
  {
    "path": "test/remarks_v_ok.txt",
    "content": "../exm/remarks.adb: 36:11-11: warning: parameter \"d1\" is read before it is ever written [-rv]\n../exm/remarks.adb: 37:11-11: warning: parameter \"e1\" is read before it is ever written [-rv]\n../exm/remarks.adb: 32:6-7: warning: parameter \"d1\" is read but never written [-rv]\n../exm/remarks.adb: 30:6-7: warning: parameter \"c1\" is never written [-rv]\n../exm/remarks.adb: 64:22-25: warning: variable \"Max\" is read before it is ever written [-rv]\n../exm/remarks.adb: 77:26-29: warning: variable \"Max_2\" may be read before it is ever written [-rv]\n../exm/remarks.adb: 97:15-15: warning: variable \"I\" is read before it is ever written [-rv]\n../exm/remarks.adb: 94:6-6: warning: variable \"I\" is never written, but is possibly read [-rv]\n../exm/remarks.adb: 115:13-13: warning: variable \"h\" is read before it is ever written [-rv]\n../exm/remarks.adb: 22:3-3: warning: variable \"h\" is read but never written [-rv]\n"
  },
  {
    "path": "test/shell_test.adb",
    "content": "with HAT; use HAT;\n\nprocedure Shell_Test is\n\n  --  Corresponds to POSIX' WEXITSTATUS in common implementations.\n  function Exit_Status (Shell_Result : Integer) return Integer is\n  begin\n    Return Shell_Result / 256 mod 256;\n  end Exit_Status;\n\n  --  Corresponds to POSIX' WSTOPSIG in common implementations.\n  function Stop_Signal (Shell_Result : Integer) return Integer is\n  begin\n    Return Shell_Result / 256 mod 128;\n  end Stop_Signal;\n\n  --  Corresponds to POSIX' WTERMSIG in common implementations.\n  function Termination_Signal (Shell_Result : Integer) return Integer is\n  begin\n    Return Shell_Result mod 128;\n  end Termination_Signal ;\n\n  procedure Pipe_Test (n: Integer) is\n    r : Integer;\n    command : constant VString := +\"exit \" & n;\n    contents : VString;\n  begin\n    Put (+\"Command: \" & command & \". Result...\");\n    Shell_Execute (command, r);\n    Put (+\" without pipe: \" & r & \", POSIX: \" & Exit_Status (r));\n    Shell_Execute (command, r, contents);\n    Put (+\", with pipe: \" & r & \", POSIX: \" & Exit_Status (r));\n    Shell_Execute (command & \">dummy_output.txt\", r);\n    Put (+\", with explicit pipe: \" & r & \", POSIX: \" & Exit_Status (r));\n    New_Line;\n  end Pipe_Test;\n  --\nbegin\n  for n in 0 .. 15 loop\n    Pipe_Test (n);\n  end loop;\n  for n in 255 .. 258 loop\n    Pipe_Test (n);\n  end loop;\nend Shell_Test;\n"
  },
  {
    "path": "test/silent_tests_single_build.adb",
    "content": "--  Single-build version of All_Silent_Tests.\n--  Differences:\n--    - The test framework targets entirely the compiler used for the build around\n--        `silent_tests_single_build.adb`.\n--    - Reversely, All_Silent_Tests calls specifically HAC for individual tests.\n\nwith HAT;\n\nwith Attributes_Test,\n     Case_Statement,\n     Constants,\n     Declarations,\n     Enumerations,\n     Floats,\n     Forward,\n     Integers,\n     Loops,\n     Object_Init,\n     Recursion,\n     Sorting_Tests,\n     Strings,\n     Type_Conversion;\n\nprocedure Silent_Tests_Single_Build is\n\n  use HAT;\n\nbegin\n  Put_Line (\"Silent_Tests_Single_Build can be used for testing any Ada compiler.\");\n  New_Line;\n  Put_Line (+\"Please use All_Silent_Tests for specifically \" &\n             \"and throughfully testing HAC (actual regression test).\");\n  New_Line;\n  Put_Line (\"Attributes_Test\");   Attributes_Test;\n  Put_Line (\"Case_Statement\");    Case_Statement;\n  Put_Line (\"Constants\");         Constants;\n  Put_Line (\"Declarations\");      Declarations;\n  Put_Line (\"Enumerations\");      Enumerations;\n  Put_Line (\"Floats\");            Floats;\n  Put_Line (\"Forward\");           Forward;\n  Put_Line (\"Integers\");          Integers;\n  Put_Line (\"Loops\");             Loops;\n  Put_Line (\"Object_Init\");       Object_Init;\n  Put_Line (\"Recursion\");         Recursion;\n  Put_Line (\"Sorting_Tests\");     Sorting_Tests;\n  Put_Line (\"Strings\");           Strings;\n  Put_Line (\"Type_Conversion\");   Type_Conversion;\nend Silent_Tests_Single_Build;\n"
  },
  {
    "path": "test/sorting_tests.adb",
    "content": "--  Silent versions of merge_sort.adb and shell_sort.adb.\n--  We check the result. No output <=> compiler is correct.\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Sorting_Tests is\n  use HAT;\n\n  expected_result : constant String (1 .. 26) := \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n  procedure Merge is\n\n    type Vector is array (1 .. 26) of Character;\n    v                : Vector;\n    temp_array       : Vector;\n    max              : Integer;\n    cur_length       : Integer;\n    m                : Integer;\n    left, top_left   : Integer;\n    right, top_right : Integer;\n\n  begin\n    v := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\n    max := 26;\n    --\n    cur_length := 1;\n    while cur_length < max loop  --  New phase\n      temp_array := v;\n      left := 1;\n      m := 1;\n      while left <= max loop  --  Find pair of subarrays\n        right := left + cur_length;\n        top_left := right;\n        if top_left > max then\n          top_left := max + 1;\n        end if;\n        top_right := right + cur_length;\n        if top_right > max then\n          top_right := max + 1;\n        end if;\n        --  Merge subarrays\n        --  Go until one subarray runs out\n        while (left < top_left) and (right < top_right) loop\n          if temp_array (left) <= temp_array (right) then\n            v (m)  := temp_array (left);\n            left  := left + 1;\n          else\n            v (m)  := temp_array (right);\n            right := right + 1;\n          end if;\n          m := m + 1;\n        end loop;\n        --  Now \"copy tail\" of whichever subarray remains\n        while left < top_left loop\n          v (m) := temp_array (left);\n          m    := m + 1;\n          left := left + 1;\n        end loop;\n        while right < top_right loop\n          v (m)  := temp_array (right);\n          right := right + 1;\n          m     := m + 1;\n        end loop;\n        left := top_right;\n      end loop;\n      --  Now double size of subarrays and go back for next phase\n      cur_length := cur_length * 2;\n    end loop;\n    for k in 1 .. 26 loop\n      Testing_Utilities.Assert\n        (v (k) = expected_result (k), +\"Wrong result in Merge Sort\");\n    end loop;\n  end Merge;\n\n  procedure Shell is\n    b : String (1 .. 26);\n    i, j, step : Integer;\n    step_size : array (1 .. 4) of Integer;\n    stop : Boolean;\n    temp : Character;\n  begin\n    b := \"ZYXWVUTSRQPONMLKJIHGFEDCBA\";\n    --  'steps' contains decreasing increments for each\n    --  pass. The last pass has increment 1.\n    step_size (4) := 1;\n    for pass in reverse 1 .. 3 loop\n      step_size (pass) := 2 * step_size (pass + 1);\n    end loop;\n    for pass in 1 .. 4 loop\n      step := step_size (pass);\n      --  Do a straight insertion sort with 'step' as\n      --  an increment instead of 1.\n      i := step + 1;\n      while i <= 26 loop\n        temp := b (i);\n        j := i;\n        stop := False;\n        while (j > step) and not stop loop\n          j := j - step;\n          if b (j) > temp then\n            b (j + step) := b (j);\n          else\n            b (j + step) := temp;\n            stop := True;\n          end if;\n        end loop;\n        if not stop then\n          b (1) := temp;\n        end if;\n        i := i + step;\n      end loop;\n    end loop; -- for pass in 1..npass\n    for k in 1 .. 26 loop\n      Testing_Utilities.Assert\n        (b (k) = expected_result (k), +\"Wrong result in Shell Sort\");\n    end loop;\n  end Shell;\n\nbegin\n  Merge;\n  Shell;\nend Sorting_Tests;\n"
  },
  {
    "path": "test/strings.adb",
    "content": "with HAT;\nwith Testing_Utilities;\n\nprocedure Strings is\n  use HAT, Testing_Utilities;\n\n  s1, s2, s3, s4, s4_s4, s4_s4_copy : VString;\n  Planck   : constant Real := 6.62607015e-34;\n  Pi_9_dgt : constant Real := 3.141592653;\n  Avogadro : constant Real := 6.02214076e023;\n  r : Real;\n  fs_1 : String (4 .. 6);\n  c : Character := '!';\n\n  type Enum is (U, V, W);\n\n  subtype Str_6 is String (1 .. 6);\n\n  procedure Test_String_Literal_Param (s : Str_6; i : Integer) is\n  begin\n    Assert (s = \"world!\", +\"Literal string passed as value is incorrect\");\n    Assert (i = 1234,     +\"Stack corruption following literal string passed as value\");\n  end Test_String_Literal_Param;\n\nbegin\n  Test_String_Literal_Param (\"world!\", 1200 + 34);\n  s4 := To_VString (\"abc\") & 'd' & \"ef\";\n  if s4 /= +\"abcdef\" then\n    Failure (+\"Comparing VString to VString, or converting Literal String to VString\");\n  end if;\n  if s4 /= \"abcdef\" then\n    Failure (+\"Comparing VString to Literal String\");\n  end if;\n  --\n  if Element (s4, 3) /= 'c'    then Failure (+\"VString Element\"); end if;\n  if Length (s4) /= 6          then Failure (+\"VString Length\"); end if;\n  if Slice (s4, 3, 5) /= \"cde\" then Failure (+\"VString Slice\"); end if;\n  --\n  s1 := +\"ab\";\n  s2 := +\"cdef\";\n  s3 := 'b' & s2;\n  --\n  if s1 & s2 /= s4      then Failure (+\"VString & VString\"); end if;\n  if s1 & \"cdef\" /= s4  then Failure (+\"VString & String\"); end if;\n  if \"ab\" & s2 /= s4    then Failure (+\"String  & VString\"); end if;\n  if 'a' & s3 /= s4     then Failure (+\"Character & VString\"); end if;\n  if 7 & s1 /= +\"7ab\"   then Failure (+\"Int & VString\"); end if;\n  --\n  if s1 & 7 /= +\"ab7\"   then Failure (+\"VStr & Int = +Str_Lit\"); end if;\n  if s1 & 7 /=  \"ab7\"   then Failure (+\"VStr & Int =  Str_Lit\"); end if;\n  --\n  if Real (3.14) & s2 /= \"3.14cdef\"     then Failure (+\"R & VString\"); end if;\n  if s2 & Pi_9_dgt /= \"cdef3.141592653\" then Failure (+\"VString & R\"); end if;\n  if s2 & Avogadro /= +\"cdef6.02214076E+23\" then\n    Failure (+\"Compiler bug - HAC_Image for HAC_Float - Avogadro : \" & Avogadro);\n    Put_Line (Avogadro);\n  end if;\n  if s1 & Planck /= +\"ab6.62607015E-34\" then\n    Failure (+\"Compiler bug - HAC_Image for HAC_Float - Planck : \" & Planck);\n    Put_Line (Planck);\n    Put_Line (Planck, 1, 7, 0);\n  end if;\n  if not (+\"A\" < +\"B\")   then Failure (+\"VString < VString\"); end if;\n  if not (+\"AA\" > +\"A\")  then Failure (+\"VString > VString\"); end if;\n  --\n  if not (+\"A\" <= +\"B\")  then Failure (+\"VString <= VString\"); end if;\n  if not (+\"AA\" >= +\"A\") then Failure (+\"VString >= VString\"); end if;\n  if not (+\"A\" <= +\"A\")  then Failure (+\"VString <= VString\"); end if;\n  if not (+\"A\" >= +\"A\")  then Failure (+\"VString >= VString\"); end if;\n  --\n  if To_Lower (+\"X\") /= +\"x\" then Failure (+\"To_Lower VString\"); end if;\n  if To_Lower  ('X') /=  'x' then Failure (+\"To_Lower Char\");    end if;\n  if To_Upper (+\"x\") /= +\"X\" then Failure (+\"To_Upper VString\"); end if;\n  if To_Upper  ('x') /=  'X' then Failure (+\"To_Upper Char\");    end if;\n  --\n  if Index (s4, +\"cat\") /= 0 then Failure (+\"Index, #1\");    end if;\n  if Index (s4, +\"cde\") /= 3 then Failure (+\"Index, #2\");    end if;\n  if Index (s4,  \"cat\") /= 0 then Failure (+\"Index, #3\");    end if;\n  if Index (s4,  \"cde\") /= 3 then Failure (+\"Index, #4\");    end if;\n  --\n  s4_s4 := s4 & s4;  --  abcdefabcdef\n                     --  123456789012\n  if Index (s4_s4, +\"cd\") /= 3 or\n     Index (s4_s4,  \"cd\") /= 3 or\n     Index (s4_s4,  'c')  /= 3\n  then\n    Failure (+\"Index\");\n  end if;\n  if Index (s4_s4, +\"cd\", 4) /= 9 or\n     Index (s4_s4,  \"cd\", 4) /= 9 or\n     Index (s4_s4,  'c', 4)  /= 9\n  then\n    Failure (+\"Index, From\");\n  end if;\n  if Index_Backward (s4_s4, +\"cd\") /= 9 or\n     Index_Backward (s4_s4,  \"cd\") /= 9 or\n     Index_Backward (s4_s4,  'c')  /= 9\n  then\n    Failure (+\"Index_Backward\");\n  end if;\n  if Index_Backward (s4_s4, +\"cd\", 8) /= 3 or\n     Index_Backward (s4_s4,  \"cd\", 8) /= 3 or\n     Index_Backward (s4_s4,  'c', 8)  /= 3\n  then\n    Failure (+\"Index_Backward, From\");\n  end if;\n  s4_s4_copy := s4_s4;  --  \"abcdefabcdef\"\n  Delete (s4_s4_copy, 4, 6);\n  Assert (s4_s4_copy = \"abcabcdef\", +\"Delete\");\n  --\n  if  0 * 'x' /= +\"\"                       then Failure (+\"\"\"*\"\", #1\"); end if;\n  if 10 * 'x' /= +\"xxxxxxxxxx\"             then Failure (+\"\"\"*\"\", #2\"); end if;\n  if  0 * (+\"Fritz\") /= +\"\"                then Failure (+\"\"\"*\"\", #3\"); end if;\n  if  3 * (+\"Fritz\") /= +\"FritzFritzFritz\" then Failure (+\"\"\"*\"\", #4\"); end if;\n  --\n  for i in -5 .. 5 loop\n    if Integer_Value (Image (i)) /= i then Failure (+\"Im/Val I\"); end if;\n    r := Real (i);\n    if Float_Value (Image (r)) /= r then Failure (+\"Im/Val R 1\"); end if;\n    r := Real (i) * 1.0e20;\n    if Float_Value (Image (r)) /= r then Failure (+\"Im/Val R 2\"); end if;\n    --  put_line (image(r));\n  end loop;\n  --\n  fs_1 := \"def\";\n  if +fs_1 /= Slice (s4, 4, 6)    then Failure (+\"Fixed String to VString\"); end if;\n  if +\"abc\" & fs_1 /= +\"abcdef\"   then Failure (+\"VString & String\"); end if;\n  if fs_1 & (+\"ghi\") /= +\"defghi\" then Failure (+\"String & VString\"); end if;\n  --\n  --  Strings_as_VStrings\n  --\n  if Enum'Image (V) /= \"V\" then Failure (+\"Strings_as_VStrings\"); end if;\n  --\n  --  Concatenation between the three String internal types or with Character.\n  --  Codes in brackets like [12] are explained in String_Concatenation,\n  --  HAC_Sys.Parser.Expressions.\n  --\n  Assert (Enum'Image (U) & Enum'Image (V) = \"UV\", +\"SVS_Concat, [11]\");\n  Assert (Enum'Image (U) & fs_1 = \"Udef\",         +\"SVS_Concat, [12]\");\n  Assert (Enum'Image (W) & \"aw\" = \"Waw\",          +\"SVS_Concat, [13]\");\n  Assert (Enum'Image (U) & 'V' = \"UV\",            +\"SVS_Concat, [14]\");\n  --\n  Assert (fs_1 & Enum'Image (W) = \"defW\",         +\"SVS_Concat, [21]\");\n  Assert (\"UB\" & Enum'Image (U) = \"UBU\",          +\"SVS_Concat, [31]\");\n  Assert ('U' & Enum'Image (V) = \"UV\",            +\"SVS_Concat, [41]\");\n  --  Combinations without any Strings_as_VStrings.\n  Assert (fs_1 & fs_1  = \"defdef\",                +\"SVS_Concat, [22]\");\n  Assert (fs_1 & \"xyz\" = \"defxyz\",                +\"SVS_Concat, [23]\");\n  Assert (fs_1 & '$'   = \"def$\",                  +\"SVS_Concat, [24]\");\n  --\n  Assert (\"hac\" & fs_1  & c = \"hacdef!\",          +\"SVS_Concat, [32]\");\n  Assert (\"hac\" & \"xyz\" & c = \"hacxyz!\",          +\"SVS_Concat, [33]\");\n  Assert (\"hac\" & '$'   & c = \"hac$!\",            +\"SVS_Concat, [34]\");\n  --\n  Assert ('%' & fs_1  & c = \"%def!\",              +\"SVS_Concat, [42]\");\n  Assert ('%' & \"xyz\" & c = \"%xyz!\",              +\"SVS_Concat, [43]\");\n  Assert ('%' & '$'   & c = \"%$!\",                +\"SVS_Concat, [44]\");\n  --\n  if To_String (To_VString (\"abcd\") & (+\"ef\")) /= \"abcdef\" then\n    Failure (+\"String <-> VString, #1\");\n  end if;\n  --\n  --  Testing HAT functions\n  --\n  Assert (not Starts_With (+\"package\",  \"proc\"), +\"SW_1\");\n  Assert (not Starts_With (+\"package\", +\"proc\"), +\"SW_2\");\n  Assert     (Starts_With (+\"package\",  \"pack\"), +\"SW_3\");\n  Assert     (Starts_With (+\"package\", +\"pack\"), +\"SW_4\");\n  --\n  Assert (not Ends_With (+\"package\",  \"proc\"), +\"EW_1\");\n  Assert (not Ends_With (+\"package\", +\"proc\"), +\"EW_2\");\n  Assert     (Ends_With (+\"package\",  \"age\"),  +\"EW_3\");\n  Assert     (Ends_With (+\"package\", +\"age\"),  +\"EW_4\");\n  --\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", '/') = \"gnx-startup\",               +\"TAM_1\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", \"ix\") = \"/gnx-startup\",             +\"TAM_2\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", +\"gene\") = \"six/gnx-startup\",       +\"TAM_3\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", +\"etc/genesix/gnx-startu\") = \"p\",   +\"TAM_4\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", +\"/etc/genesix/gnx-startu\") = \"p\",  +\"TAM_5\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", +\"/etc/genesix/gnx-startup\") = \"\",  +\"TAM_6\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", +\"/etc/genesix/gnx-startupp\") = \"\", +\"TAM_7\");\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", \"/g\") = \"nx-startup\",               +\"TAM_8\");  --  Must match the last \"/g\"\n  Assert (Tail_After_Match (+\"/etc/genesix/gnx-startup\", \"/g\") /= \"enesix/gnx-startup\",      +\"TAM_9\");\n  --\n  Assert (Head_Before_Match (+\"the quick brown fox jumps\", \"fox\") = \"the quick brown \", +\"HBM_1\");\n  Assert (Head_Before_Match (+\"the quick brown fox jumps\", \"dog\") = \"\",                 +\"HBM_2\");\n  Assert (Head_Before_Match (+\"the quick brown fox jumps\", \"jumps \") = \"\",              +\"HBM_3\");\n  Assert (Head_Before_Match (+\"the quick brown fox jumps\", +\"quick\") = \"the \",          +\"HBM_4\");\n  Assert (Head_Before_Match (+\"the quick brown fox jumps\", 'k') = \"the quic\",           +\"HBM_5\");\n  --\n  --  The following test is in one answer of\n  --  https://stackoverflow.com/questions/62080743/how-do-you-check-if-string-ends-with-another-string-in-ada\n  Assert (Ends_With (+\"John Johnson\", \"son\") = True, +\"EW_101\");\n  Assert (Ends_With (+\"\", \"\") = True,                +\"EW_102\");\n  Assert (Ends_With (+\" \", \"\") = True,               +\"EW_103\");\n  Assert (Ends_With (+\"\", \" \") = False,              +\"EW_104\");\n  Assert (Ends_With (+\" \", \" \") = True,              +\"EW_105\");\n  Assert (Ends_With (+\"\", \"n\") = False,              +\"EW_106\");\n  Assert (Ends_With (+\"n\", \"\") = True,               +\"EW_107\");\n  Assert (Ends_With (+\"n \", \"n \") = True,            +\"EW_108\");\n  Assert (Ends_With (+\" n\", \"n\") = True,             +\"EW_109\");\n  Assert (Ends_With (+\"n\", \" n\") = False,            +\"EW_110\");\n  Assert (Ends_With (+\" n\", \" n\") = True,            +\"EW_111\");\nend Strings;\n"
  },
  {
    "path": "test/t.cmd",
    "content": "@echo off\r\n\r\nrem  HAC regression test\r\nrem  -------------------\r\nrem  This script is basically the command \"hac -v2 all_silent_tests.adb\"\r\nrem  preceded by a potential rebuild of the hac executable.\r\n\r\necho (Re-)building HAC\r\ncd..\r\nset hacbuild=unknown\r\ngprbuild -P hac.gpr hac\r\nif NOT \"%ERRORLEVEL%\" == \"0\" goto hac_build_failed\r\ncd test\r\nset hacbuild=done\r\n\r\nif \"%1\"==\"\" goto regression_tests\r\n\r\nrem Try without extension\r\nif exist %1.adb ..\\hac -v2 %1.adb\r\nif exist %1.adb goto fin\r\n\r\nrem Try with extension\r\n..\\hac -v2 %1\r\ngoto fin\r\n\r\n:regression_tests\r\nrem Here HAC will call itself for each test!...\r\n\r\n..\\hac -v2 all_silent_tests.adb\r\npause\r\n\r\ngoto fin\r\n\r\n:verbose_tests\r\n..\\hac -v2 all_noisy_tests.adb\r\ngoto fin\r\n\r\n:gnat\r\nrem ******* Building all tests with GNAT.\r\ngprbuild hac_test.gpr\r\n\r\necho ******* Running all tests with GNAT.\r\nfor %%e in (*.exe) do %%e\r\n\r\npause\r\ngoto fin\r\n\r\n:hac_build_failed\r\necho --- HAC build failed (called from t.cmd) ---\r\ncd test\r\n\r\n:fin\r\nset hacbuild=unknown\r\n"
  },
  {
    "path": "test/test.adb",
    "content": "--  This is a fuzzy test for HAC, the HAC Ada compiler.\r\n--\r\n--  Historically, this was the first program to\r\n--  run with HAC after \"hello world\".\r\n--\r\n--  The official regression test for HAC is `all_silent_tests.adb`.\r\n\r\nwith HAT; use HAT;\r\n\r\nprocedure Test is\r\n  --\r\n  type Type1 is record\r\n    x : Integer;\r\n    y : Real;\r\n  end record;\r\n  --\r\n  z1 : Type1;\r\n  --\r\n  function Add (x, y : Integer) return Integer is\r\n    value : Integer;\r\n  begin\r\n    value := x + y;\r\n    return value;\r\n  end Add;\r\n  --\r\n  x_glob : Integer;\r\n\r\n  procedure Do_0 is\r\n  begin\r\n    x_glob := 54321;\r\n  end Do_0;\r\n  --\r\n  procedure Do_1 (a : Integer) is\r\n  begin\r\n    x_glob := a;\r\n  end Do_1;\r\n  --\r\n  procedure Do_1_param_in_out (a : in out Integer) is\r\n    sept : constant := 7;\r\n    septante : constant Integer := 70;\r\n  begin\r\n    a := septante + sept;\r\n    Put_Line (\"NOT in a block statement\");\r\n    a := 700 + a;\r\n    --\r\n    --  *** Block statements temporarily disabled (details in roland_01.adb) ***\r\n    --\r\n    --  What_a_nice_block:\r\n    --  declare\r\n    --    sept_cents: constant Integer:= 700;  --  sept * 100 too complicated !!\r\n    --  begin\r\n    --    a:= sept_cents + a;\r\n    --    Put_Line(\"Block statement\");\r\n    --  end What_a_nice_block;\r\n    --  Put_Line(\"NOT in a block statement\");\r\n    --  what_a_nice_block_2:\r\n    --  begin\r\n    --    Put_Line(\"Another block statement\");\r\n    --    what_a_NICE_block_3:\r\n    --    begin\r\n    --      Put_Line(\"Yet another block statement\");\r\n    --    end what_a_NICE_block_3;\r\n    --  end what_a_nice_block_2;\r\n    --  Put_Line(\"NOT in a block statement\");\r\n  end Do_1_param_in_out;\r\n  --\r\n  --  type My_String is array(1..5) of Character;\r\n  --  s: String(1..5);\r\n  --  ms: My_String;\r\n  --\r\n  --\r\n\r\n  -----------------------------------------------\r\n  -- Recursive Fibonacci numbers demonstration --\r\n  -----------------------------------------------\r\n\r\n  procedure Fibo_demo (X : Natural) is\r\n\r\n    function Fib (P : Natural) return Positive is\r\n    begin\r\n      if P <= 2 then\r\n        return 1;\r\n      else\r\n        return Fib (P - 1) + Fib (P - 2);\r\n      end if;\r\n    end Fib;\r\n\r\n  begin\r\n    Put (\"  Fibonacci(\");\r\n    Put (X, 2);\r\n    Put (\") = \");\r\n    Put (Fib (X), 5);\r\n    New_Line;\r\n  end Fibo_demo;\r\n\r\n  -------------------------------------\r\n  -- Testing multidimensional arrays --\r\n  -------------------------------------\r\n\r\n  procedure Test_multi_arrays is\r\n    l1 : constant := -3;\r\n    h1 : constant :=  9;\r\n    l2 : constant := 1;\r\n    h2 : constant := 6;\r\n    type T1 is array (l1 .. h1, l2 .. h2) of Integer;\r\n    a : T1;\r\n    b : array (l1 .. h1, l2 .. h2) of Real;\r\n    type T2 is array (6 .. 9) of Integer;\r\n    type T3 is record x : Integer; y : T2; end record;\r\n    c : array (l1 .. h1, l2 .. h2) of T3;\r\n  begin\r\n    for step in 1 .. 6 loop  --  !! HAC: compiles 1..7 OK without \"when 7\", interpreter crashes\r\n      Put (\"Multidimensional array: Step\");\r\n      Put (step);\r\n      New_Line;\r\n      for i in l1 .. h1 loop\r\n        for j in l2 .. h2 loop\r\n          case step is\r\n            when 1 =>  --  fill array a\r\n              a (i, j) := i * j;\r\n            when 2 =>  --  display array a\r\n              Put (a (i, j));\r\n              if j = h2 then\r\n                New_Line;\r\n              end if;\r\n            when 3 =>  --  fill array b\r\n              --  HAC 0.01 accepted \"b(i,j):= i * j\" without Real(...);\r\n              b (i, j) := Real (i * j);\r\n            when 4 =>  --  display array b\r\n              Put (b (i, j), 5, 1, 0);  --  Fore, Aft, Exp.\r\n              Put (' ');\r\n              if j = h2 then\r\n                New_Line;\r\n              end if;\r\n            when 5 =>  --  fill array c\r\n              c (i, j).y (7) := i * j;\r\n            when 6 =>  --  display array c\r\n              Put (c (i, j).y (7));\r\n              if j = h2 then\r\n                New_Line;\r\n              end if;\r\n          end case;\r\n        end loop;\r\n      end loop;\r\n    end loop;\r\n  end Test_multi_arrays;\r\n\r\n  Twenty : constant := 20;\r\n  Ten_point_one : constant := 10.1;\r\n  c : Character;\r\n  --  ABCDEFGHIJKLMNOPQRSTUVWXYZ: Character; -- Testing a long identifier\r\n  hs : String (1 .. 7);\r\n\r\n  procedure Show_hs is\r\n  begin\r\n    Put_Line (hs);\r\n  end Show_hs;\r\n\r\n  procedure Int_Layout is\r\n    procedure IL_Base (b : Integer) is\r\n      procedure IL_Val (i : Integer) is\r\n        procedure IL_Width (w : Integer) is\r\n        begin\r\n          --  if i >= 0 then Put (' '); end if;\r\n          Put ('['); Put (i, w, b); Put (']');\r\n        end IL_Width;\r\n      begin\r\n        Put (\"    \");\r\n        for w in 0 .. 4 loop IL_Width (w); end loop;\r\n        IL_Width (8);\r\n        IL_Width (12);\r\n        New_Line;\r\n      end IL_Val;\r\n    begin\r\n      IL_Val (+123);\r\n      IL_Val (-123);\r\n    end IL_Base;\r\n  begin\r\n    Put_Line (\"Integer layout: \");\r\n    IL_Base (2);\r\n    IL_Base (10);\r\n    IL_Base (16);\r\n  end Int_Layout;\r\n\r\n  procedure Float_Layout is\r\n    procedure FL_Exp (e : Integer) is\r\n      procedure FL_Val (r : Real) is\r\n        procedure FL_Fore (f : Integer) is\r\n        begin\r\n          --  if i >= 0 then Put (' '); end if;\r\n          Put ('['); Put (r, f, 2, e); Put (']');\r\n        end FL_Fore;\r\n      begin\r\n        Put (\"    \");\r\n        for w in 0 .. 5 loop FL_Fore (w); end loop;\r\n        New_Line;\r\n      end FL_Val;\r\n    begin\r\n      FL_Val (+123.0);\r\n      FL_Val (-123.0);\r\n    end FL_Exp;\r\n  begin\r\n    Put_Line (\"Float layout: \");\r\n    FL_Exp (0);\r\n    FL_Exp (4);\r\n  end Float_Layout;\r\n\r\nbegin\r\n  Put ('A');\r\n  c := 'B';\r\n  Put (c);\r\n  c := ''';\r\n  Put (c);\r\n  Put ('\"');\r\n  Put (\"\");\r\n  New_Line;\r\n  --\r\n  hs := \"\"\"Hello\"\"\";\r\n  Show_hs;\r\n  hs := \"\"\"Hel\"\"lo\";\r\n  Show_hs;\r\n  hs := \"Hel\"\"lo\"\"\";\r\n  Show_hs;\r\n  hs := \"Hel\"\"l\"\"o\";\r\n  Show_hs;\r\n  hs := \"Hel'l'o\";\r\n  Show_hs;\r\n  --\r\n  Int_Layout;\r\n  Float_Layout;\r\n  --  My_Put(s, 1 , 5);\r\n  New_Line;\r\n  Put (Twenty); Put_Line (\" ... should be: 20\");\r\n  Put (Ten_point_one); Put_Line (\" ... should be: 1.01000E+01\");\r\n  x_glob := 123;\r\n  z1.x := Add (432, x_glob); -- then: z1.x = 555\r\n  Put (z1.x);\r\n  Put_Line (\" ... should be: 555\");\r\n  z1.y := 1.8;\r\n  Put (z1.y); Put_Line (\" ... should be: 1.80000E+00\");\r\n  Put_Line (\"Do_0: output 54321\");\r\n  Do_0; Put (x_glob); New_Line;\r\n  Put_Line (\"6-3+2 = 5\");\r\n  Put (6 - 3 + 2); New_Line;\r\n  --\r\n  Do_1 (123);\r\n  Do_1_param_in_out (x_glob);\r\n  case x_glob is\r\n    when 123 =>\r\n      Put (\"123 (wrong)\");\r\n    when 456 =>\r\n      Put (\"456 (wrong)\");\r\n    when 777 =>\r\n      Put (\"777 (correct)\");\r\n    when others =>\r\n      Put (x_glob);\r\n      Put (\" (wrong)\");\r\n  end case;\r\n  New_Line;\r\n  Put (\"Bla bla\");\r\n  Put (\"\");\r\n  Put_Line (\" and more bla bla!\");\r\n  for gagl in 1 .. 20 loop\r\n    Put (gagl);\r\n    Put (\" choice : \");\r\n    case gagl is\r\n      when 4      => Put_Line (\"... four\");\r\n      when 2      => Put_Line (\"... two\");\r\n      when 7      => Put_Line (\"... seven\");\r\n      when others => Put (gagl, 1); Put_Line (\" (others)\");\r\n    end case;\r\n    exit when gagl = 8;\r\n  end loop;\r\n  --\r\n  Put_Line (\"Recursive Fibonacci:\");\r\n  for n in 1 .. 22 loop\r\n    Fibo_demo (n);\r\n  end loop;\r\n  --\r\n  Test_multi_arrays;\r\nend Test;\r\n"
  },
  {
    "path": "test/test1.adb",
    "content": "--  This was the initial test program for the Small-Ada Compiler.\n--  Small-Ada is a restricted subset of the full Ada Language.\n--  The Small-Ada compiler was derived from the Co-Pascal\n--      compiler which in turn was derived from Pascal-S.\n--\n--  The official regression test for HAC is `all_silent_tests.adb`.\n\nwith HAT; use HAT;\n\nprocedure Test1 is\n\n  --  Declarations\n\n  Ten : constant Integer := 10;     -- Integer    (*  test  *)\n  Twenty : constant  := 20;\n  Zwanzig : Integer;\n  Ten_plus_0_Point_One : constant := 10.1;        -- Real\n  CA : constant  Character := 'A';          -- Character\n  CE : constant  Character := 'E';          -- Character\n  B1, B2 : constant Boolean := True;        -- Boolean\n\n  type Type1 is\n     record\n        X : Integer;\n        Y : Real;\n     end record;\n  --  TYPE       Type2 IS String(1..10);\n  type Type3 is array (1 .. 4) of Type1;\n\n  --  TYPE       Type4 IS RECORD\n  --                 ay: array(1..Ten) of integer;\n  --                END RECORD;\n  type Day is\n        (Sun,\n         Mon,\n         Tue,\n         Wed,\n         Thu,\n         Fri,\n         Sat);\n\n  I1, I2, I3 :  Integer := 99;\n  I4 : constant Integer := -I1 + 10;\n  R1 : Real := 1.23;\n  R2 : Real := Ten_plus_0_Point_One;\n  C2 : constant Character := '+';\n  C1 : constant Character := '+';\n  C3 : constant Character := CA;\n  B3, B4, B5 : Boolean := False;\n  X3 : Type3;\n  A :  array (1 .. 5) of Integer;\n  r : Real;\n\n  function  Add (X, Y : Integer) return Integer is\n    Value : Integer;\n  begin\n    Value := X + Y;\n    return Value;\n  end Add;\n\n  procedure IComp (X, Y : Integer) is\n  begin\n    if X <= Y then Put (\"In \"); Put_Line (\"Order\");\n    else Put_Line (\"Reverse Order\");  end if;\n  end IComp;\n\n  weekday : Day;\n\n  procedure Comp_10_20 (I1 : Integer) is\n  begin\n    Put (I1); Put (\" compared to 10 and 20 is :  \");\n    if I1 < 10 then\n      Put_Line (\"the smallest\");\n    elsif I1 < 20 then\n      Put_Line (\"in the middle\");\n    else\n      Put_Line (\"the largest\");\n    end if;\n  end Comp_10_20;\n\nbegin\n  for d in Sun .. Sat loop\n    case d is\n      when Sun => Put (\"Sunday. \");\n      when Mon => Put (\"Monday. \");\n      when Tue => Put (\"Tuesday. \");\n      when Wed => Put (\"Wednesday. \");\n      when Thu => Put (\"Thursday. \");\n      when Fri => Put (\"Friday! \"); weekday := d;\n      when Sat => Put (\"Saturday.\");\n    end case;\n  end loop;\n  New_Line;\n  for i in 1 .. 4 loop\n    X3 (i).X := i;\n    X3 (i).Y := Real (i);\n  end loop;\n  r := 1.0;\n  for i in 1 .. 4 loop\n    r := r * X3 (i).Y;\n  end loop;\n  Put_Line (+\"Expected: 24, computed: \" & r);\n  --  CONSTANT Check\n  Put_Line (\"CONSTANT Check\");\n  Put (\"Ten     = \");  Put_Line (Ten);\n  Put (\"Twenty  = \");  Put (Twenty,  11, 16);    Put_Line (\" in base 16\");\n  Put (\"Ten_plus_0_Point_One = \");  Put (Ten_plus_0_Point_One, 10, 16);    Put_Line (\" with 16 digits\");\n  Put (\"Ten_plus_0_Point_One = \");  Put (Ten_plus_0_Point_One, 10, 16, 0); Put_Line (\" with 16 digits, no exponent\");\n  Put (\"CA      = \");  Put (CA); New_Line;\n  Put (\"B1, B2  = \");  Put (B1); Put (' '); Put_Line (B2);\n  New_Line;\n\n  Put_Line (\"Initialization Check\");\n  Put (\"i1, i2, i3  \"); Put (I1); Put (I2); Put (I3); New_Line;\n  Put (\"i4       \");    Put (I4); New_Line;\n  Put_Line (\"r1, r2 (1.23, 10.1): \");\n  Put (R1); Put (R2); New_Line;\n  Put_Line (\"c1, c2, c3 (++A):\");\n  Put (C1); Put (C2); Put (C3); New_Line;\n  Put_Line (\"b1, .., b5. Expected:  (T,T,F,F,F):\");\n  Put (\"   \");\n  Put (B1); Put (' '); Put (B2); Put (' '); Put (B3); Put (' '); Put (B4); Put (' '); Put (B5); New_Line;\n  B3 := weekday = Fri;\n  B4 := weekday /= Mon;\n  B5 := B3 = not B4;\n  Put_Line (\"b1, .., b5. Expected: (T,T,T,T,F):\");\n  Put (\"   \");\n  Put (B1); Put (' '); Put (B2); Put (' '); Put (B3); Put (' '); Put (B4); Put (' '); Put (B5); New_Line;\n  New_Line;\n\n  Put_Line (\"ARITHMETIC Check\");\n  I1 := 13;             Put (I1); Put_Line (\" (i1:= 13)\");\n  I2 := Ten;            Put (I2); Put_Line (\" (i2:= 10)\");\n  I3 := I1 + I2 + 5;    Put (I3); Put_Line (\" (i3:= i1+i2+5 = 28)\");\n  I3 := I1 - Twenty;    Put (I3); Put_Line (\" (i3:= i1-20 = -7)\");\n  I3 := I2 * I1;        Put (I3); Put_Line (\" (i3:= i1*i2 = 130)\");\n  I3 := I1 / 5;         Put (I3); Put_Line (\" (i3:= i1 DIV 5)\");\n  I3 := I1 mod 5;       Put (I3); Put_Line (\" (i3:= i1 MOD 5)\");\n  R1 := 20.4;           Put (R1); Put_Line (\" (r1:= 20.4)\");\n  R2 := R1 / 2.0;         Put (R2); Put_Line (\" (r2:= r1/2.0 = 10.2)\");\n  Put (10.0 * Ten_plus_0_Point_One); Put_Line (\" (10*10.1)\");\n  New_Line;\n\n  Put_Line (\"LOOP and ARRAY Check\");\n  I1 := 10;\n  Put_Line (\"Single FOR LOOP 1..5: filling array\");\n  for I in 1 .. 5 loop\n    A (I) := I * 2;\n  end loop;\n  Put_Line (\"Single FOR LOOP 1..5: reading array\");\n  for N in 1 .. 5 loop\n    Put (\"   n = \"); Put (N);\n    Put (\"; a(n) = n*2 = \");\n    Put (A (N)); New_Line;\n  end loop;\n  New_Line;\n  Put_Line (\"Double FOR LOOP: 1..2, then A..E\");\n  for I in 1 .. 2 loop\n    Put (\"   Line: \"); Put (I); Put (' ');\n    for J in CA .. CE  loop\n      Put (J);\n    end loop;\n    New_Line;\n  end loop;\n  Put_Line (\"Reverse FOR LOOP 1..7\");\n  for I1 in reverse 1 .. 7 loop\n    Put (I1);\n  end loop;\n  Put (\"  i1 = \"); Put (I1);\n  New_Line (2);\n\n  Put_Line (\"WHILE Check 1..5\");\n  I1 := 0;\n  while I1 < 5 loop\n    I1 := I1 + 1;\n    Put (I1);\n  end loop;\n  New_Line;\n\n  --  REPEAT Check\n  New_Line;   Put_Line (\"REPEAT Check, until Ten\");\n  loop\n    Put_Line (+\"Rpt  \" & I1);\n    I1 := I1 + 1;\n    exit when I1 = Ten;\n  end loop;\n  New_Line;\n\n  --  Function and Procedure Check\n  New_Line;   Put_Line (\"FUNCTION and PROCEDURE Check\");\n  Put (\"   compare 10 to 20 \");  IComp (Ten, Twenty);\n  Put (\"   compare 20 to 10 \");  IComp (Twenty, Ten);\n  Put (Ten);  Put (5);  Put (\"     ADD = \"); Put (Add (Ten, 5)); New_Line;\n  New_Line;\n\n  Put_Line (\"IF and BOOLEAN Check\");\n  Zwanzig := Ten + Ten + X3 (3).X - 3;\n  if Ten > Zwanzig then\n    Put (Ten); Put ('>'); Put (Twenty); Put_Line (\"O_o: bug with IF or with \"\">\"\" operator\");\n  else\n    Put (Ten); Put (\"<=\"); Put (Twenty); Put_Line (\" (Waw, the \"\">\"\" operator works on integers)\");\n  end if;\n\n  Comp_10_20 (-6);\n  Comp_10_20 (99);\n  Comp_10_20 (19);\n  New_Line;\n\n  if not False then Put_Line (\"(1/2)  NOT  is OK\");     else Put_Line (\"(1/2)  NOT  is not OK\"); end if;\n  if not True  then Put_Line (\"(2/2)  NOT  is not OK\"); else Put_Line (\"(2/2)  NOT  is OK\");     end if;\n  New_Line;\n\n  if False and False then Put_Line (\"(1/4)  AND  is not OK\"); else Put_Line (\"(1/4)  AND  is OK\");     end if;\n  if True  and False then Put_Line (\"(2/4)  AND  is not OK\"); else Put_Line (\"(2/4)  AND  is OK\");     end if;\n  if False and True  then Put_Line (\"(3/4)  AND  is not OK\"); else Put_Line (\"(3/4)  AND  is OK\");     end if;\n  if True  and True  then Put_Line (\"(4/4)  AND  is OK\");     else Put_Line (\"(4/4)  AND  is not OK\"); end if;\n  New_Line;\n\n  if False or False  then Put_Line (\"(1/4)  OR   is not OK\"); else Put_Line (\"(1/4)  OR   is OK\");     end if;\n  if True  or False  then Put_Line (\"(2/4)  OR   is OK\");     else Put_Line (\"(2/4)  OR   is not OK\"); end if;\n  if False or True   then Put_Line (\"(3/4)  OR   is OK\");     else Put_Line (\"(3/4)  OR   is not OK\"); end if;\n  if True  or True   then Put_Line (\"(4/4)  OR   is OK\");     else Put_Line (\"(4/4)  OR   is not OK\"); end if;\n  New_Line;\n\n  if False xor False then Put_Line (\"(1/4)  XOR  is not OK\"); else Put_Line (\"(1/4)  XOR  is OK\"); end if;\n  if True  xor False then Put_Line (\"(2/4)  XOR  is OK\");     else Put_Line (\"(2/4)  XOR  is not OK\"); end if;\n  if False xor True  then Put_Line (\"(3/4)  XOR  is OK\");     else Put_Line (\"(3/4)  XOR  is not OK\"); end if;\n  if True  xor True  then Put_Line (\"(4/4)  XOR  is not OK\"); else Put_Line (\"(4/4)  XOR  is OK\"); end if;\n  New_Line;\n\n  if False and then False then Put_Line (\"(1/4)  AND THEN  is not OK\"); else Put_Line (\"(1/4)  AND THEN  is OK\");     end if;\n  if True  and then False then Put_Line (\"(2/4)  AND THEN  is not OK\"); else Put_Line (\"(2/4)  AND THEN  is OK\");     end if;\n  if False and then True  then Put_Line (\"(3/4)  AND THEN  is not OK\"); else Put_Line (\"(3/4)  AND THEN  is OK\");     end if;\n  if True  and then True  then Put_Line (\"(4/4)  AND THEN  is OK\");     else Put_Line (\"(4/4)  AND THEN  is not OK\"); end if;\n  New_Line;\n\n  if False or else False  then Put_Line (\"(1/4)  OR ELSE   is not OK\"); else Put_Line (\"(1/4)  OR ELSE   is OK\");     end if;\n  if True  or else False  then Put_Line (\"(2/4)  OR ELSE   is OK\");     else Put_Line (\"(2/4)  OR ELSE   is not OK\"); end if;\n  if False or else True   then Put_Line (\"(3/4)  OR ELSE   is OK\");     else Put_Line (\"(3/4)  OR ELSE   is not OK\"); end if;\n  if True  or else True   then Put_Line (\"(4/4)  OR ELSE   is OK\");     else Put_Line (\"(4/4)  OR ELSE   is not OK\"); end if;\n  New_Line;\n\n  --  CASE Check\n  Put_Line (\"CASE Check\");\n  I1 := -1;\n  Put (\"Selector value =\"); Put (I1); New_Line;\n  case I1 is\n    when    1 | 2    =>    Put (\"Case is 1 or 2 ...\");\n      Put_Line (\"that's OK\");\n    when    3        =>    Put_Line (\"Case = 3, \");\n    when    4        =>    Put_Line (\"Case = 4, \");\n    when  others     =>    Put (\"Case is \");\n      Put_Line (\"Others (not 1,2,3,4)\");\n  end case;\n\n  New_Line;   Put_Line (\"END OF TEST\");\n\nend Test1;\n"
  },
  {
    "path": "test/test_tail_after_match.adb",
    "content": "with HAT;\n\nprocedure Test_Tail_After_Match is\n  use HAT;\n  Path : VString := +\"/etc/genesix/gnx-startup\";\nbegin\n  Put_Line (Tail_After_Match (Path,  '/'));                         --  returns \"gnx-startup\"\n  Put_Line (Tail_After_Match (Path,  \"ix\"));                        --  returns \"/gnx-startup\"\n  Put_Line (Tail_After_Match (Path,  \"gene\"));                      --  returns \"six/gnx-startup\"\n  Put_Line (Tail_After_Match (Path,  \"etc/genesix/gnx-startu\"));    --  returns \"p\"\n  Put_Line (Tail_After_Match (Path,  \"/etc/genesix/gnx-startu\"));   --  returns \"p\" \n  Put_Line (Tail_After_Match (Path,  \"/etc/genesix/gnx-startup\"));  --  returns empty string \n  Put_Line (Tail_After_Match (Path, +\"/etc/genesix/gnx-startupp\")); --  returns empty string \n  Put_Line (Tail_After_Match (Path, +\"/etc/geneseven\"));            --  returns empty string \nend Test_Tail_After_Match;\n"
  },
  {
    "path": "test/testing_utilities.adb",
    "content": "package body Testing_Utilities is\n\n  use HAT;\n\n  function OK_Code return Integer is\n  begin\n    return 0;  --  0 is the default exit code.\n  end OK_Code;\n\n  procedure Failure (Message : VString) is\n  begin\n    Put_Line (+\"   ----> Failure in test: [\" & Message & ']');\n    Set_Exit_Status (1);  --  Test failed.\n  end Failure;\n\n  procedure Assert (Check : in Boolean; Message : VString) is\n  begin\n    if not Check then\n      Failure (Message & \", assertion\");\n    end if;\n  end Assert;\n\nend Testing_Utilities;\n"
  },
  {
    "path": "test/testing_utilities.ads",
    "content": "with HAT;\n\npackage Testing_Utilities is\n\n  function OK_Code return Integer;\n\n  procedure Failure (Message : HAT.VString);\n\n  procedure Assert (Check : in Boolean; Message : HAT.VString);\n  --  Similar to pragma Assert (RM 11.4.2) but sets an exit status\n  --  instead of raising an exception.\n\nend Testing_Utilities;\n"
  },
  {
    "path": "test/tf.cmd",
    "content": "@echo off\n\nrem  HAC regression test\nrem  -------------------\nrem  Regression test in \"fast\" mode.\n\necho (Re-)building HAC\ncd..\ndel hac.exe\ngprbuild -XHAC_Build_Mode=Fast -P hac -largs obj/hac_icon.rbj \ncd test\nset hacbuild=done\n\n..\\hac -v2 all_silent_tests.adb\npause\n"
  },
  {
    "path": "test/toa.cmd",
    "content": "@echo off\r\n\r\necho HAC, *ObjectAda* build\r\n\r\ncd..\r\nCOPY /b hac_objectada-Win32(Intel)-Debug\\hac.exe .\r\ncd test\r\nset hacbuild=done\r\n\r\nif \"%1\"==\"\" goto gallery\r\n\r\nrem Try without extension\r\nif exist %1.adb ..\\hac -v2 %1.adb\r\nif exist %1.adb goto fin\r\n\r\nrem Try with extension\r\n..\\hac -v2 %1\r\ngoto fin\r\n\r\n:gallery\r\n\r\nREM We run the *GNAT-Compiled* executable of all_silent_tests\r\nREM Reason is that Shell_Execute in HAC compiled by OA fails.\r\nall_silent_tests.exe\r\nREM ..\\hac -v2 all_silent_tests.adb\r\npause\r\n\r\ngoto fin\r\n\r\n:verbose_tests\r\n..\\hac -v2 if_then_elsif_else.adb\r\ngoto fin\r\n\r\n:gnat\r\nrem ******* Building all tests with GNAT.\r\ngprbuild hac_test.gpr\r\n\r\necho ******* Running all tests with GNAT.\r\nfor %%e in (*.exe) do %%e\r\n\r\npause\r\n\r\n:fin"
  },
  {
    "path": "test/ts.cmd",
    "content": "@echo off\n\nrem  HAC regression test\nrem  -------------------\nrem  Regression test in \"small\" mode.\n\necho (Re-)building HAC\ncd..\ndel hac.exe\ngprbuild -XHAC_Build_Mode=Small -P hac -largs obj/hac_icon.rbj \nstrip -s hac*.exe\ncd test\nset hacbuild=done\n\n..\\hac -v2 all_silent_tests.adb\npause\n"
  },
  {
    "path": "test/type_conversion.adb",
    "content": "--  This example contains a feature that was missing in HAC 0.01 but is present in HAC 0.02.\n--\n--  4.6 Type Conversions\n\nwith HAT;\nwith Testing_Utilities;\n\nprocedure Type_Conversion is\n  use HAT, Testing_Utilities;\n\n  function To_Int (x : Real) return Integer is\n  begin\n    return Integer (x);\n  end To_Int;\n\n  subtype Day_Range is Integer range 1 .. 31;\n  i, j : Integer;\n  x, y : Real;\n  d, e : Duration;\n  oa_duration_delta : constant := 0.00006103515625;\n  --  ObjectAda Win 32 & 64: type Duration is delta 2.0**(-14) range -131072.0..+131072.0-2.0**(-14);\n  dd : Day_Range;\nbegin\n  i := 1234;\n  x := Real (i);\n  --  dd := Day_Range (x);  --  <---- This should raise a Constraint_Error (not in range)\n  --\n  dd := 1;\n  i := dd;\n  x := 0.0 * x + 2.0;\n  y := x + Real (i);\n  j := i + To_Int (3.51);\n  --\n  Assert (y = 3.0, +\"Compiler bug [Type_Conversion, A]\");\n  Assert (j = 5,   +\"Compiler bug [Type_Conversion, B]\");\n  --\n  --  Duration <-> Real\n  --\n  d := 0.01;\n  e := Duration (0.2 * 5.0);\n  delay d;\n  x := Real (d);\n  if abs (x * 100.0 - Real (e)) > 100.0 * oa_duration_delta then\n    Put_Line (\"Type_Conversion, Compiler bug [C]\");\n    Put_Line (+\"100 * x = \" & 100.0 * x);\n    Put_Line (+\"e = \" & Image (e));\n    Failure (+\"\");\n  end if;\nend Type_Conversion;\n"
  },
  {
    "path": "test/verif_hac.aru",
    "content": "------------------------------------------------\n--  AdaControl verification rules             --\n--  https://www.adalog.fr/en/adacontrol.html  --\n------------------------------------------------\n\n-- Set for HAC (HAC Ada Compiler).\n\n--------------------------------------\n--  (1) Required (\"check\" command)  --\n--------------------------------------\n\ncheck style (no_closing_name);\ncheck style (negative_condition);\ncheck style (casing_keyword, lowercase);\n\n------------------------------------------------------------------\n--  (2) Acceptable, but should be looked at (\"search\" command)  --\n------------------------------------------------------------------\n\nsearch simplifiable_statements;\n"
  }
]