I'm working with some alphabet coding where input is number which returns respective alphabet . Consider input is 3 it return C, for 5 its E and so on. If number is greater than 26 output changes to AA for 27, 28-AB, 29-AC
here is the code:
my $input = <>;
my @a = ("A".."B");
if($input <=26){
my $num1 = $input-1;
say $a[$num1];
}
elsif( $input <= 702 ){
#702 for ZZ
my $mod = $input % 26;
my $div = $input / 26;
my ($letter) = $div =~ /^(\d+)\./;
my $num1 = $div - 1;
my $num2 = $letter - 1;
say $a[$num1]$a[$num2];
}else{
# Here I stuck
# how to code for three or more letter combination?
}
for three letter combination any suggestions?
Update: input number can not be zero.
I wrote a full test suite because I found this surprisingly hard to get right.
You're converting from base 10 to base 26, but since 1 is A instead of 0, everything is shifted over 1. Dealing with that as early in the process as possible (ie. $number--) eliminates a lot of downstream mistakes.
#!/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;
}
The constants might seem silly, but it's the 21st century and there's a very good chance other character encodings will be a consideration. Although I doubt chr( $CHAR_BASE + $shift) will work out as neatly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With