Skip to content

Instantly share code, notes, and snippets.

@chankeypathak
Created January 8, 2015 19:10
Show Gist options
  • Save chankeypathak/ea28741d0d44fa371ae7 to your computer and use it in GitHub Desktop.
Save chankeypathak/ea28741d0d44fa371ae7 to your computer and use it in GitHub Desktop.
3=C, 5 = E. If > 26 then 27=AA, 28=AB, 29=AC
#!/usr/bin/env perl
use v5.12;
use strict;
use warnings;
use Test::More;
my %tests = (
1 => "A",
1.0 => "A",
2 => "B",
25 => "Y",
26 => "Z",
27 => "AA",
52 => "AZ",
54 => "BB",
78 => "BZ",
(26**2 + 26) => "ZZ",
(26**2 + 26 + 1) => "AAA",
(26**3 + 26**2 + 26) => "ZZZ",
(26**3 + 26**2 + 26 + 1) => "AAAA",
);
for my $have (keys %tests) {
my $want = $tests{$have};
is to_letters($have), $want, "to_letters($have) -> $want";
}
for my $negative (0, -1, -100) {
ok !eval { to_letters($negative) }, "negative input $negative";
like $@, qr{^0 and less cannot be converted to letters};
}
for my $decimal (1.1, 2.001) {
ok !eval { to_letters($decimal) }, "decimal input $decimal";
like $@, qr{^Decimals cannot be converted to letters};
}
done_testing;
use Carp;
sub to_letters {
my $number = shift;
croak "0 and less cannot be converted to letters" if $number <= 0;
croak "Decimals cannot be converted to letters" if int $number != $number;
state $BASE = 26;
state $CHAR_BASE = 65;
my @letters;
while( $number > 0 ) {
$number--; # A is 1, not 0
my $shift = $number % $BASE;
unshift @letters, chr( $CHAR_BASE + $shift );
$number = int($number / $BASE);
}
return join '', @letters;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment