24 game/Solve: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: realigned statements.) |
|||
Line 5,188: | Line 5,188: | ||
8 solutions |
8 solutions |
||
</pre> |
|||
=={{header|Picat}}== |
|||
<lang Picat>import util. |
|||
main => |
|||
Target=24, |
|||
Nums = [5,6,7,8], |
|||
All=findall(Expr, solve_num(Nums,Target,Expr)), |
|||
foreach(Expr in All) println(Expr.flatten()) end, |
|||
println(len=All.length), |
|||
nl. |
|||
% A string based approach, inspired by - among others - the Perl6 solution. |
|||
solve_num(Nums, Target,Expr) => |
|||
Patterns = [ |
|||
"A X B Y C Z D", |
|||
"(A X B) Y C Z D", |
|||
"(A X B Y C) Z D", |
|||
"((A X B) Y C) Z D", |
|||
"(A X B) Y (C Z D)", |
|||
"A X (B Y C Z D)", |
|||
"A X (B Y (C Z D))" |
|||
], |
|||
permutation(Nums,[A,B,C,D]), |
|||
Syms = [+,-,*,/], |
|||
member(X ,Syms), |
|||
member(Y ,Syms), |
|||
member(Z ,Syms), |
|||
member(Pattern,Patterns), |
|||
Expr = replace_all(Pattern, |
|||
"ABCDXYZ", |
|||
[A,B,C,D,X,Y,Z]), |
|||
catch(Target =:= Expr.eval(), E, ignore(E)). |
|||
eval(Expr) = parse_term(Expr.flatten()).apply(). |
|||
ignore(_E) => fail. % ignore zero_divisor errors |
|||
% Replace all occurrences in S with From -> To. |
|||
replace_all(S,From,To) = Res => |
|||
R = S, |
|||
foreach({F,T} in zip(From,To)) |
|||
R := replace(R, F,T.to_string()) |
|||
end, |
|||
Res = R. |
|||
</lang> |
|||
Test: |
|||
<pre> |
|||
Picat> main |
|||
(5 + 7 - 8) * 6 |
|||
((5 + 7) - 8) * 6 |
|||
(5 + 7) * (8 - 6) |
|||
(5 - 8 + 7) * 6 |
|||
((5 - 8) + 7) * 6 |
|||
6 * (5 + 7 - 8) |
|||
6 * (5 + (7 - 8)) |
|||
6 * (5 - 8 + 7) |
|||
6 * (5 - (8 - 7)) |
|||
6 * (7 + 5 - 8) |
|||
6 * (7 + (5 - 8)) |
|||
6 * (7 - 8 + 5) |
|||
6 * (7 - (8 - 5)) |
|||
(6 * 8) / (7 - 5) |
|||
6 * (8 / (7 - 5)) |
|||
(7 + 5 - 8) * 6 |
|||
((7 + 5) - 8) * 6 |
|||
(7 + 5) * (8 - 6) |
|||
(7 - 8 + 5) * 6 |
|||
((7 - 8) + 5) * 6 |
|||
(8 - 6) * (5 + 7) |
|||
(8 - 6) * (7 + 5) |
|||
(8 * 6) / (7 - 5) |
|||
8 * (6 / (7 - 5)) |
|||
len = 24 |
|||
</pre> |
|||
Another approach: |
|||
<lang Picat>import util. |
|||
main => |
|||
Target=24, |
|||
Nums = [5,6,7,8], |
|||
_ = findall(Expr, solve_num2(Nums,Target)), |
|||
nl. |
|||
solve_num2(Nums, Target) => |
|||
Syms = [+,-,*,/], |
|||
Perms = permutations([I.to_string() : I in Nums]), |
|||
Seen = new_map(), % weed out duplicates |
|||
foreach(X in Syms,Y in Syms, Z in Syms) |
|||
foreach(P in Perms) |
|||
[A,B,C,D] = P, |
|||
if catch(check(A,X,B,Y,C,Z,D,Target,Expr),E,ignore(E)), |
|||
not Seen.has_key(Expr) then |
|||
println(Expr.flatten()=Expr.eval().round()), |
|||
Seen.put(Expr,1) |
|||
end |
|||
end |
|||
end. |
|||
to_string2(Expr) = [E.to_string() : E in Expr].flatten(). |
|||
ignore(_E) => fail. % ignore zero_divisor errors |
|||
check(A,X,B,Y,C,Z,D,Target,Expr) ?=> |
|||
Expr = ["(",A,Y,B,")",X,"(",C,Z,D,")"].to_string2(), |
|||
Target =:= Expr.eval(). |
|||
check(A,X,B,Y,C,Z,D,Target,Expr) ?=> |
|||
Expr = [A,X,"(",B,Y,"(",C,Z,D,")",")"].to_string2(), |
|||
Target =:= Expr.eval(). |
|||
check(A,X,B,Y,C,Z,D,Target,Expr) ?=> |
|||
Expr = ["(","(",C,Z,D,")",Y,B,")",X,A].to_string2(), |
|||
Target =:= Expr.eval(). |
|||
check(A,X,B,Y,C,Z,D,Target,Expr) ?=> |
|||
Expr = ["(",B,Y,"(",C,Z,D,")",")",X,A].to_string2(), |
|||
Target =:= Expr.eval(). |
|||
check(A,X,B,Y,C,Z,D,Target,Expr) => |
|||
Expr = [A,X,"(","(",B,Y,C,")", Z,D,")"].to_string2(), |
|||
Target =:= Expr.eval(). |
|||
</lang> |
|||
Test: |
|||
<pre> |
|||
> main |
|||
6*(5+(7-8)) = 24 |
|||
6*(7+(5-8)) = 24 |
|||
(5+7)*(8-6) = 24 |
|||
(7+5)*(8-6) = 24 |
|||
6*((7-8)+5) = 24 |
|||
6*((5-8)+7) = 24 |
|||
((5+7)-8)*6 = 24 |
|||
((7+5)-8)*6 = 24 |
|||
(8-6)*(5+7) = 24 |
|||
(8-6)*(7+5) = 24 |
|||
6*(7-(8-5)) = 24 |
|||
6*(5-(8-7)) = 24 |
|||
6*(8/(7-5)) = 24 |
|||
8*(6/(7-5)) = 24 |
|||
6/((7-5)/8) = 24 |
|||
8/((7-5)/6) = 24 |
|||
(6*8)/(7-5) = 24 |
|||
(8*6)/(7-5) = 24 |
|||
</pre> |
</pre> |
||