Skip to main content
2 of 2
added 300 characters in body
kglr
  • 400.5k
  • 18
  • 488
  • 929

Three variants of the idea in @Simon's answer using FixedPoint, NestWhile and ReplaceRepeated:

ClearAll[chrctrDgtsF1,chrctrDgtsF2,chrctrDgtsF3];

FixedPoint:

chrctrDgtsF1 =  Function[{n}, FromCharacterCode[65 + 
  FixedPoint[If[First[#] < 26, #, 
     Join[QuotientRemainder[First@#, 26] + {-1, 0},  Rest[#]]] &, {n}]]];

NestWhile:

chrctrDgtsF2 = Function[{n}, FromCharacterCode[65 +
  NestWhile[Join[QuotientRemainder[First@#, 26] + {-1, 0}, Rest[#]] &, {n}, 
    (First[#] >= 26 &)]]];

ReplaceRepeated:

chrctrDgtsF3 = FromCharacterCode[65 + ({#} //.
   {x_, y___} /; x >= 26 :> Flatten@{QuotientRemainder[x, 26] + {-1, 0}, y})] &;

Examples:

chrctrDgtsF1 /@ (10^Range[8])
(* {"K","CW","ALM","NTQ","EQXE","BDWGO","UVXWK","HJUNYW"} *)

(f /@ # == chrctrDgtsF1 /@ # == chrctrDgtsF2 /@ # == chrctrDgtsF3 /@ #) &@
    RandomInteger[10^9, {1000}]  
(* True *)
kglr
  • 400.5k
  • 18
  • 488
  • 929