24 points is small game. You must use +
-
*
/
to get the result 24 from 4 numbers. I wrote a Perl script to solve this problem. But I feel my code is too long and it looks like C.
I hope someone can give me some advice. Thank you very much!
Other language are possible, too, for example Python, Scala, F#, C++.
my @test_arr = (10, 4, 7, 6);
my @oprator_arr = ('+', '-', '*', '/');
rec_cala(\@test_arr);
sub rec_cala {
my ($arr_ref) = @_;
my @input_arr = ();
push @input_arr, @$arr_ref;
if (scalar(@input_arr) <= 1) {
$result = eval $input_arr[0];
if ($result > 23.9 && $result < 24.1) {
print $input_arr[0];
print " = 24\n";
}
} else {
my @perm_arr = perm(\@input_arr);
foreach (@perm_arr) {
my @next_arr = @$_;
my $op1 = pop @next_arr;
my $op2 = pop @next_arr;
foreach (@oprator_arr) {
@op_expr_arr = @next_arr;
push @op_expr_arr, "($op1 $_ $op2)";
rec_cala(\@op_expr_arr);
}
}
}
}
sub perm {
my ($arr_ref) = @_;
my @arr = @$arr_ref;
my @result = [];
while (scalar(@arr)) {
my $curr_element = pop @arr;
my @next_step = ();
foreach $curr_array (@result) {
$curr_len = scalar(@$curr_array);
for ($i = 0; $i <= $curr_len; $i++) {
push @next_step, [
(@$curr_array[0 .. $i], $curr_element, @$curr_array[$i + 1 .. $curr_len])
];
}
}
@result = @next_step;
}
return @result;
}
OK, two points:
1) You said "improve".
While code golf is "cool" and, if studied and applied properly, helps the developer increase their knowledge and grokking of the nuances and depths of the chosen language, the resulting golf code is, broadly speaking, NOT an improvement from software development point of view.
While good, elegant code often results in shorter program, the opposite is not necessarily (or usually) true. Merely having shorter code more likely than not means the code is harder to read and harder to maintain, and these two qualities are pretty much paramount as far as good software development.
2) Having said that, Perl does provide many syntactic facilities and idioms that achieve better code while shortening it as a side effect. I will try to point out some possible changes to your code that would make it more idiomatic in my opinion, though not necessarily shorter.
OLD:
my @input_arr = ();
push @input_arr, @$arr_ref;
NEW:
my @input_arr = (@$arr_ref);
Explanation: You don't need to declare an array and initialize it separately.
OLD:
if (scalar(@input_arr) <= 1) {
NEW:
if (@input_arr <= 1) {
Explanation: Arrays in Perl, when evaluated in scaalar context (which a numeric comparison operator like <=
imposes), evaluate to the size of array. So scalar()
is superfluous.
More to be added later - gotta run
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With