Skip to content

Instantly share code, notes, and snippets.

@shintakezou
Created July 20, 2016 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shintakezou/18a0b3ce9a14b627e9bf11bbe6c288bd to your computer and use it in GitHub Desktop.
Save shintakezou/18a0b3ce9a14b627e9bf11bbe6c288bd to your computer and use it in GitHub Desktop.
Solving Susi's problem 934 in the Italian magazine "La settimana enigmistica"
/*
A quiz with Susi 934 (in the Italian magazine
La settimana enigmistica)
Alfio, Biagio, Carlo and Dino are four children,
one of them broke the window of a building while
all four were playing with slingshots.
Questioned to know who did it,
Alfio said Biagio is a liar,
Biagio said Carlo is a liar,
Carlo said Biagio is a liar,
Dino said Alfio is a liar.
How many youngsters are not liars?
*/
#include <stdio.h>
enum child
{
ALFIO = 0,
BIAGIO,
CARLO,
DINO
};
const char *names[] = {
[ALFIO] = "Alfio",
[BIAGIO] = "Biagio",
[CARLO] = "Carlo",
[DINO] = "Dino"
};
// [] says that {} is a liar...
struct
{
int who_lies;
} child_says[] = {
[ALFIO] = {BIAGIO},
[BIAGIO] = {CARLO},
[CARLO] = {BIAGIO},
[DINO] = {ALFIO}
};
// this should be generated from child_says...
struct
{
int a_liar_by[4];
} is_said_to_be[] = {
[ALFIO] = { {DINO, -1} },
[BIAGIO] = { {ALFIO, CARLO, -1} },
[CARLO] = { {BIAGIO, -1} },
[DINO] = { {-1} }
};
void liars_to_map(int n, int *l)
{
int m = 1, i;
for (i = 0; i < 4; ++i, m <<= 1, ++l) {
*l = (n & m) >> i;
}
}
int main(void)
{
/*
Let us suppose the Truth is that:
0 0 0 0 no one lies
0 0 0 1 ALFIO lies,
0 0 1 0 BIAGIO lies,
0 0 1 1 BIAGIO and ALFIO lie...
...
*/
int liars;
int liars_map[4];
int found;
for (liars = 0; liars < 16; ++liars) {
liars_to_map(liars, liars_map);
found = 1;
for (int i = 0; i < 4; ++i) {
int h = !liars_map[i];
if ((h && !liars_map[child_says[i].who_lies]) ||
(!h && liars_map[child_says[i].who_lies])) {
found = 0;
goto skip; // or break;
}
int who;
for (int j = 0;
(who = is_said_to_be[i].a_liar_by[j]) >= 0;
++j) {
if ((h && !liars_map[who]) ||
(!h && liars_map[who])) {
found = 0;
goto skip;
}
}
}
skip:
if (found) {
for (int k = 0; k < 4; ++k) {
printf("%s %s\n",
names[k], liars_map[k] ? "lies" : "is honest");
}
printf("\n");
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment