-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
two-bucket: Fix incorrect test case to resolve #794
- Loading branch information
1 parent
677241e
commit cd10851
Showing
2 changed files
with
50 additions
and
55 deletions.
There are no files selected for viewing
This file contains 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
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) |
This file contains 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