Browse Source

hhhhhhhhhhhhhhhhhhhhhhhhh

main
Luna Lailatova 2 years ago
parent
commit
a0192880a3
  1. 148
      day16-2.py
  2. 99
      day16-2take2.py

148
day16-2.py

@ -1,11 +1,13 @@
import queue import queue
q = queue.Queue() MAX_STEPS = 26
q = queue.PriorityQueue()
valves = {} valves = {}
valvesConsider = {} valvesConsider = {}
destinationQue = queue.Queue()
shortest = None
distanceMap = {} distanceMap = {}
eliminated = {}
numTotalSteps = 0
class Valve(): class Valve():
def __init__(self, flowRate, tunnels, name): def __init__(self, flowRate, tunnels, name):
@ -16,25 +18,71 @@ class Valve():
def getFlowrate(self): def getFlowrate(self):
return self.flowRate return self.flowRate
def moves(self, destination, length): def genDistanceMap(self):
global shortest nextValves = queue.PriorityQueue()
if shortest is not None and length >= shortest: nextValves.put((0, self))
return
if self.name == destination: distanceMap[(self.name, self.name)] = 0
if shortest is None or length <= shortest:
shortest = length while not nextValves.empty():
return curDist, valve = nextValves.get()
_length = length + 1
for val in self.tunnels: for tunnel in valve.tunnels:
destinationQue.put((val, destination, _length)) 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 maxRemaining(remainingTime, possibleValves):
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
def step(position1, position2, busy1, busy2, currentTime, pressure, _valvesCons): def step(position1, position2, busy1, busy2, currentTime, pressure, _valvesCons):
global curentbest global curentbest
global numTotalSteps
global maxRemaining
numTotalSteps += 1
if maxRemaining(MAX_STEPS - currentTime, _valvesCons) + pressure < curentbest:
# There's no way we can get better than the current max pressure, so bail.
eliminated.setdefault('maxRemaining', 0)
eliminated['maxRemaining'] += 1
return
done = False done = False
if pressure > curentbest: if pressure > curentbest:
print(1)
curentbest = pressure curentbest = pressure
if len(_valvesCons) == 0: if len(_valvesCons) == 0:
return return
@ -42,47 +90,45 @@ def step(position1, position2, busy1, busy2, currentTime, pressure, _valvesCons)
for destination in _valvesCons: for destination in _valvesCons:
_CopyCons = _valvesCons.copy() _CopyCons = _valvesCons.copy()
_dist = distanceMap[(position1, destination)] _dist = distanceMap[(position1, destination)]
if (currentTime + _dist + 1) >= 26: if (currentTime + _dist + 1) >= MAX_STEPS:
continue continue
_busy1 = _dist + 1 _busy1 = _dist + 1
_pressure = pressure + ((26 - currentTime - _busy1)* _CopyCons[destination]) _pressure = pressure + ((MAX_STEPS - currentTime - _busy1) * _CopyCons[destination])
_CopyCons.pop(destination) _CopyCons.pop(destination)
done = True done = True
q.put((destination, position2, _busy1, busy2, currentTime, _pressure, _CopyCons)) q.put((_pressure * -1, destination, position2, _busy1, busy2, currentTime, _CopyCons))
if done: if done:
return return
if busy2 == 0: if busy2 == 0:
for destination in _valvesCons: for destination in _valvesCons:
_CopyCons = _valvesCons.copy() _CopyCons = _valvesCons.copy()
_dist = distanceMap[(position2, destination)] _dist = distanceMap[(position2, destination)]
if (currentTime + _dist + 1) >= 26: if (currentTime + _dist + 1) >= MAX_STEPS:
continue continue
_busy2 =_dist + 1 _busy2 =_dist + 1
_pressure = pressure + ((26 - currentTime - _busy2)* _CopyCons[destination]) _pressure = pressure + ((MAX_STEPS - currentTime - _busy2)* _CopyCons[destination])
_CopyCons.pop(destination) _CopyCons.pop(destination)
q.put((position1, destination, busy1, _busy2, currentTime, _pressure, _CopyCons)) done = True
q.put((_pressure * -1, position1, destination, busy1, _busy2, currentTime, _CopyCons))
if done:
return return
_currentTime = currentTime + 1 if busy1 <= 0 and busy2 <= 0:
_busy1 = busy1 - 1 return
_busy2 = busy2 - 1 elif busy2 == 0:
idle = busy1
elif busy1 == 0:
idle = busy2
else:
idle = min(busy1, busy2)
_currentTime = currentTime + idle
_busy1 = busy1 - idle
_busy2 = busy2 - idle
_CopyCons = _valvesCons.copy() _CopyCons = _valvesCons.copy()
if _currentTime >= 26: if _currentTime >= MAX_STEPS:
return return
q.put((position1, position2, _busy1, _busy2, _currentTime, pressure, _CopyCons)) q.put((pressure * -1, position1, position2, _busy1, _busy2, _currentTime, _CopyCons))
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 = [] openvalves = []
@ -103,21 +149,8 @@ for line in inp:
newValve = Valve( flowRate, tunnels, _valve) newValve = Valve( flowRate, tunnels, _valve)
valves[_valve] = newValve valves[_valve] = newValve
n = 0 for _, valve in valves.items():
valve.genDistanceMap()
for start in valvesConsider:
n += 1
distanceMap[('AA', start)] = distance('AA', start)
print(n)
for end in valvesConsider:
if (start, end) in distanceMap:
continue
n += 1
_dist = distance(start, end)
distanceMap[(start, end)] = _dist
distanceMap[(end, start)] = _dist
print(n)
for i in distanceMap: for i in distanceMap:
print(i, distanceMap[i]) print(i, distanceMap[i])
@ -126,12 +159,13 @@ position = 'AA'
currentTime = 0 currentTime = 0
pressure = 0 pressure = 0
curentbest = 0 curentbest = 0
q.put((position, position, 0, 0, currentTime, pressure, valvesConsider)) q.put((pressure, position, position, 0, 0, currentTime, valvesConsider))
while not q.empty(): while not q.empty():
print(q.qsize()) #print(q.qsize())
position1, position2, busy1, busy2, currentTime, pressure, _valvesConsider = q.get() pressure, position1, position2, busy1, busy2, currentTime, _valvesConsider = q.get()
step(position1, position2, busy1, busy2, currentTime, pressure, _valvesConsider) # print(q.qsize(), pressure, position1, position2, busy1, busy2, currentTime, numTotalSteps, eliminated)
step(position1, position2, busy1, busy2, currentTime, pressure * -1, _valvesConsider)
print(curentbest) print(curentbest)

99
day16-2take2.py

@ -1,11 +1,23 @@
import queue import queue
q = queue.Queue() MAX_STEPS = 26
q = queue.PriorityQueue()
valves = {} valves = {}
valvesConsider = {} valvesConsider = {}
destinationQue = queue.Queue()
shortest = None
distanceMap = {} 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(): class Valve():
def __init__(self, flowRate, tunnels, name): def __init__(self, flowRate, tunnels, name):
@ -16,42 +28,64 @@ class Valve():
def getFlowrate(self): def getFlowrate(self):
return self.flowRate return self.flowRate
def moves(self, destination, length): def genDistanceMap(self):
global shortest nextValves = queue.PriorityQueue()
if shortest is not None and length >= shortest: nextValves.put((0, self))
return
if self.name == destination:
if shortest is None or length <= shortest:
shortest = length
return
_length = length + 1
for val in self.tunnels:
destinationQue.put((val, destination, _length))
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
def step(position, currentTime, pressure, _valvesCons, elephant): 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 global curentbest
_pos = position _pos = position
best = None best = None
if tuple(path) in visited:
return
visited[tuple(path)] = 1
for destination in _valvesCons: for destination in _valvesCons:
_elephant = elephant _elephant = elephant
_openvalves = _valvesCons.copy() _openvalves = _valvesCons.copy()
dist = distanceMap[(_pos, destination)] dist = distanceMap[(_pos, destination)]
value = (26 - currentTime - dist - 1) * _openvalves[destination] value = (MAX_STEPS - currentTime - dist - 1) * _openvalves[destination]
best = (destination, value , dist) best = (destination, value , dist)
_time = currentTime + best[2] + 1 _time = currentTime + best[2] + 1
if _time >= 26: if _time >= MAX_STEPS:
if _elephant: if _elephant:
continue continue
q.put(('AA', 0, pressure, _openvalves, True)) _path = path.copy()
_path.append('AA')
q.put(pressure* -1,('AA', 0, pressure, _openvalves, True, _path))
continue continue
_pressure = pressure + best[1] _pressure = pressure + best[1]
_position = best[0] _position = best[0]
_openvalves.pop(destination) _openvalves.pop(destination)
q.put((_position, _time, _pressure, _openvalves, elephant)) _path = path.copy()
_path.append(destination)
q.put(_pressure * -1,(_position, _time, _pressure, _openvalves, elephant, _path))
if pressure > curentbest: if pressure > curentbest:
curentbest = pressure 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): def distance(position, destination):
@ -67,7 +101,7 @@ def distance(position, destination):
openvalves = [] openvalves = []
with open('in.txt','r') as f: with open('input16.txt','r') as f:
inp = f.read().splitlines(keepends=False) inp = f.read().splitlines(keepends=False)
for line in inp: for line in inp:
@ -84,21 +118,8 @@ for line in inp:
newValve = Valve( flowRate, tunnels, _valve) newValve = Valve( flowRate, tunnels, _valve)
valves[_valve] = newValve valves[_valve] = newValve
n = 0 for _, valve in valves.items():
valve.genDistanceMap()
for start in valvesConsider:
n += 1
distanceMap[('AA', start)] = distance('AA', start)
print(n)
for end in valvesConsider:
if (start, end) in distanceMap:
continue
n += 1
_dist = distance(start, end)
distanceMap[(start, end)] = _dist
distanceMap[(end, start)] = _dist
print(n)
for i in distanceMap: for i in distanceMap:
print(i, distanceMap[i]) print(i, distanceMap[i])
@ -107,12 +128,12 @@ position = 'AA'
currentTime = 0 currentTime = 0
pressure = 0 pressure = 0
curentbest = 0 curentbest = 0
q.put((position, currentTime, pressure, valvesConsider, False)) q.put(0, (position, currentTime, pressure, valvesConsider, False, []))
while not q.empty(): while not q.empty():
print(q.qsize()) print_every_n(q.qsize())
position, currentTime, pressure, _valvesConsider, elephant = q.get() position, currentTime, pressure, _valvesConsider, elephant, path = q.get()
step(position, currentTime, pressure, _valvesConsider, elephant) step(position, currentTime, pressure, _valvesConsider, elephant, path)
print(curentbest) print(curentbest)

Loading…
Cancel
Save