Solved by hand by visualizing the filesystem as
a grid, and put into a simple formula.
In Sweden, this is called a "Femtonspel".
https://sv.wikipedia.org/wiki/Femtonspel
Did brute force, but earlier drafts of the code
failed to exit the while loop correcly.
By manual testing, an odd number is required in reg
a to set the first output to 0 (for my puzzle
input at least). Hence, only odd numbers are tested.
Solution cide works, but is slow. According to the
subreddit, pt 2 is meant to be an exercise in
optimization.
Turns out the assembly instructions do a factorial,
i.e 7! and 12! and adds a salt (5840).
Got that spoiled. :)
A good day to utilize lots of unit testing!
For pt 2, the code initially tried to reverse
the scramble algorithm. The final code however
got the unscrambled version by the traditional
method most password crackers would resolve to:
basic brute forcing with permutations as a list
of candidates.
The code at one time used cached responses for
in range bools, but it seems that does not improve
performance.
Some IP addresses are allowed multiple times, so
min() and set() are used to find the distinct
values.
Learned a lot about the Josephus' Problem today!
Solved part 1 by using a dict, but eventually
ended up just adding the mathematical shortcut
and rewriting both parts to use deque() for
performance.
Part 2 was tricky, since k (the elf to remove
after all presents were stolen from them) is a
index that changes over time. No tries for a
solution that was performant enough using lists
and dicts were succesfull, so by inspiration from
the subreddit the final solution code is based on
2 deque() that pops and appends between them.
There are 2 part 1 solutions.
- A correct implementation of the Josephus' Problem,
using deque(). Recursion would have worked as well,
but Python do not like recursions.
- The mathematical superior version, with a link
to the Youtube video were it is introduced.
Figured out that the center position did not matter,
as long as left hand side tile and right hand side
tile on previous row are not equal.
Also tried to find a recurring pattern to speed
p2 up a bit, but it seems it does not have a
recurring pattern in the 400 000s first rows.
Lost 60 minutes due to misinterpreting this in p2:
> *whenever* you generate a hash
The code initially only did the 2016 stretching for
the triplet hash, not the quintet hash. By doing it
to both, pt 2 is solved.
Not sure the lru cache actually speeds anything up.
Many on the subreddit used the approach to generate
the quintet first and look backwards 1000 times
for a matching quintet (since quintets are more
rare than triplets), this will most likely speed
things up.
Also, this solution do not store the found keys.
Many other solutions do, I believe this is some
presumptions.
Hard one, an infamous AoC puzzle according to
Reddit.
Apparently, this is a classic logic problem named
"Missionaries and cannibals", or "Jealous husbands".
Hard lessons:
- Always use set() for visited nodes during BFS.
- Always use collections.queue() to create to queue
traversals for BFS.
- itertools permutations(), combinations() and
pairwise() may look similar, but they are not.
- Learned to use (?:chunk of text)? in regex.
Test data was achieved without bigger hazzles, but
to optimize code required a lot of Reddit browsing
and code reading from blogs. I have mentioned the
sources in a doc string.
These are already done in Elixir, so this is
just done for the flex.
Also, coming from Day 16-18 from 2023 calendar,
it is safe to say 2015 puzzles are easier and more
manageable.
* Solve 2015:16 "Aunt Sue"
* Make 2023:08 future compatible
Code used to work with another version of python.
* Solve 2015:17 "No such Thing as Too much"
* Solve 2015:18 "Like a GIF For Your Yard"
Also solve 2015:06 just in case, was just a ref
in the end.
* Solve 2015:19 "Medicine for Rudolph"
* Solve 2015:20 "Infinite Elves and Infinite Houses"
* Solve 2023:21 "RPG Simulator 20XX"
* Solve 2015:22 "Wizard Simulator 20XX"
* Solve 2015:23 "Opening the Turing Lock"
* Solve 2015:25 "Let it Snow"
Wrote p2rc and rc2p just for academic purposes.
Puzzles could be solved anyway.
* Solve 2015:24 "Hangs in the Balance"
---------
Co-authored-by: Anders Englöf Ytterström <anders@playmaker.ai>
* Prep Advent of Code 2023
* Solve 2023:01 "Trebuchet?!"
Turns out re methods are non-overlapping. And in
true AoC manners, no provided test cases had
overlaps.
Luckily for me, some of the last lines in the input
contained the string "oneight", so I was able to
find it out quite fast.
Revisions:
1) Reverse strings to find last digit
2) Use isdigit() and skip regex.
3) Use regexp with positive look-ahead.
* Solve 2023:02 "Cube Conundrum"
Very intermediate pythonic solution,
regex would have made the code more compact.
But since 2023:01 decreased the regex courage,
This code will do.
* Solve 2023:03 "Gear Ratios"
Overslept, took about 55 mins.
* Solve 2023:04 "Scratchcards"
On a train that according to swedish tradition
was late. Not a good environment to focus.
Got stuck 2 times:
- Initial code asumed the | was always after the 5th
number, because of the example. Puzzle input had
it at pos 10. Classic AoC mistake.
- I had a hard time trying to understand the score
count, I insisted there was meant to be a +1 at
some point.
> That 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)
I should instead have just looked at the numbers.
* Solve 2023:05 "If You Give A Seed A Fertilizer"
Part 2 takes 66 minutes to run. There is some smart
things to realize here.
* Solve 2023:06 "Wait for it"
* Solve 2023:07 "Camel Cards"
* Solve 2023:08 "Haunted Wasteland"
Part 2 would have taken 10-15 hours with brute force.
After I figured out the puzzle input had circular
A-Z paths, it was plain as day that LCM was the
solution to the problem.
https://en.wikipedia.org/wiki/Least_common_multiple
* Solve 2023:09 "Mirage Maintenance"
* Remove parse_input helper
* Refactor 2023:05
Increasing speed from 66mins to 4mins. Caching the
location value in the code to keep things at highest
speed.
From the subreddit, the algorithm looks like this.
1. Start att location 0
2. Traverse the whole process backwards, by
reversing process steps and flipping dest/src
positions.
3. Output is not a location, instead it's a seed.
4. if seed is in any seed range, use seed to get
location as in step 1.
5. If not, increase location by 1 and repeat 2-4.
* Solve 2023:10 "Pipe Maze"
Got completely stuck on part 2. Tried some polygon
area calculations, but none provided the correct
answer, most likely due to the unorthodox polygon
points.
I also tried _shoelace method_ without any luck.
Had not heard about that one earlier, it was a good
learning experience even though I vould not use it
here.
By the subreddit, several people had had luck
using the ray method.
> Part 2 using one of my favorite facts from
> graphics engineering: lets say you have an
> enclosed shape, and you want to color every
> pixel inside of it. How do you know if a given
> pixel is inside the shape or not? Well, it
> turns out: if you shoot a ray in any direction
> from the pixel and it crosses the boundary an
> _odd number_ of times, it's _inside_. if it crosses
> an even number of times, it's outside. Works
> for all enclosed shapes, even self-intersecting
> and non-convex ones.
* Fix flake8 errors for 2023:1-10
* Solve 2023:11 "Cosmic Expansion"
* Solve 2023:12 "Hot Springs"
* Solve 2023:13 "Point of Incidence"
* Solve 2023:14 "Parabolic Reflector Dish"
* Solve 2023:15 "Lens Library"
WALLOFTEXT for part 2, took me 90 minutes to find
this important text:
> Each step begins with a sequence of letters that
> indicate the label of the lens on which the step
> operates. The result of running the HASH algorithm
> on the label indicates the correct box for that
> step.
It also clarifies how part 2 and part 1 relates.
* Solve 2023:16 "The Floor Will Be Lava"
---------
Co-authored-by: Anders Englöf Ytterström <anders@playmaker.ai>
I brainfarted and had a hard time trying to
understand the instructions.
> Incrementing is just like counting with numbers: xx, xy, xz, ya, yb, and so on. Increase the rightmost letter one step; if it was z, it wraps around to a, and repeat with the next letter to the left until one doesn't wrap around.
I only managed to understand it by looking at solutions on the
subreddit, figuring out the correct behavior:
az -> ba, azzz -> baaa, azzzzz -> baaaaa etc.
I also sped up the test case containing `ghi` as initial password,
by looking for the leftmost invalid I, L or O and increase it,
replacing all following chars with `a`.
ghijklmn -> ghjaaaaa.
tried to solve this one using only incrementing sums, which
worked fine for the test input but not the actual puzzle input.
By a complete rewrite to actually render the tree as a map,
it worked. The spontanious data store is a mess and cost me
much time to work around, since I wanted to have a list of tuples
with all the sizes for each directory.
Took 2 days to figure this one out. Not proud.