Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to write a function f.

example:

 f /@ Range[0, 52]

 (* ==> {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
   AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA} *)

f /@ (10^Range[8])

(* ==> {K,CW,ALM,NTQ,EQXE,BDWGO,UVXWK,HJUNYW} *)

How I do it?

share|improve this question
    
Look up FromCharacterCode, that should help you along the way. –  jVincent Oct 25 '12 at 9:48
1  
A few ways here stackoverflow.com/questions/4447550/… –  belisarius Oct 25 '12 at 12:08
add comment

3 Answers 3

up vote 9 down vote accepted

A version using recursion:

g[n_ /; n < 26] := {n}
g[n_] := {g[Quotient[n, 26] - 1], Mod[n, 26]}
f[n_] := FromCharacterCode[65 + Flatten[g[n]]]

f /@ (10^Range[8])

{"K", "CW", "ALM", "NTQ", "EQXE", "BDWGO", "UVXWK", "HJUNYW"}

share|improve this answer
add comment

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 *)
share|improve this answer
add comment

Edit 1 Thanks to Simon and whuber for pointing out that the original post contained an error. While the approach that I described yields the correct results for the test range, it produces wrong results for other ranges. For example, for Range[670, 680] the results are {"YU", "YV", "YW", "YX", "YY", "YZ", "A@A", "A@B", "A@C", "A@D", "A@E"}, which is clearly not as required.

Edit 2 As whuber points out, the problem with this base is that depending on the circumstances either a 0 or a 1 may correspond with A. For example, when the result of IntegerDigits[n, 26] is {1,0} the string should be AA.

I have adapted the function in such a way that all 0's are done away with, and 1 is set to always mean A. First I increment the input by 1, so the result for 0 becomes {1}, which equals A. Then all 0's which are not at the starting position are replaced by 26 while the preceding number is decremented by one. Then all 0 at the start of the list are simply removed.

This means that the previous result of "A@A" ({1,0,1}) becomes "ZA" ({26, 1}).

 j[n_] := FromCharacterCode[64 + (IntegerDigits[n + 1, 26]
          //. {
                  {s___, p_, 0, r___} -> {s, p - 1, 26, r},
                  {0, r___} -> {r}
          })]

I have validated the results with the method of Simon up to 10^6.

Original post This uses IntegerDigits with base 26 and a correction for the last digit:

FromCharacterCode[64 + (IntegerDigits[#, 26] /. {m___, n_} -> {m, n + 1})] & /@ (10^Range[8])
(* {"K", "CW", "ALM", "NTQ", "EQXE", "BDWGO", "UVXWK", "HJUNYW"} *)
share|improve this answer
3  
Nice code, but it gives A@A instead of ZA for an input value of 676 –  Simon Woods Oct 25 '12 at 20:06
2  
This is a great idea, but implementing it is a little trickier than it may look: although this looks like a base 26 code, the correction for the last digit is not what you would expect. The roles of the digits 'a' through 'z' are different in the units place than elsewhere. In the units place, 'a' is a zero, whereas elsewhere, 'a' is a one and the role of zero is played by a blank. This makes it a combination of a base 26 and a base 27 code. –  whuber Oct 25 '12 at 20:26
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.