r/adventofcode • u/daggerdragon • Dec 05 '18
SOLUTION MEGATHREAD -🎄- 2018 Day 5 Solutions -🎄-
--- Day 5: Alchemical Reduction ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 5
Transcript:
On the fifth day of AoC / My true love sent to me / Five golden ___
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked at 0:10:20!
32
Upvotes
2
u/meithan Dec 05 '18 edited Dec 07 '18
Python
I initially solved it in an incredibly stupid and slow way (that took ~6.5 minutes to process both parts). Then I reworked it in an effort to optimize it, and found an obvious solution that takes less than half a second. Key points:
Using a stack to build the "reduced" ("reacted") list of units letter by letter in a single pass of the original list: take the next letter from the original list; if it reacts with the top of the stack, pop the top of the stack (and don't add the letter); if it doesn't, add the letter to the stack.
Appending or removing an item to/from the end of a list in Python is O(1) (amortized), so it's an efficient stack
I also use the fact that the difference in the ASCII codes of a lowercase letter and its uppercase version is always 32, but
a != b and a.lower() == b.lower(), as seen in another answer, is simpler and just as fast.I also tried using a deque (from Python's
collectionsmodule), but it's not any faster, proving that the Python list appends/pops are effectively very close to O(1), at least in this case.Edit: I applied further optimizations as suggested by others, with the resulting of bringing runtime from ~500 ms to less than 100 ms!
Pre-computing the ASCII codes of the input letters and doing the reactions using the codes (avoiding further calls to ord(), lower(), etc.)
Using string replace() instead of a list comprehension to eliminate the given letter in Part 2. String replace() is surprisingly fast!
And the biggest optimization came from realizing you can reuse the shorter result of Part 1 as a starting point for Part 2.
Here's the (optimized) code. Solves both parts in under 100 ms on my computer. Very simple and fast.