#!/usr/bin/env perl6
use v6.c;
sub dragon-data(Str $seed, Int $length)
{
my $data = $seed;
while $data.chars < $length {
$data ~= '0' ~ $data.flip.trans('0'=>'1', '1'=>'0');
}
return $data.substr(0, $length);
}
sub checksum-orig(Str $data)
{
# Too slow for part 2
if $data.chars %% 2 {
return checksum($data.comb(/../).map({ $_ eq any('00','11') ?? '1' !! '0' }).join);
}
else {
return $data;
}
}
sub checksum(Str $data)
{
# We can consolidate the checksum process: instead of looking at 2 chars, we can look at any
# 2^n chars: if an even number of digits is 1, then 1, else 0.
my $pow-two = 1;
$pow-two *= 2 while $data.chars %% ($pow-two * 2);
say "$pow-two | $data.chars()";
if $pow-two > 1 {
return $data.comb.rotor($pow-two).map({ ([+] $_) %% 2 ?? '1' !! '0' }).join;
}
else {
return $data;
}
}
#| Fill disk with data seeded from input file
multi sub MAIN(IO() $inputfile where *.f, :$size=272)
{
my ($seed) = $inputfile.words;
MAIN($seed, :$size);
}
#| Fill disk with data seeded from command line
multi sub MAIN(Str $seed where !*.IO.f, :$size=272)
{
my $data = dragon-data($seed, $size);
say "Data: $data.chars() bits";
say 'Checksum: ', checksum($data);
}
Comments