Skip to content

Commit cae70a6

Browse files
committed
2024 d1: Add walkthrough, clean and original solution
1 parent 4d3079b commit cae70a6

File tree

3 files changed

+138
-52
lines changed

3 files changed

+138
-52
lines changed

2024/README.md

+96-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,94 @@
11
Advent of Code 2024 walkthrough
22
===============================
33

4-
*Coming soon!*
4+
Table of Contents
5+
-----------------
56

7+
- [Day 1 - Historian Hysteria][d01]
8+
<!--
9+
- [Day 2 - xxx][d02]
10+
- [Day 3 - xxx][d03]
11+
- [Day 4 - xxx][d04]
12+
- [Day 5 - xxx][d05]
13+
- [Day 6 - xxx][d06]
14+
- [Day 7 - xxx][d07]
15+
- [Day 8 - xxx][d08]
16+
- [Day 9 - xxx][d09]
17+
- [Day 10 - xxx][d10]
18+
- [Day 11 - xxx][d11]
19+
- [Day 12 - xxx][d12]
20+
- [Day 13 - xxx][d13]
21+
- [Day 14 - xxx][d14]
22+
- [Day 15 - xxx][d15]
23+
- [Day 16 - xxx][d16]
24+
- [Day 17 - xxx][d17]
25+
- [Day 18 - xxx][d18]
26+
- [Day 19 - xxx][d19]
27+
- [Day 20 - xxx][d20]
28+
- [Day 21 - xxx][d20]
29+
- [Day 22 - xxx][d20]
30+
- [Day 23 - xxx][d20]
31+
- [Day 24 - xxx][d20]
32+
- [Day 25 - xxx][d20]
33+
-->
34+
35+
36+
37+
Day 1 - Historian Hysteria
38+
--------------------------
39+
40+
[Problem statement][d01-problem][Complete solution][d01-solution][Back to top][top]
41+
42+
### Part 1
43+
44+
All right, let's get this year started! We have two lists of integers and need
45+
to find differences between their elements, pairing them up in increasing order.
46+
First, read each input line, split it and convert to `int` using
47+
[`map()`][py-builtin-map].
48+
49+
```python
50+
fin = open(...)
51+
52+
total = 0
53+
left = []
54+
right = []
55+
56+
for line in fin:
57+
l, r = map(int, line.split())
58+
left.append(l)
59+
right.append(r)
60+
```
61+
62+
Now all we need to do is [`.sort()`][py-list-sort] them, then then iterate over
63+
the sorted pairs obtained via [`zip()`][py-builtin-zip] summing up their
64+
differences. For that, [`sum()`][py-builtin-sum] plus a [generator
65+
expression][py-gen-expr] will do the trick.
66+
67+
68+
```python
69+
left.sort()
70+
right.sort()
71+
72+
total = sum(abs(l - r) for l, r in zip(left, right))
73+
print('Part 1:', total)
74+
```
75+
76+
### Part 2
77+
78+
Now instead of summing differences we need to sum products. Each number on the
79+
left list needs to be multiplied by the number of times it appears on the right
80+
list. We can again use a generator expression or convert everything into a `for`
81+
loop to do both parts at once. The number of occurrences can be obtained via
82+
[`.count()`][py-list-count].
83+
84+
```python
85+
for l, r in zip(left, right):
86+
total1 += abs(l - r)
87+
total2 += l * right.count(l)
88+
89+
print('Part 1:', total1)
90+
print('Part 2:', total2)
91+
```
692

793
---
894

@@ -86,3 +172,12 @@ Advent of Code 2024 walkthrough
86172
[d22-solution]: solutions/day22.py
87173
[d24-solution]: solutions/day24.py
88174
[d25-solution]: solutions/day25.py
175+
176+
177+
[py-gen-expr]: https://docs.python.org/3/reference/expressions.html#generator-expressions
178+
179+
[py-builtin-map]: https://docs.python.org/3/library/functions.html#map
180+
[py-builtin-sum]: https://docs.python.org/3/library/functions.html#sum
181+
[py-builtin-zip]: https://docs.python.org/3/library/functions.html#zip
182+
[py-list-count]: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
183+
[py-list-sort]: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists

2024/original_solutions/day01.py

+16-51
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,25 @@
22

33
from utils.all import *
44

5-
# advent.setup(2024, )
6-
DEBUG = 'debug' in map(str.lower, sys.argv)
7-
fin = advent.get_input() if not DEBUG else io.StringIO('''\
5+
advent.setup(2024, 1)
86

9-
''')
10-
eprint(*fin, sep='', end='----- end of input -----\n\n'); fin.seek(0, 0)
7+
fin = advent.get_input()
8+
lines = read_lines(fin)
119

12-
try: data = fin.read(); fin.seek(0, 0)
13-
except: pass
14-
try: ints = extract_ints(data)
15-
except: pass
16-
try: intmat = read_int_matrix(fin); fin.seek(0, 0)
17-
except: pass
18-
try: lines = read_lines(fin); fin.seek(0, 0)
19-
except: pass
20-
try: grid = read_char_matrix(fin); fin.seek(0, 0)
21-
except: pass
22-
try: intgrid = read_digit_matrix(fin); fin.seek(0, 0)
23-
except: pass
24-
try: g = graph_from_grid(grid, find='QWERTYUIOPASDFGHJKLZXCVBNM', avoid='#', coords=False, get_neighbors=neighbors4)
25-
except: pass
26-
timer_start()
10+
l = []
11+
r = []
2712

28-
ans1 = ans2 = 0
29-
# g = defaultdict(list)
13+
for line in lines:
14+
a, b = map(int, line.split())
15+
l.append(a)
16+
r.append(b)
3017

31-
# for r, row in enumerate(grid):
32-
# for c, char in enumerate(row):
33-
# pass
18+
l.sort()
19+
r.sort()
3420

35-
# for r, row in enumerate(intgrid):
36-
# for c, num in enumerate(row):
37-
# pass
21+
for a, b in zip(l, r):
22+
ans1 += abs(a - b)
23+
ans2 += a * r.count(a)
3824

39-
# for line in lines:
40-
41-
42-
43-
44-
45-
46-
advent.print_and_submit(1, ans1)
47-
# advent.print_answer(1, ans1)
48-
49-
50-
51-
52-
53-
54-
advent.print_and_submit(2, ans2)
55-
# advent.print_answer(2, ans2)
56-
57-
58-
# - Can you memoize some state for which the solution will always be the same?
59-
# - Can you batch operations together instead of doing them singularly?
60-
# - Too many points? Coordinate compression? Shoelace formula?
61-
# - Can you go blind with Z3 (or GCC+IDA+Z3) instead of reverse engineering?
25+
advent.print_answer(1, ans1)
26+
advent.print_answer(2, ans2)

2024/solutions/day01.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
5+
# Open the first argument as input or use stdin if no arguments were given
6+
fin = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
7+
8+
total1 = total2 = 0
9+
10+
left = []
11+
right = []
12+
13+
for line in fin:
14+
l, r = map(int, line.split())
15+
left.append(l)
16+
right.append(r)
17+
18+
left.sort()
19+
right.sort()
20+
21+
for l, r in zip(left, right):
22+
total1 += abs(l - r)
23+
total2 += l * right.count(l)
24+
25+
print('Part 1:', total1)
26+
print('Part 2:', total2)

0 commit comments

Comments
 (0)