1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
#
# Using four '4's, find
# equations using unary and binary operators
# which compute ever integer from 1 to 100
#
typedef struct {
string s; /* string equation */
rational v; /* equation value */
int p; /* higher are preferred forms */
} v_t;
/* generator for primitive operands */
poly() argloop() {
int i = 0;
static poly[] a = {
(v_t) { .s = "4", .v = 4, .p = 25 },
(v_t) { .s = ".4", .v = .4, .p = 5 },
(v_t) { .s = ".{4}", .v =.{4}, .p = 1 },
(v_t) { .s = "4!", .v = 4!, .p = 25 },
(v_t) { .s = "√4", .v = sqrt(4), .p = 25 },
(v_t) { .s = "√.{4}", .v = sqrt(.{4}), .p = 1 },
◊
};
return poly func() = a[i++ % dim(a)];
}
/* generator for binary operators */
poly () binloop(poly() l, poly() r) {
int i = 0;
poly la = ◊, ra = ◊;
static (poly(poly, poly))[] a = {
poly func(x,y) = (v_t) { .s = "(" + x.s + " + " + y.s + ")", .v = x.v + y.v, .p = x.p + y.p },
poly func(x,y) = (v_t) { .s = "(" + x.s + " - " + y.s + ")", .v = x.v - y.v, .p = x.p + y.p },
poly func(x,y) = (v_t) { .s = "(" + x.s + " * " + y.s + ")", .v = x.v * y.v, .p = x.p + y.p },
poly func(x,y) = (v_t) { .s = "(" + x.s + " / " + y.s + ")", .v = x.v / y.v, .p = x.p + y.p },
poly func(x,y) {
if (y.v > 4)
raise invalid_argument ("rhs of ** too large", 1, y.v);
return (v_t) { .s = "(" + x.s + " ^ " + y.s + ")", .v =x.v ** y.v, .p = x.p + y.p };
}
};
return poly func() {
for (;;)
try {
if (i % dim(a) == 0) {
ra = r ();
if (ra == ◊ || la == ◊) {
la = l ();
if (la == ◊)
return ◊;
if (ra == ◊)
ra = r ();
}
}
return a[i++ % dim(a)](la, ra);
}
catch divide_by_zero (real x, real y) { continue; }
catch invalid_argument (string a, int i, poly p) { continue; }
catch invalid_binop_values (string a, poly l, poly r) { continue; }
};
}
/* generator for associating operations */
poly() parenloop(poly() x, poly() y, poly() z) {
int i = 0;
(poly())[] a = { binloop (x, binloop(y,z)), binloop (binloop(x,y), z) };
return poly func() {
for (;;) {
poly v = a[i]();
if (v != ◊)
return v;
if (++i == dim(a)) {i = 0; return ◊; }
}
};
}
/* find equations which compute all values */
void main () {
int limit = 100;
v_t[limit + 1] values = { { .s = "no solution", .v = 0, .p = 0 } ... };
poly() f = parenloop (binloop(argloop(), argloop()),
argloop(), argloop());
while (((poly value) = f()) != ◊) {
if (is_int(value.v) && 1 <= value.v && value.v <= limit) {
if (values[value.v].p < value.p)
values[value.v] = value;
}
}
for (int i = 1; i <= limit; i++)
printf ("%3d (score %3d) = %s\n", i, values[i].p, values[i].s);
}
main();
|