Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
238
Task/Zebra-puzzle/C/zebra-puzzle-1.c
Normal file
238
Task/Zebra-puzzle/C/zebra-puzzle-1.c
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
enum HouseStatus { Invalid, Underfull, Valid };
|
||||
|
||||
enum Attrib { C, M, D, A, S };
|
||||
|
||||
// Unfilled attributes are represented by -1
|
||||
enum Colors { Red, Green, White, Yellow, Blue };
|
||||
enum Mans { English, Swede, Dane, German, Norwegian };
|
||||
enum Drinks { Tea, Coffee, Milk, Beer, Water };
|
||||
enum Animals { Dog, Birds, Cats, Horse, Zebra };
|
||||
enum Smokes { PallMall, Dunhill, Blend, BlueMaster, Prince };
|
||||
|
||||
|
||||
void printHouses(int ha[5][5]) {
|
||||
const char *color[] = { "Red", "Green", "White", "Yellow", "Blue" };
|
||||
const char *man[] = { "English", "Swede", "Dane", "German", "Norwegian" };
|
||||
const char *drink[] = { "Tea", "Coffee", "Milk", "Beer", "Water" };
|
||||
const char *animal[] = { "Dog", "Birds", "Cats", "Horse", "Zebra" };
|
||||
const char *smoke[] = { "PallMall", "Dunhill", "Blend", "BlueMaster", "Prince" };
|
||||
|
||||
printf("%-10.10s%-10.10s%-10.10s%-10.10s%-10.10s%-10.10s\n",
|
||||
"House", "Color", "Man", "Drink", "Animal", "Smoke");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
printf("%-10d", i);
|
||||
if (ha[i][C] >= 0)
|
||||
printf("%-10.10s", color[ha[i][C]]);
|
||||
else
|
||||
printf("%-10.10s", "-");
|
||||
if (ha[i][M] >= 0)
|
||||
printf("%-10.10s", man[ha[i][M]]);
|
||||
else
|
||||
printf("%-10.10s", "-");
|
||||
if (ha[i][D] >= 0)
|
||||
printf("%-10.10s", drink[ha[i][D]]);
|
||||
else
|
||||
printf("%-10.10s", "-");
|
||||
if (ha[i][A] >= 0)
|
||||
printf("%-10.10s", animal[ha[i][A]]);
|
||||
else
|
||||
printf("%-10.10s", "-");
|
||||
if (ha[i][S] >= 0)
|
||||
printf("%-10.10s\n", smoke[ha[i][S]]);
|
||||
else
|
||||
printf("-\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int checkHouses(int ha[5][5]) {
|
||||
int c_add = 0, c_or = 0;
|
||||
int m_add = 0, m_or = 0;
|
||||
int d_add = 0, d_or = 0;
|
||||
int a_add = 0, a_or = 0;
|
||||
int s_add = 0, s_or = 0;
|
||||
|
||||
// Cond 9: In the middle house they drink milk.
|
||||
if (ha[2][D] >= 0 && ha[2][D] != Milk)
|
||||
return Invalid;
|
||||
|
||||
// Cond 10: The Norwegian lives in the first house.
|
||||
if (ha[0][M] >= 0 && ha[0][M] != Norwegian)
|
||||
return Invalid;
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
// Uniqueness tests.
|
||||
if (ha[i][C] >= 0) {
|
||||
c_add += (1 << ha[i][C]);
|
||||
c_or |= (1 << ha[i][C]);
|
||||
}
|
||||
if (ha[i][M] >= 0) {
|
||||
m_add += (1 << ha[i][M]);
|
||||
m_or |= (1 << ha[i][M]);
|
||||
}
|
||||
if (ha[i][D] >= 0) {
|
||||
d_add += (1 << ha[i][D]);
|
||||
d_or |= (1 << ha[i][D]);
|
||||
}
|
||||
if (ha[i][A] >= 0) {
|
||||
a_add += (1 << ha[i][A]);
|
||||
a_or |= (1 << ha[i][A]);
|
||||
}
|
||||
if (ha[i][S] >= 0) {
|
||||
s_add += (1 << ha[i][S]);
|
||||
s_or |= (1 << ha[i][S]);
|
||||
}
|
||||
|
||||
// Cond 2: The English man lives in the red house.
|
||||
if ((ha[i][M] >= 0 && ha[i][C] >= 0) &&
|
||||
((ha[i][M] == English && ha[i][C] != Red) || // Checking both
|
||||
(ha[i][M] != English && ha[i][C] == Red))) // to make things quicker.
|
||||
return Invalid;
|
||||
|
||||
// Cond 3: The Swede has a dog.
|
||||
if ((ha[i][M] >= 0 && ha[i][A] >= 0) &&
|
||||
((ha[i][M] == Swede && ha[i][A] != Dog) ||
|
||||
(ha[i][M] != Swede && ha[i][A] == Dog)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 4: The Dane drinks tea.
|
||||
if ((ha[i][M] >= 0 && ha[i][D] >= 0) &&
|
||||
((ha[i][M] == Dane && ha[i][D] != Tea) ||
|
||||
(ha[i][M] != Dane && ha[i][D] == Tea)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 5: The green house is immediately to the left of the white house.
|
||||
if ((i > 0 && ha[i][C] >= 0 /*&& ha[i-1][C] >= 0 */ ) &&
|
||||
((ha[i - 1][C] == Green && ha[i][C] != White) ||
|
||||
(ha[i - 1][C] != Green && ha[i][C] == White)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 6: drink coffee in the green house.
|
||||
if ((ha[i][C] >= 0 && ha[i][D] >= 0) &&
|
||||
((ha[i][C] == Green && ha[i][D] != Coffee) ||
|
||||
(ha[i][C] != Green && ha[i][D] == Coffee)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 7: The man who smokes Pall Mall has birds.
|
||||
if ((ha[i][S] >= 0 && ha[i][A] >= 0) &&
|
||||
((ha[i][S] == PallMall && ha[i][A] != Birds) ||
|
||||
(ha[i][S] != PallMall && ha[i][A] == Birds)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 8: In the yellow house they smoke Dunhill.
|
||||
if ((ha[i][S] >= 0 && ha[i][C] >= 0) &&
|
||||
((ha[i][S] == Dunhill && ha[i][C] != Yellow) ||
|
||||
(ha[i][S] != Dunhill && ha[i][C] == Yellow)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 11: The man who smokes Blend lives in the house next to the house with cats.
|
||||
if (ha[i][S] == Blend) {
|
||||
if (i == 0 && ha[i + 1][A] >= 0 && ha[i + 1][A] != Cats)
|
||||
return Invalid;
|
||||
else if (i == 4 && ha[i - 1][A] != Cats)
|
||||
return Invalid;
|
||||
else if (ha[i + 1][A] >= 0 && ha[i + 1][A] != Cats && ha[i - 1][A] != Cats)
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
// Cond 12: In a house next to the house where they have a horse, they smoke Dunhill.
|
||||
if (ha[i][S] == Dunhill) {
|
||||
if (i == 0 && ha[i + 1][A] >= 0 && ha[i + 1][A] != Horse)
|
||||
return Invalid;
|
||||
else if (i == 4 && ha[i - 1][A] != Horse)
|
||||
return Invalid;
|
||||
else if (ha[i + 1][A] >= 0 && ha[i + 1][A] != Horse && ha[i - 1][A] != Horse)
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
// Cond 13: The man who smokes Blue Master drinks beer.
|
||||
if ((ha[i][S] >= 0 && ha[i][D] >= 0) &&
|
||||
((ha[i][S] == BlueMaster && ha[i][D] != Beer) ||
|
||||
(ha[i][S] != BlueMaster && ha[i][D] == Beer)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 14: The German smokes Prince
|
||||
if ((ha[i][M] >= 0 && ha[i][S] >= 0) &&
|
||||
((ha[i][M] == German && ha[i][S] != Prince) ||
|
||||
(ha[i][M] != German && ha[i][S] == Prince)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 15: The Norwegian lives next to the blue house.
|
||||
if (ha[i][M] == Norwegian &&
|
||||
((i < 4 && ha[i + 1][C] >= 0 && ha[i + 1][C] != Blue) ||
|
||||
(i > 0 && ha[i - 1][C] != Blue)))
|
||||
return Invalid;
|
||||
|
||||
// Cond 16: They drink water in a house next to the house where they smoke Blend.
|
||||
if (ha[i][S] == Blend) {
|
||||
if (i == 0 && ha[i + 1][D] >= 0 && ha[i + 1][D] != Water)
|
||||
return Invalid;
|
||||
else if (i == 4 && ha[i - 1][D] != Water)
|
||||
return Invalid;
|
||||
else if (ha[i + 1][D] >= 0 && ha[i + 1][D] != Water && ha[i - 1][D] != Water)
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((c_add != c_or) || (m_add != m_or) || (d_add != d_or)
|
||||
|| (a_add != a_or) || (s_add != s_or)) {
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
if ((c_add != 0b11111) || (m_add != 0b11111) || (d_add != 0b11111)
|
||||
|| (a_add != 0b11111) || (s_add != 0b11111)) {
|
||||
return Underfull;
|
||||
}
|
||||
|
||||
return Valid;
|
||||
}
|
||||
|
||||
|
||||
int bruteFill(int ha[5][5], int hno, int attr) {
|
||||
int stat = checkHouses(ha);
|
||||
if ((stat == Valid) || (stat == Invalid))
|
||||
return stat;
|
||||
|
||||
int hb[5][5];
|
||||
memcpy(hb, ha, sizeof(int) * 5 * 5);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hb[hno][attr] = i;
|
||||
stat = checkHouses(hb);
|
||||
if (stat != Invalid) {
|
||||
int nexthno, nextattr;
|
||||
if (attr < 4) {
|
||||
nextattr = attr + 1;
|
||||
nexthno = hno;
|
||||
} else {
|
||||
nextattr = 0;
|
||||
nexthno = hno + 1;
|
||||
}
|
||||
|
||||
stat = bruteFill(hb, nexthno, nextattr);
|
||||
if (stat != Invalid) {
|
||||
memcpy(ha, hb, sizeof(int) * 5 * 5);
|
||||
return stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We only come here if none of the attr values assigned were valid.
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
int ha[5][5] = {{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
|
||||
{-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1},
|
||||
{-1, -1, -1, -1, -1}};
|
||||
|
||||
bruteFill(ha, 0, 0);
|
||||
printHouses(ha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
176
Task/Zebra-puzzle/C/zebra-puzzle-2.c
Normal file
176
Task/Zebra-puzzle/C/zebra-puzzle-2.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use utf8;
|
||||
no strict;
|
||||
|
||||
my (%props, %name, @pre, @conds, @works, $find_all_solutions);
|
||||
|
||||
sub do_consts {
|
||||
local $";
|
||||
for my $p (keys %props) {
|
||||
my @s = @{ $props{$p} };
|
||||
|
||||
$" = ", ";
|
||||
print "enum { ${p}_none = 0, @s };\n";
|
||||
|
||||
$" = '", "';
|
||||
print "const char *string_$p [] = { \"###\", \"@s\" };\n\n";
|
||||
}
|
||||
print "#define FIND_BY(p) \\
|
||||
int find_by_##p(int v) { \\
|
||||
int i; \\
|
||||
for (i = 0; i < N_ITEMS; i++) \\
|
||||
if (house[i].p == v) return i; \\
|
||||
return -1; }\n";
|
||||
|
||||
print "FIND_BY($_)" for (keys %props);
|
||||
|
||||
local $" = ", ";
|
||||
my @k = keys %props;
|
||||
|
||||
my $sl = 0;
|
||||
for (keys %name) {
|
||||
if (length > $sl) { $sl = length }
|
||||
}
|
||||
|
||||
my $fmt = ("%".($sl + 1)."s ") x @k;
|
||||
my @arg = map { "string_$_"."[house[i].$_]" } @k;
|
||||
print << "SNIPPET";
|
||||
int work0(void) {
|
||||
int i;
|
||||
for (i = 0; i < N_ITEMS; i++)
|
||||
printf("%d $fmt\\n", i, @arg);
|
||||
puts(\"\");
|
||||
return 1;
|
||||
}
|
||||
SNIPPET
|
||||
|
||||
}
|
||||
|
||||
sub setprops {
|
||||
%props = @_;
|
||||
my $l = 0;
|
||||
my @k = keys %props;
|
||||
for my $p (@k) {
|
||||
my @s = @{ $props{$p} };
|
||||
|
||||
if ($l && $l != @s) {
|
||||
die "bad length @s";
|
||||
}
|
||||
$l = @s;
|
||||
$name{$_} = $p for @s;
|
||||
}
|
||||
local $" = ", ";
|
||||
print "#include <stdio.h>
|
||||
#define N_ITEMS $l
|
||||
struct item_t { int @k; } house[N_ITEMS] = {{0}};\n";
|
||||
}
|
||||
|
||||
sub pair {NB. h =.~.&> compose&.>~/y,<h
|
||||
|
||||
my ($c1, $c2, $diff) = @_;
|
||||
$diff //= [0];
|
||||
$diff = [$diff] unless ref $diff;
|
||||
|
||||
push @conds, [$c1, $c2, $diff];
|
||||
}
|
||||
|
||||
sub make_conditions {
|
||||
my $idx = 0;
|
||||
my $return1 = $find_all_solutions ? "" : "return 1";
|
||||
print "
|
||||
#define TRY(a, b, c, d, p, n) \\
|
||||
if ((b = a d) >= 0 && b < N_ITEMS) { \\
|
||||
if (!house[b].p) { \\
|
||||
house[b].p = c; \\
|
||||
if (n()) $return1; \\
|
||||
house[b].p = 0; \\
|
||||
}}
|
||||
";
|
||||
|
||||
while (@conds) {
|
||||
my ($c1, $c2, $diff) = @{ pop @conds };
|
||||
my $p2 = $name{$c2} or die "bad prop $c2";
|
||||
|
||||
if ($c1 =~ /^\d+$/) {
|
||||
push @pre, "house[$c1].$p2 = $c2;";
|
||||
next;
|
||||
}
|
||||
|
||||
my $p1 = $name{$c1} or die "bad prop $c1";
|
||||
my $next = "work$idx";
|
||||
my $this = "work".++$idx;
|
||||
|
||||
print "
|
||||
/* condition pair($c1, $c2, [@$diff]) */
|
||||
int $this(void) {
|
||||
int a = find_by_$p1($c1);
|
||||
int b = find_by_$p2($c2);
|
||||
if (a != -1 && b != -1) {
|
||||
switch(b - a) {
|
||||
";
|
||||
print "case $_: " for @$diff;
|
||||
print "return $next(); default: return 0; }\n } if (a != -1) {";
|
||||
print "TRY(a, b, $c2, +($_), $p2, $next);" for @$diff;
|
||||
print " return 0; } if (b != -1) {";
|
||||
print "TRY(b, a, $c1, -($_), $p1, $next);" for @$diff;
|
||||
print "
|
||||
return 0; }
|
||||
/* neither condition is set; try all possibles */
|
||||
for (a = 0; a < N_ITEMS; a++) {
|
||||
if (house[a].$p1) continue;
|
||||
house[a].$p1 = $c1;
|
||||
";
|
||||
|
||||
print "TRY(a, b, $c2, +($_), $p2, $next);" for @$diff;
|
||||
print " house[a].$p1 = 0; } return 0; }";
|
||||
}
|
||||
|
||||
print "int main() { @pre return !work$idx(); }";
|
||||
}
|
||||
|
||||
sub make_c {
|
||||
do_consts;
|
||||
make_conditions;
|
||||
}
|
||||
|
||||
# ---- above should be generic for all similar puzzles ---- #
|
||||
|
||||
# ---- below: per puzzle setup ---- #
|
||||
# property names and values
|
||||
setprops (
|
||||
'nationality' # Svensk n. a Swede, not a swede (kålrot).
|
||||
# AEnglisk (from middle Viking "Æŋløsåksen") n. a Brit.
|
||||
=> [ qw(Deutsch Svensk Norske Danske AEnglisk) ],
|
||||
'pet' => [ qw(birds dog horse zebra cats) ],
|
||||
'drink' => [ qw(water tea milk beer coffee) ],
|
||||
'smoke' => [ qw(dunhill blue_master prince blend pall_mall) ],
|
||||
'color' => [ qw(red green yellow white blue) ]
|
||||
);
|
||||
|
||||
# constraints
|
||||
pair(AEnglisk, red);
|
||||
pair(Svensk, dog);
|
||||
pair(Danske, tea);
|
||||
pair(green, white, 1); # "to the left of" can mean either 1 or -1: ambiguous
|
||||
pair(coffee, green);
|
||||
pair(pall_mall, birds);
|
||||
pair(yellow, dunhill);
|
||||
pair(2, milk);
|
||||
pair(0, Norske);
|
||||
pair(blend, cats, [-1, 1]);
|
||||
pair(horse, dunhill, [-1, 1]);
|
||||
pair(blue_master, beer); # Nicht das Deutsche Bier trinken? Huh.
|
||||
pair(Deutsch, prince);
|
||||
pair(Norske, blue, [-1, 1]);
|
||||
pair(water, blend, [-1, 1]);
|
||||
|
||||
# "zebra lives *somewhere* relative to the Brit". It has no effect on
|
||||
# the logic. It's here just to make sure the code will insert a zebra
|
||||
# somewhere in the table (after all other conditions are met) so the
|
||||
# final print-out shows it. (the C code can be better structured, but
|
||||
# meh, I ain't reading it, so who cares).
|
||||
pair(zebra, AEnglisk, [ -4 .. 4 ]);
|
||||
|
||||
# write C code. If it's ugly to you: I didn't write; Perl did.
|
||||
make_c;
|
||||
Loading…
Add table
Add a link
Reference in a new issue