aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2020-05-13 18:02:17 +0200
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2020-05-13 18:02:17 +0200
commit4393ea61d3e1d29924cbd193b902bca0082898b6 (patch)
treeb7dbf8dddd78cd0d6ff588926c80a1e80899f895
parenta81a9a4457e24869795c2bd6aa19199645e98b94 (diff)
downloadperlweeklychallenge-club-4393ea61d3e1d29924cbd193b902bca0082898b6.tar.gz
perlweeklychallenge-club-4393ea61d3e1d29924cbd193b902bca0082898b6.tar.bz2
perlweeklychallenge-club-4393ea61d3e1d29924cbd193b902bca0082898b6.zip
rename
-rwxr-xr-xchallenge-060/jo-37/perl/ch-1.pl56
1 files changed, 36 insertions, 20 deletions
diff --git a/challenge-060/jo-37/perl/ch-1.pl b/challenge-060/jo-37/perl/ch-1.pl
index f75023447c..e26be8cafa 100755
--- a/challenge-060/jo-37/perl/ch-1.pl
+++ b/challenge-060/jo-37/perl/ch-1.pl
@@ -1,37 +1,53 @@
#!/usr/bin/perl
-# Input: column number (>=1), output: excel column name
-# Input: excel column name ([A-Z]+), output: column number
+# Input: column numbers (>=1) or column labels ([A-Z]+),
+# output: column labels or column numbers
+# Without arguments, converts some example values
+
+# The numbering schema differs from the usual base(k) in the absence
+# of a digit "zero". I.e. there are digits for 1 .. k instead of
+# 0 .. (k -1). This results in the off-by-one modifications
+# from the known formulae
use strict;
use warnings;
use bigint;
+use constant BASE => 26;
-sub dectoxls {
- my $dec = $_[0] - 1;
- my @b26;
- while ($dec >= 0) {
- unshift @b26, chr(ord('A') + $dec % 26);
- $dec = $dec / 26 - 1;
+sub int2label {
+ my $int = $_[0] - 1;
+ my @label;
+ while ($int >= 0) {
+ unshift @label, chr(ord('A') + $int % BASE);
+ $int = $int / BASE - 1;
}
- return join '', @b26;
+ return join '', @label;
}
-sub xlstodec {
- my @b26 = split '', $_[0];
- my $dec = 0;
- for my $b26 (@b26) {
- $dec *= 26;
- $dec += ord($b26) - ord('A') + 1;
+sub label2int {
+ my @label = split '', $_[0];
+ my $int = 0;
+ for my $label (@label) {
+ $int *= BASE;
+ $int += ord($label) - ord('A') + 1;
}
- return $dec;
+ return $int;
+}
+
+# last digit for BASE
+my $last = chr(ord('A') + BASE - 1);
+
+# build example input data if none provided
+unless (@ARGV) {
+ @ARGV =
+ map {((BASE ** ($_ + 1) - 1)/(BASE - 1) - 1, $last x $_)} (1 .. 14);
}
-for ($ARGV[0]) {
+for (@ARGV) {
if (/^\d+$/) {
- print dectoxls($_), "\n";
- } elsif (/^[A-Z]+$/) {
- print xlstodec($_), "\n";
+ print "$_ -> ", int2label($_), "\n";
+ } elsif (/^[A-$last]+$/) {
+ print "$_ -> ", label2int($_), "\n";
} else {
print "input invalid: $_\n";
}