08-18-2004, 10:26 PM
Yeah, it's only a week old.
/* 8 balls algorithm */
#include <stdlib.h>
#include <stdarg.h>
#define BALL_N 8
#define NORMAL_WEIGHT 10
#define MAX_WEIGHS 2
static int balls[BALL_N + 1]; /* ball weights */
static int weight_c = 0; /* number of weighs performed */
/* positions of each ball for each weight, position 0 is not used */
static char weigh1_positions[] = " L--LLRR--LRR";
static char weigh2_positions[] = " -L---LRLRRLR";
/* returns: <0 if right heavier, 0 if equal, >0 if left heaver */
static int weigh(const char *positions)
{
int ball_c, ball, total = 0;
weight_c++;
if (weight_c > MAX_WEIGHS) abort();
for (ball_c = 1; ball_c <= BALL_N; ball_c++) {
if (positions[ball_c] == 'L') {
total += balls[ball_c];
}
else if (positions[ball_c] == 'R') {
total -= balls[ball_c];
}
}
return total;
}
/*
* Do the 2 weighs and then figure out which ball is different. It
* will return the number of the ball as a negative number if it is
* lighter than the others or a position value if it is heavier.
*/
int do_it(void)
{
int ball_c, weigh1, weigh2;
weigh1 = weigh(weigh1_positions);
weigh2 = weigh(weigh2_positions);
/* check for heavier */
for (ball_c = 1; ball_c <= BALL_N; ball_c++) {
switch (weigh1_positions[ball_c]) {
case 'L': if (weigh1 <= 0) continue; break;
case 'R': if (weigh1 >= 0) continue; break;
case '-': if (weigh1 != 0) continue; break;
}
switch (weigh2_positions[ball_c]) {
case 'L': if (weigh2 <= 0) continue; break;
case 'R': if (weigh2 >= 0) continue; break;
case '-': if (weigh2 != 0) continue; break;
}
return ball_c;
}
/* check for lighter */
for (ball_c = 1; ball_c <= BALL_N; ball_c++) {
switch (weigh1_positions[ball_c]) {
case 'L': if (weigh1 >= 0) continue; break;
case 'R': if (weigh1 <= 0) continue; break;
case '-': if (weigh1 != 0) continue; break;
}
switch (weigh2_positions[ball_c]) {
case 'L': if (weigh2 >= 0) continue; break;
case 'R': if (weigh2 <= 0) continue; break;
case '-': if (weigh2 != 0) continue; break;
}
return -ball_c;
}
abort();
}
int main()
{
int diff_c, ball_c;
/* init all of the balls */
for (ball_c = 1; ball_c <= BALL_N; ball_c++)
balls[ball_c] = NORMAL_WEIGHT;
for (diff_c = 1; diff_c <= BALL_N; diff_c++) {
(void)printf("Odd is %2d: ", diff_c);
weight_c = 0;
balls[diff_c] = NORMAL_WEIGHT - 1;
if (do_it() != -diff_c) abort();
(void)printf("lighter, ");
weight_c = 0;
balls[diff_c] = NORMAL_WEIGHT + 1;
if (do_it() != diff_c) abort();
(void)printf("heavier\n");
balls[diff_c] = NORMAL_WEIGHT;
}
return 0;
}
/* end program */
Put 2 of the balls aside. Weigh 3 of the remaining balls against the other 3 remaining. If they are the same then weigh the 2 balls that you put aside to find out which of them is heavier. If, instead, one of the sets of 3 balls was heavier, put one of the balls from the heavier set aside. Weigh the remaining two balls from the set to find out which one is heavier. If they are equal then you know it is the 1 ball that you put aside. If they aren't equal... well, then you're screwed, because you can only weigh twice. =D
Oh, and yeah, highschool is a lot better. We have block scheduling, which basically involves having 8 rotating classes in pairs of 4 per day. So I have 4 one day, which rotate, and then the 4 other the next day. Anywho, I have 3 classes, then lunch, and then my 4th period. So on the first day, I had Study Hall 4th period, so I went out to lunch and then just went home afterwards. Good stuff for the first day. =P
/* 8 balls algorithm */
#include <stdlib.h>
#include <stdarg.h>
#define BALL_N 8
#define NORMAL_WEIGHT 10
#define MAX_WEIGHS 2
static int balls[BALL_N + 1]; /* ball weights */
static int weight_c = 0; /* number of weighs performed */
/* positions of each ball for each weight, position 0 is not used */
static char weigh1_positions[] = " L--LLRR--LRR";
static char weigh2_positions[] = " -L---LRLRRLR";
/* returns: <0 if right heavier, 0 if equal, >0 if left heaver */
static int weigh(const char *positions)
{
int ball_c, ball, total = 0;
weight_c++;
if (weight_c > MAX_WEIGHS) abort();
for (ball_c = 1; ball_c <= BALL_N; ball_c++) {
if (positions[ball_c] == 'L') {
total += balls[ball_c];
}
else if (positions[ball_c] == 'R') {
total -= balls[ball_c];
}
}
return total;
}
/*
* Do the 2 weighs and then figure out which ball is different. It
* will return the number of the ball as a negative number if it is
* lighter than the others or a position value if it is heavier.
*/
int do_it(void)
{
int ball_c, weigh1, weigh2;
weigh1 = weigh(weigh1_positions);
weigh2 = weigh(weigh2_positions);
/* check for heavier */
for (ball_c = 1; ball_c <= BALL_N; ball_c++) {
switch (weigh1_positions[ball_c]) {
case 'L': if (weigh1 <= 0) continue; break;
case 'R': if (weigh1 >= 0) continue; break;
case '-': if (weigh1 != 0) continue; break;
}
switch (weigh2_positions[ball_c]) {
case 'L': if (weigh2 <= 0) continue; break;
case 'R': if (weigh2 >= 0) continue; break;
case '-': if (weigh2 != 0) continue; break;
}
return ball_c;
}
/* check for lighter */
for (ball_c = 1; ball_c <= BALL_N; ball_c++) {
switch (weigh1_positions[ball_c]) {
case 'L': if (weigh1 >= 0) continue; break;
case 'R': if (weigh1 <= 0) continue; break;
case '-': if (weigh1 != 0) continue; break;
}
switch (weigh2_positions[ball_c]) {
case 'L': if (weigh2 >= 0) continue; break;
case 'R': if (weigh2 <= 0) continue; break;
case '-': if (weigh2 != 0) continue; break;
}
return -ball_c;
}
abort();
}
int main()
{
int diff_c, ball_c;
/* init all of the balls */
for (ball_c = 1; ball_c <= BALL_N; ball_c++)
balls[ball_c] = NORMAL_WEIGHT;
for (diff_c = 1; diff_c <= BALL_N; diff_c++) {
(void)printf("Odd is %2d: ", diff_c);
weight_c = 0;
balls[diff_c] = NORMAL_WEIGHT - 1;
if (do_it() != -diff_c) abort();
(void)printf("lighter, ");
weight_c = 0;
balls[diff_c] = NORMAL_WEIGHT + 1;
if (do_it() != diff_c) abort();
(void)printf("heavier\n");
balls[diff_c] = NORMAL_WEIGHT;
}
return 0;
}
/* end program */
Put 2 of the balls aside. Weigh 3 of the remaining balls against the other 3 remaining. If they are the same then weigh the 2 balls that you put aside to find out which of them is heavier. If, instead, one of the sets of 3 balls was heavier, put one of the balls from the heavier set aside. Weigh the remaining two balls from the set to find out which one is heavier. If they are equal then you know it is the 1 ball that you put aside. If they aren't equal... well, then you're screwed, because you can only weigh twice. =D
Oh, and yeah, highschool is a lot better. We have block scheduling, which basically involves having 8 rotating classes in pairs of 4 per day. So I have 4 one day, which rotate, and then the 4 other the next day. Anywho, I have 3 classes, then lunch, and then my 4th period. So on the first day, I had Study Hall 4th period, so I went out to lunch and then just went home afterwards. Good stuff for the first day. =P

