From c7396ad141bfa2f547fa5124d658156f889df2e0 Mon Sep 17 00:00:00 2001 From: "exercism-solutions-syncer[bot]" <211797793+exercism-solutions-syncer[bot]@users.noreply.github.com> Date: Sun, 18 Jan 2026 09:59:46 +0000 Subject: [PATCH] [Sync Iteration] c/two-bucket/1 --- solutions/c/two-bucket/1/two_bucket.c | 78 +++++++++++++++++++++++++++ solutions/c/two-bucket/1/two_bucket.h | 21 ++++++++ 2 files changed, 99 insertions(+) create mode 100644 solutions/c/two-bucket/1/two_bucket.c create mode 100644 solutions/c/two-bucket/1/two_bucket.h diff --git a/solutions/c/two-bucket/1/two_bucket.c b/solutions/c/two-bucket/1/two_bucket.c new file mode 100644 index 0000000..d25a30c --- /dev/null +++ b/solutions/c/two-bucket/1/two_bucket.c @@ -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; +} diff --git a/solutions/c/two-bucket/1/two_bucket.h b/solutions/c/two-bucket/1/two_bucket.h new file mode 100644 index 0000000..3bfd22f --- /dev/null +++ b/solutions/c/two-bucket/1/two_bucket.h @@ -0,0 +1,21 @@ +#ifndef TWO_BUCKET_H +#define TWO_BUCKET_H + +#include + +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