我正在尝试解决一个代码高尔夫练习,其中涉及输入测试用例的数量,然后在每个测试用例的每行中输入一个整数。
在寻求尽可能短的解决方案时,我遇到了 this解决办法:
#!perl -lp
use bigint;$_=???<>+1:bnok{2*$_}$_
我是 Perl 新手,因此我不明白这段代码实际上是如何工作的。如果有人帮我解决这个问题,我将不胜感激。
最佳答案
有一些工具可以帮助您了解 Perl 高尔夫。一是perlsecret其中记录了许多 Perl 高尔夫球手使用的“ secret 运算符(operator)”和技巧。
对于这个特定的代码,了解 -p
does 的含义也很重要。 。它将代码包装在一堆其他代码中,然后可以将其用于打高尔夫球的目的。
最后,解压 Perl Golf 的终极工具是 B::Deparse 。这将 Perl 如何理解代码转回人类可读的带有缩进等的 Perl。 -p 选项使 B::Deparse 添加括号,即使它们不是必需的,这可以帮助澄清优先级。 -d 选项可以更准确地表示对象。什么对象?观察。
$ perl -MO=Deparse,-p,-d
#!perl -lp
use bigint;$_=???<>+1:bnok{2*$_}$_
Use of ?PATTERN? without explicit operator is deprecated at - line 2.
BEGIN { $/ = "\n"; $\ = "\n"; }
use bigint;
LINE: while (defined(($_ = <ARGV>))) {
chomp($_);
BEGIN {
$^H{'bigint'} = '1';
$^H{'binary'} = 'CODE(0x7fc88ba3d580)';
$^H{'float'} = 'CODE(0x7fc88ba3d478)';
$^H{'integer'} = 'CODE(0x7fc88b298428)';
}
($_ = (?? ? (<ARGV> + bless( {"sign" => "+","value" => [1]}, 'Math::BigInt' )) : (bnok {
(bless( {"sign" => "+","value" => [2]}, 'Math::BigInt' ) * $_)
} $_)));
}
continue {
(print($_) or die("-p destination: $!\n"));
}
- syntax OK
这揭示了一些更深奥的事情......
- >???是
?PATTERN?
运算符加上?:
三元运算符。具体来说,??
是三元的条件。 -
??
工作方式就像//
但它只会匹配一次,直到reset
叫做。由于在此程序中从未调用过重置,因此该程序只会匹配一次。//
会匹配任何东西。 -
use bigint
将所有整数转换为 Math::BigInt 对象。 -
bnok
是来自 Math::BigInt 的二项式系数法. -
bnok
被用作整数(实际上是 Math::BigInt 对象)的间接方法调用。间接方法调用的形式为method $object @args
所以bnok{2*$_}$_
实际上是(2*$_)->bnok($_)
这是 central binomial coefficient .
通过一些缩进和垂直空格,可以更容易地理解程序的核心内容。您只需要一个具有良好括号匹配的编辑器即可解决它们。
(
$_ =
(?? ? (<ARGV> + bless( {"sign" => "+","value" => [1]}, 'Math::BigInt' ))
: (bnok {(bless( {"sign" => "+","value" => [2]}, 'Math::BigInt' ) * $_) } $_)
)
);
- 因为
??
整个程序只会匹配一次,用于跳过第一行,即测试次数。 - 第一行之后,
??
将为 false,这将触发bnok
计算。
有一个细节我还没有弄清楚。这是为什么<>+1
而不是<>
?它似乎抑制了一个空行,但我不知道为什么。
关于regex - 了解这个 Perl 解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26792570/