Skip to content

Commit fc94585

Browse files
committed
Added day 2021-07 & 2021-08
1 parent f7e470a commit fc94585

File tree

2 files changed

+388
-0
lines changed

2 files changed

+388
-0
lines changed

2021/07-The Treachery of Whales.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, dot, assembly, re, itertools, statistics
3+
from collections import Counter, deque, defaultdict
4+
5+
from compass import *
6+
7+
8+
# This functions come from https://github.com/mcpower/adventofcode - Thanks!
9+
def lmap(func, *iterables):
10+
return list(map(func, *iterables))
11+
12+
13+
def ints(s: str):
14+
return lmap(int, re.findall(r"-?\d+", s)) # thanks mserrano!
15+
16+
17+
def positive_ints(s: str):
18+
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
19+
20+
21+
def floats(s: str):
22+
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
23+
24+
25+
def positive_floats(s: str):
26+
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
27+
28+
29+
def words(s: str):
30+
return re.findall(r"[a-zA-Z]+", s)
31+
32+
33+
test_data = {}
34+
35+
test = 1
36+
test_data[test] = {
37+
"input": """16,1,2,0,4,2,7,1,2,14""",
38+
"expected": ["37", "168"],
39+
}
40+
41+
test = "real"
42+
input_file = os.path.join(
43+
os.path.dirname(__file__),
44+
"Inputs",
45+
os.path.basename(__file__).replace(".py", ".txt"),
46+
)
47+
test_data[test] = {
48+
"input": open(input_file, "r+").read(),
49+
"expected": ["347449", "98039527"],
50+
}
51+
52+
53+
# -------------------------------- Control program execution ------------------------- #
54+
55+
case_to_test = "real"
56+
part_to_test = 2
57+
58+
# -------------------------------- Initialize some variables ------------------------- #
59+
60+
puzzle_input = test_data[case_to_test]["input"]
61+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
62+
puzzle_actual_result = "Unknown"
63+
64+
65+
# -------------------------------- Actual code execution ----------------------------- #
66+
67+
# Conver integer to 36-character binary
68+
# str_value = "{0:>036b}".format(value)
69+
# Convert binary string to number
70+
# value = int(str_value, 2)
71+
72+
73+
if part_to_test == 1:
74+
crabs = ints(puzzle_input)
75+
target = statistics.median(crabs)
76+
fuel = int(sum([abs(crab - target) for crab in crabs]))
77+
78+
puzzle_actual_result = fuel
79+
80+
81+
else:
82+
crabs = ints(puzzle_input)
83+
square_crabs = sum([crab ** 2 for crab in crabs])
84+
sum_crabs = sum(crabs)
85+
min_crabs = min(crabs)
86+
max_crabs = max(crabs)
87+
fuel = min(
88+
[
89+
sum([abs(crab - t) * (abs(crab - t) + 1) / 2 for crab in crabs])
90+
for t in range(min_crabs, max_crabs)
91+
]
92+
)
93+
94+
puzzle_actual_result = int(fuel)
95+
96+
# -------------------------------- Outputs / results --------------------------------- #
97+
98+
print("Case :", case_to_test, "- Part", part_to_test)
99+
print("Expected result : " + str(puzzle_expected_result))
100+
print("Actual result : " + str(puzzle_actual_result))
101+
# Date created: 2021-12-07 08:14:33.977835
102+
# Part 1 : 2021-12-07 08:16:08
103+
# Part 2 : 2021-12-07 08:33:12

2021/08-Seven Segment Search.py

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, dot, assembly, re, itertools
3+
from collections import Counter, deque, defaultdict
4+
5+
from compass import *
6+
7+
8+
# This functions come from https://github.com/mcpower/adventofcode - Thanks!
9+
def lmap(func, *iterables):
10+
return list(map(func, *iterables))
11+
12+
13+
def ints(s: str):
14+
return lmap(int, re.findall(r"-?\d+", s)) # thanks mserrano!
15+
16+
17+
def positive_ints(s: str):
18+
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
19+
20+
21+
def floats(s: str):
22+
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
23+
24+
25+
def positive_floats(s: str):
26+
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
27+
28+
29+
def words(s: str):
30+
return re.findall(r"[a-zA-Z]+", s)
31+
32+
33+
test_data = {}
34+
35+
test = 1
36+
test_data[test] = {
37+
"input": """acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf""",
38+
"expected": ["Unknown", "5353"],
39+
}
40+
41+
test = 2
42+
test_data[test] = {
43+
"input": """be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
44+
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
45+
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
46+
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
47+
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
48+
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
49+
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
50+
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
51+
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
52+
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce""",
53+
"expected": [
54+
"26",
55+
"8394, 9781, 1197, 9361, 4873, 8418, 4548, 1625, 8717, 4315 ==> 61229",
56+
],
57+
}
58+
59+
test = "real"
60+
input_file = os.path.join(
61+
os.path.dirname(__file__),
62+
"Inputs",
63+
os.path.basename(__file__).replace(".py", ".txt"),
64+
)
65+
test_data[test] = {
66+
"input": open(input_file, "r+").read(),
67+
"expected": ["Unknown", "Unknown"],
68+
}
69+
70+
71+
# -------------------------------- Control program execution ------------------------- #
72+
73+
case_to_test = "real"
74+
part_to_test = 2
75+
76+
# -------------------------------- Initialize some variables ------------------------- #
77+
78+
puzzle_input = test_data[case_to_test]["input"]
79+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
80+
puzzle_actual_result = "Unknown"
81+
82+
83+
# -------------------------------- Actual code execution ----------------------------- #
84+
85+
# Conver integer to 36-character binary
86+
# str_value = "{0:>036b}".format(value)
87+
# Convert binary string to number
88+
# value = int(str_value, 2)
89+
90+
91+
if part_to_test == 1:
92+
nb_digits = 0
93+
for string in puzzle_input.split("\n"):
94+
output = words(string)[-4:]
95+
nb_digits += len([x for x in output if len(x) in [2, 3, 4, 7]])
96+
97+
puzzle_actual_result = nb_digits
98+
99+
100+
else:
101+
digit_to_real_segments = {
102+
"0": "abcefg",
103+
"1": "cf",
104+
"2": "acdeg",
105+
"3": "acdfg",
106+
"4": "bcdf",
107+
"5": "abdfg",
108+
"6": "abdefg",
109+
"7": "acf",
110+
"8": "abcdefg",
111+
"9": "abcdfg",
112+
}
113+
digit_container = {
114+
"0": ["8"],
115+
"1": ["0", "3", "4", "7", "8", "9"],
116+
"2": ["8"],
117+
"3": ["8", "9"],
118+
"4": ["8", "9"],
119+
"5": ["6", "8", "9"],
120+
"6": ["8"],
121+
"7": ["0", "3", "8", "9"],
122+
"8": [],
123+
"9": ["8"],
124+
}
125+
shared_segments = {
126+
digit1: {
127+
digit2: len(
128+
[
129+
segment
130+
for segment in digit_to_real_segments[digit2]
131+
if segment in digit_to_real_segments[digit1]
132+
]
133+
)
134+
for digit2 in digit_to_real_segments
135+
}
136+
for digit1 in digit_to_real_segments
137+
}
138+
nb_segments = {
139+
digit: len(digit_to_real_segments[digit]) for digit in digit_to_real_segments
140+
}
141+
for digit in digit_to_real_segments:
142+
digit_to_real_segments[digit] = [
143+
"r_" + x for x in digit_to_real_segments[digit]
144+
]
145+
digit_to_real_segments[digit].sort()
146+
147+
digits = [str(i) for i in range(10)]
148+
149+
sum_displays = 0
150+
151+
for string in puzzle_input.split("\n"):
152+
signals = ["".join(sorted(x)) for x in words(string.replace("| ", ""))[:-4]]
153+
displayed_words = ["".join(sorted(x)) for x in words(string)[-4:]]
154+
155+
edges = {}
156+
vertices = signals + digits
157+
for word in signals:
158+
edges[word] = [
159+
digit for digit in nb_segments if nb_segments[digit] == len(word)
160+
]
161+
162+
mapping = {}
163+
i = 0
164+
while len(mapping) != 9 and i != 5:
165+
i += 1
166+
changed = True
167+
while changed:
168+
changed = False
169+
for word in edges:
170+
if len(edges[word]) == 1:
171+
mapping[word] = edges[word][0]
172+
edges = {
173+
w: [edge for edge in edges[w] if edge != mapping[word]]
174+
for w in edges
175+
}
176+
changed = True
177+
del edges[word]
178+
179+
for known_word in mapping: # abd
180+
digit = mapping[known_word][0] # 7
181+
182+
for word in edges: # bcdef
183+
same_letters = len([x for x in word if x in known_word])
184+
for possible_digit in edges[word]: # '2', '3', '5'
185+
if shared_segments[digit][possible_digit] != same_letters:
186+
edges[word].remove(possible_digit)
187+
188+
# exit()
189+
190+
# Second try, not the right approach (easier to do with shared_segments)
191+
192+
# for known_word in mapping: # abd
193+
# digit = mapping[known_word][0] # 7
194+
# #print ('known_word', known_word, '- digit', digit, 'container', digit_container[digit])
195+
# if digit_container[digit] == []:
196+
# continue
197+
# for word in edges: # bcdef
198+
# #print ('tried word', word, '- digits', edges[word])
199+
# for possible_digit in edges[word]: # '2', '3', '5'
200+
# #print ('possible_digit', possible_digit, possible_digit in digit_container[digit])
201+
# if possible_digit in digit_container[digit]: # '0', '3', '8', '9'
202+
# #print ([(letter, letter in word) for letter in known_word])
203+
# if not all([letter in word for letter in known_word]):
204+
# edges[word].remove(possible_digit)
205+
206+
# print (edges, mapping)
207+
output = ""
208+
for displayed_word in displayed_words:
209+
output += "".join(mapping[displayed_word])
210+
211+
sum_displays += int(output)
212+
213+
puzzle_actual_result = sum_displays
214+
215+
# First try, too complex
216+
217+
# for string in puzzle_input.split("\n"):
218+
# randomized_words = words(string.replace('| ', ''))
219+
# randomized_displayed_words = words(string)[-4:]
220+
221+
# randomized_segments = [x for x in 'abcdefg']
222+
# real_segments = ['r_'+x for x in 'abcdefg']
223+
# edges = {randomized: {real:1 for real in real_segments} for randomized in randomized_segments}
224+
# vertices = randomized_segments + real_segments
225+
226+
# for randomized_word in randomized_words:
227+
# for randomized_segment in randomized_word:
228+
# possible_segments = []
229+
# for digit in nb_segments:
230+
# if nb_segments[digit] == len(randomized_word):
231+
# possible_segments += digit_to_real_segments[digit]
232+
# possible_segments = set(possible_segments)
233+
234+
235+
# for real_segment in real_segments:
236+
# if real_segment in possible_segments:
237+
# continue
238+
# if randomized_segment in edges:
239+
# if real_segment in edges[randomized_segment]:
240+
# del edges[randomized_segment][real_segment]
241+
242+
# #if randomized_segment in 'be':
243+
# #print (randomized_word, digit, nb_segments[digit], randomized_segment, possible_segments, edges[randomized_segment])
244+
# print (randomized_words)
245+
# print ([x for x in randomized_words if len(x) in [2,3,4,7]])
246+
# print ({x: list(edges[x].keys()) for x in edges})
247+
248+
# mapping = graph.WeightedGraph(vertices, edges)
249+
# result = mapping.bipartite_matching(randomized_segments, real_segments)
250+
# print ('flow_graph ', mapping.flow_graph)
251+
# segment_mapping = {}
252+
# for randomized_segment in mapping.flow_graph:
253+
# segment_mapping[randomized_segment] = mapping.flow_graph[randomized_segment]
254+
255+
# final_number = ''
256+
# for randomized_word in randomized_displayed_words:
257+
# print('')
258+
# real_segments = []
259+
# for letter in randomized_word:
260+
# real_segments.append(''.join([k for k in mapping.flow_graph[letter]]))
261+
# print ('real_segments', real_segments)
262+
# real_segments = list(set(real_segments))
263+
# real_segments.sort()
264+
# real_segments = ''.join(real_segments)
265+
266+
267+
# final_number += ''.join([str(key) for key in digit_to_real_segments if ''.join(digit_to_real_segments[key]) == real_segments])
268+
# print ('real_segments', real_segments)
269+
# print (randomized_word, [(str(key), ''.join(digit_to_real_segments[key])) for key in digit_to_real_segments])
270+
# print (randomized_word, final_number)
271+
272+
# print (final_number)
273+
274+
275+
# break
276+
277+
278+
# -------------------------------- Outputs / results --------------------------------- #
279+
280+
print("Case :", case_to_test, "- Part", part_to_test)
281+
print("Expected result : " + str(puzzle_expected_result))
282+
print("Actual result : " + str(puzzle_actual_result))
283+
# Date created: 2021-12-08 08:11:57.138188
284+
# Part 1 : 2021-12-08 08:13:56
285+
# Part 2 : 2021-12-08 14:12:15

0 commit comments

Comments
 (0)