tracks/perl6/exercises/all-your-base/example.yaml in trackler-2.2.1.65 vs tracks/perl6/exercises/all-your-base/example.yaml in trackler-2.2.1.66

- old
+ new

@@ -1,73 +1,53 @@ exercise: AllYourBase -version: 2 +version: 3 plan: 23 imports: '&convert-base' tests: |- + for $c-data<cases>.values -> $case { + sub call-convert-base { + convert-base( + bases => %(<from to> Z=> .<input_base output_base>), + digits => .<input_digits>, + ) given $case; + } - for @($c-data<cases>) -> $case { - if $case<expected> ~~ Array:D { test } - else { - given $case<description> { - when 'empty list' { test [] } - when /base|digit/ { throws-like {call-convert-base}, Exception, $_ } - when /zero/ { - when 'leading zeros' { test [4,2] } - default { test [0] } - } - flunk "$_; not tested" if %*ENV<EXERCISM>; # To ensure that no canonical-data cases are missed. + given $case { + if .<expected><error> { + throws-like {call-convert-base}, Exception, .<description>; } + else { + cmp-ok call-convert-base, ‘~~’, |.<expected description>; + } } - - sub test (Array:D $expected = $case<expected>) { - is-deeply call-convert-base, $expected, $case<description> - } - - sub call-convert-base { convert-base(|$case<input_base input_digits output_base>) } } unit: module example: |- - class X::AllYourBase::InvalidBase is Exception { - has $.payload; - method message {"$!payload is not a valid base."} + sub convert-base ( + :%bases! where all(.keys ~~ <from to>.Set, .values.all > 1), + :@digits! where %bases<from> > .all ~~ UInt:D, + --> Array[UInt:D] + ) is export { + from-decimal %bases<to>, to-decimal(%bases<from>, @digits); } - class X::AllYourBase::InvalidDigit is Exception { - has %.payload; - method message {"%!payload<digit> is not a valid digit for base %!payload<base>."} - } - - sub convert-base (Int:D $input-base, @input-digits, Int:D $output-base --> Array:D) is export { - for $input-base, $output-base { - X::AllYourBase::InvalidBase.new(payload => $_).throw if $_ < 2; - } - from-decimal($output-base, (to-decimal $input-base, @input-digits)); - } - sub to-decimal ($input-base, @input-digits) { - return [].Slip if !@input-digits; my $elems = @input-digits.elems; - for @input-digits { - if $_ == 0 { $elems-- } - else { last } - } - my $dec = 0; - loop (my $i = 0; $i < $elems; $i++) { - if @input-digits.reverse[$i] < 0 || @input-digits.reverse[$i] >= $input-base { - X::AllYourBase::InvalidDigit.new( :payload(base => $input-base, digit => @input-digits.reverse[$i]) ).throw; - } - $dec += @input-digits.reverse[$i] * $input-base ** $i; - } - return $dec; + $_ == 0 ?? $elems-- !! last for @input-digits; + (loop (my $i = 0; $i < $elems; $i++) { + @input-digits.reverse[$i] * $input-base ** $i; + }).sum; } - sub from-decimal ($output-base, $dec) { - my @output-digits; - my $num = $dec; + sub from-decimal ($output-base, $num is copy) { + my UInt:D @output-digits; while $num >= $output-base { unshift @output-digits, $num % $output-base; $num div= $output-base; } - unshift @output-digits, $num; - return @output-digits; + @output-digits.unshift: $num; + } + +stub: |- + sub convert-base (:%bases!, :@digits!) is export { }