Skip to content

Instantly share code, notes, and snippets.

@HerringtonDarkholme
Created November 2, 2013 10:09
Show Gist options
  • Save HerringtonDarkholme/7277422 to your computer and use it in GitHub Desktop.
Save HerringtonDarkholme/7277422 to your computer and use it in GitHub Desktop.
ヒマ(´・ω・`)
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define swap(a, b) (a)^=(b); (b)^=(a); (a)^=(b);
struct balance {
uint16_t real;
uint16_t left;
uint16_t right;
uint16_t heavy;
uint16_t light;
};
uint16_t read_num(char *);
void reset_game(struct balance *);
void read_line(struct balance *, char [3][12]);
void handle_even(struct balance *);
void handle_up(struct balance *);
void report(struct balance *);
int main(int argc, char *argv[])
{
int line_num;
int i, j = 3, past = 0;
char line[3][12];
struct balance *game = malloc(sizeof *game);
scanf("%d", &line_num);
for ( i = 0; i < line_num * 3; i += 3) {
reset_game(game);
while (j--) {
read_line(game, line);
if (!strcmp("even", line[2])) {
handle_even(game);
} else if (!strcmp("up", line[2])) {
handle_up(game);
} else {
swap(game->left, game->right);
handle_up(game);
}
}
report(game);
j = 3;
}
return 0;
}
uint16_t read_num(char *s)
{
int i, l = strlen(s);
uint16_t ret = 0;
for (i = 0; i < l; ++i) {
if (isalpha(s[i]))
ret |= 1 << (s[i] - 'A');
}
return ret;
}
void reset_game(struct balance *game)
{
game->real = 0;
game->heavy = 0;
game->light = 0;
}
void read_line(struct balance *game, char line [3][12])
{
scanf("%s %s %s", line[0], line[1], line[2]);
game->left = read_num(line[0]);
game->right = read_num(line[1]);
}
void handle_even(struct balance *game)
{
game->real |= game->left;
game->real |= game->right;
game->light &= ~(game->real);
game->heavy &= ~(game->real);
if (!game->light && game->heavy)
game->real |= ~(game->heavy) & 0xfff;
else if (!game->heavy && game->light)
game->real |= ~(game->light) & 0xfff;
}
void handle_up(struct balance *game)
{
game->real |= ~(game->left | game->right) & 0xfff;
if (game->heavy | game->light) {
game->heavy &= game->left;
game->light &= game->right;
} else {
game->heavy = game->left;
game->light = game->right;
}
game->light &= ~(game->real);
game->heavy &= ~(game->real);
if (!game->light)
game->real |= ~(game->heavy) & 0xfff;
if (!game->heavy)
game->real |= ~(game->light) & 0xfff;
}
void report(struct balance *game)
{
char r = 'A';
uint16_t t = game->real;
char weight[5];
while(t & 1) {
r++;
t >>= 1;
}
if (~game->real & game->light)
strcpy(weight, "light");
else
strcpy(weight, "heavy");
printf("%c is the counterfeit coin and it is %s.\n", r, weight);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment