Created
April 24, 2012 21:52
-
-
Save masak/2484152 to your computer and use it in GitHub Desktop.
Solving the apples-and-guards problem symbolically
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# <masak> a boy wants to give an apple to a girl. to get to her, he has to pass through | |
# five gates, each with a guard. he bribes each guard with half of his apples, | |
# plus one. after he's given the apple to the girl, he has no apples left. how | |
# many did he have to begin with? | |
use v6; | |
role Expr { | |
} | |
class Var does Expr { | |
method code() { -> $x { $x } } | |
} | |
class Op does Expr { | |
has &.op; | |
has $.l; | |
has $.r; | |
method code() { -> $x { &!op($.l.code()($x), $.r) } } | |
} | |
multi infix:</>(Expr $l, $r) { Op.new: :op(&[/]), :$l, :$r } | |
multi infix:<->(Expr $l, $r) { Op.new: :op(&[-]), :$l, :$r } | |
sub guard($x) { | |
$x / 2 - 1 | |
} | |
sub replace-var(Expr $_, Expr $inner) { | |
when Op { Op.new( :op(.op), :l(replace-var(.l, $inner)), :r(.r) ) } | |
when Var { $inner } | |
} | |
sub solve(Expr $_) { | |
when Op { | |
my ($l, $r) = .l, .r; | |
my $inv = do given .op { | |
when $_ === &infix:</> { Op.new: :op(&[*]), :l(Var.new), :$r } | |
when $_ === &infix:<-> { Op.new: :op(&[+]), :l(Var.new), :$r } | |
}; | |
replace-var(solve($l), $inv); | |
} | |
when Var { | |
Var.new | |
} | |
} | |
my &id = -> $x { $x }; | |
multi infix:<**>(&code, 0) { &id } | |
multi infix:<**>(&code, Int $n where * > 0) { | |
-> $x { &code((&code ** ($n - 1))($x)) } | |
} | |
my &anti-guard = solve( guard(Var.new) ).code; | |
say (&anti-guard ** 5)(1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment