Advent of Code 2025 - Day 12: Christmas Tree Farm (The Finale!)
Day 12 was the finale of Advent of Code 2025. The puzzle appeared to be about fitting oddly-shaped presents into regions under Christmas trees - a classic constraint satisfaction problem. But there was a twist.
Part 1: Can They Fit?
Given various present shapes and regions under trees, determine how many regions can fit all their listed presents.
Example shapes:
|
|
Example regions:
4x4: 0 0 0 0 2 0- a 4×4 grid needing two shape-4 presents12x5: 1 0 1 0 2 2- a 12×5 grid needing various shapes
This looks like it’s asking for a full solution using something like Dancing Links (DLX) or Algorithm X - the kind of thing used for Sudoku solvers and exact cover problems.
The Suspicion
After reading the problem carefully, I had a suspicion: this might be simpler than it appears. Implementing DLX for the final day would be intense, especially with rotations and flips to consider.
The Simple Solution
I wrote a custom parser for the funky input format (hardcoded for 6 shapes at 3×3 size):
|
|
Then I tested my hunch: maybe we just need to check if there’s enough space:
|
|
It worked! The puzzle was a red herring. You don’t actually need to solve the packing problem - you just need to check if there’s enough space. If the grid has more cells than the total cells needed by all presents, it’s solvable. Otherwise, it’s not.
This is brilliant problem design: it looks like you need a complex constraint solver, but the test cases are specifically crafted so simple space checking works.
Part 2: The Star on the Tree
Part 2 is where Advent of Code traditionally gets wild. But for the last day, Part 2 was just placing the star on top of the Christmas tree:
Before any of them can find a ladder, a particularly large Christmas tree suddenly flashes brightly when a large star magically appears above it!
No code needed. Just collect your final star. All 24 stars collected! 🎄⭐
But What If We Actually Solved It?
After finishing, I was curious: could we actually solve the packing problem? I had Claude help me implement two approaches:
Z3 SMT Solver
Using Microsoft’s Z3 theorem prover to encode the constraint satisfaction problem. Result: never finished. The search space was too large.
OR-Tools (Google’s Constraint Solver)
Using Google’s OR-Tools constraint programming library. Result: used too many resources, but gave some progress.
For the 46×46 grid with 44+43+34+34+28+41 = 224 pieces, OR-Tools estimated over 200,000 possible placements to explore. It’s technically solvable but computationally expensive.
Visualizing a Solution
I did manage to generate a valid packing for the first solvable grid (46×46 with 224 pieces). Here’s what it looks like:
|
|
Each letter represents a different instance of a present, and the shape template it uses. The . characters are empty spaces.
The Lesson
Day 12 was a perfect finale because it taught a meta-lesson: don’t overthink it.
Sometimes the hardest part of a problem is recognizing that you don’t need to solve it completely. The puzzle appears to require a complex constraint satisfaction solver, but the actual question is much simpler: “Can it fit?” not “Show me how it fits.”
This mirrors real-world engineering: sometimes a quick feasibility check is all you need before diving into implementation details.
Advent of Code 2025: Complete! 🎄⭐
24 stars collected. From Day 1’s circular dial to Day 12’s present packing, this year had great variety:
- Grid problems (Days 4, 6, 7, 12)
- Graph problems (Days 8, 11)
- Geometry (Day 9)
- Range merging (Day 5)
- Recursion (Day 7)
- Combinatorics (Day 11)
- Pattern matching (Day 2)
Some days rewarded careful implementation (Day 4’s queue optimization), others rewarded insight (Day 3’s skip budget, Day 5’s range merging, Day 11’s multiplication principle).
My helper library fred.py grew this year by adding dfs_all_paths(), improving loadFile() with CSV support, and proving its worth with grid utilities on nearly every other day.
Thanks for following along! Time for a well-deserved break before next year. 🎅