The objective is to create a function that returns a string from an integer based on 1=A, 26=Z, 27=AA, 52=AZ, 53=AAA, etc.
My bloated attempt is below, but I know that a number of you wizards can do a lot better, even keeping the function producing correct results on up to 1000 and more. I am personally challenged with recursive functions which I think is the way to go.
(defun alpha (n / a) (cond ((<= n 26) (chr (+ 64 n))) ((< 26 n 52) (strcat "A" (chr (+ 64 (if (= (setq a (rem n 26)) 0) 1 a))))) ((= n 52) "AZ") ((< 52 n 78) (strcat "AA" (chr (+ 64 (if (= (setq a (rem n 26)) 0) 1 a))))) ("ZZZZZ") ;; Just a bail-out condition ) )
The winner will receive a personally autographed digital copy of my AARP card, if I can find it.
John F. Uhden
Solved! Go to Solution.
Solved by dbroad. Go to Solution.
Solved by dbroad. Go to Solution.
Around here, which has $milions of boats, the saying goes, "A boat is a hole in the water into which you pour money."
John F. Uhden
From my early days, where I had to make Autocad to connect to a DBASEIII database and needed a "autonumber" field I used this function to create a record with a uniquely indexed textnumber column. First record was constructed with "AAAAA" in it. Followed with "AAAAB" etc. As disk space then was an issue I preferred to have something in which large numbers could be stored in a very limited column width. The function would be called with an argument from an sql like "select max(autonum) from database"
The date on my computer for this file is 1-11-2011 but the original is older still... 1995 or there about
(defun chartel (term / i l maxim) (setq maxim "Z") (while (< (strlen maxim) (strlen term)) (setq maxim (strcat "Z" maxim)) ) (setq term (strcat (substr term 1 (- (strlen term) 1)) (chr (1+ (ascii (substr term (strlen term))))) ) l (strlen term) i (- l 1) ) (while (and (> (substr term (+ i 1) 1) "Z") (> i 0)) (setq term (strcat (substr term 1 (- i 1)) (chr (1+ (ascii (substr term i 1)))) "A" (if (= i (- l 1)) "" (substr term (+ i 2)) ) ) i (1- i) ) ) (if (>= maxim term) term) )
I hope this might still be useful within this discussion. although a good solution has already been accepted as the "winner"
BTW After I retired I lived in a "hole in the water" and sailed from Holland via Brazil to South Africa. I never poured money in it since I never had any...
Thank you for that clever contribution. Works as well as Owen Wengerd's str+ function. Actually better 'cause it handles both numerics and alphas.
"Holland via Brazil to South Africa?!" Magellan's got nothing on you. The furthest I've ever gone was in my brother's 34' ketch from Manasquan to the Chesapeake. We stayed in Atlantic City overnight and poured our money into the dealer's stack. We even flew the chute in a 25 knot wind in the ocean. Was a lot faster than his little engine could take us. I was thinking, "Hey, it's not MY mast." Though I've snapped a couple of them in my life.
John F. Uhden
Another one that I use to increment the alphanumeric.
It is near to (chartel) just the difference that it differentiates uppercase and lowercase.
(defun inc_txt (Txt / Boucle Val_Txt Ascii_Txt Decalage) (setq Boucle 1 Val_txt "" ) (while (<= Boucle (strlen Txt)) (setq Ascii_Txt (vl-string-elt Txt (- (strlen Txt) Boucle))) (if (not Decalage) (setq Ascii_Txt (1+ Ascii_Txt)) ) (if (or (= Ascii_Txt 58) (= Ascii_Txt 91) (= Ascii_Txt 123)) (setq Ascii_Txt (cond ((= Ascii_Txt 58) 48) ((= Ascii_Txt 91) 65) ((= Ascii_Txt 123) 97) ) Decalage nil ) (setq Decalage T) ) (setq Val_Txt (strcat (chr Ascii_Txt) Val_Txt)) (setq Boucle (1+ Boucle)) ) (if (not Decalage) (setq Val_Txt (strcat (cond ((< Ascii_Txt 58) "0") ((< Ascii_Txt 91) "A") ((< Ascii_Txt 123) "a") ) Val_Txt ) ) ) Val_Txt )
An impressed Uhden.... Wow...
Some comments though. Going back to the initial challenge:.
The objective is to create a function that returns a string from an integer based on 1=A, 26=Z, 27=AA, 52=AZ, 53=AAA, etc.
One could argue, that the definition of an integer allows for numbers that are huge, approaching infinity. To represent those huge integers we use symbols (characters) in the range of "0" to "9", ordered in the way we all know like "10" ,"11",...."19" ..etc. If I were to represent an integer like "88888888888888884444444444444488888888888888888888888888888888888888888888888888888866666666666666666666666666666888888888888888888888889999999999999999993333333444444444444444" the integer would exist and be a real number. What we read though is a string whose contents are limited to the characters "0" to "9" !
The challenge would be a real one if we were to represent above integer into a notation such as proposed above, and that includes PRINTABLE characters like ascii 33 to ascii 126. It would save a lot of paper if we were to print these integers.
So, John, Dough Broad, Kent Cooper and all others feel free to throw your talents to this one
BTW, in the function (chartel arg) there is the line
(setq maxim "Z")
Change "Z" to "z" and the function would return a valid value for a lot more unique records even if the start if the sequence would be only 3 or 4 characters long...
This all had to do with creating @Kyle.para's attribute autogeneration routine. He estimated that he woudn't need to go any higher than 50, so dealing with large values isn't necessary. But I love reading all the contributions. I have learned a lot and hope that others have as well.
John F. Uhden
Can't find what you're looking for? Ask the community or share your knowledge.