# # 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();