aboutsummaryrefslogtreecommitdiff
path: root/challenge-002/ryan-thompson/perl5/ch-2.pl
blob: 6f67afd439ac42ee84a82216942063d0aecd4197 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/env perl
#
# ch-2.pl - Convert integers to and from base35
#
# 2019 Ryan Thompson <rjt@cpan.org>

use 5.010;
use warnings;
use strict;
no warnings 'uninitialized';

my @base35 = (0..9, 'a'..'y'); # Display representation
my %val; @val{@base35} = 0..34;

# Verification: Covert 20 random numbers to and from base35
printf "%8d => %8s => %8d\n", 
    $_, int_to_base35($_), base35_to_int(int_to_base35($_)) 
        for map { int rand(1e8) } 1..20;

sub int_to_base35 {
    my $int = shift;
    die "Expecting integer" unless $int =~ /^\d+$/;

    my $base35;
    while ($int) {
        $base35 = $base35[ $int % 35 ] . $base35;
        my $digit = $int % 35;
        $int = int($int / 35);
    }

    $base35 // 0;
}

sub base35_to_int {
    my $base35 = lc( shift );
    die "Expecting [0-9a-y]" unless $base35 =~ /^[0-9a-y]+$/;

    my $mul = 1; # Digits multiplier
    my $int = 0; # Result
    for (reverse split '', $base35) {
        $int += $mul * $val{$_};
        $mul *= 35;
    }

    $int;
}