LoginSignup
0
0

More than 5 years have passed since last update.

Advent of Code day10をPerl 6で

Last updated at Posted at 2017-12-22

こんにちは、16日目になります。

今日は特に投稿がなかったので、例によって私のAdvent of Code day10の回答を貼っておきます。

use v6;                                                                                             

my Int @length-list = $*IN.get.split(",")>>.Int;                                                              
my Int @circular-list = @(^256);                                                                    

my Int $mod = +@circular-list;                                                                      
my Int $current-pos = 0;                                                                            
my Int $skip = 0;                                                                                   

while @length-list {                                                                                          
    my $length = @length-list.shift;                                                                          
    @circular-list = reverse-partially(@circular-list, $current-pos, $length);                      
    $current-pos = ($current-pos + $length + $skip) % $mod;                                         
    $skip++;                                                                                        
}                                                                                                   

say [*] @circular-list[^2];                                                                         

sub reverse-partially(Int @circular-list, Int $current-pos, Int $length --> List) {                 
    my Int $mod = +@circular-list;                                                                  
    my Bool @visited;                                                                               
    my $last-pos = $current-pos;                                                                    
    my $first-pos = $current-pos;                                                                   

    my Int @med = do for $current-pos..^($current-pos + $length) {                                  
        $last-pos = $_ % $mod;                                                                      
        @visited[$last-pos] = True;                                                                 
        @circular-list[$last-pos]                                                                   
    }.reverse; # (#1)                                                                                     

    do for ^@circular-list {                                                                        
        do if @visited[$_] {                                                                        
            @med[$_ - $first-pos < 0 ?? (+@circular-list - $first-pos) + $_ !! $_ - $first-pos] # (#2)    
        } else {                                                                                    
            @circular-list[$_]                                                                      
        }                                                                                           
    }                                                                                               
}                                                                                                                                          
  • ポイント
    • do for $current-pos..^($current-pos + $length)でリバース対象の部分の位置を取ってくることができます(このそれぞれの位置は法をとる) (#1)
    • リバース済みのリストを格納した@medのローカルな位置と元々の@circular-listでのグローバルな位置との変換を行います。do-if節の中で書くと多少は可読性がましになると思います (#2)

以上16日目でした

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0