public
Created

permutations game

  • Download Gist
perms.pl
Perl
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
use strict;
use warnings;
use v5.14;
use Algorithm::Combinatorics qw/combinations permutations/;
 
my @numbers = qw/2 4 6 8/;
my @ops = qw{* - + /};
my $goal = 25;
 
my %ops = (
'a+b' => sub { @_ == 2 ? $_[0] + $_[1] : "($_[0] + $_[1])" },
'a-b' => sub { @_ == 2 ? $_[0] - $_[1] : "($_[0] - $_[1])" },
'b-a' => sub { @_ == 2 ? $_[1] - $_[0] : "($_[1] - $_[0])" },
'a*b' => sub { @_ == 2 ? $_[0] * $_[1] : "($_[0] * $_[1])" },
'a/b' => sub { @_ == 2 ? $_[0] / $_[1] : "($_[0] / $_[1])" },
'b/a' => sub { @_ == 2 ? $_[1] / $_[0] : "($_[1] / $_[0])" },
);
 
 
 
#######################################################
# Program Main
#
my @parsed_ops = parse_ops(@ops);
 
OUT: foreach my $np ( permutations( \@numbers ) ) {
foreach my $op ( permutations( \@parsed_ops) ) {
 
my $sol;
eval {
$sol = solves([@$np], $op, $goal);
};
 
if ( $sol ) {
say "sol = $sol";
last OUT;
}
}
}
 
 
###############################################
# Subroutine Definitions
#
 
sub solves {
my ($numbers, $ops, $goal) = @_;
 
my $sol = $numbers[-1];
 
while ( @$numbers > 1) {
my ($n1, $n2, $op) = (pop $numbers, pop $numbers, pop $ops);
push $numbers, $op->($n1, $n2);
 
$sol = $op->($sol, $n2, 'p');
}
 
my $guess = pop $numbers;
 
if ( abs( $guess - $goal ) < 0.001 ) {
return $sol;
} else {
return;
}
}
 
sub parse_ops {
my @parsed;
 
foreach my $op (@_) {
given ($op) {
when ('+') { push @parsed, $ops{'a+b'} };
when ('*') { push @parsed, $ops{'a*b'} };
when ('-') { push @parsed, $ops{'a-b'}, $ops{'b-a'} };
when ('/') { push @parsed, $ops{'a/b'}, $ops{'b/a'} };
}
}
return @parsed;
}
perms.rb
Ruby
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
require 'combinatorics'
 
numbers = %w[2 4 6 8]
ops = %w[* - + / ]
goal = 25
 
 
class Operation
def initialize(op, desc)
@op = op
@desc = desc
end
 
def call(n1, n2)
@op.call(n1, n2)
end
 
def desc(n1, n2)
@desc.call(n1, n2)
end
end
 
def solves(numbers, ops, goal)
way = numbers.last
 
while numbers.count > 1
n1, n2 = numbers.pop, numbers.pop
op = ops.pop
 
guess = op.call(n1, n2)
 
numbers.push(guess)
 
way = op.desc(way, n2)
end
 
return (numbers.first - goal).abs < 0.001 ? way : false
 
end
 
def parse_ops(ops)
parsed = []
ops.each do |op|
case op
when '+'
parsed.push(Operation.new(
lambda { |a, b| a.to_f + b.to_f },
lambda { |a, b| "(#{a} + #{b})"} ) )
 
when '*'
parsed.push(Operation.new(
lambda { |a, b| a.to_f * b.to_f },
lambda { |a, b| "(#{a} * #{b})"} ) )
 
when '-'
parsed.push(Operation.new(
lambda { |a, b| a.to_f - b.to_f },
lambda { |a, b| "(#{a} - #{b})"} ) )
parsed.push(Operation.new(
lambda { |a, b| b.to_f - a.to_f },
lambda { |a, b| "(#{b} - #{a})"} ) )
 
when '/'
parsed.push(Operation.new(
lambda { |a, b| a.to_f / b.to_f },
lambda { |a, b| "(#{a} / #{b})"} ) )
parsed.push(Operation.new(
lambda { |a, b| b.to_f / a.to_f },
lambda { |a, b| "(#{b} / #{a})"} ) )
end
end
return parsed
end
 
 
############################
 
parsed_ops = parse_ops(ops)
numbers.permute(numbers.count).each do |np|
parsed_ops.permute(parsed_ops.count).each do |op|
 
begin
sol = solves(np.clone, op.clone, goal)
if sol
puts "Sol = #{sol}"
exit
end
end
end
end
 
#############################

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.