tracks/perl6/exercises/all-your-base/example.yaml in trackler-2.1.0.33 vs tracks/perl6/exercises/all-your-base/example.yaml in trackler-2.1.0.34

- old
+ new

@@ -2,13 +2,62 @@ version: 2 plan: 23 imports: '&convert-base' tests: | sub test ($case, $expected) { is-deeply &::('convert-base')(|$case<input_base input_digits output_base>), $expected, $case<description> } + for @($c-data<cases>) { when .<expected> ~~ Array { test $_, .<expected> } when .<description> ~~ /base|digit/ { throws-like {&::('convert-base')(|.<input_base input_digits output_base>)}, Exception, .<description> } when .<description> eq 'leading zeros' { test $_, [4,2] } when .<description> eq 'empty list' { test $_, [] } when .<description> ~~ /zero/ { test $_, [0] } default { flunk .<description> } # To ensure that no canonical-data cases are missed. } + +unit: module +example: | + class X::AllYourBase::InvalidBase is Exception { + has $.payload; + method message {"$!payload is not a valid base."} + } + + 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; + } + + sub from-decimal ($output-base, $dec) { + my @output-digits; + my $num = $dec; + while $num >= $output-base { + unshift @output-digits, $num % $output-base; + $num div= $output-base; + } + unshift @output-digits, $num; + return @output-digits; + } +