Skip to content
Open
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
78 changes: 78 additions & 0 deletions solutions/c/two-bucket/1/two_bucket.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "two_bucket.h"

// typedef enum { BUCKET_ID_1, BUCKET_ID_2 } bucket_id_t;
//
// typedef unsigned int bucket_liters_t;
//
// typedef struct {
// bool possible;
// int move_count;
// bucket_id_t goal_bucket;
// bucket_liters_t other_bucket_liters;
// } bucket_result_t;
static inline int gcd(int a, int b);

bucket_result_t measure(bucket_liters_t bucket_1_size,
bucket_liters_t bucket_2_size,
bucket_liters_t goal_volume, bucket_id_t start_bucket){

bucket_result_t res = { .possible = false, .move_count = 0 };

if (goal_volume > (bucket_1_size > bucket_2_size ? bucket_1_size : bucket_2_size)) return res;
if (goal_volume % gcd(bucket_1_size, bucket_2_size) != 0) return res;

bucket_liters_t start_cap = (start_bucket == BUCKET_ID_1) ? bucket_1_size : bucket_2_size;
bucket_liters_t other_cap = (start_bucket == BUCKET_ID_1) ? bucket_2_size : bucket_1_size;


bucket_liters_t start_vol = 0;
bucket_liters_t other_vol = 0;

start_vol = start_cap;
res.move_count = 1;

if (other_cap == goal_volume) {
other_vol = other_cap;
res.move_count = 2;
}

// There are only 3 possible actions:
// Pouring one bucket into the other bucket until either: a) the first bucket is empty b) the second bucket is full
// Emptying a bucket and doing nothing to the other.
// Filling a bucket and doing nothing to the other.

while (start_vol != goal_volume && other_vol != goal_volume) {
if (other_vol == other_cap) {
other_vol = 0;
} else if (start_vol == 0) {
start_vol = start_cap;
} else {
unsigned int amount = (start_vol < (other_cap - other_vol)) ? start_vol : (other_cap - other_vol);
start_vol -= amount;
other_vol += amount;
}
res.move_count++;
}

res.possible = true;
if (start_vol == goal_volume) {
res.goal_bucket = start_bucket;
res.other_bucket_liters = other_vol;
} else {
res.goal_bucket = (start_bucket == BUCKET_ID_1) ? BUCKET_ID_2 : BUCKET_ID_1;
res.other_bucket_liters = start_vol;
}

return res;

}

static inline int gcd(int a, int b) {
while (b) {
a %= b;
int tmp = a;
a = b;
b = tmp;
}
return a;
}
21 changes: 21 additions & 0 deletions solutions/c/two-bucket/1/two_bucket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef TWO_BUCKET_H
#define TWO_BUCKET_H

#include <stdbool.h>

typedef enum { BUCKET_ID_1, BUCKET_ID_2 } bucket_id_t;

typedef unsigned int bucket_liters_t;

typedef struct {
bool possible;
int move_count;
bucket_id_t goal_bucket;
bucket_liters_t other_bucket_liters;
} bucket_result_t;

bucket_result_t measure(bucket_liters_t bucket_1_size,
bucket_liters_t bucket_2_size,
bucket_liters_t goal_volume, bucket_id_t start_bucket);

#endif