2014-11-07 94 views
3

我正在尝试解决代码高尔夫练习,其中涉及输入测试用例的数量,然后在每个测试用例的每行中输入一个整数。了解此perl解决方案

在我的追求,以获得尽可能短的解决方案,我整个this解决方案来:

#!perl -lp 
use bigint;$_=???<>+1:bnok{2*$_}$_ 

我很新的Perl,所以我没有得到如何代码是实际工作。如果有人帮我解决这个问题,我将不胜感激。

PS:Asked and closed at codegolf.stackexhange

回答

7

有几个工具可以用来计算Perl高尔夫。一个是perlsecret,它记录了许多Perl高尔夫球手使用的“秘密操作员”和技巧。

对于这个特定的代码,了解什么是-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对象。
  • bnokMath::BigInt的二项式系数法。
  • bnok被用作对整数(这实际上是Math :: BigInt对象)的间接方法调用。间接方法调用的格式为method $object @args,因此bnok{2*$_}$_实际上是(2*$_)->bnok($_),这是central binomial coefficient

程序的肉可以通过一些缩进和垂直空白来理解。一个有良好paren匹配的编辑是你需要解决的。

(
    $_ = 
     (?? ? (<ARGV> + bless({"sign" => "+","value" => [1]}, 'Math::BigInt')) 
      : (bnok {(bless({"sign" => "+","value" => [2]}, 'Math::BigInt') * $_) } $_) 
    ) 
); 
  • 因为??只会对整个程序匹配一次,它被用来跳过第一行是测试次数。
  • 第一行之后,??将是错误的,这将触发bnok计算。

有一个细节我还没有制定出来。为什么它<>+1而不是<>?它似乎压制了一条空白线路,但我不知道为什么。

+0

我大大扩展了我的答案,以揭示几乎完整的解决方案。 – Schwern 2014-11-07 19:51:36

+1

我想+1是用来提供标量上下文的。 – tripleee 2014-11-07 19:55:45