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;
+ }
+