Solved 2017/24 P1
This commit is contained in:
parent
5ac5a847f2
commit
2fe83ed32b
@ -59,7 +59,28 @@ a strength of `0+1 + 1+10 + 10+9 = 31`.
|
|||||||
*What is the strength of the strongest bridge you can make* with the
|
*What is the strength of the strongest bridge you can make* with the
|
||||||
components you have available?
|
components you have available?
|
||||||
|
|
||||||
To begin, [get your puzzle input](24/input).
|
Your puzzle answer was `2006`.
|
||||||
|
|
||||||
|
The first half of this puzzle is complete! It provides one gold star: \*
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
The bridge you\'ve built isn\'t long enough; you can\'t [jump the rest
|
||||||
|
of the way]{title="Who do you think you are, Mario?"}.
|
||||||
|
|
||||||
|
In the example above, there are two longest bridges:
|
||||||
|
|
||||||
|
- `0/2`\--`2/2`\--`2/3`\--`3/4`
|
||||||
|
- `0/2`\--`2/2`\--`2/3`\--`3/5`
|
||||||
|
|
||||||
|
Of them, the one which uses the `3/5` component is stronger; its
|
||||||
|
strength is `0+2 + 2+2 + 2+3 + 3+5 = 19`.
|
||||||
|
|
||||||
|
*What is the strength of the longest bridge you can make?* If you can
|
||||||
|
make multiple bridges of the longest length, pick the *strongest* one.
|
||||||
|
|
||||||
Answer:
|
Answer:
|
||||||
|
|
||||||
|
Although it hasn\'t changed, you can still [get your puzzle
|
||||||
|
input](24/input).
|
||||||
|
|
||||||
|
@ -1,62 +1,47 @@
|
|||||||
#!/bin/python3
|
#!/bin/python3
|
||||||
import sys,re
|
import sys,re
|
||||||
from copy import deepcopy
|
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
sys.path.insert(0, '../../')
|
sys.path.insert(0, '../../')
|
||||||
from fred import list2int, lprint,get_re
|
from fred import list2int,get_re,nprint,lprint
|
||||||
|
|
||||||
input_f = 'test'
|
input_f = 'input'
|
||||||
|
|
||||||
part = 1
|
part = 2
|
||||||
log = True
|
|
||||||
#########################################
|
#########################################
|
||||||
# #
|
# #
|
||||||
# Part 1 #
|
# Part 1 #
|
||||||
# #
|
# #
|
||||||
#########################################
|
#########################################
|
||||||
|
|
||||||
def find_match(comp:list,match:str,result:list):
|
def parse_input(input_f):
|
||||||
i_match = get_re(r"^(\d+)\/(\d+)$",match)
|
list_of_components = []
|
||||||
#print(comp,match)
|
|
||||||
comp = [i for i in comp if i != match]
|
|
||||||
#print(comp,result)
|
|
||||||
for i in result:
|
|
||||||
try:
|
|
||||||
comp = [j for j in comp if j != i]
|
|
||||||
except:
|
|
||||||
print(i,'cant be removed from',j)
|
|
||||||
for j in comp:
|
|
||||||
j_match = get_re(r"^(\d+)\/(\d+)$",j)
|
|
||||||
#print(match,j)
|
|
||||||
#input()
|
|
||||||
if i_match.group(2) == j_match.group(1) or i_match.group(2) == j_match.group(2):
|
|
||||||
result.append(j)
|
|
||||||
find_match(comp[:],match,result[:])
|
|
||||||
return result
|
|
||||||
|
|
||||||
if part == 1:
|
|
||||||
components = []
|
|
||||||
with open(input_f) as file:
|
with open(input_f) as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
components.append(line.rstrip())
|
l = get_re(r"^(\d+)\/(\d+)$",line.rstrip())
|
||||||
|
list_of_components.append([int(l.group(1)),int(l.group(2))])
|
||||||
lprint(components,log)
|
return list_of_components
|
||||||
original_comp = deepcopy(components)
|
|
||||||
pairs = []
|
|
||||||
result = []
|
|
||||||
|
|
||||||
for i in components[:]:
|
|
||||||
print(i)
|
|
||||||
if i[0] == '0':
|
|
||||||
result.append(find_match(original_comp,i,[i]))
|
|
||||||
|
|
||||||
|
|
||||||
pprint(result)
|
|
||||||
#nput()
|
|
||||||
#lprint(pairs,log)
|
|
||||||
|
|
||||||
|
def make_bridge(components, last):
|
||||||
|
score = 0
|
||||||
|
longest_bridge = []
|
||||||
|
for cdx, component in enumerate(components):
|
||||||
|
if component[0] == last or component[1] == last:
|
||||||
|
if component[0] == last:
|
||||||
|
tmp = component[1]
|
||||||
|
else:
|
||||||
|
tmp = component[0]
|
||||||
|
x = component + make_bridge(components[:cdx]+components[cdx+1:],tmp)
|
||||||
|
if sum(x) > score:
|
||||||
|
score = sum(x)
|
||||||
|
longest_bridge = x
|
||||||
|
return longest_bridge
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
components = parse_input(input_f)
|
||||||
|
#print(components)
|
||||||
|
|
||||||
|
bridge = make_bridge(components,0)
|
||||||
|
print(bridge)
|
||||||
|
|
||||||
|
|
||||||
#########################################
|
#########################################
|
||||||
@ -64,5 +49,31 @@ if part == 1:
|
|||||||
# Part 2 #
|
# Part 2 #
|
||||||
# #
|
# #
|
||||||
#########################################
|
#########################################
|
||||||
|
|
||||||
|
def make_bridge_longest(components, last):
|
||||||
|
score = 0
|
||||||
|
longest_bridge = []
|
||||||
|
for cdx, component in enumerate(components):
|
||||||
|
if component[0] == last or component[1] == last:
|
||||||
|
if component[0] == last:
|
||||||
|
tmp = component[1]
|
||||||
|
else:
|
||||||
|
tmp = component[0]
|
||||||
|
x = component + make_bridge(components[:cdx]+components[cdx+1:],tmp)
|
||||||
|
if len(x) > len(longest_bridge) and sum(x) > score:
|
||||||
|
score = sum(x)
|
||||||
|
longest_bridge = x
|
||||||
|
|
||||||
|
return longest_bridge
|
||||||
|
|
||||||
|
|
||||||
if part == 2:
|
if part == 2:
|
||||||
exit()
|
components = parse_input(input_f)
|
||||||
|
#print(components)
|
||||||
|
|
||||||
|
bridge = make_bridge_longest(components,0)
|
||||||
|
|
||||||
|
print(bridge)
|
||||||
|
#print(sum(bridge))
|
||||||
|
|
||||||
|
#print(sum(bridge))
|
||||||
|
85
2017/24/solution_old.py
Normal file
85
2017/24/solution_old.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from copy import deepcopy
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int, lprint,get_re
|
||||||
|
|
||||||
|
input_f = 'test'
|
||||||
|
|
||||||
|
part = 1
|
||||||
|
log = True
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
# def find_match(comp:list,match:str,result:list):
|
||||||
|
# #i_match = get_re(r"^(\d+)\/(\d+)$",match)
|
||||||
|
# #print(comp,match)
|
||||||
|
# #comp = [i for i in comp if i != match]
|
||||||
|
# #print(comp,result)
|
||||||
|
# #for i in result:
|
||||||
|
# # try:
|
||||||
|
# # comp = [j for j in comp if j != i]
|
||||||
|
# # except:
|
||||||
|
# # print(i,'cant be removed from',j)
|
||||||
|
# for j in comp:
|
||||||
|
# j_match = get_re(r"^(\d+)\/(\d+)$",j)
|
||||||
|
# #print(match,j)
|
||||||
|
# #input()
|
||||||
|
# if i_match.group(2) == j_match.group(1) or i_match.group(2) == j_match.group(2):
|
||||||
|
# result.append(j)
|
||||||
|
# find_match(comp[:],match,result[:])
|
||||||
|
# return result
|
||||||
|
|
||||||
|
# def find_match(components,match,results):
|
||||||
|
# #print(match,results)
|
||||||
|
# for j in components[:]:
|
||||||
|
# if match[1] == j[0] and j not in results:
|
||||||
|
# results.append(j)
|
||||||
|
# return find_match(components,j,results)
|
||||||
|
# return results
|
||||||
|
|
||||||
|
def build_chain(chain:list, components:list):
|
||||||
|
last_componet = chain[len(chain)-1]
|
||||||
|
next_component = None
|
||||||
|
while len(components) > 0:
|
||||||
|
next_component = components.pop()
|
||||||
|
if (
|
||||||
|
next_component[0] == last_componet[1] or
|
||||||
|
next_component[0] == last_componet[0] or
|
||||||
|
next_component[1] == last_componet[1] or
|
||||||
|
next_component[1] == last_componet[0]
|
||||||
|
):
|
||||||
|
#print(next_component,components)
|
||||||
|
|
||||||
|
chain.append(next_component)
|
||||||
|
build_chain(chain,deepcopy(components))
|
||||||
|
return chain
|
||||||
|
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
components = []
|
||||||
|
with open(input_f) as file:
|
||||||
|
for line in file:
|
||||||
|
l = get_re(r"^(\d+)\/(\d+)$",line.rstrip())
|
||||||
|
components.append(sorted([int(l.group(1)),int(l.group(2))]))
|
||||||
|
|
||||||
|
pprint(components)
|
||||||
|
original_comp = deepcopy(components)
|
||||||
|
|
||||||
|
for c in components[:]:
|
||||||
|
if c[0] == 0:
|
||||||
|
chain = build_chain([c],components)
|
||||||
|
print(chain)
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
exit()
|
@ -1,14 +1,33 @@
|
|||||||
from collections import defaultdict
|
def build_graph(node_list):
|
||||||
import pprint
|
"""
|
||||||
def build_graph(pairs):
|
Build a graph where:
|
||||||
graph = defaultdict(list)
|
- Each graph starts with a node containing `0`.
|
||||||
for pair in pairs:
|
- Nodes are connected if they share a common value, except `0` cannot connect to another `0`.
|
||||||
a, b = map(int, pair.split('/'))
|
"""
|
||||||
graph[a].append(b)
|
graph = {}
|
||||||
graph[b].append(a)
|
|
||||||
|
# Parse nodes
|
||||||
|
parsed_nodes = [tuple(map(int, node.split('/'))) for node in node_list]
|
||||||
|
|
||||||
|
# Build adjacency list
|
||||||
|
for node1 in parsed_nodes:
|
||||||
|
for node2 in parsed_nodes:
|
||||||
|
# Skip if both nodes contain `0`
|
||||||
|
if node1 == node2 or (0 in node1 and 0 in node2):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Add edge if they share a common value
|
||||||
|
if node1[0] == node2[0] or node1[1] == node2[1] or node1[0] == node2[1] or node1[1] == node2[0]:
|
||||||
|
graph.setdefault(node1, []).append(node2)
|
||||||
|
graph.setdefault(node2, []).append(node1)
|
||||||
|
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
def find_all_paths(graph, start, visited=None, path=None):
|
def find_paths(graph, start, visited=None, path=None):
|
||||||
|
"""
|
||||||
|
Recursively find all paths starting from a given node.
|
||||||
|
Ensures that each node is visited only once per path.
|
||||||
|
"""
|
||||||
if visited is None:
|
if visited is None:
|
||||||
visited = set()
|
visited = set()
|
||||||
if path is None:
|
if path is None:
|
||||||
@ -17,42 +36,32 @@ def find_all_paths(graph, start, visited=None, path=None):
|
|||||||
visited.add(start)
|
visited.add(start)
|
||||||
path.append(start)
|
path.append(start)
|
||||||
|
|
||||||
paths = [list(path)] # Store the current path as a possible connection
|
# Print the current path
|
||||||
|
#print(" \--".join(f"{node[0]}/{node[1]}" for node in path))
|
||||||
|
|
||||||
for neighbor in graph[start]:
|
# Explore neighbors
|
||||||
|
for neighbor in graph.get(start, []):
|
||||||
if neighbor not in visited:
|
if neighbor not in visited:
|
||||||
paths.extend(find_all_paths(graph, neighbor, visited.copy(), path.copy()))
|
find_paths(graph, neighbor, visited.copy(), path.copy())
|
||||||
|
return path
|
||||||
|
|
||||||
return paths
|
def main():
|
||||||
|
# Input list of nodes
|
||||||
|
nodes = [
|
||||||
|
"0/2", "2/2", "2/3", "3/4", "3/5", "0/1", "10/1", "9/10"
|
||||||
|
]
|
||||||
|
|
||||||
def count_connections(pairs):
|
# Build the graph
|
||||||
graph = build_graph(pairs)
|
graph = build_graph(nodes)
|
||||||
all_paths = []
|
results = []
|
||||||
|
# Find and print all paths for each subgraph starting with a `0` node
|
||||||
|
zero_nodes = [node for node in graph if 0 in node]
|
||||||
|
for start in zero_nodes:
|
||||||
|
print(f"Starting from {start[0]}/{start[1]}:")
|
||||||
|
tmp = find_paths(graph, start)
|
||||||
|
results.append(tmp)
|
||||||
|
|
||||||
for pair in pairs:
|
print(results)
|
||||||
a, b = map(int, pair.split('/'))
|
|
||||||
paths_a = find_all_paths(graph, a)
|
|
||||||
paths_b = find_all_paths(graph, b)
|
|
||||||
|
|
||||||
# Combine paths starting from both nodes in the pair
|
if __name__ == "__main__":
|
||||||
for path in paths_a:
|
main()
|
||||||
if b in path:
|
|
||||||
all_paths.append(path)
|
|
||||||
|
|
||||||
for path in paths_b:
|
|
||||||
if a in path:
|
|
||||||
all_paths.append(path)
|
|
||||||
|
|
||||||
# Remove duplicate paths
|
|
||||||
unique_paths = {tuple(path) for path in all_paths}
|
|
||||||
return len(unique_paths), unique_paths
|
|
||||||
|
|
||||||
# Example usage
|
|
||||||
pairs = ['0/2','2/2','2/3','3/4','3/5','0/1','10/1','9/10']
|
|
||||||
connection_count, connections = count_connections(pairs)
|
|
||||||
|
|
||||||
print(f"Number of connections: {connection_count}")
|
|
||||||
print("Connections:")
|
|
||||||
for connection in connections:
|
|
||||||
print(connection)
|
|
||||||
pprint(connections)
|
|
||||||
|
36
2017/24/test2.py
Normal file
36
2017/24/test2.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import time
|
||||||
|
def solve(blocks):
|
||||||
|
new_bridges = [[block] for block in blocks if 0 in block]
|
||||||
|
strongest = 0
|
||||||
|
longest_strength = 0
|
||||||
|
while new_bridges:
|
||||||
|
bridges = new_bridges
|
||||||
|
new_bridges = []
|
||||||
|
for bridge in bridges:
|
||||||
|
new_bridges.extend(list(extend(bridge, blocks)))
|
||||||
|
if new_bridges:
|
||||||
|
longest_strength = max(bridge_strength(bridge) for bridge in new_bridges)
|
||||||
|
strongest = max(strongest, longest_strength)
|
||||||
|
return strongest, longest_strength
|
||||||
|
|
||||||
|
def bridge_strength(bridge):
|
||||||
|
return sum(map(sum, bridge))
|
||||||
|
|
||||||
|
def extend(bridge, blocks):
|
||||||
|
unused = list(filter(lambda b: b not in bridge and b[::-1] not in bridge, blocks))
|
||||||
|
for block in unused:
|
||||||
|
if bridge[-1][1] == block[0]:
|
||||||
|
yield bridge + [block]
|
||||||
|
elif bridge[-1][1] == block[1]:
|
||||||
|
yield bridge + [block[::-1]]
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
start = time.time()
|
||||||
|
block_list = []
|
||||||
|
with open('input') as f:
|
||||||
|
for line in f:
|
||||||
|
block_list.append(tuple(map(int, line.split('/'))))
|
||||||
|
block_list = [(a, b) if a < b else (b, a) for a, b in block_list]
|
||||||
|
|
||||||
|
print('Part 1: {}\nPart 2: {}'.format(*solve(block_list)))
|
||||||
|
print(f'Solved in {time.time() - start}')
|
@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
.-----------------------------------------------.
|
.-----------------------------------------------.
|
||||||
| o──────*──────┐o┬──────────────────┐┌───────┐ | 25 *
|
| o──────*──────┐o┬──────────────────┐┌───────┐ | 25 *
|
||||||
| o──*──┐└───┐o─┴─┘o────────┬─────o┌─┘├───o┌──┤ | 24
|
| o──*──┐└───┐o─┴─┘o────────┬─────o┌─┘├───o┌──┤ | 24 *
|
||||||
| ┌──┘o─┴────┘┌────────────*├──────┘o─┘┌───┘┌─┘ | 23 *
|
| ┌──┘o─┴────┘┌────────────*├──────┘o─┘┌───┘┌─┘ | 23 *
|
||||||
| ├───┐┌──────┴o*──|(────┐┌┘└──────────┘o┬──┘o┐ | 22 **
|
| ├───┐┌──────┴o*──|(────┐┌┘└──────────┘o┬──┘o┐ | 22 **
|
||||||
| └┐o┐└┘*───────┘o┬─┬──┬┴┴┴┬───┬┴┴┴┴┬───┐└────┤ | 21 **
|
| └┐o┐└┘*───────┘o┬─┬──┬┴┴┴┬───┬┴┴┴┴┬───┐└────┤ | 21 **
|
||||||
|
Loading…
Reference in New Issue
Block a user