Как я могу улучшить эту программу, чтобы получить 24 с 4 номерами? - PullRequest
4 голосов
/ 24 июля 2010

24 балла это маленькая игра. Вы должны использовать + - * /, чтобы получить результат 24 из 4 чисел. Я написал Perl-скрипт для решения этой проблемы. Но я чувствую, что мой код слишком длинный и выглядит как C.

Надеюсь, кто-нибудь может дать мне совет. Большое спасибо!

Возможны и другие языки, например, 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;
}

Ответы [ 2 ]

4 голосов
/ 24 июля 2010

Вы сформулировали вопрос так, как будто вы ищете советы по улучшению работающей программы. Но ваша программа не работает под use strict и use warnings, и, насколько я могу судить, не работает вообще. Даже метод perm не работает, генерируя как предупреждения, так и неверные результаты.

Прежде чем вы сможете создать даже простую программу, вы должны убедиться, что ваши строительные блоки прямые. Для начала нужно выяснить, как написать правильный perm метод, который будет работать в use strict и use warnings. Если ваша цель - решить эту головоломку самостоятельно, это здорово. В противном случае, ознакомьтесь с Perl FAQ, Как переставить N элементов списка ?

4 голосов
/ 24 июля 2010

ОК, два очка:

1) Вы сказали «улучшить».

Несмотря на то, что «гольф-код» «крут» и, если он изучен и правильно применен, помогает разработчику расширить свои знания и уловить нюансы и глубины выбранного языка, результирующий гольф-код, в общем, НЕ являетсяулучшение с точки зрения разработки программного обеспечения.

Хотя хороший, элегантный код часто приводит к более короткой программе, обратное не обязательно (или обычно) верно.Наличие более короткого кода, скорее всего, означает, что код труднее читать и труднее поддерживать, и эти два качества имеют первостепенное значение для хорошей разработки программного обеспечения.

2) Сказав это, Perl обеспечиваетмножество синтаксических средств и идиом, которые улучшают код, сокращая его как побочный эффект.Я попытаюсь указать на некоторые возможные изменения в вашем коде, которые, на мой взгляд, сделают его более идиоматичным, хотя и не обязательно более коротким.


СТАРЫЙ:

my @input_arr = ();
push @input_arr, @$arr_ref;

NEW:

my @input_arr = (@$arr_ref);

Объяснение: Вам не нужно объявлять массив и инициализировать его отдельно.


OLD:

if (scalar(@input_arr) <= 1) {

NEW:

if (@input_arr <= 1) {

Объяснение: Массивы в Perl, при оценке в скалярном контексте (который накладывает оператор числового сравнения, такой как <=), оценивают размер массива.Так что scalar() - это лишнее.


Больше будет добавлено позже - нужно запустить

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...