# 2023 Day 6: Wait For It

**URL:** <https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576>\
**Category:** Advent of Code\
**Tags:** spoilers\
**Created:** [December 6, 2023, 10:39pm UTC](https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576 "2023-12-06T22:39:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jere](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/jere/32/87_2.png) [@jere](https://forum.ada-lang.io/u/jere)\
**Post date:** [December 6, 2023, 10:39pm UTC](https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576/1 "2023-12-06T22:39:04Z")

</div>

Didn’t see a thread for this yet, so figured I would start one. I’ve only worked on part 1. I did like that I could come up with various methods of doing this right off the bat. I decided on an algorithmic approach .

---

<div class="post-metadata">

**Author:** ![rocher](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/rocher/32/89_2.png) [@rocher](https://forum.ada-lang.io/u/rocher)\
**Post date:** [December 6, 2023, 11:21pm UTC](https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576/2 "2023-12-06T23:21:11Z")

</div>

Yes, there are various methods to solve this problem.  
I also followed an algorithmic approach for part 1, just for fun. I solved part two with the `bc` calculator: `sqrt(T^2-4*D)`.

---

<div class="post-metadata">

**Author:** ![cantanima](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/cantanima/32/121_2.png) [@cantanima](https://forum.ada-lang.io/u/cantanima)\
**Post date:** [December 7, 2023, 7:07am UTC](https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576/3 "2023-12-07T07:07:49Z")

</div>

I solved both approaches with the quadratic formula (@rocher what calls the bc calculator is part of it). The difficulties I had with this problem are that it’s been so long since I used Ada’s `digits` type and the `Numerics.Elementary_Functions` crate that I had to spend some time reading up on those, experimenting with them, and, once the inevitable bug arose, figuring out what I’d misunderstood.

---

<div class="post-metadata">

**Author:** ![jere](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/jere/32/87_2.png) [@jere](https://forum.ada-lang.io/u/jere)\
**Post date:** [December 7, 2023, 4:24pm UTC](https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576/4 "2023-12-07T16:24:37Z")

</div>

My general solution:

I kept the times and distances as integers to make the math at the end a bit easier (comparing floats has a lot of edge cases to consider). I converted them all to Floats for the quadratic equation match, found the X intercepts, rounded the result (casting rounds in Ada), use the integer version of the X intercepts to calculate the corresponding distance and then compared the distances to the record to see if the x intercepts rounded past the values I needed (in which case I adjusted them).

```ada
   type Race_Time is new Positive;
   type Race_Distance is new Positive;
   type Ways_To_Win is new Natural;

   -- Calculation that lets all execptions propagate
   function Calculate_Ways_To_Win_Unhandled
      (Max_Time : Race_Time;
       Distance_Record : Race_Distance)
       return Ways_To_Win
   is 

      -- Hold time can never be 0 nor can it be the maximum time
      -- or the boat would never move
      subtype Hold_Time is Race_Time range 1..Max_Time-1;

      -- (Max_Time - Hold_Time) * Hold_Time > Distance_Record
      --
      -- -(Hold_Time**2) + Max_Time * Hold_Time - Distance_Record > 0
      --
      -- -B +- SQRT(B**2 - 4*A*C)
      -- => ------------------------ = X intercepts
      -- 2*A
      -- Where:
      -- A = -1
      -- B = Max_Time
      -- C = - (Distance_Record)
      --
      -- Inverted quadratic means all integer values between X intercepts are
      -- win conditions
      A : constant := -1.0;
      B : constant Float := Float(Max_Time);
      C : constant Float := -1.0 * Float(Distance_Record);
      Square_Root : constant Float := Sqrt((B**2) - (4.0 * A * C));

      -- Calculate X intercepts as rounded integers, where X is the hold time
      -- Values may be outside the range of Hold_Time initially, so temporarily
      -- use Hold_Time'Base for intermediate calculations. Note that converting
      -- from Float to Hold_Time'Base does a rounding operation
      x1 : constant Hold_Time'Base := Hold_Time'Base((((-1.0) * B) + Square_Root ) / (2.0 * A));
      x2 : constant Hold_Time'Base := Hold_Time'Base((((-1.0) * B) - Square_Root ) / (2.0 * A));

      -- Calculate corresponding y values for integer x intercepts
      -- Values may be outside the range of Race_Distance initially, so temporarily
      -- use Race_Distance'Base for intermediate calculations
      x1_Distance : constant Race_Distance'Base := Race_Distance'Base((Max_Time - x1) * x1);
      x2_Distance : constant Race_Distance'Base := Race_Distance'Base((Max_Time - x2) * x2);

      -- Rounding may have pushed x1 and x2 out of range.
      -- Adjust values based on how y values compared to the record
      -- This assignment should ensure the results are in the correct
      -- range of the Hold_Time type.
      First : constant Hold_Time := 
         (if x1_Distance > Distance_Record then
            x1
          else
            x1 + 1); -- A little too far left, so adjust
      Last : constant Hold_Time :=
         (if x2_Distance > Distance_Record then
            x2
          else
            x2 - 1); -- A little too far right, so adjust
   begin
      -- since these are essentially integers, the number of ways to win
      -- is just the number of integers in the range of values
      -- or the length of the range;
      return Ways_To_Win((Last - First) + 1);
   end Calculate_Ways_To_Win_Unhandled;

   function Calculate_Ways_To_Win
      (Max_Time : Race_Time;
       Distance_Record : Race_Distance)
       return Ways_To_Win
   is begin
      return Calculate_Ways_To_Win_Unhandled
         (Max_Time => Max_Time,
          Distance_Record => Distance_Record);
   exception
      when others => return 0; -- Means no solution
   end Calculate_Ways_To_Win;

```

---

<div class="post-metadata">

**Author:** ![cantanima](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/cantanima/32/121_2.png) [@cantanima](https://forum.ada-lang.io/u/cantanima)\
**Post date:** [December 7, 2023, 10:41pm UTC](https://forum.ada-lang.io/t/2023-day-6-wait-for-it/576/5 "2023-12-07T22:41:12Z")

</div>

Yep, that was my approach
