Skip to content

Instantly share code, notes, and snippets.

@shiracamus
Last active July 28, 2019 01:50
Show Gist options
  • Save shiracamus/5136934efd94aace60affb540cec259a to your computer and use it in GitHub Desktop.
Save shiracamus/5136934efd94aace60affb540cec259a to your computer and use it in GitHub Desktop.
class Bottle:
def __init__(self, capacity, water):
self.capacity = capacity
self.water = water
def __repr__(self):
return repr(self.water)
def __eq__(self, water):
return self.water == water
def __add__(self, water):
return Bottle(self.capacity, self.water + water)
def __sub__(self, water):
return Bottle(self.capacity, self.water - water)
def full(self):
return Bottle(self.capacity, self.capacity)
def empty(self):
return Bottle(self.capacity, 0)
def pour(self, another):
water = min(self.water, another.capacity - another.water)
return self - water, another + water
def operations(self, another):
yield self.full(), another
yield self.empty(), another
yield self.pour(another)
yield self, another.full()
yield self, another.empty()
yield another.pour(self)[::-1]
def water_jug_problem(capacity1, capacity2, target):
operation = Bottle(capacity1, 0), Bottle(capacity2, 0)
operations = [operation]
candidates = [operations]
while candidates:
operations = candidates.pop(0)
bottle1, bottle2 = operations[-1]
for operation in bottle1.operations(bottle2): # operation has 2 bottles
if target in operation: # compare using Bottle.__eq__
return operations[1:] + [operation] # without origin (0, 0)
if operation in operations: # because operations not in candidates
continue
if any(operation in candidate for candidate in candidates):
continue
candidates.append(operations + [operation])
return None
def main():
capacity1 = int(input("Bottle1? "))
capacity2 = int(input("Bottle2? "))
target = int(input("How much do you want? "))
operations = water_jug_problem(capacity1, capacity2, target)
if operations:
print(*operations, sep='\n')
else:
print('無理です')
if __name__ == '__main__':
main()
import queue
class Bottle:
def __init__(self,one,two):
self.one = 0 #一個目のボトル
self.two = 0 #二個目のボトル
self.one_max = one
self.two_max = two
def put(self,now_one,now_two,num,past_list): #oneのボトルを水で満たす
copy = past_list.copy()
if num ==1:
now_one = self.one_max
elif num ==2:
now_two = self.two_max
for i in range(len(copy)):
if copy[i] != [now_one,now_two]:
if (i== len(copy)-1):
copy.append([now_one,now_two])
queue.put(copy)
break
else:
break
def pour(self,now_one,now_two,num,past_list): #numから一方のボトルに水を移す
copy = past_list.copy()
if num==1: #oneからtwo
now_two += now_one
if now_two >= self.two_max: #あふれる場合,全部は入れない場合
now_one = now_two - self.two_max
now_two = self.two_max
else:
now_one = 0
elif num ==2: #twoからone
now_one += now_two
if now_one >= self.one_max: #あふれる場合,全部は入れない場合
now_two = now_one - self.one_max
now_one = self.one_max
else:
now_two = 0
for i in range(len(copy)):
if copy[i] != [now_one,now_two]:
if (i== len(copy)-1):
copy.append([now_one,now_two])
queue.put(copy)
break
else:
break
def away(self,now_one,now_two,num,past_list): #水を捨てる
copy = past_list.copy()
if num==1:
now_one = 0
elif num==2:
now_two = 0
for i in range(len(copy)):
if copy[i] != [now_one,now_two]:
if (i== len(copy)-1):
copy.append([now_one,now_two])
queue.put(copy)
break
else:
break
past_op = []
queue = queue.Queue()
num_one = int(input("Bottle1? "))
num_two = int(input("Bottle2? "))
num_Want = int(input("How much do you want? "))
bottle = Bottle(num_one,num_two)
bottle.one = bottle.one_max
past_op.append([bottle.one,bottle.two])
queue.put(past_op)
while (True):
get_queue = queue.get()
now = get_queue[-1]
bottle.one,bottle.two = now[0],now[1]
if (bottle.one == num_Want or bottle.two == num_Want):
for i in get_queue:
print(i)
break
if bottle.one > 0 and num_one > bottle.one:
bottle.put(bottle.one,bottle.two,1,get_queue)
bottle.pour(bottle.one,bottle.two,1,get_queue) #oneからtwo
bottle.away(bottle.one,bottle.two,1,get_queue) #oneを捨てる
if bottle.one == 0:
bottle.put(bottle.one,bottle.two,1,get_queue)
if bottle.one == num_one:
bottle.pour(bottle.one,bottle.two,1,get_queue) #oneからtwo
bottle.away(bottle.one,bottle.two,1,get_queue)
if bottle.two > 0 and num_two > bottle.two:
bottle.put(bottle.one,bottle.two,2,get_queue)
bottle.pour(bottle.one,bottle.two,2,get_queue) #oneからtwo
bottle.away(bottle.one,bottle.two,2,get_queue) #oneを捨てる
if bottle.two == 0:
bottle.put(bottle.one,bottle.two,2,get_queue)
if bottle.two == num_two:
bottle.pour(bottle.one,bottle.two,2,get_queue) #oneからtwo
bottle.away(bottle.one,bottle.two,2,get_queue)
if(queue.empty()):
print("無理です")
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment