Added 2017/07 part 2
This commit is contained in:
parent
0f6bf9563e
commit
70aa64c63a
46
2017/07/7.md
46
2017/07/7.md
@ -67,6 +67,48 @@ larger.)
|
|||||||
Before you\'re ready to help them, you need to make sure your
|
Before you\'re ready to help them, you need to make sure your
|
||||||
information is correct. *What is the name of the bottom program?*
|
information is correct. *What is the name of the bottom program?*
|
||||||
|
|
||||||
To begin, [get your puzzle input](7/input).
|
Your puzzle answer was `xegshds`.
|
||||||
|
|
||||||
Answer:
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
The programs explain the situation: they can\'t get down. Rather, they
|
||||||
|
*could* get down, if they weren\'t expending all of their energy trying
|
||||||
|
to keep the tower balanced. Apparently, one program has the *wrong
|
||||||
|
weight*, and until it\'s fixed, they\'re stuck here.
|
||||||
|
|
||||||
|
For any program holding a disc, each program standing on that disc forms
|
||||||
|
a sub-tower. Each of those sub-towers are supposed to be the same
|
||||||
|
weight, or the disc itself isn\'t balanced. The weight of a tower is the
|
||||||
|
sum of the weights of the programs in that tower.
|
||||||
|
|
||||||
|
In the example above, this means that for `ugml`\'s disc to be balanced,
|
||||||
|
`gyxo`, `ebii`, and `jptl` must all have the same weight, and they do:
|
||||||
|
`61`.
|
||||||
|
|
||||||
|
However, for `tknk` to be balanced, each of the programs standing on its
|
||||||
|
disc *and all programs above it* must each match. This means that the
|
||||||
|
following sums must all be the same:
|
||||||
|
|
||||||
|
- `ugml` + (`gyxo` + `ebii` + `jptl`) = 68 + (61 + 61 + 61) = 251
|
||||||
|
- `padx` + (`pbga` + `havc` + `qoyq`) = 45 + (66 + 66 + 66) = 243
|
||||||
|
- `fwft` + (`ktlj` + `cntj` + `xhth`) = 72 + (57 + 57 + 57) = 243
|
||||||
|
|
||||||
|
As you can see, `tknk`\'s disc is unbalanced: `ugml`\'s stack is heavier
|
||||||
|
than the other two. Even though the nodes above `ugml` are balanced,
|
||||||
|
`ugml` itself is too heavy: it needs to be `8` units lighter for its
|
||||||
|
stack to weigh `243` and keep the towers balanced. If this change were
|
||||||
|
made, its weight would be `60`.
|
||||||
|
|
||||||
|
Given that exactly one program is the wrong weight, *what would its
|
||||||
|
weight need to be* to balance the entire tower?
|
||||||
|
|
||||||
|
Your puzzle answer was `299`.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars:
|
||||||
|
\*\*
|
||||||
|
|
||||||
|
At this point, you should [return to your Advent calendar](/2017) and
|
||||||
|
try another puzzle.
|
||||||
|
|
||||||
|
If you still want to see it, you can [get your puzzle
|
||||||
|
input](7/input).
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#!/bin/python3
|
#!/bin/python3
|
||||||
import sys, re
|
import sys, re
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
input_f = 'test'
|
input_f = 'input'
|
||||||
part = 2
|
part = 2
|
||||||
|
|
||||||
|
|
||||||
@ -11,7 +12,8 @@ part = 2
|
|||||||
# Part 1 #
|
# Part 1 #
|
||||||
# #
|
# #
|
||||||
#########################################
|
#########################################
|
||||||
if part == 1:
|
|
||||||
|
def part1():
|
||||||
children = []
|
children = []
|
||||||
mains = []
|
mains = []
|
||||||
with open(input_f)as file:
|
with open(input_f)as file:
|
||||||
@ -27,7 +29,10 @@ if part == 1:
|
|||||||
|
|
||||||
for x in mains:
|
for x in mains:
|
||||||
if x not in children:
|
if x not in children:
|
||||||
print(x)
|
return x
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
print(part1())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -36,17 +41,136 @@ if part == 1:
|
|||||||
# Part 2 #
|
# Part 2 #
|
||||||
# #
|
# #
|
||||||
#########################################
|
#########################################
|
||||||
|
|
||||||
|
def find_children(x,grid):
|
||||||
|
# x will be a string like 'tknk'
|
||||||
|
print('Testing ',x)
|
||||||
|
found = []
|
||||||
|
for i in grid:
|
||||||
|
if i.startswith(x):
|
||||||
|
|
||||||
|
match = re.search(r"-> (.+)", i)
|
||||||
|
if match:
|
||||||
|
found = [item.strip() for item in match.group(1).split(",")]
|
||||||
|
print(found)
|
||||||
|
else:
|
||||||
|
print([i for i in grid if i.startswith(x)])
|
||||||
|
if found != None:
|
||||||
|
for j in found:
|
||||||
|
find_children(j,grid)
|
||||||
|
|
||||||
|
def calculate_weights(node, tree, weights, total_weights):
|
||||||
|
# Compute total weight for the current node
|
||||||
|
total = weights[node]
|
||||||
|
for child in tree[node]:
|
||||||
|
total += calculate_weights(child, tree, weights, total_weights)
|
||||||
|
total_weights[node] = total
|
||||||
|
return total
|
||||||
|
|
||||||
|
def find_outlier(lst):
|
||||||
|
count = Counter(lst)
|
||||||
|
outlier = None
|
||||||
|
reference = None
|
||||||
|
for num, freq in count.items():
|
||||||
|
if freq == 1 or freq < len(lst) - 1:
|
||||||
|
outlier = num
|
||||||
|
else:
|
||||||
|
reference = num
|
||||||
|
return outlier,reference
|
||||||
|
|
||||||
|
def find_unbalanced(node, tree, weights, total_weights):
|
||||||
|
child_weights = [total_weights[child] for child in tree[node]]
|
||||||
|
if len(set(child_weights)) == 1:
|
||||||
|
return None
|
||||||
|
|
||||||
|
weight_counts = {w: child_weights.count(w) for w in child_weights}
|
||||||
|
incorrect_weight = next(w for w, count in weight_counts.items() if count == 1)
|
||||||
|
correct_weight = next(w for w, count in weight_counts.items() if count > 1)
|
||||||
|
unbalanced_child = tree[node][child_weights.index(incorrect_weight)]
|
||||||
|
|
||||||
|
deeper_issue = find_unbalanced(unbalanced_child, tree, weights, total_weights)
|
||||||
|
if deeper_issue:
|
||||||
|
return deeper_issue
|
||||||
|
else:
|
||||||
|
return unbalanced_child, weights[unbalanced_child] + (correct_weight - incorrect_weight)
|
||||||
|
|
||||||
if part == 2:
|
if part == 2:
|
||||||
children = []
|
children = []
|
||||||
mains = []
|
mains = []
|
||||||
|
grid = []
|
||||||
with open(input_f)as file:
|
with open(input_f)as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
l = line.rstrip()
|
l = line.rstrip()
|
||||||
if '->' in l:
|
grid.append(l)
|
||||||
x = l.split('->')
|
|
||||||
for i in x[1].split(','):
|
tree = {}
|
||||||
children.append(i.strip())
|
weights = {}
|
||||||
match = re.match(r"^(\S+)",x[0])
|
for line in grid:
|
||||||
if match:
|
match = re.match(r"(\w+) \((\d+)\)(?: -> (.+))?", line)
|
||||||
mains.append(match.group(1))
|
if match:
|
||||||
|
name = match.group(1)
|
||||||
|
weight = int(match.group(2))
|
||||||
|
children = match.group(3).split(", ") if match.group(3) else []
|
||||||
|
tree[name] = children
|
||||||
|
weights[name] = weight
|
||||||
|
|
||||||
|
total_weights = {}
|
||||||
|
|
||||||
|
calculate_weights(part1(),tree,weights,total_weights)
|
||||||
|
result = find_unbalanced(part1(), tree, weights, total_weights)
|
||||||
|
print(result)
|
||||||
|
#unbalanced_values = []
|
||||||
|
#for key,value in tree.items():
|
||||||
|
# if value:
|
||||||
|
# t_values = []
|
||||||
|
# max_v = 0
|
||||||
|
# change = 0
|
||||||
|
# for i in value:
|
||||||
|
# t_values.append(int(total_weights[i]))
|
||||||
|
# if all(v == t_values[0] for v in t_values):
|
||||||
|
# continue
|
||||||
|
# else:
|
||||||
|
# print('STOP')
|
||||||
|
# print(t_values)
|
||||||
|
# input()
|
||||||
|
# unbalanced_values.append(t_values)
|
||||||
|
|
||||||
|
|
||||||
|
#print(unbalanced_values)
|
||||||
|
#unbalanced_values = list(reversed(unbalanced_values))
|
||||||
|
#print(unbalanced_values)
|
||||||
|
|
||||||
|
#for t_values in unbalanced_values:
|
||||||
|
# outlier,reference = find_outlier(t_values)
|
||||||
|
# change = max(outlier,reference) - min(outlier,reference)
|
||||||
|
# max_v = max(outlier,reference)
|
||||||
|
|
||||||
|
#if t_values[0] == t_values[1]:
|
||||||
|
# if t_values[0] == t_values[2]:
|
||||||
|
# if t_values[1] == t_values[2]:
|
||||||
|
# change = t_values[1] - t_values[2]
|
||||||
|
# max_v = max(t_values[1],t_values[2])
|
||||||
|
# else:
|
||||||
|
# change = t_values[0]-t_values[2]
|
||||||
|
# max_v = max(t_values[0],t_values[2])
|
||||||
|
#else:
|
||||||
|
# change = t_values[0] - t_values[1]
|
||||||
|
# max_v = max(t_values[0],t_values[1])
|
||||||
|
|
||||||
|
# print(change)
|
||||||
|
# print(max_v)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# new_val = max_v-change
|
||||||
|
# print(new_val)
|
||||||
|
|
||||||
|
# for odx,o in enumerate(t_values):
|
||||||
|
# if o == max_v:
|
||||||
|
# total_weights[value[odx]] = new_val
|
||||||
|
|
||||||
|
#for kx,x in total_weights.items():
|
||||||
|
# if x == max_v:
|
||||||
|
# print(weights[kx])
|
||||||
|
# print(weights[kx]-change)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user