Convert integer to English
Given a nonnegative integer up to $999\,999\,999$, write it in English.
The input number can be in any form other than English (though you'll typically want to use the native integer type of your language).
The numbers must be formatted as follows:

Twodigit numbers must be written with dashes where applicable e.g.
twentyfive
, nottwenty five
. 
powers of ten start with “one”, e.g.
one hundred
, not justhundred
. 
The tens/ones part, if not zero, must be separated from the hundreds part with
and
, e.g.two hundred and five
, nottwo hundred five
. 
The above rules are applied also to the factors of thousand and million.

moreover the global tens/ones part has to be separated by
and
whenever anything larger is present, even if the hundreds part is missing. 
Adjacent words must be separated by a single space, or a single dash without space where applicable.

Leading and/or trailing spaces are not allowed. However, if the result is printed, a single trailing newline (not preceded by any spaces) is allowed.
Ungolfed reference implementation
Test cases:
0 zero
1 one
4 four
10 ten
16 sixteen
42 fortytwo
125 one hundred and twentyfive
1024 one thousand and twentyfour
1100 one thousand one hundred
12345 twelve thousand three hundred and fortyfive
1000000 one million
1000001 one million and one
7023000 seven million twentythree thousand
11012021 eleven million twelve thousand and twentyone
999999999 nine hundred and ninetynine million nine hundred and ninetynine thousand nine hundred and ninetynine
[Sclipting], (UTF16) 454 406 …
11mo ago
[Python 3], 399 bytes ``` …
11mo ago
[Python 3], 596 589 585 482 46 …
11mo ago
3 answers
Sclipting, (UTF16) 454 406 bytes
Yes.
塊匱❸곴김分倘標⓶❹演긆륩닆롩닶밎併鈉不終⓷곴김剩❶갾밈分倘⓷標⓷❺演긇끨닷녳눖멤併鈉⓶不終갾밈剩❶뉀分倘⓷標⓷❺演긆둵닦끲뉖밄併鈉⓶不終뉀剩⓶글會⓶倘❷長是긆굮뉂밀⓶終긇끨늗긠뉦뭵댢걦늖눠댶땸긇꽥덦녮긆녩뉶될닦땮뉐❷굀瀰是❶銅긂건덶녮融壹坼❸겠分掘덇밉⓸겠剩倘껐⓶⓹逆⓸終終긆뭮뉒건덶묠덆둲뉖넠뉦뭵댢걦늗뉥긇꽩뎂걳뉗뉥닢걥늖덨덂걮늖멥긇끥닢걥닆녶뉖먠덇덥닇뉥融壹坼❷掘⓶곀大是덆녥닠終不梴沒뎦녲닰終終終演
Explanation
塊 Function
匱 Begin with an empty list
❸곴김分倘 Divide number by 1,000,000; if quotient is nonzero:
標
⓶❹演 Apply function to the quotient (millions place)
긆륩닆롩닶밎 " million"
併 Concat
鈉 Add "... million" to the list
不終 End if
⓷곴김剩 Take modulo 1,000,000
Repeat the above for the thousands and hundreds
❶갾밈分倘
⓷標⓷❺演긇끨닷녳눖멤併鈉⓶
不終
갾밈剩
❶뉀分倘
⓷標⓷❺演긆둵닦끲뉖밄併鈉⓶
不終
뉀剩
Now for the tens/ones places
⓶글會⓶ Join the list with spaces (S)
倘 If there's stuff remaining (tens/units)
❷長是 If the length of (S) is nonzero
긆굮뉂밀 Push an " and "
⓶終 End if
긇끨늗긠뉦뭵댢걦늖눠댶땸긇꽥덦녮긆녩뉶될닦땮뉐
" thir four fif six seven eigh nine" (A)
This is shared between the teens and tys
❷굀瀰是 If greater than or equal to 20
❶ Copy the shared string
銅 drop the 9th character (four > for)
긂건덶녮 " twen"
融 Concatenate
壹坼 Split into a list
❸겠分 Divide by 10
掘 Index into the list
덇밉 Push "ty"
⓸겠剩 Take modulo 10
倘 If nonzero
껐⓶⓹ Push a dash ""
逆⓸終 End if
終
긆뭮뉒건덶묠덆둲뉖넠뉦뭵댢걦늗뉥긇꽩뎂걳뉗뉥닢걥늖덨덂걮늖멥긇끥닢걥닆녶뉖먠덇덥닇뉥
" one two three four five six seven eight nine ten eleven twelve"
融 Concatenate with the shared string (A)
壹坼 Split into a list
❷掘 Index into the list
⓶곀大是 If greater than 12
덆녥닠 Push "teen"
終 End if
不 Otherwise (if zero)
梴沒 If the length of (S) is zero
뎦녲닰 Push "zero"
終 End if
終 End if
終 End function
演 Call function
0 comment threads
The following users marked this post as Works for me:
User  Comment  Date 

General Sebast1an  (no comment)  Oct 6, 2021 at 02:49 
Python 3, 399 bytes
def f(n):
if n<1:return'zero'
t=1000;m=t*t;r='r fif six seven eigh nine ';b=f'one two three four five six seven eight nine ten eleven twelve thir fou{r}twen thir fo{r}'.split(' ');s=' '.join([f(k:=n//m)+' million'][:k]+[f(k:=(n:=n%m)//t)+' thousand'][:k]+[f(k:=(n:=n%t)//100)+' hundred'][:k]);n%=100;s+=' and '*(s*n>'')
if n>19:s+=b[n//10+17]+'ty'+''*((n:=n%10)>0)
return s+b[n1]+'teen'*(n>12)
0 comment threads
Python 3, 596 589 585 482 468 467 429 bytes
def f(x):
s="";i="r fif six seven eigh nine";a=f"zero one two three four five six seven eight nine ten eleven twelve thir fou{i} twen thir fo{i}".split();t=1000;c=t*t
if x>=c:s=f(x//c)+" million";x%=c
if x>=t:s+=" "*(s>"")+f(x//t)+" thousand";x%=t
if s*x:s+=" "
n=x>99
if n:s+=a[x//100]+" hundred";x%=100
if s*x:s+=" "*n+"and "
return x<20 and s+a[x]*(not(x<1)*s)+"teen"*(x>12)or s+a[x//10+18]+"ty"+(""+a[x%10])*(x%10>0)
Golfed 7 bytes thanks to @celtschk's advice. Golfed a massive 103 bytes thanks to @Moshi's advice. Golfed another 14 bytes thanks to @Moshi's advice. Golfed 38 bytes thanks to @celtschk's advice.
1 comment thread