(PARI) /* Because names with ä, ö, ü or ß can't be entered directly as a string in the GP interface, we use a separate list for the names, for efficiency and readability of the main function. Note that the default lexicographical order is that of ISO 8859-1 character codes ("z" < "ß" < "ä"). In applications where this is not suitable, the special characters below can be replaced, e.g., with "ae, oe, ue, ss" or "a, o, u, s". [
M. F. Hasler, Jul 05 2024] */
{deutsch = ["eins", "zwei", "drei", "vier", Str("f"Strchr(252)"nf"), "sechs", "sieben", "acht", "neun", "zehn", "elf", Str("zw"Strchr(246)"lf"), "dreizehn", "vierzehn", Str("f"Strchr(252)"nfzehn"), "sechzehn", "siebzehn", "achtzehn", "neunzehn", "zwanzig", Str("drei"Strchr(223)"ig"), "vierzig", Str("f"Strchr(252)"nfzig"), "sechzig", "siebzig", "achtzig", "neunzig"]}
German(n, e="eins", power=0, name="")={ if(power /* internal helper function */
, n = divrem(n, power); Str(German(n[1], e) name, if(n[2], German(n[2]), ""))
, n < 20, if(n>1, deutsch[n], n, e, "null")
, n < 100, Str(if(n%10, Str(German(n%10, "ein") "und"), "") deutsch[n\10+18])
, n < 1000, German(n, "ein", 100, "hundert") \\ replace "ein" with "" to get
, n < 10^6, German(n, "ein", 1000, "tausend")\\ hundert/tausend without "ein-"
, my(t=3); while(n>=10^t, t+=3); German(n, "ein", 10^t-=3, strprintf(
if(n\10^t>1, " %sen", t%2, "e %se", "e %s") if(n%10^t, " ", ""),
Str(["M", "B", "Tr", "Quadr", "Quint", "Sext", "Sept", "Oct", "Non",
"Dez", "Undez" /* etc. */][t\6], "illi", ["on", "ard"][t%2+1])))
)} \\ updated Mar 03 2020, Apr 08 2023, Jul 05 2024
A007208(n) = vecsum([c>32|c<-Vecsmall(German(n))]) \\ To exclude spaces; irrelevant for n < 10^6. -
M. F. Hasler, Jul 05 2024