Skip to content

Commit 018be98

Browse files
committed
Add days 1-13, 2018
1 parent b70b005 commit 018be98

File tree

13 files changed

+586
-0
lines changed

13 files changed

+586
-0
lines changed

2018/day01/solution.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import re
2+
from itertools import count
3+
4+
with open("input") as f:
5+
inp = f.read().strip()
6+
7+
# Part 1
8+
nums = list(map(int, re.findall("-?\d+", inp)))
9+
print(sum(nums))
10+
11+
# Part 2
12+
seen = set()
13+
freq = 0
14+
for i in count():
15+
freq += nums[i%len(nums)]
16+
if freq in seen:
17+
print(freq)
18+
break
19+
seen.add(freq)

2018/day02/solution.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from collections import Counter
2+
from itertools import combinations
3+
4+
with open("input") as f:
5+
inp = f.read().strip().split("\n")
6+
7+
8+
# Part 1
9+
twos, threes = 0, 0
10+
for id_ in inp:
11+
counts = Counter(id_).values()
12+
twos += (2 in counts)
13+
threes += (3 in counts)
14+
15+
print(twos*threes)
16+
17+
# Part 2
18+
for id1, id2 in combinations(inp, 2):
19+
if sum(l1 != l2 for l1, l2 in zip(id1, id2)) == 1:
20+
print("".join(c for i, c in enumerate(id1) if c == id2[i]))
21+
break

2018/day03/solution.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import re
2+
from itertools import combinations
3+
4+
with open("input") as f:
5+
inp = f.read().strip().split("\n")
6+
7+
claims = {}
8+
for line in inp:
9+
id_, ox, oy, w, h = list(map(int, re.findall("\d+", line)))
10+
claims[id_] = {
11+
x + y*1j
12+
for x in range(ox, ox + w)
13+
for y in range(oy, oy + h)
14+
}
15+
16+
# Part 1
17+
res = set()
18+
for cl1, cl2 in combinations(claims.values(), 2):
19+
res |= cl1 & cl2
20+
21+
print(len(res))
22+
23+
# Part 2
24+
for i, claim in claims.items():
25+
no_overlap = True
26+
for j, other_claim in claims.items():
27+
if i == j:
28+
continue
29+
if len(claim & other_claim) > 0:
30+
no_overlap = False
31+
break
32+
if no_overlap:
33+
print(i)
34+
break

2018/day04/solution.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import re
2+
from collections import defaultdict
3+
4+
with open("input") as f:
5+
inp = f.read().strip().split("\n")
6+
7+
records = []
8+
for line in inp :
9+
year, month, day, hour, minute, *rest = list(map(int, re.findall("\d+", line)))
10+
if "shift" in line:
11+
event = rest[0]
12+
elif "asleep" in line:
13+
event = -1
14+
elif "wakes" in line:
15+
event = 0
16+
records.append((month, day, hour, minute, event))
17+
18+
records = sorted(records)
19+
20+
sleep = defaultdict(list)
21+
for record in records:
22+
month, day, hour, minute, event = record
23+
if event > 0:
24+
cur_id = event
25+
elif event == -1:
26+
start_minute = minute
27+
elif event == 0:
28+
sleep[cur_id].append((month, day, start_minute, minute - 1))
29+
30+
# Part 1
31+
def days_asleep(id_, n):
32+
res = 0
33+
for _, _, start, end in sleep[id_]:
34+
res += (start <= n <= end)
35+
return res
36+
37+
38+
max_ = 0
39+
for id_, ranges in sleep.items():
40+
minutes = sum(end - start + 1 for (_, _, start, end) in ranges)
41+
if minutes > max_:
42+
max_ = minutes
43+
max_id = id_
44+
45+
max_ = 0
46+
for n in range(60):
47+
val = days_asleep(max_id, n)
48+
if val > max_:
49+
max_ = val
50+
max_minute = n
51+
52+
print(max_id*max_minute)
53+
54+
# Part 2
55+
max_ = 0
56+
for id_, ranges in sleep.items():
57+
for n in range(60):
58+
val = days_asleep(id_, n)
59+
if val > max_:
60+
max_ = val
61+
max_id = id_
62+
max_minute = n
63+
64+
print(max_id*max_minute)

2018/day05/solution.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
with open("input") as f:
2+
s = f.read().strip()
3+
4+
5+
def react(s):
6+
for i in range(len(s) - 1):
7+
if s[i].lower() == s[i+1].lower() and s[i] != s[i+1]:
8+
return False, s[:i] + s[i+2:]
9+
return True, s
10+
11+
12+
def reduce(s):
13+
while True:
14+
done, s = react(s)
15+
if done:
16+
return s
17+
18+
19+
# Part 1
20+
s = reduce(s)
21+
print(len(s))
22+
23+
# Part 2
24+
letters = (chr(97 + i) for i in range(26))
25+
print(
26+
min(
27+
map(
28+
len,
29+
(
30+
reduce(
31+
s.replace(letter, "").replace(letter.upper(), ""))
32+
for letter in letters
33+
)
34+
)
35+
)
36+
)

2018/day06/solution.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from collections import defaultdict
2+
3+
with open("input") as f:
4+
inp = f.read().strip().split("\n")
5+
6+
coords = [tuple(map(int, line.split(","))) for line in inp]
7+
8+
# Part 1
9+
minx = min(x for x, _ in coords)
10+
maxx = max(x for x, _ in coords)
11+
miny = min(y for _, y in coords)
12+
maxy = max(y for _, y in coords)
13+
14+
regions = defaultdict(set)
15+
for x in range(minx, maxx + 1):
16+
for y in range(miny, maxy + 1):
17+
dists = [(abs(x - cx) + abs(y - cy), (cx, cy)) for (cx, cy) in coords]
18+
dists = sorted(dists)
19+
(d1, (c1x, c1y)), (d2, (c2x, c2y)) = dists[0], dists[1]
20+
if d1 != d2:
21+
regions[(c1x, c1y)].add((x, y))
22+
23+
corners = []
24+
left = sorted([(cx, cy) for cx, cy in regions.keys() if cx == minx])
25+
right = sorted([(cx, cy) for cx, cy in regions.keys() if cx == maxx])
26+
corners = [left[0], left[-1], right[0], right[-1]]
27+
28+
print(max(len(region) for c, region in regions.items() if c not in corners))
29+
30+
# Part 2
31+
total_dist = 10000
32+
33+
region = set()
34+
for x in range(minx - total_dist // len(coords), maxx + total_dist // len(coords)):
35+
for y in range(miny - total_dist // len(coords), maxy + total_dist // len(coords)):
36+
if sum(abs(x - cx) + abs(y - cy) for cx, cy in coords) < total_dist:
37+
region.add((x, y))
38+
39+
print(len(region))

2018/day07/solution.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import re
2+
from collections import defaultdict
3+
4+
with open("input") as f:
5+
inp = f.read().strip().split("\n")
6+
7+
reqs = defaultdict(set)
8+
reqs_inv = defaultdict(set)
9+
for line in inp:
10+
first, second = list(re.findall("(?<=\s)[A-Z](?=\s)", line))
11+
reqs[second].add(first)
12+
reqs_inv[first].add(second)
13+
14+
15+
# Part 1
16+
temp = [item for ls in reqs.values() for item in ls]
17+
avail = set()
18+
for item in temp:
19+
if item not in reqs.keys():
20+
avail.add(item)
21+
22+
order = []
23+
while avail:
24+
new_avail = sorted(list(avail))
25+
order.append(new_avail.pop(0))
26+
new_avail = set(new_avail)
27+
for candidate in reqs_inv[order[-1]]:
28+
if reqs[candidate] <= set(order):
29+
new_avail.add(candidate)
30+
avail = new_avail
31+
32+
print("".join(order))
33+
34+
# Part 2
35+
letters = set(order)
36+
37+
steps = 0
38+
done = []
39+
workers = [(0, None)]*5
40+
q = []
41+
42+
while len(done) < len(order):
43+
for letter in list(letters):
44+
if reqs[letter] <= set(done):
45+
q.append(letter)
46+
letters.remove(letter)
47+
48+
# Update workers and take in new orders.
49+
for i, (time, item) in enumerate(workers):
50+
if item is not None:
51+
workers[i] = (time - 1, item)
52+
else:
53+
if q:
54+
item = q.pop(0)
55+
workers[i] = (ord(item) - 4 - 1, item)
56+
57+
# Check if workers are done.
58+
for i, (time, item) in enumerate(workers):
59+
if time == 0 and item is not None:
60+
done.append(item)
61+
workers[i] = (0, None)
62+
steps += 1
63+
64+
print(steps)

2018/day08/solution.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from collections import defaultdict
2+
3+
with open("input") as f:
4+
inp = f.read().strip()
5+
6+
7+
inp = list(map(int, inp.split(" ")))
8+
metadata = defaultdict(list)
9+
children = defaultdict(list)
10+
descendants = defaultdict(set)
11+
p = 0
12+
route = []
13+
while p < len(inp):
14+
jump = 2 + sum(len(metadata[desc]) + 2 for desc in descendants[p]) + len(metadata[p])
15+
if len(children[p]) < inp[p]:
16+
route.append(p)
17+
p += jump
18+
else:
19+
metadata[p] = inp[p + jump: p + jump + inp[p + 1]]
20+
if route:
21+
for q in route:
22+
descendants[q].add(p)
23+
children[route[-1]].append(p)
24+
p = route.pop()
25+
else:
26+
p += 2 + jump + len(metadata[p])
27+
28+
print(sum(val for ls in metadata.values() for val in ls))
29+
30+
# Part 2
31+
def value(node):
32+
if len(children[node]) == 0:
33+
return sum(metadata[node])
34+
res = 0
35+
for entry in metadata[node]:
36+
if 0 <= entry - 1 < len(children[node]):
37+
res += value(children[node][entry - 1])
38+
return res
39+
40+
41+
print(value(0))

2018/day09/solution.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from itertools import cycle
2+
from collections import defaultdict
3+
4+
5+
class Marble:
6+
def __init__(self, value):
7+
self.value = value
8+
self.next = None
9+
self.prev = None
10+
11+
12+
def solve(max_value):
13+
scores = defaultdict(int)
14+
players = cycle(range(418))
15+
circle = [Marble(0)]
16+
circle[0].next = circle[0]
17+
circle[0].prev = circle[0]
18+
player = next(players)
19+
cur_marble = circle[0]
20+
for value in range(1, max_value + 1):
21+
player = next(players)
22+
if value % 23 == 0:
23+
scores[player] += value
24+
for _ in range(7):
25+
cur_marble = cur_marble.prev
26+
scores[player] += cur_marble.value
27+
cur_marble.prev.next = cur_marble.next
28+
cur_marble.next.prev = cur_marble.prev
29+
cur_marble = cur_marble.next
30+
else:
31+
marble = Marble(value)
32+
right = cur_marble.next.next
33+
left = cur_marble.next
34+
right.prev = marble
35+
marble.next = right
36+
left.next = marble
37+
marble.prev = left
38+
cur_marble = marble
39+
circle.append(marble)
40+
41+
return max(scores.values())
42+
43+
44+
# Part 1
45+
print(solve(71339))
46+
47+
# Part 2
48+
print(solve(71339*100))

0 commit comments

Comments
 (0)