Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I improve this program to get 24 with 4 numbers?

Tags:

algorithm

perl

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;
}
like image 213
smilefoxzhu Avatar asked Feb 26 '23 14:02

smilefoxzhu


1 Answers

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

like image 56
DVK Avatar answered Mar 06 '23 16:03

DVK