diff --git a/day10/2.py b/day10/2.py index af71756..70eca27 100644 --- a/day10/2.py +++ b/day10/2.py @@ -1,77 +1,47 @@ +from tqdm import tqdm + 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): - return (abs(a[0]-b[0])+1)*(abs(a[1]-b[1])+1) +def add_joltage(config,button): + 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)): - hotspots.add(lines[i][0]) - hotspots.add(lines[i][0]-1) - hotspots.add(lines[i][0]+1) - hotspots.add(lines[i][1]) - hotspots.add(lines[i][1]-1) - hotspots.add(lines[i][1]+1) - j = (i+1)%len(lines) - if lines[i][0] == lines[j][0]: - sign = 1 if lines[i][1] <= lines[j][1] else -1 - for x in range(lines[i][1],lines[j][1],sign): - border.add((lines[i][0],x)) - else: - 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)) + # On compte combien de fois on peut presser le bouton en cours + max_push = 99999 + for pos in buttons[0]: + max_push = min(max_push,target[pos]-current[pos]) + + # On cherche une solution pour chaque nombre de pressions + pushes = 0 + new = current + for _ in range(max_push+1): + find_min_tries(target,buttons[1:],new,current_total+pushes,GLOBAL_MIN_PUSH,i) + new=add_joltage(new,buttons[0]) + pushes+=1 + return None - for border_2 in [upper_border,lower_border,left_border,right_border]: - for i in border_2[0]: - for j in border_2[1]: - if (i,j) not in border and not is_point_inside((i,j)): - return False - return True +joltage = [] +buttons = [] -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)): - print(i,len(lines)) - 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) +for i in tqdm(range(len(lines))): + find_min_tries(joltage[i],buttons[i],tuple(0 for _ in joltage[i]),0,GLOBAL_MIN_PUSH,i) +print(sum(GLOBAL_MIN_PUSH)) diff --git a/day10/2linearopt.py b/day10/2linearopt.py new file mode 100644 index 0000000..0c93686 --- /dev/null +++ b/day10/2linearopt.py @@ -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)