Skip to main content
added 928 characters in body
Source Link
lericr
  • 34.1k
  • 2
  • 22
  • 78

Updated answer

The problem I was struggling with when trying to use IntegerDigits was that the leading digit for any number in "normal form" can never be zero. The fancy Mod stuff couldn't correct for that, because no matter the modulus, there are only 25 options for the leading digit. There is a padding option for IntegerDigits, but ultimately just "manually" correcting the problem (see ModStep) was simpler. I've been staring at letter sequences long enough now that my eyes may have glossed over, so there may still be an error, but I don't see it if it's there.

IntToLetterSequence[n_Integer?Positive] := 
  StringJoin@Part[Alphabet[], Rest@FixedPoint[ModStep, {n}]];
ModStep[{d_, 0, ds___}] := {d - 1, 26, ds};
ModStep[ds : {0, __}] := ds;
ModStep[ds : {d_, ___}] := 
  ReplacePart[ds, 1 -> Splice[QuotientRemainder[d, 26]]]

Original answer didn't rollover correctly

I'd write a function like this:

ModulusLetter[n_Integer?(GreaterThan[26])] := 
  StringJoin[Part[Alphabet[], 1 + MapAt[# - 1 &, IntegerDigits[n - 1, 26], 1]]];
ModulusLetter[n_Integer?Positive] := Alphabet[][[n]]

It's a bit messy, because the "modulus" of the first character is different than the subsequent characters. Might be a more elegant way with Mod or QuotientRemainder or something.

I'd write a function like this:

ModulusLetter[n_Integer?(GreaterThan[26])] := 
  StringJoin[Part[Alphabet[], 1 + MapAt[# - 1 &, IntegerDigits[n - 1, 26], 1]]];
ModulusLetter[n_Integer?Positive] := Alphabet[][[n]]

It's a bit messy, because the "modulus" of the first character is different than the subsequent characters. Might be a more elegant way with Mod or QuotientRemainder or something.

Updated answer

The problem I was struggling with when trying to use IntegerDigits was that the leading digit for any number in "normal form" can never be zero. The fancy Mod stuff couldn't correct for that, because no matter the modulus, there are only 25 options for the leading digit. There is a padding option for IntegerDigits, but ultimately just "manually" correcting the problem (see ModStep) was simpler. I've been staring at letter sequences long enough now that my eyes may have glossed over, so there may still be an error, but I don't see it if it's there.

IntToLetterSequence[n_Integer?Positive] := 
  StringJoin@Part[Alphabet[], Rest@FixedPoint[ModStep, {n}]];
ModStep[{d_, 0, ds___}] := {d - 1, 26, ds};
ModStep[ds : {0, __}] := ds;
ModStep[ds : {d_, ___}] := 
  ReplacePart[ds, 1 -> Splice[QuotientRemainder[d, 26]]]

Original answer didn't rollover correctly

I'd write a function like this:

ModulusLetter[n_Integer?(GreaterThan[26])] := 
  StringJoin[Part[Alphabet[], 1 + MapAt[# - 1 &, IntegerDigits[n - 1, 26], 1]]];
ModulusLetter[n_Integer?Positive] := Alphabet[][[n]]

It's a bit messy, because the "modulus" of the first character is different than the subsequent characters. Might be a more elegant way with Mod or QuotientRemainder or something.

Source Link
lericr
  • 34.1k
  • 2
  • 22
  • 78

I'd write a function like this:

ModulusLetter[n_Integer?(GreaterThan[26])] := 
  StringJoin[Part[Alphabet[], 1 + MapAt[# - 1 &, IntegerDigits[n - 1, 26], 1]]];
ModulusLetter[n_Integer?Positive] := Alphabet[][[n]]

It's a bit messy, because the "modulus" of the first character is different than the subsequent characters. Might be a more elegant way with Mod or QuotientRemainder or something.