Last active
July 28, 2019 01:50
-
-
Save shiracamus/5136934efd94aace60affb540cec259a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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