Browse Source

dont ask how long it took but it executes in 2s

main
Luna Lailatova 2 years ago
parent
commit
40bfb499f7
  1. 84
      day16-2.py
  2. 139
      day16-2take2.py

84
day16-2.py

@ -41,28 +41,70 @@ class Valve():
return self.flowRate < other.flowRate and self.name < other.name return self.flowRate < other.flowRate and self.name < other.name
def maxRemaining(remainingTime, possibleValves): def maxRemaining(remainingTime1, remainingTime2, pos1, pos2, possibleValves):
nextSteps = [2 * x for x in range(int(remainingTime / 2) + 1)]
allValveValues = list(reversed([v for _, v in possibleValves.items()])) volves = possibleValves.copy()
possibleRemaining = 0 possibleRemaining = 0
done = False
for timeOffset in nextSteps: newpos = pos1
if timeOffset > remainingTime: besttime = remainingTime1
break
while not done:
if len(allValveValues) == 0: best = 0
break done = True
for valve in volves:
openFor = remainingTime - timeOffset if remainingTime1 - distanceMap[pos1, valve] - 1 > 0:
possibleRemaining += allValveValues[0] * (remainingTime - timeOffset) press = (remainingTime1 - distanceMap[pos1, valve] - 1) * possibleValves[valve]
allValveValues = allValveValues[1:] if press > best:
done = False
if len(allValveValues) == 0: best = press
break newpos = valve
besttime = remainingTime1 - distanceMap[pos1, valve] - 1
possibleRemaining += allValveValues[0] * (remainingTime - timeOffset) if not done:
allValveValues = allValveValues[1:] volves.pop(newpos)
possibleRemaining += best
remainingTime1 = besttime
pos1 = newpos
done = False
besttime = remainingTime2
while not done:
best = 0
done = True
for valve in volves:
if remainingTime2 - distanceMap[pos2, valve] - 1 > 0:
press = (remainingTime2 - distanceMap[pos2, valve] - 1) * possibleValves[valve]
if press > best:
done = False
best = press
newpos = valve
besttime = remainingTime2 - distanceMap[pos2, valve] - 1
if not done:
volves.pop(newpos)
possibleRemaining += best
remainingTime1 = besttime
pos2 = newpos
# nextSteps = [2 * x for x in range(int(remainingTime / 2) + 1)]
# allValveValues = list(reversed([v for _, v in possibleValves.items()]))
# possibleRemaining = 0
# for timeOffset in nextSteps:
# if timeOffset > remainingTime:
# break
# if len(allValveValues) == 0:
# break
# openFor = remainingTime - timeOffset
# possibleRemaining += allValveValues[0] * (remainingTime - timeOffset)
# allValveValues = allValveValues[1:]
# if len(allValveValues) == 0:
# break
# possibleRemaining += allValveValues[0] * (remainingTime - timeOffset)
# allValveValues = allValveValues[1:]
return possibleRemaining return possibleRemaining
@ -75,7 +117,7 @@ def step(position1, position2, busy1, busy2, currentTime, pressure, _valvesCons)
numTotalSteps += 1 numTotalSteps += 1
if maxRemaining(MAX_STEPS - currentTime, _valvesCons) + pressure < curentbest: if maxRemaining(MAX_STEPS - currentTime - busy1,MAX_STEPS - currentTime - busy2, position1, position2, _valvesCons) + pressure < curentbest:
# There's no way we can get better than the current max pressure, so bail. # There's no way we can get better than the current max pressure, so bail.
eliminated.setdefault('maxRemaining', 0) eliminated.setdefault('maxRemaining', 0)
eliminated['maxRemaining'] += 1 eliminated['maxRemaining'] += 1

139
day16-2take2.py

@ -1,139 +0,0 @@
import queue
MAX_STEPS = 26
q = queue.PriorityQueue()
valves = {}
valvesConsider = {}
distanceMap = {}
visited = {}
this_is_n = 0
def print_every_n(*args):
global this_is_n
if this_is_n >= 10000:
this_is_n = 0
print(*args)
this_is_n += 1
class Valve():
def __init__(self, flowRate, tunnels, name):
self.flowRate = flowRate
self.tunnels = tunnels
self.name = name
def getFlowrate(self):
return self.flowRate
def genDistanceMap(self):
nextValves = queue.PriorityQueue()
nextValves.put((0, self))
distanceMap[(self.name, self.name)] = 0
while not nextValves.empty():
curDist, valve = nextValves.get()
for tunnel in valve.tunnels:
if (self.name, tunnel) in distanceMap:
continue
nextValve = valves[tunnel]
nextDist = curDist + 1
distanceMap[(self.name, nextValve.name)] = nextDist
nextValves.put((nextDist, nextValve))
def __lt__(self, other):
return self.flowRate < other.flowRate and self.name < other.name
def step(position, currentTime, pressure, _valvesCons, elephant, path):
global curentbest
_pos = position
best = None
if tuple(path) in visited:
return
visited[tuple(path)] = 1
for destination in _valvesCons:
_elephant = elephant
_openvalves = _valvesCons.copy()
dist = distanceMap[(_pos, destination)]
value = (MAX_STEPS - currentTime - dist - 1) * _openvalves[destination]
best = (destination, value , dist)
_time = currentTime + best[2] + 1
if _time >= MAX_STEPS:
if _elephant:
continue
_path = path.copy()
_path.append('AA')
q.put(pressure* -1,('AA', 0, pressure, _openvalves, True, _path))
continue
_pressure = pressure + best[1]
_position = best[0]
_openvalves.pop(destination)
_path = path.copy()
_path.append(destination)
q.put(_pressure * -1,(_position, _time, _pressure, _openvalves, elephant, _path))
if pressure > curentbest:
curentbest = pressure
_openvalves = _valvesCons.copy()
if not elephant:
_path = path.copy()
_path.append('AA')
q.put(pressure*-1 ,('AA', 0, pressure, _openvalves, True, _path))
def distance(position, destination):
global destinationQue
global shortest
shortest = None
destinationQue.put((position, destination, 0))
while not destinationQue.empty():
_position, _destination, length = destinationQue.get()
valves[_position].moves(_destination, length)
return shortest
openvalves = []
with open('input16.txt','r') as f:
inp = f.read().splitlines(keepends=False)
for line in inp:
tempA, tempB = line.split(' has flow rate=')
_valve = tempA[-2:]
tempB = tempB.replace('; tunnel leads to valve ','; tunnels lead to valves ')
flowRate, tempA = tempB.split('; tunnels lead to valves ')
flowRate = int(flowRate)
tunnels = tempA.split(', ')
if flowRate == 0:
openvalves.append(_valve)
else:
valvesConsider[_valve] = flowRate
newValve = Valve( flowRate, tunnels, _valve)
valves[_valve] = newValve
for _, valve in valves.items():
valve.genDistanceMap()
for i in distanceMap:
print(i, distanceMap[i])
position = 'AA'
currentTime = 0
pressure = 0
curentbest = 0
q.put(0, (position, currentTime, pressure, valvesConsider, False, []))
while not q.empty():
print_every_n(q.qsize())
position, currentTime, pressure, _valvesConsider, elephant, path = q.get()
step(position, currentTime, pressure, _valvesConsider, elephant, path)
print(curentbest)
Loading…
Cancel
Save