8b21ab556a
FossilOrigin-Name: 54a80479319c1ce4c27fdae1169b09159fb624f6d10c5224a338273ec1ea160a
106 lines
3 KiB
Forth
106 lines
3 KiB
Forth
# Day 1: Report Repair
|
|
|
|
After saving Christmas five years in a row, you've decided
|
|
to take a vacation at a nice resort on a tropical island.
|
|
Surely, Christmas will go on without you.
|
|
|
|
The tropical island has its own currency and is entirely
|
|
cash-only. The gold coins used there have a little picture
|
|
of a starfish; the locals just call them stars. None of the
|
|
currency exchanges seem to have heard of them, but somehow,
|
|
you'll need to find fifty of these coins by the time you
|
|
arrive so you can pay the deposit on your room.
|
|
|
|
To save your vacation, you need to get all fifty stars by
|
|
December 25th.
|
|
|
|
Collect 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!
|
|
|
|
Before you leave, the Elves in accounting just need you to
|
|
fix your expense report (your puzzle input); apparently,
|
|
something isn't quite adding up.
|
|
|
|
Specifically, they need you to find the two entries that
|
|
sum to 2020 and then multiply those two numbers together.
|
|
|
|
For example, suppose your expense report contained the
|
|
following:
|
|
|
|
1721
|
|
979
|
|
366
|
|
299
|
|
675
|
|
1456
|
|
|
|
In this list, the two entries that sum to 2020 are 1721
|
|
and 299. Multiplying them together produces
|
|
1721 \* 299 = 514579, so the correct answer is 514579.
|
|
|
|
Of course, your expense report is much larger. Find the
|
|
two entries that sum to 2020; what do you get if you
|
|
multiply them together?
|
|
|
|
----
|
|
|
|
The first step is to get the input into something I
|
|
can work with. My sample input has 200 entries, so I
|
|
can fit them all on the stack, which means it's easy
|
|
to create an array with them.
|
|
|
|
Put your input into a file named `input-day-1`.
|
|
|
|
~~~
|
|
{ 'input-day-1 [ s:to-number ] file:for-each-line }
|
|
'INPUT const
|
|
~~~
|
|
|
|
And then a simple approach is to just loop through the
|
|
input twice, looking for any two values that add up to
|
|
2020.
|
|
|
|
----
|
|
|
|
~~~
|
|
:2020? dup-pair + #2020 eq? ;
|
|
:display dup-pair * n:put nl ;
|
|
|
|
INPUT [ INPUT [ 2020? [ display ] if drop ] a:for-each drop ] a:for-each
|
|
~~~
|
|
|
|
The second part is just slightly different:
|
|
|
|
----
|
|
|
|
The Elves in accounting are thankful for your help; one
|
|
of them even offers you a starfish coin they had left
|
|
over from a past vacation. They offer you a second one
|
|
if you can find three numbers in your expense report that
|
|
meet the same criteria.
|
|
|
|
Using the above example again, the three entries that
|
|
sum to 2020 are 979, 366, and 675. Multiplying them
|
|
together produces the answer, 241861950.
|
|
|
|
In your expense report, what is the product of the
|
|
three entries that sum to 2020?
|
|
|
|
----
|
|
|
|
For this, I just add an additional iteration through the
|
|
input. This can be *slow*, but does work. To save time,
|
|
I `abort` after a match is found, so processing stops at
|
|
the first match.
|
|
|
|
~~~
|
|
:dup-three 'abc 'abcabc reorder ;
|
|
:2020? dup-three + + #2020 eq? ;
|
|
:display dup-three * * n:put nl abort ;
|
|
|
|
:inner INPUT [ 2020? [ display ] if drop ] a:for-each drop ;
|
|
|
|
INPUT [ INPUT [ inner ] a:for-each drop ] a:for-each
|
|
~~~
|