Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

two-bucket: fix incorrect test case #795

Merged
merged 2 commits into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 49 additions & 54 deletions exercises/two-bucket/example.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,54 @@
'''
The solution follows the following approach:

->Pour from first bucket to second
1.Fill the first bucket and empty it into the second bucket.
2.If first bucket is empty fill it.
3.If the second bucket is full empty it.
4.Repeat steps 1,2,3 till either the first or second bucket contains the
desired amount.

->Pour from first bucket to second
1.Fill the second bucket and empty it into the first bucket.
2.If second bucket is empty fill it.
3.If the firts bucket is full empty it.
4.Repeat steps 1,2,3 till either the first or second bucket contains the
desired amount.
This solution implements a breadth-first search of the graph
of possible valid states for the two buckets until it reaches a state
in which one of the two buckets contains the goal amount
'''


def two_bucket(bucket_one_cap, bucket_two_cap, desired_liters, first):
if first == "one":
moves = 0
bucket_one, bucket_two = 0, 0
while(True):
if bucket_one == 0:
moves += 1
bucket_one = bucket_one_cap
elif bucket_two == bucket_two_cap:
moves += 1
bucket_two = 0
else:
moves += 1
measure = min(bucket_one, bucket_two_cap - bucket_two)
bucket_one -= measure
bucket_two += measure
if bucket_one == desired_liters:
return (moves, "one", bucket_two)
elif bucket_two == desired_liters:
return (moves, "two", bucket_one)

elif first == "two":
moves = 0
bucket_one, bucket_two = 0, 0
while(True):
if bucket_two == 0:
moves += 1
bucket_two = bucket_two_cap
elif bucket_one == bucket_one_cap:
moves += 1
bucket_one = 0
else:
moves += 1
measure = min(bucket_two, bucket_one_cap - bucket_one)
bucket_two -= measure
bucket_one += measure
if bucket_one == desired_liters:
return (moves, "one", bucket_two)
elif bucket_two == desired_liters:
return (moves, "two", bucket_one)
sizes = [bucket_one_cap, bucket_two_cap]
goal = desired_liters
goalIndex = 0 if first == 'one' else 1

def empty(buckets, i):
return [0, buckets[1]] if i == 0 else [buckets[0], 0]

def fill(buckets, i):
return [sizes[0], buckets[1]] if i == 0 else [buckets[0], sizes[1]]

def consolidate(buckets, i):
amount = min(buckets[1 - i], sizes[i] - buckets[i])
target = buckets[i] + amount
src = buckets[1 - i] - amount
return [target, src] if i == 0 else [src, target]

def bucket_str(buckets):
return '{},{}'.format(*buckets)

invalid = [0, 0]
invalid[1 - goalIndex] = sizes[1 - goalIndex]
invalidStr = bucket_str(invalid)
buckets = [0, 0]
buckets[goalIndex] = sizes[goalIndex]
toVisit = []
visited = set()
count = 1
while goal not in buckets:
key = bucket_str(buckets)
if key != invalidStr and key not in visited:
visited.add(key)
nc = count + 1
for i in range(2):
if buckets[i] != 0:
toVisit.append((empty(buckets, i), nc))
if buckets[i] != sizes[i]:
toVisit.append((fill(buckets, i), nc))
toVisit.append((consolidate(buckets, i), nc))
if not any(toVisit):
raise ValueError('No more moves!')
buckets, count = toVisit.pop(0)

goalIndex = buckets.index(goal)
goalBucket = ['one', 'two'][goalIndex]
otherBucket = buckets[1 - goalIndex]
return (count, goalBucket, otherBucket)
2 changes: 1 addition & 1 deletion exercises/two-bucket/two_bucket_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_bucket_one_size_1_bucket_two_size_3_start_with_bucket_two(self):
self.assertEqual(two_bucket(1, 3, 3, "two"), (1, "two", 0))

def test_bucket_one_size_2_bucket_two_size_3_start_with_bucket_one(self):
self.assertEqual(two_bucket(2, 3, 3, "one"), (4, "two", 1))
self.assertEqual(two_bucket(2, 3, 3, "one"), (2, "two", 2))


if __name__ == '__main__':
Expand Down