day 10 part 2
This commit is contained in:
parent
6f29e48807
commit
e086476976
2 changed files with 73 additions and 67 deletions
104
day10/2.py
104
day10/2.py
|
|
@ -1,77 +1,47 @@
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
with open(r'day10/input.txt', 'r') as input:
|
with open(r'day10/input.txt', 'r') as input:
|
||||||
lines = list(map(lambda x: list(map(lambda y: int(y),x.split(','))),input.read().split('\n')[:-1]))
|
lines = input.read().split('\n')[:-1]
|
||||||
|
|
||||||
def surface(a,b):
|
def add_joltage(config,button):
|
||||||
return (abs(a[0]-b[0])+1)*(abs(a[1]-b[1])+1)
|
return tuple(config[i]+1 if i in button else config[i] for i in range(len(config)))
|
||||||
|
|
||||||
dim = [100000,100000]
|
GLOBAL_MIN_PUSH = [10**6 for _ in lines]
|
||||||
|
|
||||||
hotspots = set()
|
def find_min_tries(target,buttons,current,current_total,GLOBAL_MIN_PUSH,i):
|
||||||
|
|
||||||
border = set()
|
# On élimine les cas triviaux.
|
||||||
|
if current==target and GLOBAL_MIN_PUSH[i] > current_total :
|
||||||
|
GLOBAL_MIN_PUSH[i] = current_total
|
||||||
|
return None
|
||||||
|
if buttons == []:
|
||||||
|
return None
|
||||||
|
if current_total >= GLOBAL_MIN_PUSH[i]:
|
||||||
|
return None
|
||||||
|
|
||||||
for i in range(len(lines)):
|
# On compte combien de fois on peut presser le bouton en cours
|
||||||
hotspots.add(lines[i][0])
|
max_push = 99999
|
||||||
hotspots.add(lines[i][0]-1)
|
for pos in buttons[0]:
|
||||||
hotspots.add(lines[i][0]+1)
|
max_push = min(max_push,target[pos]-current[pos])
|
||||||
hotspots.add(lines[i][1])
|
|
||||||
hotspots.add(lines[i][1]-1)
|
# On cherche une solution pour chaque nombre de pressions
|
||||||
hotspots.add(lines[i][1]+1)
|
pushes = 0
|
||||||
j = (i+1)%len(lines)
|
new = current
|
||||||
if lines[i][0] == lines[j][0]:
|
for _ in range(max_push+1):
|
||||||
sign = 1 if lines[i][1] <= lines[j][1] else -1
|
find_min_tries(target,buttons[1:],new,current_total+pushes,GLOBAL_MIN_PUSH,i)
|
||||||
for x in range(lines[i][1],lines[j][1],sign):
|
new=add_joltage(new,buttons[0])
|
||||||
border.add((lines[i][0],x))
|
pushes+=1
|
||||||
else:
|
return None
|
||||||
sign = 1 if lines[i][0] <= lines[j][0] else -1
|
|
||||||
for x in range(lines[i][0],lines[j][0],sign):
|
|
||||||
border.add((x,lines[i][1]))
|
|
||||||
|
|
||||||
print(hotspots)
|
|
||||||
|
|
||||||
def is_point_inside(a):
|
|
||||||
# up, down, left, right
|
|
||||||
ranges = [[0,a[1]],[a[1],dim[1]],[a[0],dim[0]],[0,a[0]]]
|
|
||||||
for j in range(4):
|
|
||||||
count = 0
|
|
||||||
last = False
|
|
||||||
for i in hotspots:
|
|
||||||
if i < ranges[j][0] or i > ranges[j][1]: continue
|
|
||||||
coord = (a[0],i) if j < 2 else (i,a[1])
|
|
||||||
if coord in border: last = True
|
|
||||||
elif last and coord not in border:
|
|
||||||
last = False
|
|
||||||
count +=1
|
|
||||||
if count%2 == 0:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def is_rect_inside(a,b):
|
|
||||||
precision = 1000
|
|
||||||
upper_left = (min(a[0],b[0]),min(a[1],b[1]))
|
|
||||||
lower_right = (max(a[0],b[0]),max(a[1],b[1]))
|
|
||||||
upper_right = (max(a[0],b[0]),min(a[1],b[1]))
|
|
||||||
lower_left = (min(a[0],b[0]),max(a[1],b[1]))
|
|
||||||
upper_border = (range(upper_left[0],upper_right[1],precision),[upper_left[1]])
|
|
||||||
lower_border = (range(lower_left[0],lower_right[0],precision),[lower_left[1]])
|
|
||||||
right_border = ([lower_right[0]], range(upper_right[1],lower_right[1],precision))
|
|
||||||
left_border = ([lower_left[0]],range(upper_left[1],lower_left[0],precision))
|
|
||||||
|
|
||||||
for border_2 in [upper_border,lower_border,left_border,right_border]:
|
joltage = []
|
||||||
for i in border_2[0]:
|
buttons = []
|
||||||
for j in border_2[1]:
|
|
||||||
if (i,j) not in border and not is_point_inside((i,j)):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
best = surface(lines[0],lines[1])
|
for line in lines:
|
||||||
|
split_line = line.split(' ')
|
||||||
|
buttons.append(list(map(lambda x: set(map(int,(x[1:-1]).split(','))),split_line[1:-1])))
|
||||||
|
joltage.append(tuple(map(lambda x:int(x),split_line[-1][1:-1].split(','))))
|
||||||
|
|
||||||
for i in range(len(lines)):
|
for i in tqdm(range(len(lines))):
|
||||||
print(i,len(lines))
|
find_min_tries(joltage[i],buttons[i],tuple(0 for _ in joltage[i]),0,GLOBAL_MIN_PUSH,i)
|
||||||
for j in range(i):
|
|
||||||
if surface(lines[i],lines[j]) > best and is_rect_inside(lines[i],lines[j]):
|
|
||||||
best = max(best,surface(lines[i],lines[j]))
|
|
||||||
print("new best found")
|
|
||||||
|
|
||||||
print(best)
|
|
||||||
|
|
||||||
|
print(sum(GLOBAL_MIN_PUSH))
|
||||||
|
|
|
||||||
36
day10/2linearopt.py
Normal file
36
day10/2linearopt.py
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
from typing import final
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from scipy.optimize import LinearConstraint, milp
|
||||||
|
|
||||||
|
with open(r'day10/input.txt', 'r') as input:
|
||||||
|
lines = input.read().split('\n')[:-1]
|
||||||
|
|
||||||
|
joltage = []
|
||||||
|
buttons = []
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
split_line = line.split(' ')
|
||||||
|
buttons.append(list(map(lambda x: set(map(int,(x[1:-1]).split(','))),split_line[1:-1])))
|
||||||
|
joltage.append(tuple(map(lambda x:int(x),split_line[-1][1:-1].split(','))))
|
||||||
|
|
||||||
|
finalsum = 0
|
||||||
|
for i,buttonlist in enumerate(buttons):
|
||||||
|
c = np.array([1]*len(buttonlist))
|
||||||
|
A_array = []
|
||||||
|
BL_array = []
|
||||||
|
for j in range(len(joltage[i])):
|
||||||
|
array = []
|
||||||
|
for button in buttonlist:
|
||||||
|
array.append(1 if j in button else 0)
|
||||||
|
A_array.append(array)
|
||||||
|
BL_array.append(joltage[i][j])
|
||||||
|
A = np.array(A_array)
|
||||||
|
b_l = np.array(BL_array)
|
||||||
|
b_u = np.array(BL_array)
|
||||||
|
constraints = LinearConstraint(A,b_l,b_u)
|
||||||
|
integrality = np.ones_like(c)
|
||||||
|
res = milp(c=c, constraints=constraints, integrality=integrality)
|
||||||
|
print(res.x)
|
||||||
|
finalsum += sum(res.x)
|
||||||
|
print(finalsum)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue